Word register order
It appears that openPLC stores multi-word values differently to how modbus-cli sends/receives them. The bits seem to be the correct edian order, but the words should not always be in the same order.
This page (https://csimn.com/CSI_pages/Modbus101.html under heading "Registers Are 16-bits - How Do I Read Floating Point or 32-bit Data?") has a short section that explains it better than I can. That section also suggests that there are other PLCs that store values in this different way.
Can an option be added to swap the word order for multi-word values?
We could definitively add a reverse endian mode. What is implemented is what is used in Schneider PLCs so I would think this would be correct in most cases. You are the first to comment this.
The link you send does not really add much to the discussion. Because Modbus internally just supports words and bits.
I would need a way to test this...
I'm willing to help with testing. Though I'm not a dev so it may take be a few days to fumble through learning how git works (in the context of testing).
Alternatively I could set up a Linux VM with openPLC running on it and open up a firewall rule from an IP of your choosing. That way you can read/write from modbus-cli and confirm the readings on openPLC's monitoring page.
EDIT: A possible workaround for testing: pick an arbitrary value for a float/DWORD, calculate what the value would be when word-reversed and see if that value appears using normal testing methods.
EDIT 2: I tried simply removing the two reverses from the lines in functions read_and_unpack() & pack_and_write() - it worked successfully in reading and writing floats that openPLC recognises correctly. The lines now read as such:
def read_and_unpack(sl, format)
# the word ordering is wrong. calling reverse two times effectively swaps every pair
read_data_words(sl).pack('n*').unpack("#{format}*")
end
and
def pack_and_write(sl, format)
# the word ordering is wrong. calling reverse two times effectively swaps every pair
sliced_write_registers(sl, addr_offset, values_list.pack("#{format}*").unpack('n*'))
end
Obviously this doesn't implement a toggle option though.