Search code examples
pythonjsonserial-portmodbuspymodbus

How to read all Holding Registers from Modbus Slave?


I am using Delta PLC which supports modbus232 communication.

The holding registers which contains data are not sequential.

i.e., 4246,6622,6626,6676,6624,6496,6658,4096,4346.

So to read each register I need to request separately.

actual_floor = client.read_holding_registers(4246,1,unit=0x01)
fault = client.read_holding_registers(6622,1,unit=0x01)

This is quite a huge task to do if I want to read more than 200 registers.

Is there any way to read all holding registers at once which gives all registers and its data in json or any other format?


Solution

  • At first, you should get min and max registers, then read by a request with count argument, and then you must assign the consider value to each register.

    Note: maximum count is 125.

    Something like this:

    def chunking(registers):
        # do stuff.
    
    def assignment_regs_to_values(values, registesr):
       # do stuff.
    
    registers = [4246,6622,6626,6676,6624,6496,6658,4096,4346]
    min_reg = min(registers)
    max_reg = max(registers)
    count_ = max_reg - min_reg + 1
    
    if count_ > 125:
        sub_regs = chunking(registers)
        # get min & max of each sub_reg list ...
    else:
        sorted_regs = sorted(registers)
        res = client.read_holding_registers(min_reg, count=count_ , unit=1)  # Note
        assignment_regs_to_values(res.registes, sorted_regs)
    

    The best number of request in your case will be 4 requests (instead of 9 reqeusts):

    sub_regs1 = [6676, 6658, 6626, 6624, 6622]
    sub_regs2 = [6496]
    sub_regs3 = [4336, 4246]
    sub_regs3 = [4096]
    
    count1 = max(sub_regs1) - min(sub_regs1) + 1
    res1 = client.read_holding_registers(min(sub_regs1), count=count1, unit=1)
    res2 = client.read_holding_registers(6496, count=1, unit=1)
    count3 = max(sub_regs3) - min(sub_regs3) + 1
    res3 = client.read_holding_registers(min(sub_regs3), count=count3, unit=1)
    res4 = client.read_holding_registers(4096, count=1, unit=1)