So I was trying to write myself a little logger basically, but I came across something weird.
When I ask for the register 4100-1 on the Classic 150 it gives me "1174", but the documentation says it should give me the model number, "150"
Hoping for some help on this one!
Code:
#include <stdio.h>
#include <inttypes.h>
#include <modbus/modbus.h>
int main(void)
{
int rc;
char *ip;
uint port;
modbus_t *midnite;
uint16_t tab_reg[32];
ip = "192.168.0.200";
port = 502;
midnite = modbus_new_tcp(ip, port);
modbus_connect(midnite);
rc = modbus_read_registers(midnite, 4100, 1, tab_reg);
if (rc != -1)
printf("%hu\n", *tab_reg);
else
printf("[ERR] Could not read register(s)\n");
modbus_close(midnite);
modbus_free(midnite);
return 0;
}
Hi,
doing it without the h modifier for the printf, does your c++ compiler support lowbyte for 16bit integer?
if not then just mask out the upper byte of tab_reg[0]
dgd
uint16_t cmodel;
...
cmodel = (uint16_t) lowbyte(tab_reg[0]);
printf ("%u\n", cmodel );
...
dgd's example is really what you want to be doing.
Just dereferencing a uint16 array won't necessarily give you the first uint16 in the array, it will decompose into whatever value type that printf is expecting in the VA_ARGS, probably an int which will corrupt the value. Even just doing a printf("%hu", tab_reg[0]); might fix it.
I may be wrong, but I also think that 4100-1 (nice notation!) register is a combo of the Classic type and the hardware rev, so you may have to further bit manipulate it to get a nice "150" out of it. I think it was the lower 8-bits so you'd really want something more like:
uint8_t revision = (uint8_t) tab_reg[0];
or even
uint8_t revision = (uint8_t) (tab_reg[0] & 0x00FF);
if you want to be super pedantic about it (always good when writing portable code).
Thank you!
I see now that I didn't actually grab the least significant byte of my returned value...like the docs say to do.
Thanks again for the great responses!