In the ‘good old days’ RS232 and RS485 had quite high signal levels (>10V)
I see the specs of these USB converters are working at USB voltage (5V)
The technician in me says this could be an issue…
Is there a way to check the signal by a simple command to the slave device that then responds with a known response??
In my day with RS422/232 one could do this hardware test by running Hyperterminal and connecting the Rx and Tx lines so one could then see the keyboard characters being returned on the Rx input.
Yeah, I’m going to have to try various things now and figure out where the problem is.
I suspect its something on the inverter, either a setting I’m not aware of that needs to be enabled / set / changed or its an issue with the connection on the inverter.
I’ll do some experimenting this week.
Richard_Mackay:
In the ‘good old days’ RS232 and RS485 had quite high signal levels (>10V)
I see the specs of these USB converters are working at USB voltage (5V)
The technician in me says this could be an issue…
Even back in the day, the interface chips ran from 5V and they had charge pumps in them to get to the 10V. Just check the spec sheet for a MAX232
I don’t think it’s anything on the inverter.
As mentioned, I got it working on the first inverter, then when I added my second inverter, I just added a usb-485 adapter, duplicated the flow to talk to the second inverter and that was it. Didn’t have to set anything on the inverter.
Did you try using my flow I attached above. Manually trigger it and use the debug to check what’s returned from the inverter.
Remember, you need to poll the different registers of the inverter and the inverter just responds with whatever is in that register.
Drop me a message with your email address and I will send you the flow and we can work from there.
The 485 adapter that you have should work for a single register call but doesn’t handle continuous polling at high frequency very well.
Here is a python script (needs pymodbus to be installed) that I use to query registers (on a different kind of hardware, but that should not matter). The slave address is hardcoded to 1 and the baud rate to 9600, so you may want to mess with that, but otherwise it’s a fairly good tool to read and write registers, eg:
python3 modbusrtu.py /dev/ttyUSB0 read 0x01 1
It even has some smarts to convert hex arguments for you, just to make life easier.
The “write” part I sometimes use on Carlo Gavazzi meters to write the reset registers (that resets the energy counters to zero).
import sys
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.pdu import ExceptionResponse
def main():
if len(sys.argv) < 5:
print ("Usage: {} port read|write register count")
return
modbus = ModbusClient(method='rtu', port=sys.argv[1], baudrate=9600, timeout=1)
if not modbus.connect():
logger.error("Cannot connect to modbus")
return
action = sys.argv[2]
if action not in ("read", "write"):
print ("Read or Write?")
return
register = sys.argv[3]
if register.startswith('0x'):
register = int(register, 16)
else:
register = int(register)
count = int(sys.argv[4])
if action == "read":
r = modbus.read_holding_registers(register, count, unit=1)
if isinstance(r, ExceptionResponse):
print (r)
else:
print (r.registers)
total = 0
for _ in reversed(r.registers):
total <<= 16
total |= _
print ("{} (0x{:X})".format(total, total))
elif action == "write":
v = int(sys.argv[5])
payload = []
while v > 0:
payload.append(v & 0xFFFF)
v >>=16
while len(payload) < count:
payload.append(0)
print ("Writing {} to register {:X}".format(payload, register))
if len(payload) > 1:
r = modbus.write_registers(register, payload, unit=1)
else:
r = modbus.write_register(register, payload[0], unit=1)
print (r)
main()
Hmm… Must be missing a library or something ? I’ve installed pymodbus.
If I just get it to print(r)
Then :
Modbus Error: [Input/Output] Modbus Error: [Invalid Message] No response received, expected at least 2 bytes (0 received)
Traceback (most recent call last):
File “./script.py”, line 54, in
main()
File “./script.py”, line 33, in main
print (r.registers)
AttributeError: ‘ModbusIOException’ object has no attribute ‘registers’
Well, there’s the answer. It’s not receiving an answer. Possible issues could be wrong baud rate or wrong slave id. Or whatever is on the other end is just not talking back.
I’m assuming you have at least some programming background and the required information to fill the gaps. I don’t know the sunsynk and have no intention of getting to know it… that’s just my generic script for poking registers, and it’s helped me a lot. I have a few others for poking the registers of sunspec PV-inverters too
Yup - exactly what I’ve been saying for a while now, there is a comms / hardware issue here.
I’ll try and do some experimenting today (if I get a chance)
Hi @ozziej did you ever resolve this issue? I’m having the same problem and have no idea what to do.
Thanks Brett
No, unfortunately not. I gave up a couple months ago in disgust and will just have to live with the painful solar man app.
If anyone can shed some light on this it would be great, but I’m convinced there is more than just a software issue here.
My Sunsynk did get a few firmware updates a couple weeks ago, so I might try revisit this.
(it was having an issue with the touchscreen not responding correctly / delayed and those firmware updates fixed it.)
ok cool, thanks for getting back to me. someone also mentioned that they had a firmware update on their Sunsynk inverter and the modbus ID changed to 00 they said that they changed it to 01 and that resolved some of their issues. It’s under advanced settings. I have a Deye 8KW inverter and my ID also changed to 00 after they did a firmware update last week. I did change it in my settings however i get the same issue. it just keeps flipping between “active” “initialise” “init” “Opened” “connected” “queing” “sending” and “reconnecting”. I’m running Node-Red in homeassistant and I’ve tried so many different settings and no luck. The only thing i haven’t managed to do is change the permissions on the /dev/ttyUSB0 i’m not sure if that’s the issue because if i type it out in terminal i get access denied.
Have you tried the guide and the node red flow that I posted in this thread.
The first step is to try and debug within nodered itself. Add a debug node and check what data is being sent and received.
Which 485 adapter are you using. I found that the cheap ones (R30) don’t work. I posted links to the one I’m using.
Also been struggling with this.
Modbus RTU addresses are 1-255, with 0 being reserved for broadcast messages.
However, the 0 address is rarely used since there is no confirmation that the message was properly received at the slave node.
Try using the broadcast slave address
Change unit=1 to unit=0
r = modbus.read_holding_registers(register, count, unit=1)
I’m not a python expert… there may have been a change on pymodbus to the return type.
For pymodbus 2.5.3, the return type when there is a error is: <class 'pymodbus.exceptions.ModbusIOException'>
When there is no error the return type is: <class 'pymodbus.register_read_message.ReadHoldingRegistersResponse'>
here is a corrected version for use with 2.5.3:
import sys
from pymodbus.client.sync import ModbusSerialClient as ModbusClient
from pymodbus.register_read_message import ReadHoldingRegistersResponse
def main():
if len(sys.argv) < 5:
print ("Usage: {} port read|write register count")
return
modbus = ModbusClient(method='rtu', port=sys.argv[1], baudrate=9600, timeout=1)
if not modbus.connect():
logger.error("Cannot connect to modbus")
return
action = sys.argv[2]
if action not in ("read", "write"):
print ("Read or Write?")
return
register = sys.argv[3]
if register.startswith('0x'):
register = int(register, 16)
else:
register = int(register)
count = int(sys.argv[4])
if action == "read":
r = modbus.read_holding_registers(register, count, unit=0) # NOTE: Change Unit to match your Inverter
print (type(r))
if not isinstance(r, ReadHoldingRegistersResponse):
print (r)
else:
print (r.registers)
total = 0
for _ in reversed(r.registers):
total <<= 16
total |= _
print ("{} (0x{:X})".format(total, total))
elif action == "write":
v = int(sys.argv[5])
payload = []
while v > 0:
payload.append(v & 0xFFFF)
v >>=16
while len(payload) < count:
payload.append(0)
print ("Writing {} to register {:X}".format(payload, register))
if len(payload) > 1:
r = modbus.write_registers(register, payload, unit=1)
else:
r = modbus.write_register(register, payload[0], unit=1)
print (r)
main()
I did try addresses 0-255, seems SunSynk only responds to the broadcast address 0.
EDIT:
You can change SunSynk modbus ID from 0 (broadcast) in Advanced->Multi-Inverter
Hi there must be some HW error with the device connecting to the inverter. I’ve tried everything as mentioned in the post above mentioned by @Vassen and no luck. My MQTT connects but the Inverter just keeps switching between connected, queueing, timeout, reconnecting, initialise, init, opened. Like i said i tried 2 different USB adapters and also 2 different RPI’s and the same thing happens.