Skip to content

Serial + Async + RTU violates modbus protocol, results in bugs #156

@k2nsloos

Description

@k2nsloos

Hi,

I recently tried to communicate with an SC2004MBS over RS485 using the pymodmus async library.
However I noticed that several commands got dropped by the slave, whenever they we're issued in a small time frame.

Upon reading the Modbus specification (http://www.modbus.org/docs/Modbus_over_serial_line_V1_02.pdf) I found two issues:

  1. At most one transaction can be active at any given time.
  2. The minimal idle time between messages is at-least the time equivalent of 3.5 characters

Whenever a request is build using ModbusClientProtocol class, it is passed to the following function:

def execute(self, request):
        ''' Starts the producer to send the next request to
        consumer.write(Frame(request))
        '''
        request.transaction_id = self.transaction.getNextTID()
        packet = self.framer.buildPacket(request)
        self.transport.write(packet)
        return self._buildResponse(request.transaction_id)

This function build the packet and immediately writes it to the transport. Possibly violating issue 1 and 2.

Because if request B is written to the transport before request A is fully sent, then they'll be fused together resulting most likely in an invalid message (CRC). The specification dictates that slaves must drop these kind of packets silently.

Furthermore the 3.5 characters of silence is not enforced before sending any reply, which is also violates the specification.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions