modbus library not working on 1.19 and up firmware

  • Hi All,

    I have a program works great reading a modbus sensors i had this working on firmware version 1.18.
    so i just got in new wipy3s and updated them to the newest firmware ( 1.20 RC13 ) put my sensor on my board and it did not read. First i thought it was my board so i tired another board same result. so then i went and loaded Firmware 1.18 on the same wipy and plugged it in and it started working.

    Then i went to the github page to pull the last modbus library and that also doenst solve any problems on the newer firmwares. does anyone know why the modbus library doesnt work on the newer firmwares over 1.18?

    FYI i went to 1.19b4 and that also did not work.

  • I made it work in version 1.20.2.rc7 (dated 2020-05-04) by going into file and replacing readall function call by read.

    Anyhow, isn't a better library? A port of minimalmodbus will be great as I hard to hardcode some things to be able to read inverse float values.

    I've filled this issue at github's repo, but last commit is 12 months ago...

    Issue content:

    I'm reading values from a sensor that uses RS485 and sends inverse float values with function code 4 (addresses 0, 2 and 4) and it was imposible for me to read those values using the read_input_registers function (which uses function code 4).

    I had to add another function for converting values to float instead of short (quite hardcoded for my case, not so much into modbus):

    def _to_float(self, byte_array, signed=True):
            # response_quantity = int(len(byte_array) / 2)
            # this always returned 2
            # fmt = '>' + ('f' * response_quantity)
            # so fmt ended up like '>ff' and caused a buffer issue, so I hardcoded it to ' >f'
            # also, no idea about signed floats, just left the signed var to be consistent
            return struct.unpack('>f', byte_array)

    and a new function copy&pasted from read_input_registers, but using the _to_float` function defined above:

    def read_float_registers(self, slave_addr, starting_address, register_quantity, signed=True):
            modbus_pdu = functions.read_input_registers(starting_address, register_quantity)
            resp_data = self._send_receive(modbus_pdu, slave_addr, True)
            register_value = self._to_float(resp_data, signed)
            return register_value

    Any cleaner/correct/good way to implement this?

Log in to reply

Pycom on Twitter