Essentially, what I'm hoping to achieve is a canvas based web interface to control an Arduino, via a Raspberry Pi. The use case is that a user navigates to raspberrypi:8080
which displays a canvas. Then upon moving a slider, a websocket message is sent to the Tornado server on the Raspberry Pi. Tornado then sends a serial message to the Arduino which changes the RGB value of an LED. So far so good, I've been able to do this with the help of the documentation by a developer, Raspberry Pi Android HTML5 Realtime Servo Control.
However, the communication is only one-way from Raspberry Pi to Arduino. I'd like Tornado to also monitor the serial port to get any sensor data back to the front-end. Here's where I'm unsure about how to proceed. I was able to accomplish something like this using Node.js, which monitors for both websocket messages as well as serial messages asynchronously.
Should an asynchronous process be spawned which constantly monitors the port? I've seen a couple of options for this sort of solution.
tornado.gen.Task
, but for single HTTP requests, not for constant serial data.tornado.ioloop.PeriodicCallback
which I could set up to check for serial data every millisecond, but that sounds like a lot of overhead.Or should I set up a separate Python application which monitors serial and then communicates to the Tornado application on something it can understand like the following?
So there are lots of options... What are some recommendations and some reasons to try out or avoid any of the above options?
Here's what I have and need to add serial monitoring to:
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web
import tornado.websocket
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)
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)
]
)
httpServer = tornado.httpserver.HTTPServer(app)
httpServer.listen(options.port)
print "Listening on port:", options.port
tornado.ioloop.IOLoop.instance().start()
I have figured out a solution that involves using Python's multiprocessing library. I just wrote up a detailed blog post about it:
Raspberry Pi + Tornado + Arduino
Hope others find it useful...