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
log = logging.getLogger()

#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)


#Closes the underlying socket connection

Output is:

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

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

  • 1
    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
    Commented May 27, 2018 at 3:21

5 Answers 5


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)


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.
    – Cugomastik
    Commented Jan 14, 2015 at 7:59

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

  • 2
    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.
    – Cugomastik
    Commented Oct 3, 2014 at 21:13

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


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


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

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

Try like this


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