A Forum run by Enthusiasts of MidNite Solar

MidNite Solar Monitoring software and hardware => MidNite Monitoring FAQ'S => Topic started by: natux on December 15, 2015, 09:54:27 PM

Title: Midnite Classic TCP Modbus Help
Post by: natux on December 15, 2015, 09:54:27 PM
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;
}
Title: Re: Midnite Classic TCP Modbus Help
Post by: dgd on December 15, 2015, 11:37:13 PM
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 );
...
Title: Re: Midnite Classic TCP Modbus Help
Post by: atop8918 on December 16, 2015, 03:49:02 AM
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).
Title: Re: Midnite Classic TCP Modbus Help
Post by: natux on December 25, 2015, 12:32:01 AM
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!