Midnite Classic TCP Modbus Help

Started by natux, December 15, 2015, 09:54:27 PM

Previous topic - Next topic

natux

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;
}

dgd

#1
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 );
...
Classic 250, 150,  20 140w, 6 250w PVs, 2Kw turbine, MN ac Clipper, Epanel/MNdc, Trace SW3024E (1997), Century 1050Ah 24V FLA (1999). Arduino power monitoring and web server.  Off grid since 4/2000
West Auckland, New Zealand

atop8918

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).

natux

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!