pymodbus-dev / pymodbus

A full modbus protocol written in python
Other
2.25k stars 921 forks source link

Read data with RTS #2074

Closed fredrik-jansson-se closed 7 months ago

fredrik-jansson-se commented 7 months ago

I'm trying to replicate this call:

mbpoll -m rtu -a 2 -b 9600 -P none -r 1 -1 -F /dev/ttymxc2
mbpoll 1.0-0 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [2]
                        start reference = 1, count = 1
Communication.........: /dev/ttymxc2,       9600-8N1
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 2...
[1]:    672

I believe the -F flag (RS-485 mode (/RTS on (0) when sending)) is what I can't figure out how to enable in pymodbus.

The code:

      client=ModbusSerialClient("/dev/ttymxc2", baudrate=9600)
      client.connect()
      print("Connected")
      try:
          r = client.read_holding_registers(address=1, count=1, slave=2)
          print(f"read: {r}")
      except Exception as e:
          print(f"Exception {e}")
          print(f"Exception {e.message}")
      finally:
          print("Closing")
          client.close()

And I get this output:

Connected
read: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received)
Closing

Similar to what I get if I skip the -F flag to mbpoll

 mbpoll -m rtu -a 2 -b 9600 -P none -r 1 -1 /dev/ttymxc2
mbpoll 1.0-0 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright © 2015-2019 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.

Protocol configuration: Modbus RTU
Slave configuration...: address = [2]
                        start reference = 1, count = 1
Communication.........: /dev/ttymxc2,       9600-8N1
                        t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, output (holding) register table

-- Polling slave 2...
Read output (holding) register failed: Connection timed out

Any idea on how to set RTS during send?

fredrik-jansson-se commented 7 months ago

I have tried client.socket.setRTS(True) before the read_holding_registers call, but no difference.

janiversen commented 7 months ago

You need to find out how pyserial sets that flag and then modify the corresponding call to pymodbus.

janiversen commented 7 months ago

We use pyserial so we do not call the device directly, hence the socket is a pyserial object.

fredrik-jansson-se commented 7 months ago

Ok, thanks, I'll see what I can come up with!

janiversen commented 7 months ago

Closing as this is not really pymodbus bug. If you find a missing parameter, feel free to reopen or even better make a pull request.

fredrik-jansson-se commented 7 months ago

Thank you. I got it to work, I'll add the code below as reference in case someone else has this issue.

Not sure if this could be integrated into pymodbus in a good way.

client=ModbusSerialClient(port = "dev/ttymxc2", baudate = 9600)
ser = serial.rs485.RS485(port='/dev/ttymxc2', baudrate=9600)
ser.rs485_mode = serial.rs485.RS485Settings(rts_level_for_tx=False, rts_level_for_rx=True, delay_before_tx=0.001)
client.socket = ser