Modbus TCP with uint64_t type answer

Hi
I have a mega 2560 and an Ethernet module.
I am trying to communicate with Carlo Gavacci WM40 with Modbus TCP.

I have got it to work but still have a problem with data that sends with uint64_t.

The request looks like this:

uint64_t = Total_kWh_Pos;
Total_kWh_Pos = modbusTCPClient.holdingRegisterRead(0x00, 0x050C);

I found in the library that the function use uint16_t and looks like this:

uint16_t ModbusClient::holdingRegisterRead(int id, int address) { uint64_t value;

modbus_set_slave(_mb, id);

if (modbus_read_registers(_mb, address, 1, &value) < 0) {
return -1;
}

So I guess that's the reason why I can't get higher value than 2 bytes.
I have tried to change this in the library but can't compile if I change it to uint64_t.

Anyone that knows how I can handle uint64_t?

modbus registers are 2 bytes. larger values are stored in multiple registers. so you have to read the registers and then combine them to the larger value

Thanks @Juraj for the answer.
So if you look at the picture below I should read 500, 501,502 and 503 and combined them?
I have tried that but I got zero for 501, 502 and 503.

do you know what valued should it be?

Yes I know the value and I know that I only get 2 bytes.
I got the correct value until it goes above 2 bytes.

I got a lot of 1 in the other 3 responses.

Screenshot 2021-05-25 at 18.46.15

then the zeros in 501, 502, 503 are ok?
does the documentation say in what order are the bytes of the 64 bit value. because it is not defined by the standard

No the value are more than 2 bytes now so its should not be 11111111.


As you can see at the calculator I am missing the last byte 00001001
Screenshot 2021-05-25 at 19.40.50

I don't understand the output.
do

uint16_t value[4];
modbus_read_registers(_mb, address, 4, &value);

and print the 4 values

What is _mb?

And I think you mean like this, because its TCP not RTU.

modbusTCPClient.holdingRegisterRead(_mb, 0x504, 4, &value);

Here can you see the bytes

I copied modbus_read_registers(_mb, address, 1, &value); from your post.

the order of bytes doesn't have to be 4 3 2 1. it could be 3 4 1 2

Oh my mistake, that's code came from the .CPP file.
I have tried to change it to 4 but no success, I got error message.

That the order can be the opposite I understand but I am still missing data.

Must be someone else that have this problem too?

Hi
Finally I found what was wrong!

@Juraj you was right that I should read each register and I used the wrong command.
I used holdingregisterread() and that is only for one.

I shall use requestFrom() and then use read() to get the data.

But the documentation was not so clear how it works.
To request the data was clear but not how to read it.

Example so other people can have help from this and understand:

modbusTCPClient.requestFrom(0x00,3, 0x500, 4)); //request 4 register with start at 500

//Then you need to ask 4 times for the data with read()

    Total_kWh_Pos0 = modbusTCPClient.read();
    Total_kWh_Pos1 = modbusTCPClient.read();
    Total_kWh_Pos2 = modbusTCPClient.read();
    Total_kWh_Pos3 = modbusTCPClient.read();

Thanks again @Juraj to help me to get progress in this problem.