DFROBOT_RTU: ReadHoldingRegister for multiple register and conversion
I use the DFRobot_RTU library for Modbus Master.
I use
uint8_t readHoldingRegister(uint8_t id, uint16_t reg, uint16_t *data, uint16_t regNum)
to read two holding registers (regNum = 2).
Can you give a code sample how uint16_t *data has to be defined and how the result is converted to a float value?
The Modbus data is big endian.
Thank you
You could define an array in your code, and then pass the name of the array(which is the pointer) to the readHoldingRegister() function. Like the following:
uint16_t array[8];
int result = readHoldingRegister(0x01, 0x08, array, 2);
Then the data you need would be stored in the array. I don't know the detail for your Modbus protocol. So I assumed that the data you need was stored in the fourth and fifth byte. And the endian byte is the third byte.
So you could use the “<<” to move your third byte to get the data you need.
uint16_t data = (array[4]<<8) + array[5];
For eample, if your array[4] is 0x08, your array[5] is 0xFA.
The above line will make you get 0x08FA
Yeez_BThank you for pointing me to the right direction.
It seems that readHoldingRegister() returns the data value in array[0] and array[1].
So ended up with the follwing code giving the correct float value from two subsequent registers:
uint16_t array[2];
float floatValue;
unsigned long *p;
p = (unsigned long*)&floatValue;
// read register a118 and a119 from slaveId 3
uint8_t result = modbus.readHoldingRegister(0x03, 0xa118, array, 2);
if(!result)
{
*p = (unsigned long)array[0]<<16 | array[1]; //considers big-endian
Serial.print("Value: "); Serial.println(floatValue);
}
else
{
Serial.print("Error number: "); Serial.println(result);
}