Serial port does not work in rewritten Python code

ぐ巨炮叔叔 提交于 2019-12-23 15:36:46

问题


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

(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 ...

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

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.

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


回答1:


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).

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.



来源:https://stackoverflow.com/questions/16243752/serial-port-does-not-work-in-rewritten-python-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!