0
\$\begingroup\$

I'm trying to implement Modbus reading on Jetson Nano (Linux - Ubuntu operation system).System include 3 part:

-MODBUS device which I would like to achieve input registers. --> Krohne Signal Converter-IFC050

-USB converter --> RS485 to USB(UART) reading. I can see the CH340 driver on Jetson Nano.

-Jetson Nano --> NVIDIA's development board. I'm using SSH connection to connect Jetson Nano.

I'm using pyModbus library on python which like:

from pymodbus.client.sync import ModbusSerialClient

client =  ModbusSerialClient (

method = 'rtu' ,
port   = 'dev/ttyUSB0',
baudrate = 9600 ,
timeout = 3 ,
parity = 'N',
stopbits = 1 ,
bytesize = 8   )



for address in range()

if client.connect():

   res = client.read_input_registers(address = 30000  , count = 20 , unit = 1 )


   if not res.isError():
       print(res.Registers)
   else:
       print(res)


else:
     print('Can not connect to the Modbus Slave/Server')

I'm sure about configuration which is 9600 baudrate , 8 byte , 1 stopbit , etc...

When I try to run the program it always return false which says 'Can not connect to the Modbus Slave/Server'.

What could be the problem about this matter? I can see CH340 driver(USB converter driver) on Jetson Nano as ttyUSB0.

\$\endgroup\$
6
  • \$\begingroup\$ Are you sure if the script that you have posed is correct? \$\endgroup\$ Commented Mar 2, 2021 at 8:10
  • \$\begingroup\$ What could be false?I just try to connect modbus device. \$\endgroup\$ Commented Mar 2, 2021 at 8:14
  • \$\begingroup\$ Well what does the client.connect() do and does the target device support this operation? \$\endgroup\$
    – Justme
    Commented Mar 2, 2021 at 8:36
  • \$\begingroup\$ Actually I assume that client.connect() tries to open the port with configurations e.g. 9600 baudrate.I'm taking reference this video youtube.com/watch?v=ZlHqEOmvW6M&ab_channel=RocketSystems . I think there is no so much differences between RPi and Jetson Nano because each of them has Linux based operation system. \$\endgroup\$ Commented Mar 2, 2021 at 10:45
  • \$\begingroup\$ Am I the only one that had frame timing issues on modbus? it has pretty strict interbyte and interchar timing (it uses them as actual end of frame) and with, for example, USB or LAN adapters there's no way to make it work (unless they have a special 'modbus mode') \$\endgroup\$ Commented Mar 8, 2021 at 6:55

2 Answers 2

1
\$\begingroup\$

Well , I changed the code like that;

from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.register_read_message import ReadInputRegistersResponse

client = ModbusClient(method = 'rtu', port='/dev/ttyUSB0', stopbits = 1, bytesize = 8, parity = 'N' , baudrate= 9600)   
                                                                                                                      
connection = client.connect()                                                                                          
print(connection)                                                                                                      
hlist = []                                       
data = client.read_input_registers(address=30000,count=20,unit=1)                                                      
print(data.registers)                                                                                                  
                                                                                                                        
for i in data.registers:                                                                                               
        print("i:", i)                                                                                                  
        hlist.append(i)                                                                                                                                                                 
print(hlist)                                                                                                                                                                                                                          
client.close()

and I'm using that commend to run script:

sudo python3 yourFileName.py

\$\endgroup\$
3
  • \$\begingroup\$ Not to rain on your parade or anything but if you add your user to the dialout group with sudo adduser $USER dialout you won't need to elevate yourself with sudo to use your serial port. I'm also curious about the register offsets, did you have to change to register 0? \$\endgroup\$
    – Marcos G.
    Commented Mar 8, 2021 at 7:16
  • \$\begingroup\$ In this script , register '0' and register '30000' shows exactly same values. \$\endgroup\$ Commented Mar 8, 2021 at 8:59
  • \$\begingroup\$ OK, thanks for the info. It's the first time I see that. But it is indeed what I understood reading the manual of your device, so I was curious. \$\endgroup\$
    – Marcos G.
    Commented Mar 8, 2021 at 9:16
0
\$\begingroup\$

EDIT

========================================================================

I'm keeping this answer just in case somebody stumbles on something similar for other devices. But for the particular device of the question, it seems it is actually smart enough to answer queries to registers with and without offset (the devices answers the same when you query register 0 and register 30000).

========================================================================

You are facing what is probably the number one problem with pymodbus: register addresses must be referred to with no offset.

So when your device's manufacturer says you need to read register 30000 you should consider register 0 in pymodbus. I know, it sounds confusing and it is. For holding registers the same rule applies but the offset is 40000.

To add up to an already confusing subject some devices have offsets of 30001 and 40001 instead. Sometimes this means some trial and error will be involved if you want to find the right registers.

Just change this line:

res = client.read_input_registers(address = 30000  , count = 20 , unit = 1 )

to:

res = client.read_input_registers(address = 0  , count = 20 , unit = 1 )

and you are done.

Once you are able to read the correct registers you will probably need to take a look at how to read a float value that spans two registers. In your device, flow rate, for instance, will be received within registers 0 and 1 (or 30000 and 30001 in the manual). But that's for a different question, I guess...

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.