arduino-libraries/ArduinoModbus

Can I write to multiple holding registers?

Kedaro opened this issue · 2 comments

In ModbusServer.h and ModbusClient.h I only see holdingRegisterWrite (write to a single register). Does the interface support an action for multiple writes, like writeHoldingRegisters? I know that the Modbus protocol does support this.

Nistp commented

@per1234 is that something that would be a good addition to the library? If so, I can implement it with something like this:

/*Take in a set of matching addresses and values those addresses to be set to */
int ModbusServer::holdingRegistersWrite(int addresses[], uint16_t values[], size_t length)
{
 
 if(sizeof(addresses/addresses[0]) || sizeof(values/values[0]) != length)
 {
    return -1;
 }

  for(size_t element = 0; element < length; element++)
  {
     if (_mbMapping.start_registers > addresses[element] || 
        (_mbMapping.start_registers + _mbMapping.nb_registers) < (addresses[element] + 1)) 
        {
          errno = EMBXILADD;

          return 0;
         }
  }
 
 for(element = 0; element < length; element++)
 { 
    _mbMapping.tab_registers[addresses[element] - _mbMapping.start_registers] = values[element];
  }
  return 1;
}

For the master/client, the write multiple registers function is supported by using beginTransmission/endTransmission.
For example

        uint8_t slaveId = 1;
        uint16_t startAddress = 2000;
        uint16_t registerCount = 3;
        ModbusRTUClient.beginTransmission(slaveId, HOLDING_REGISTERS, startAddress, registerCount);
        ModbusRTUClient.write(1);
        ModbusRTUClient.write(2);
        ModbusRTUClient.write(3);
        ModbusRTUClient.endTransmission();

Note if memory is constrained, this can cause high memory usage due to a dynamic memory allocation to hold the register values, and large local variables in the modbus_write_registers function to store the Modbus request and response.