2014-04-19 77 views
1

我开发了一个Python上的小型网络服务器。它的目标是在一个命令(这里是RLY71)中翻译一个URL的参数(如http://192.168.0.17:6066/?rly=7&status=1&port=ttyUSB0),并将其写入到Arduino连接的串行端口(此处为/ dev/ttyUSB0)。Arduino和RaspberryPi之间的Python通信

这里是Web服务器的代码(很多很多的“打印”为了调试的需要):

__author__ = 'deadbird' 

import time 
import BaseHTTPServer 
from urlparse import urlparse, parse_qs 
import serial 
from time import sleep 

HOST_NAME = '192.168.0.17' 
PORT_NUMBER = 6066 


class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler): 

    def do_HEAD(s): 
     s.send_response(200) 
     s.send_header("Content-type", "text/html") 
     s.end_headers() 

    def do_GET(s): 
     port = -1 
     status = -1 
     rly = -1 

     """Respond to a GET request.""" 
     s.send_response(200) 
     s.send_header("Content-type", "text/html") 
     s.end_headers() 
     s.wfile.write("<html><head><title>Piscine</title></head>") 

     parameters = parse_qs(urlparse(s.path).query) 
     if parameters.has_key('rly'): 
      rly = parameters['rly'][0] 

     if parameters.has_key('status'): 
      status = parameters['status'][0] 

     if parameters.has_key('port'): 
      port = parameters['port'][0] 

     if port != -1 and status !=-1 and rly !=-1: 
      #ser = serial.Serial("/dev/ttyUSB0") 
      #ser.write("RLY11\n") 
      #ser.close() 
      try: 
       print "All parameters ok, sending command\n" 

       print "Opening port: {0}".format(port) 
       ser = serial.Serial("/dev/{0}".format(port), 9600, timeout=1) 
       print "Opened port \'{0}\'".format(ser.name) 
       if ser.isOpen(): 
        print "Port successfully opened" 
        print "isWritable = {0}".format(ser.writable()) 
       else: 
        print "Cannot open port :(" 

       command = "RLY{0}{1}".format(rly, status) 
       print "Command = \'{0}\'".format(command) 

       print "Writing command on serial port" 
       written = ser.write("RLY{0}{1}\n".format(rly, status)) 
       print "Bytes written = {0}".format(written) 

       print "Reading result" 
       ret = ser.readline() 
       if len(ret) == 0: 
        s.wfile.write("NOTHING DONE") 
       else: 
        print ret 
        s.wfile.write(ret) 
       ser.flushOutput() 
       ser.flushInput() 
       ser.close() 
      except (serial.SerialException, serial.SerialTimeoutException) as e: 
       s.wfile.write(e) 
     s.wfile.write("</body></html>") 


if __name__ == '__main__': 
    server_class = BaseHTTPServer.HTTPServer 
    httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler) 
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER) 
    try: 
     httpd.serve_forever() 
    except KeyboardInterrupt: 
     pass 
    httpd.server_close() 
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER) 

此安装了PySerial在Mac上完美地工作。当我在RaspberryPi上运行相同的脚本时,没有任何反应。例如,当我使用的URL http://192.168.0.17:6066/?rly=7&status=1&port=ttyUSB0,在控制台上的结果如下:

192.168.0.16 - - [19/Apr/2014 20:59:28] "GET /?rly=7&status=1&port=ttyUSB0 HTTP/1.1" 200 - 
All parameters ok, sending command 

Opening port: ttyUSB0 
Opened port '/dev/ttyUSB0' 
Port successfully opened 
isWritable = True 
Command = 'RLY71' 
Writing command on serial port 
Bytes written = 6 
Reading result 
192.168.0.16 - - [19/Apr/2014 20:59:30] "GET /favicon.ico HTTP/1.1" 200 - 

我试图chmown-ING端口用户“PI”,执行命令chmod-ING为777,没有什么变化。

我跑了一些测试。我写这个精简版,如果脚本:

import serial 
ser = serial.Serial("/dev/ttyUSB0") 
ser.write("RLY11\n") 
ser.close() 

当我运行它作为一个.py文件,是失败。但是当我使用python交互式shell(即:每行一行)从命令行运行它时,它可以工作!我完全不知道该怎么做,有人可以帮忙吗?

+0

添加一个shebang并将该脚本标记为可执行文件:http://stackoverflow.com/questions/7574453/shebang-notation-python-scripts-on-windows-and-linux – User

回答

0

发现了什么错,但无法解释为什么。现在我开始打开串口并在httpd.server_close()之后关闭它。现在它完美地工作,但我无法解释原因。

+0

奇数。也许串口需要一些时间来打开/关闭,并且请求太快了? – dsolimano

+0

这就是我的想法。无论如何,它现在完美的工作;) – deadbird