[Twisted-Python] Question about SerialPort

Albert Brandl albert.brandl at weiermayer.com
Thu Jan 20 04:32:22 MST 2011


Hi!

I am trying to read Modbus RTU messages over the serial line. There is a
library called pyModbus which is very usable for Modbus TCP/IP, but the
support for RTU is a bit lacking.

The main problem seems to be the specification of Modbus RTU. RTU
messages are separated by time gaps that are at least 3.5 characters
long. Unfortunately, this is the only reliable way for separating
messages - there is no length header or something similar. The
specification does define a trailing CRC, though.

As far as I understand the event loop, I will not be able to guarantee 
that will not miss such a gap - the reactor might be busy handling some 
other events while the gap arrives. 

But when the reactor assigns some time to read from the serial port, I'd 
like it to read until the gap is detected. My current attempt is to 
override the doRead method of SerialPort by something like this:

    def doRead(self):
        port = self.fileno()
        result = []
        while True:
            # The following code is stolen from fdesc.readFromFD
            try:
                output = os.read(port, 1)
                if output:
                    result.append(output)
                else:
                    break
            except (OSError, IOError), ioe:
                if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
                    return
                else:
                    return CONNECTION_LOST
        if not result:
            return CONNECTION_DONE
        else:
            self.protocol.rawDataReceived("".join(result))

If the serial port is configured with a timeout about the size of the
gap, os.read() should return an empty string, thus indicating that
the message is complete.

Most of the code above is a copy of t.i.fdesc.readFromFD. The main 
difference is that I don't read 8192 bytes, but only one at a time,
to detect a time gap.

Does this make sense? Do you think it would be possible to replace the 
constant 8192 in readFromFD by a parameter (that defaults to 8192)? This 
would allow me to replace the content of the while loop with a simple 
function call.

TIA and best regards,

Albert
-- 
Albert Brandl
Weiermayer Solutions GmbH      | Abteistraße 12, A-4813 Altmünster
phone: +43 (0) 720 70 30 14    | fax: +43 (0) 7612 20 3 56
web: http://www.weiermayer.com




More information about the Twisted-Python mailing list