简体   繁体   中英

Serial Communications with twisted

I have inherited python/twisted code written by a former employee.

The code that I have (and it works) opens a serial port and receives data for 5 seconds, then writes it back in reverse order. Here is the code:

from twisted.internet import reactor
from twisted.internet.protocol import Protocol
from twisted.internet.serialport import SerialPort
import serial
class ReverseEchoProtocol(Protocol):
    """Wait for specific amount of data.
       Regardless of success, closes connection timeout seconds after opening.
    """
    def __init__(self, port, timeout, logger):
        self._logger = logger
        self._timeout = timeout

    def connectionMade(self):
        self._logger.info('RS485 connection made.')
        reactor.callLater(self._timeout, self.transport.loseConnection, 'timeout')

    def connectionLost(self, reason):
        self._logger.info('RS485 connection lost. ' + str(reason))

    def dataReceived(self, data):
        self._logger.info('RS485 received data. ' + repr(data))
        self.transport.write(data[::-1])
        self.transport.flushOutput()

And from inside a python function the above code is initiated with this call:

protocol = ReverseEchoProtocol(port, 5 self._logger)
try:
    port.open(protocol)
except serial.SerialException as err:
    # print/log err.message here
    return False
return True

This call to port.open returns immediately after successfully opening the port (well before the 5 seconds complete)

Here is what I am trying to write. From inside a python function, I need to initiate a serial transaction. It needs to wait for the transaction to either complete, fail or timeout. Here is what the serial transaction needs to do:

  1. The transaction is passed in a string and a timeout value.
  2. The serial port is opened. Failure to open results in an error being returned
  3. The string is written to the serial port. Failure to write results in an error being returned
  4. If write is successful, the same port is then continually read for "timeout" seconds. As data is read (could be multiple reads), it is appended to a string.
  5. After "timeout" seconds, the string of all data read from the port during that time is returned (or the empty string if nothing is read).

Here is my question....trying to adapt the code I already have, I can write a new protocol. In connectionMade , it can do the write, initiate the read and then setup a timeout by calling reactor.callLater . Inside dataReceived I can append the read data to a string. And inside connectionLost I can return the string read.

But how do I make the python function calling port.open wait until the transaction completes? (Is there something like a reactor.wait function or a join function?) Also, if there is an error (or exception), how do I pass that up (a try block?) How do I pass the string back up to the python function?

I think the code I inherited gets me close...I just need those couple of questions answered for me to be able to complete the task.

To answer your first two questions, you are looking for reactor.run() to run the twisted mainloop but it sounds like and looks like you are expecting a blocking api and twisted is event driven which could possibly mean you are forcing the use of twisted. You could just use the serial module directly without twisted to get what you want done. If you do want to be event driven to be non-blocking then you will have to ask more specific questions about that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM