I am trying to use Python (PyCharm) to read a register on a modbus device. I have confirmed the COM port, Baud rate and other communication settings and I can use the devices application to read the value (it is a water level logger). I am getting no response from the instrument.
Register is readable in mbpoll using -
mbpoll -B -m RTU -t 4:float -a 1 -b 19200 -r 46 -c 2 /dev/ttyUSB0
(Address different as running on Pi not PC)
My code is as follows -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 3 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
instrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=40046, functioncode=3, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
print(temperature)
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 0.1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
temperature = instrument.read_float(registeraddress=45, functioncode=4, number_of_registers=2, byteorder=0) # Registernumber, number of decimals
try:
print(temperature)
except:
print(temperature)
Edit to include a try - except
Any help appreciated!
EDIT: Link to device manual - https://in-situ.com/en/pub/media/support/documents/Modbus_Manual.pdf Device is a Level Troll 400 Connected to PC via manufactures cable
EDIT 2: I have tried to incorporate minimal modbus structure but to no avail.
EDIT 3: I am able to read a register using Modbus Poll. Register is 40046, so I understand this to be register 45 of the holding registers? How do I translate this to minimalmodbus?
EDIT 4: I am not married to minimal modbus - I am happy to use any tool to get this done
EDIT 5:
I have also tried depth = instrument.read_long(x, x)
with different values
Just updating with the solution if anyone happens to stumble upon this and has the same problem. As semi-alluded to in other suggestions the device I am connecting to has a 'sleep' period or the like and needs to be polled once, unsuccessfully, before successfully returning values for any subsequent polls. I apologies for my armature code but the solution that works for me is the below -
import minimalmodbus
import serial
instrument = minimalmodbus.Instrument('COM5', 1) # port name, slave address (in decimal)
instrument.serial.port = 'COM5' # this is the serial port name
instrument.serial.baudrate = 19200 # Baud
instrument.serial.bytesize = 8
instrument.serial.parity = serial.PARITY_EVEN
instrument.serial.stopbits = 1
instrument.serial.timeout = 1 # seconds
instrument.address = 1 # this is the slave address number
instrument.mode = minimalmodbus.MODE_RTU # rtu or ascii mode
#nstrument.clear_buffers_before_each_transaction = True
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass
try:
temperature = instrument.read_long(registeraddress=9001, functioncode=3,
byteorder=0) # Registernumber, number of decimals
print(temperature)
except:
pass