5

I have this little device for communication, and I can see the dongle after lsusb, and it is attached to ttyUSB0 (output from dmesg). Since the module has its driver that is installed to Raspberry Pi, I don't need another CPU for handshake. I am using pymodbus, and I wrote the code segment below.

import pymodbus
import serial
from pymodbus.pdu import ModbusRequest
from pymodbus.client.sync import ModbusSerialClient as ModbusClient #initialize a serial RTU client instance
from pymodbus.transaction import ModbusRtuFramer

import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)

#count= the number of registers to read
#unit= the slave unit this request is targeting
#address= the starting address to read from

client= ModbusClient(method = "rtu", port="/dev/ttyUSB0",stopbits = 1, bytesize = 8, parity = 'E' baudrate= 9600)

#Connect to the serial modbus server
connection = client.connect()
print connection

#Starting add, num of reg to read, slave unit.
result= client.read_holding_registers(0x00,2,unit= 0xff)

print(result)

#Closes the underlying socket connection
client.close()

Output is:

True
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:getting transaction 1
None

It obvious I am doing something wrong, but I don't know what. How can I fix this problem?

  • Why are you setting unit id 0xff. It can be only up to 247 from 1 for slave? I am not sure if you have already solved it. – prashant May 27 '18 at 3:21
2

I had the same initial problem with pymodbus using a Beaglebone Black to read and write data to a heat recovery ventilator. I had already tried minimalmodbus, so I knew that the hardware side was fine. The documentation, including the recent document (https://media.readthedocs.org/pdf/pymodbus/latest/pymodbus.pdf) is not clear on this. The output seems to be a register, which needs to be accessed to get the actual returned values. This is what worked for me:

temps  = client.read_input_registers(30001, 4, unit=0x0a) # address, count, slave address
print temps.registers
coil  = client.read_coils(10001, 8, unit=0x0a) # address, count, slave address
print coil.bits

Writing seems more straightforward:

rq = client.write_coil(10001, 1, unit=0x0a)
rq = client.write_register(40001, 2, unit=0x0a)

Just for completeness, here are the equivalent commands in minimalmodbus and modbus-tk that mostly worked for me.

Minimalmodbus: I think that the instrument.read_bit command should work, but I get a "ValueError: Could not convert bit response to a value. Input: '\x10'". Coil reads work in pymodbus and Modbus-tk.

temps = instrument.read_registers(30001, 4, 3) # address, count, function code (3 or 4)
print temps
coil = instrument.read_bit(10001, 1) # address, function code (1 or 2), generates error
print coil
instrument.write_bit(10001, 1, 5) # address, value, function code (5 or 15)
instrument.write_register(40001, 2, 0, 6, False) # address, value, number of decimals, function code, signed)

modbus-tk:

temps = master.execute(10, cst.READ_HOLDING_REGISTERS, 30001, 4)
print temps
coil = master.execute(10, cst.READ_COILS, 10001, 8)
print coil
logger.info(master.execute(10, cst.WRITE_SINGLE_COIL, 10001, output_value=0))
logger.info(master.execute(10, cst.WRITE_SINGLE_REGISTER, 40001, output_value=2))
  • Thank you for your detailed answer P Mess. I will try what you did and let you know. – Caglar Sekmen Jan 14 '15 at 7:59
1

Maybe you should try minimalmodbus library: https://pypi.python.org/pypi/MinimalModbus/0.5. I will check with input register reading and writing soon.

  • 1
    To be honest I am using pymodbus because I started with it and read about it a lot. minimalmodbus is my second choice. Seems like I will have to use it eventually. Thank you for your reply. – Caglar Sekmen Oct 3 '14 at 21:13
0

Try using something like: print('result received is ', ':'.join('{:02x}'.format(x) for x in result.receive(16))). This will read up to 16 characters or everything in the buffer up to 16 chars and show it as hex

0

The None result could be due to wrong parameters for serial connection. See this line:

client= ModbusClient(method = "rtu", port="/dev/ttyUSB0",stopbits = 1, bytesize = 8, parity = 'E' baudrate= 9600)

In my script, this works: parity = 'N'

Refer to the device documentation if you are not sure about the parameters

0

Start with adding number of registers to read, slave unit.

result= client.read_holding_registers(0x00,2,unit= 0xff)

Try like this

print(result[0])

protected by Community Jun 21 at 15:09

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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