I have attempted many of the fixes related to pymodpoll that exist on this platform. I am able to successfully write to the register but I am unable to read from it, I have confirmed that the register I am attempting to read from is in fact a RW register. Datasheet of the product.
The mod poll command that works properly for reading the register is this
modpoll -m rtu -0 -1 -a 1 -b 9600 -p none -r 48 /dev/ttyUSB0
from pymodbus.client import ModbusSerialClient as modbus
#Connection to the modbus
def connect(self) -> None:
self.modbus = modbus(method='rtu',
port="/dev/ttyUSB0",
baudrate=9600,
stopbits=1,
bytesize=8,
timeout=1)
self.modbus.connect()
#function that works properly for setting the register value
def set_voltage(self, voltage:float =0) -> None:
if (voltage < self.min_volt) or (voltage > self.max_volt):
raise modbusError(
"Invalid voltage provided to the interface, voltage provided: {0}"
.format(voltage))
self.modbus.write_register(0x0030, int(voltage*100), unit=1)
#Read register function
def get_voltage_target(self) -> float:
reg = self.modbus.read_holding_registers(0x0030, 1, unit=1)
print(reg.registers)
Output:
AttributeError: 'ModbusIOException' object has no attribute 'registers'
I receive this error from the reg.registers print, I am assuming this is just from the fact that I am not connecting properly to the modbus to read the proper registers.
This is the code I am currently working with, thanks for the help!
Simplified version Edit:
from pymodbus.client import ModbusSerialClient as RTUClient
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
PowerSupplyMB = RTUClient(method='rtu', port="/dev/ttyUSB0", baudrate=9600,stopbits=1,bytesize=8,timeout=1)
PowerSupplyMB.connect()
PowerSupplyMB.write_register(0x0030, int(10.2*100), unit=1)
mb_response = PowerSupplyMB.read_holding_registers(0x0030, 1, unit=1)
if not mb_response.isError():
'''isError() method implemented in pymodbus 1.4.0 and above'''
print(mb_response.registers) # Your problem is here.
else:
# Do stuff for error handling.
print('Error message: {}'.format(mb_response))
Output:
DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x3 0x0 0x30 0x0 0x1 0x85 0xd4
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Transaction failed. (Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received))
DEBUG:pymodbus.logging:Frame - [b''] not ready
DEBUG:pymodbus.logging:Getting transaction 0
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Error message: Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 4 bytes (0 received)
Further investigation showed that registers
contains an error - Modbus Error: [Input/Output] No Response received from the remote slave/Unable to decode response
.
Your modpoll
command includes -a 1
(Slave address = 1) but looking at the debugging info the request is being sent to slave 0 ("0x0 0x3 0x0 0x30 0x0 0x1 0x85 0xd4") so that would explain the lack of response.
From the docs the function definition is read_holding_registers(address: int, count: int = 1, slave: int = 0, **kwargs: Any) → ModbusResponse
; in your code you say unit=1
not slave=1
... (I did not pick this up because you said the write_register
works; it may well do so because you are writing to the broadcast address 0
but you cannot read using that address).