所以我编写了一个Web界面来与Arduino Uno交互,使用cherrypy和pyserial。它非常完整,我唯一缺少的,而且我一直试图找出一天,就是不断读取Arduino发送的数据,并自动显示包含html代码中的消息的div。我可以在控制台中显示它,但我无法返回实际的html。事实上,我无法使用return,我必须使用print,这不方便,因为我想要html页面中的数据,而不是控制台。 我已经尝试了很多方法来做到这一点。
这是我的代码,非常简单。常量函数继续读取从Arduino发送的数据,并将其发送到控制台。我希望它将它发送到html代码,就像实时更新一样。我该怎么做?
# -*- coding: Utf-8 -*-
import cherrypy, arduino, time, threading
ser=arduino.Serial('COM4', 9600)
def constant():
while True:
m=''
print('running')
while True:
print('sub_running')
byte=(ser.read().encode('Utf-8'))
if byte=='*':
break
m=m+byte
time.sleep(1)
print(m)
time.sleep(1)
class website(object):
def index(self):
return '''
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script><script src="annexes/functions.js"></script>
<link rel=stylesheet type=text/css media=screen href="/annexes/design.css">
<form action="command" method="POST">
<input type="submit" name="command" value="Turn the LED on" text="hey"/>
<input type="submit" name="command" value="Turn the LED off"/>
</form>
'''
index.exposed=True
def command(self, command):
m=''
if command=='Turn the LED on':
ser.write('1')
if command=='Turn the LED off':
ser.write('0')
self.index
command.exposed=True
_thread = threading.Thread(target=constant)
_thread.setDaemon(True)
_thread.start()
cherrypy.quickstart(website(), config='config.conf')
答案 0 :(得分:0)
让它做你想做的事你有两个选择:
但我认为您的问题的核心与如何将线程函数中的值发送到您的网站类有关。您需要使用Queue.Queue
:
这些示例显示了如何使用cherrypy进行长轮询请求。
在以下示例中,您将错过this site上提供的jsonyield
装饰器,这是了解樱桃和长轮询的好方法。
# -*- coding: utf-8 -*-
import cherrypy, arduino, time, threading
import Queue
def serialWatcher(ser, queue):
while True:
m=''
print('running')
while True:
print('sub_running')
byte=(ser.read().encode('Utf-8'))
if byte=='*':
break
m=m+byte
time.sleep(1)
queue.put(m)
time.sleep(1)
class website(object):
def __init__(self, ser, queue):
self.serial = ser
self.queue = queue
# it's often better to use decorators when you can
@cherrypy.expose
def index(self):
return '''
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js" ></script><script src="annexes/functions.js"></script>
<link rel=stylesheet type=text/css media=screen href="/annexes/design.css">
<form action="command" method="POST">
<input type="submit" name="command" value="Turn the LED on" text="hey"/>
<input type="submit" name="command" value="Turn the LED off"/>
</form>
'''
@cherrypy.expose
def command(self, command):
m=''
if command=='Turn the LED on':
self.serial.write('1')
if command=='Turn the LED off':
self.serial.write('0')
return self.index() # I assume that's what you wanted to write
@cherrypy.expose
@json_yield
def get_arduino_results(self):
"""you can get the result of this long polling request using a JS AJAX query"""
while True:
while not self.queue.empty():
yield self.queue.get()
# always use the following, so you can also use the module you're writing as imports
# in other modules
if __name__ == "__main__":
q = Queue.Queue()
# Never use global variables, always pass them as parameters
ser = arduino.Serial('COM4', 9600)
_thread = threading.Thread(target=serialWatcher, args=(ser, q))
_thread.setDaemon(True)
_thread.start()
cherrypy.quickstart(website(ser, q), config='config.conf')
but the same principle would work for a standard page, something like:
@cherrypy.expose
get_arduino_results(self):
out = "<ul>"
while not self.queue.empty():
out += "<li>" + self.queue.get() + "</li>"
return out + "</ul>
使用Queue
的整个想法是,在你的arduino观看线程和cherrypy线程之间交换信息时,你不会冒险遇到线程问题。队列是线程安全的,并且同步读/写以使它们按顺序排列,并且一次一个线程。
HTH