简体   繁体   English

Python龙卷风停止功能

[英]Python tornado stop function

I've got a tornado web server running on my Raspberry and a ultrasonic sensor connected to it. 我在Raspberry上运行了一个龙卷风Web服务器,并连接了一个超声波传感器。 I've got a html page with a start and stop button, when I click start the script is sending a message "start" to the serwer and it runs a function that prints the distance. 我有一个带有“开始”和“停止”按钮的html页面,当我单击“开始”时,脚本会向服务器发送一条“开始”消息,并运行一个打印距离的函数。

Now i'm trying to stop the function when clicking stop button. 现在,我试图在单击停止按钮时停止该功能。 But when te function is printing the distances and I click the stop button on my website the server doesnt recive the "stop" message. 但是当功能正在打印距离时,当我单击网站上的停止按钮时,服务器不会收到“停止”消息。

在此处输入图片说明

The code is here: http://pastebin.com/SVRZNXgH 代码在这里: http : //pastebin.com/SVRZNXgH

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
import time
import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BOARD)

# Ta funkcja dokonuje pomiaru odleglosci
def pomiar():
  # Ustawienie pinow czujnika odleglosci
  GPIO_TRIGGER = 16
  GPIO_ECHO    = 18

  # Ustawienie pinu buzzera
  GPIO_BUZZER = 22

  # Ustawienie pinu serwomechanizmu
  GPIO_SERVO = 13

  # Ustawienie pinow
  GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
  GPIO.setup(GPIO_ECHO,GPIO.IN)
  GPIO.setup(GPIO_SERVO,GPIO.OUT)

  # Ustawienie Trigget jako false (stan niski)
  GPIO.output(GPIO_TRIGGER, False)

  GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
  GPIO.output(GPIO_TRIGGER, True)

  time.sleep(0.00001)
  GPIO.output(GPIO_TRIGGER, False)
  start = time.time()

  while GPIO.input(GPIO_ECHO)==0:
    start = time.time()

  while GPIO.input(GPIO_ECHO)==1:
    stop = time.time()

  elapsed = stop-start
  distance = (elapsed * 34300)/2
  print "odleglosc :  %.1f" % distance
  time.sleep(2)

  return distance

# Funkcja dokonujaca sprawdzenia kata
def sprawdz_kat():
  GPIO_SERVO = 13
  GPIO.setup(GPIO_SERVO,GPIO.OUT)
  p = GPIO.PWM(GPIO_SERVO,50)

  katy = [10,12.5,5,2.5];
  start = 20.0;
  for x in katy:
      p.ChangeDutyCycle(x)
      time.sleep(0.5)
      odleglosc = pomiar()
      print "odleglosc :  %.1f" % odleglosc
      if(odleglosc>start):
          start=odleglosc
          kat = x
  if(kat==10):        
      return float(-45)
  if(kat==12.5):
      return float(-90)
  if(kat==5):
      return float(45)
  if(kat==2.5):
      return float(90)

# Funkcja do obrotu robota o zadany kat   
def obrot(kat):
  obrot=abs(kat/100)
  print(obrot)
  if(kat<0):
      GPIO.output(M1_EN, True) # True - do przodu, False - do tylu
      GPIO.output(M2_EN, True) # False - do przodu, True - do tylu
  else:
      GPIO.output(M1_EN, False) # True - do przodu, False - do tylu
      GPIO.output(M2_EN, False) # False - do przodu, True - do tylu
  LEWA_PWM.ChangeDutyCycle(25)
  PRAWA_PWM.ChangeDutyCycle(25)
  time.sleep(obrot)
  LEWA_PWM.ChangeDutyCycle(0)
  PRAWA_PWM.ChangeDutyCycle(0)
  GPIO.output(M1_EN, True)
  GPIO.output(M2_EN, False)   

# Program labiryntu
def labirynt():
  distance = pomiar()
  p.start(7.5)
  while True:
    distance = pomiar()
    GPIO.setup(GPIO_BUZZER,GPIO.OUT)
    GPIO.output(GPIO_BUZZER, False)
    time.sleep(0.08)
    GPIO.setup(GPIO_BUZZER,GPIO.IN)
    time.sleep(distance/500)
    LEWA_PWM.ChangeDutyCycle(10)
    PRAWA_PWM.ChangeDutyCycle(10)
    if(distance<50):
      LEWA_PWM.ChangeDutyCycle(0)
      PRAWA_PWM.ChangeDutyCycle(0)
      kat = sprawdz_kat()
      print kat
      obrot(kat)
      p.ChangeDutyCycle(7.5)
      time.sleep(0.5)
    GPIO.setup(GPIO_SERVO,GPIO.IN)
  GPIO.cleanup  

def stop_all():
  GPIO.output(GPIO_TRIGGER, False)
  GPIO.output(GPIO_ECHO, False)
  GPIO.cleanup()

# Ustawienie pinow czujnika odleglosci
GPIO_TRIGGER = 16
GPIO_ECHO    = 18

# Ustawienie pinu buzzera
GPIO_BUZZER = 22

# Ustawienie pinu serwomechanizmu
GPIO_SERVO = 13

# Ustawienie pinow
GPIO.setup(GPIO_TRIGGER,GPIO.OUT)
GPIO.setup(GPIO_ECHO,GPIO.IN)
GPIO.setup(GPIO_SERVO,GPIO.OUT)

# Ustawienie Trigget jako false (stan niski)
GPIO.output(GPIO_TRIGGER, False)

# Ustawienia dla serwa
p = GPIO.PWM(GPIO_SERVO,50) #Ustawienie czestotliwosci na 50Hz
 #poczatkowy kat serwa 90 stopni (neutralny)

# Ustawienia buzzera
GPIO.setup(GPIO_BUZZER,GPIO.IN)  

# -----------------------
# Ustawienia silnikow
# -----------------------

# Prawa strona
M1_PWM = 26
M1_EN = 24

# Lewa strona
M2_PWM = 23
M2_EN = 21

# Prawa strona ustawienia jako output
GPIO.setup(M1_PWM,GPIO.OUT)
GPIO.setup(M1_EN,GPIO.OUT)

# Lewa strona ustawienia jako output
GPIO.setup(M2_PWM,GPIO.OUT)
GPIO.setup(M2_EN,GPIO.OUT)

# Prawa strona ustawienie stanow niskich
GPIO.output(M1_PWM, False)
GPIO.output(M1_EN, True) # True - do przodu, False - do tylu

# Lewa strona ustawienie stanow niskich
GPIO.output(M2_PWM, False)
GPIO.output(M2_EN, False) # False - do przodu, True - do tylu

# Ustawienie PWM dla prawej strony
PRAWA_PWM = GPIO.PWM(26,50)

# Ustawienie PWM dla lewej strony
LEWA_PWM = GPIO.PWM(23,50)

# Poczatkowe ustawienia PWM silnikow
PRAWA_PWM.start(0)
LEWA_PWM.start(0)



from tornado.options import define, options
define("port", default=8080, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.render('index.html')

class WebSocketHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print 'new connection'
        self.write_message("connected")

    def on_message(self, message):
        print 'message received %s' % message
        self.write_message('message received %s' % message)
        aaa = message
        if message == "gora":
          GPIO.output(M1_EN, True)
          GPIO.output(M2_EN, False)
          LEWA_PWM.ChangeDutyCycle(8)
          PRAWA_PWM.ChangeDutyCycle(8)
        if message == "dol":
          GPIO.output(M1_EN, False)
          GPIO.output(M2_EN, True)
          LEWA_PWM.ChangeDutyCycle(8)
          PRAWA_PWM.ChangeDutyCycle(8)
        if message == "stop":
          LEWA_PWM.ChangeDutyCycle(0)
          PRAWA_PWM.ChangeDutyCycle(0)
        if message == "lewo":
          GPIO.output(M1_EN, True)
          GPIO.output(M2_EN, True)
          LEWA_PWM.ChangeDutyCycle(20)
          PRAWA_PWM.ChangeDutyCycle(20)
        if message == "prawo":
          GPIO.output(M1_EN, False)
          GPIO.output(M2_EN, False)
          LEWA_PWM.ChangeDutyCycle(20)
          PRAWA_PWM.ChangeDutyCycle(20)
        while (aaa == "start_maze"):
          pomiar()
    def on_close(self):
        print 'connection closed'

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(
        handlers=[
            (r"/", IndexHandler),
            (r"/ws", WebSocketHandler),
            (r'/js/(.*)', tornado.web.StaticFileHandler, {'path': "/home/pi/js"}),
            (r'/css/(.*)', tornado.web.StaticFileHandler, {'path': "/home/pi/css"}),
            (r'/fonts/(.*)', tornado.web.StaticFileHandler, {'path': "/home/pi/fonts"}),
        ]
    )
    httpServer = tornado.httpserver.HTTPServer(app)
    httpServer.listen(options.port)
    print "Listening on port:", options.port
    tornado.ioloop.IOLoop.instance().start()

The reason is that you got an endless loop in line 227. 原因是您在第227行出现了一个无限循环。

One possible solution: 一种可能的解决方案:

  1. Make your pomiar function a method of the websocket handler 使您的pomiar函数成为websocket处理程序的方法
  2. Use a variable on your websocket handler self.running and on start set it to true. 在websocket处理程序self.running上使用变量,并在启动时将其设置为true。 And call self.pomiar() 并调用self.pomiar()
  3. On stop just set self.running to false 停止时将self.running设置为false
  4. At the end of pomiar remove the time.sleep it does block the complete tornado server. 在结束pomiar删除time.sleep它阻止完整的龙卷风服务器。 Instead: 代替:

... ...

if self.running:
    tornado.ioloop.IOLoop.instance().add_timeout(time.time() + 2, self.pomiar)

The add_timeout makes tornado call your pomiar function again in two seconds. add_timeout使龙卷风在两秒钟内再次调用您的pomiar函数。 Checking first if self.running is still true makes sure your pomiar function is only called as long as stop is not called. 首先检查self.running是否仍然为true ,以确保仅在未调用stop的情况下才调用pomiar函数。

There are a lot of other ways to solve this. 还有很多其他方法可以解决此问题。 You might want to read more about tornado and the asynchronous functions it provides, for example: http://tornado.readthedocs.org/en/latest/gen.html 您可能需要阅读有关龙卷风及其提供的异步功能的更多信息,例如: http : //tornado.readthedocs.org/en/latest/gen.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM