2014-04-19 111 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