2013-01-06 11 views
16

In sostanza, quello che spero di ottenere è un'interfaccia web su tela per controllare un Arduino, tramite un Raspberry Pi. Il use case è che un utente si sposta su raspberrypi:8080 che visualizza un'area di disegno. Quindi, spostando un cursore, viene inviato un messaggio Websocket al server Tornado sul Raspberry Pi. Tornado invia quindi un messaggio seriale all'Arduino che modifica il valore RGB di uno LED. Fin qui tutto bene, sono stato in grado di farlo con l'aiuto della documentazione di uno sviluppatore, Raspberry Pi Android HTML5 Realtime Servo Control.Tornado su Raspberry Pi per utilizzare websockets e monitor seriale porta comunicazione Arduino

Tuttavia, la comunicazione è solo a senso unico da Raspberry Pi a Arduino. Vorrei che Tornado monitorasse anche la porta seriale per riportare i dati dei sensori sul front-end. Ecco dove non sono sicuro su come procedere. Sono stato in grado di realizzare qualcosa di simile usando Node.js, che controlla sia i messaggi websocket che i messaggi seriali in modo asincrono.

È necessario generare un processo asincrono che monitora costantemente la porta? Ho visto un paio di opzioni per questo tipo di soluzione.

  1. Alcune persone suggeriscono tornado.gen.Task, ma per richieste HTTP singole, non per dati seriali costanti.
  2. tornado.ioloop.PeriodicCallback che potrei impostare per controllare i dati seriali ogni millisecondo, ma che suona come un sacco di spese generali.
  3. Ho anche visto strumenti separati come Swirl. (Swirl è aggiornato in base alle it's Github repo)

o devo impostare un Python un'applicazione separata che controlla serie e poi comunica all'applicazione Tornado su qualcosa si può capire come la seguente?

  1. messaggi websocket utilizzando un websocket client
  2. ZeroMQ (esempio di funzionamento: pyzmq/examples/eventloop/web.py)

quindi ci sono un sacco di opzioni ... Quali sono alcune raccomandazioni e alcuni motivi per provare o evitare una delle opzioni di cui sopra?

Ecco quello che ho e bisogno di aggiungere il monitoraggio di serie a:

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() 
+0

+1 per la bella idea! – Rafa

risposta

10

Ho trovato una soluzione che implica l'utilizzo della libreria di multiprocessing di Python.Ho appena scritto un post dettagliato blog su di esso:

Raspberry Pi + Tornado + Arduino

spero che altri lo trovano utile ...

+1

Il tuo link è morto:/ – Outpox

+0

Ecco una copia di archive.org http://web.archive.org/web/20160521032515/http://niltoid.com/blog/raspberry-pi-arduino-tornado/ –

0

Qui ci sono i miei 2 centesimi. Vorrei sostenere per il percorso Python -> websockets-client. Il software del server Tornado è realizzato e ottimizzato per gestire le richieste dei client Web. Lascia che faccia sia un lavoro. Qualsiasi tentativo di caricarlo in un altro ruolo (come il monitoraggio dell'hardware locale) causerà più sovraccarico di qualcosa che è (a) progettato per svolgere tale lavoro (come un programma C/C++) o (b) abbastanza flessibile da gestire un compito simile con un sovraccarico abbastanza piccolo (come uno script Python).

Esperienza pertinente: programmato sia per Raspberry Pi che per Arduino. Ufficiale nel club di robotica locale.

+0

Grazie per il suggerimento. Sono d'accordo che è meglio mantenere la COM seriale in un programma separato. Vedi la mia soluzione finale nella risposta se sei curioso. – niltoid