0
votes

I have been trying to connect to a device using a serial port and RTU Modbus. The device is a variable frequency controller:

enter image description here

Which is connected to my laptop via the following RS485 to USB converter:

https://www.amazon.co.uk/gp/product/B01E8JRL6O/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1

The instructions with the device I'm connected to provide a usage example for reading data with Modbus, as shown below: enter image description here

With the above, provided, I have tried to perform a read request with the below code:

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print (test)

Where I assume, above, that the line:

test = modbus.read_holding_registers(1, 1, unit=1)

means that register address 1 is read, for 1 reading frame, and for device ID 1. To my understanding, this request corresponds to the instruction example shown above. Unfortunately, however, I consistently get the error message:

Modbus Error: [Input/Output] Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (1 received)

Does anyone know why I am getting this error? And, secondly, is the CRC calculated on-the-fly by the pymodbus? Or am I supposed to some how calculate this and include it?

Any help is much appreciated!

1
You should not have to worry about CRC, that's handled by pymodbus. Can you post a link to some info on your RS485 converter? Some of those are not good Modbus. It would also help if you post a link to your external device, just to be sure you are using the correct settingsMarcos G.
Thank you Marcos, I have added a link of the USB to the description, as well as the external advice.Hayden Eastwood
Great edit, thank you. I could not find a manual for your pid controller. I've seen some devices like that but sometimes they are not Modbus but they have a very similar but simplified protocol. Are you absolutely sure this one supports Modbus? Your USB convert looks good and if you are only getting one byte back the only remaining explanation is a problem with the protocol.Marcos G.
Hi Marcos, thanks for the feedback. The device definitely supports Modbus, and the example for the read command, above in the table, is an example of a Modbus request provided by the device manufacturer.Hayden Eastwood
OK clear. Then the only other ideas I can offer you are: double check baud rate and parity and try to use debug/log to see what is that byte you are getting back, you can take a look at this example to add the configuration you need to print debug messagesMarcos G.

1 Answers

1
votes

As discussed in the comments you are facing a strange issue.

To sum up:

-Your PID controller supports Modbus RTU over RS485.

-Wiring is correct: T/R+ on the USB converter goes to T/R(A) on the controller and T/R- to T/R(B).

-The USB converter seems to be good and supports Modbus (RS485 half-duplex).

-Your code should work.

-Baud rate and parity are correct. (EDIT: this was actually the problem according to the comment below, oftentimes the baud rate the manual claims to be the default was changed in a new revision of the firmware or by somebody else manipulating the device for their own needs).

To have more details you can add debugging/logging as follows:

from pymodbus.client.sync import ModbusSerialClient as ModbusClient

import logging
FORMAT = ('%(asctime)-15s %(threadName)-15s '
          '%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.DEBUG)


modbus = ModbusClient(method='rtu', port='/dev/tty.usbserial-AQ00BYCR', baudrate=9600, timeout=1)
modbus.connect()
test = modbus.read_holding_registers(1, 1, unit=1)
print(test.registers)

Try that and you'll convince yourself that pymodbus is indeed writing the following bytes on the port:

0x01 0x03 0x00 0x01 0x00 0x01 0xD5 0xCA

Looking at the log (it should be similar to mine but in your you'll see the answer from the device too):

2019-12-03 18:24:45,262 MainThread      DEBUG    transaction    :111      Current transaction state - IDLE
2019-12-03 18:24:45,262 MainThread      DEBUG    transaction    :116      Running transaction 1
2019-12-03 18:24:45,262 MainThread      DEBUG    transaction    :215      SEND: 0x1 0x3 0x0 0x1 0x0 0x1 0xd5 0xca
2019-12-03 18:24:45,262 MainThread      DEBUG    sync           :73       New Transaction state 'SENDING'
2019-12-03 18:24:45,262 MainThread      DEBUG    transaction    :224      Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
2019-12-03 18:24:46,264 MainThread      DEBUG    transaction    :234      Transaction failed. (Modbus Error: [Invalid Message] Incomplete message received, expected at least 2 bytes (0 received)) 
2019-12-03 18:24:46,265 MainThread      DEBUG    rtu_framer     :235      Frame - [] not ready
2019-12-03 18:24:46,265 MainThread      DEBUG    transaction    :390      Getting transaction 1
2019-12-03 18:24:46,265 MainThread      DEBUG    transaction    :189      Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'

At this point, all I end up with are extremely far-fetched theories (if you are running on a very very old version of pymodbus, the endianness of the CRC was wrong, and you would see 0xca 0xd5 instead).