串行端口在重写的 Python 代码中不起作用 [英] Serial port does not work in rewritten Python code

查看:32
本文介绍了串行端口在重写的 Python 代码中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Python 程序,它从 Arduino 读取一些参数并将其存储在数据库中.串口设置和使用如下:

I have a Python program that reads some parameters from an Arduino and stores it in a database. The serial port is set up and used like this:

ser = serial.Serial(port=port, baudrate=9600)
ser.write('*')
while 1 :
    ser.write('*')
    out = ''
    # Let's wait one second before reading output (let's give device time to answer).
    time.sleep(1)
    while ser.inWaiting() > 0:
        out += ser.read(1)
    if out != '': 
        etc ... handling data

(Arduino 被设置为当它收到一颗星星时,它会发回一个数据字符串.)我想将其重写为 daemon,所以我使用的是 python-daemon 库.在init部分,我只定义了端口名,然后:

(The Arduino is set up so when it receives a star, it sends back a data string.) I would like to rewrite this as a daemon, so I am using the python-daemon library. In the init-part, I just define the port name, and then:

def run(self):
    self.ser = serial.Serial(port=self.port,baudrate=9600)
    while True:
        self.ser.write('*')
        out = ''
        # Let's wait one second before reading output (give device time to answer).
        time.sleep(1)
        while self.ser.inWaiting() > 0:
            out += self.ser.read(1)
        if out != '':
            etc ...

一切都是平等的,除了我现在在 App 对象中进行串行处理.第一个版本运行良好,当我尝试运行后者时,我得到

Everything is equal, except that I am now doing the serial handling within an App-object. The first version runs fine, when I try to run the latter, I get

File "storedaemon.py", line 89, in run
 while self.ser.inWaiting() > 0:
 File "/usr/lib/python2.7/dist-packages/serial/serialposix.py", line 435, in inWaiting
 s = fcntl.ioctl(self.fd, TIOCINQ, TIOCM_zero_str)
 IOError: [Errno 9] Bad file descriptor

我无法看到发生了什么变化 - 除了我已经将代码扔到了一个新对象中.我已经尝试在 init 和 run 中进行初始化,但我最终得到了相同的结果.

I am not able to see what has changed - except that I have tossed the code inside a new object. I have tried both to do the initialisation in init and in run, but I end up with the same result.

(完整的脚本可在 hhv3.sickel.net/b/storedata.pyhhv3.sickel.net/b/storedaemon.py 获得.)

(The complete scripts are available at hhv3.sickel.net/b/storedata.py and hhv3.sickel.net/b/storedaemon.py.)

推荐答案

在应用程序的守护进程期间,除标准输入、标准错误和标准输出之外的所有文件处理程序都将关闭.这包括到 /dev/log 的连接,然后连接失败并出现 fd 错误(所以看起来这与串行 fd 无关,而是与处理程序的套接字有关).

During the daemonization of your app, all file handlers are closed except stdin, stderr and stdout. This includes the connection to /dev/log, which then fails with the fd error (so it looks like this has nothing to do with the serial fd, but instead with the handler's socket).

您需要将此 FD 添加到排除列表中:

You need either to add this FD to the exclusion list:

class App():
    def __init__(self):
        ...
        self.files_preserve = [handler.socket]
        ...

或者,在守护进程分叉后设置处理程序:

Or alternatively, set up the handler after the daemon process forked:

class App():
    def run(self):
        handler = logging.handlers.SysLogHandler(address = '/dev/log')
        my_logger.addHandler(handler)
        my_logger.debug(appname+': Starting up storedata')
        ...

在我的测试中,两个版本都运行良好.

Both version ran fine during my tests.

这篇关于串行端口在重写的 Python 代码中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆