# # #toenado +websocket+ to achieve:
1.index.html
<! DOCTYPE html>
2.main.js
$ (document). Ready (function () {var received = $ (' #received '); var socket = new WebSocket ("Ws://localhost:8080/ws"); Socket.onopen = function () { Console.log ("Connected");}; socket.onmessage = function (message) { Console.log (" Receiving: "+ message.data); Received.append (message.data); Received.append ($ (' <br/> '));}; Socket.onclose = function () { Console.log ("Disconnected");}; var sendMessage = function (message) { Console.log ("Sending:" + message.data); Socket.send (message.data);};/ /GUI stuff//send a command to the serial port$ ("#cmd_send"). Click (function (EV) { ev.preventdefault (); var cmd = $ (' #cmd_value '). Val (); SendMessage ({' Data ': cmd}); $ (' #cmd_value '). Val ("");}); $ (' #clear '). Click (function () { received.empty ();});});
3.serialworker.py
Import serialimport Timeimport multiprocessing## change this to match your local settingsserial_port = '/dev/ttyacm0 ' seria L_baudrate = 115200class serialprocess (multiprocessing. Process): Def __init__ (self, Input_queue, output_queue): multiprocessing. Process.__init__ (self) self.input_queue = Input_queue Self.output_queue = Output_queue SELF.SP = Seri Al. Serial (Serial_port, Serial_baudrate, Timeout=1) def close (self): Self.sp.close () def writeserial (self, data ): Self.sp.write (data) # Time.sleep (1) def readserial (self): return Self.sp.readline (). Rep Lace ("\ n", "") def Run (self): Self.sp.flushInput () and True: # Look for incoming tornado requ EST if not self.input_queue.empty (): data = Self.input_queue.get () # Send it to The serial device self.writeserial (data) print "Writing to Serial:" + Data # Lo OK for incoming serial data if (self.sp.inWaiting () > 0): data = self.readserial () pri NT "reading from Serial:" + data # Send it back to Tornado self.output_queue.put (data)
4.server.py
Import tornado.httpserverimport tornado.ioloopimport tornado.webimport tornado.websocketimport tornado.genfrom Tornado.options import define, Optionsimport Osimport timeimport multiprocessingimport serialworkerimport json define (" Port ", default=8080, help=" run on the given port ", type=int) clients = [] Input_queue = multiprocessing. Queue () Output_queue = multiprocessing. Queue () class Indexhandler (Tornado.web.RequestHandler): Def get (self): Self.render (' index.html ') class Staticfileh Andler (tornado.web.RequestHandler):d EF Get (self): Self.render (' main.js ') class Websockethandler ( Tornado.websocket.WebSocketHandler): def open: print ' New Connection ' clients.append (self) s Elf.write_message ("Connected") def on_message (self, message): print ' Tornado received from client:%s '% JSON.D UMPS (Message) #self. Write_message (' ack ') input_queue.put (message) def on_close (self): print ' conn Ection closed ' clients.remove (self) # #Check the queue for pending messages, and rely, which is connected Clientsdef checkqueue (): If not Output_queue.empty (): M Essage = Output_queue.get () for C in clients:c.write_message (message) if __name__ = = ' __main__ ': # # Start the serial worker I n Background (as a deamon) SP = Serialworker. Serialprocess (Input_queue, output_queue) Sp.daemon = Truesp.start () tornado.options.parse_command_line () app = Tornado.web.Application (handlers=[(r "/", Indexhandler), (R "/static/(. *)", Tornado.web.StaticFileHandler {' path ': './'}, (R "/ws", Websockethandler)]) Httpserver = tornado.httpserver.HTTPServer (APP) Httpserver.liste N (options.port) print "Listening on port:", Options.portmainloop = Tornado.ioloop.IOLoop.instance () # # Adjust the Scheduler_interval According to the frames sent by the serial portscheduler_interval = 100scheduler = Tornado.ioloop.Perio Diccallback (Checkqueue, scheduler_interval, Io_loop = Mainloop) Scheduler.start () Mainloop.start ()
5. Extension: Each page when the user logs on to generate a unique key, the user binds to the user's operation of the session, when the operation, the key is also passed to the server side of the input queue, and then in the Serialworker run loop to process data data, The Self.output_queue.put (data) operation is to take this key again, and then return, the server in the Checkqueue method execution is only sent to this key session, and then the front-end display results. This enables each session information to be uninterrupted. If you do not mark with a key, all session operation information can be seen between all sessions. At the same time, whether the serial can be combined with os.openpty (), realize the serial operation of the new pseudo terminal to achieve shell Terminal operation mode. The pty creation of Linux is a pair occurrence, a master, a slave, a command that executes from, and then returns to the main display. Pty Create the following simple code:
#!/usr/bin/python#-*-coding:utf-8-*-import osimport serial# main pty, from ttym,s = Os.openpty () print mprint s# display terminal name s = os. Ttyname (s) print mprint Sser = serial. Serial (s,9600,timeout=0.5) print "Open Port successful! The port information: "Print ser print" \ n "while Ser.isopen (): #the return is True or faulse print" Please write the M SG (Exit to break) " msg=raw_input () #add a break reason:::kill the child thread if msg = = ' exit ': print" \ n "
print "Waiting to close the connection ..." sleep (1) break ; Msg=msg + ' \ r ' + ' \ n ' #AT form define #data =ser.write (msg) os.write (Master, msg) Sys.stdout.flush () #flush the BUF Fer print "\ n" print ("Waiting to recv the data ...") sleep (2) msg_recv = Os.read (master,128) Print ("\ n") print ("\tok! The recv msg is%s "% (MSG_RECV))
Create a pseudo-terminal communication diagram:
[Record]python using serial module for real-time webconsole