eModbus / eModbus

Modbus library for RTU, ASCII and TCP protocols. Primarily developed on and for ESP32 MCUs.

Home Page:https://emodbus.github.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Strange results

georgeslegros opened this issue · comments

Do not use to discuss topics!

Describe the bug
I am using the ModbusTcpClient and based my code partly on the examples I found in this repo.
I'm sending the following request

Error err = MB.addRequest((uint32_t)millis(), modbusSlave, READ_HOLD_REGISTER, modbusPowerAddress, 2);

I have validated the modbusSlave and modbusPowerAddress.

Anyway, I am asking to read 2 words from a holding register.

The handle data returns the following results:

Response: serverID=3, FC=3, Token=00001283, length=7:
03 03 04 00 00 03 55 

I'm a bit puzzled to have a response that has 7 bytes and to be honest, I'm not too sure how to interpret the result.

Expected behavior
I expect to receive a 4 bytes result and if I could get a way to transform this into a decimal (int) value that'd be great.

EDIT: I checked with a piece of code written in dotnet reading the same register and I receive a response containing 2 bytes (well, it's actually an array of 2 ushorts) of data. I transform those to a uint by doing this:

var value = (uint)(data[0] << 16) + data[1];

I'm reading the data from my solar inverter and as it is dark right now, I get 0 as a result but this code definitely works when the sun is shining.

Hi,

You in fact do get 4 data bytes, you will have to take the necessary header into consideration:

  • 03 is the server ID
  • the next 03 is the function code for "read holding register"
  • 04 is the number of bytes to follow - this ends the header
  • The next 00 00 is the first register content
  • 03 55 is the second uint16_t value

To read these, you need to do something like

uint16_t value1, value2;
uint16_t offset = 3;   // skip the header
offset = response.get(offset, value1);
offset = response.get(offset, value2);

// Alternatively to get a 4 byte int
uint32_t value3;
offset = 3;  // reset offset to first data byte
offset = response.get(offset, value3);

Assuming that your received response message is named response.

Thanks a lot, that makes a lot of sense!