Python在Arduino与Raspberry Pi之间的通信

1 投票
1 回答
822 浏览
提问于 2025-04-18 03:25

我在Python上开发了一个小型的网页服务器。它的目的是把一个网址里的参数(比如 http://192.168.0.17:6066/?rly=7&status=1&port=ttyUSB0)转换成一个命令(这里是RLY71),然后把这个命令发送到一个串口(这里是/dev/ttyUSB0),而Arduino就连接在这个串口上。

下面是这个网页服务器的代码(为了调试,里面有很多很多的“print”语句):

__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上运行同样的脚本时,却什么都没有发生。例如,当我使用网址 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 -

我尝试把串口的拥有者改成“pi”,并把权限改成777,但没有任何变化。

我进行了更多的测试,写了一个简化版的脚本:

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

当我把它作为.py文件运行时,它失败了。但是当我在命令行中用Python的交互式命令行(也就是一行一行地运行)时,它却能正常工作!我完全不知道该怎么办,有人能帮帮我吗?

1 个回答

0

我找到了问题所在,但不知道为什么会这样。现在我在一开始就打开串口,然后在调用httpd.server_close()之后立刻关闭它。现在一切都正常了,但我无法解释原因。

撰写回答