Measurement App and 32 bit numbers

Discussion in 'C-Bus Serial Protocols' started by pspeirs, May 6, 2021.

  1. pspeirs

    pspeirs

    Joined:
    Nov 23, 2013
    Messages:
    159
    Likes Received:
    5
    Location:
    Sydney
    Hey all,

    I guess this was about the most appropriate place to post this. I want to transmit a 32 bit unsigned counter value through the measurement app. All is good until I hit 32767 obviously as beyond that I start to send the value with a scaling value which is fine for voltages, currents, etc. I'm trying to work out a way that I can send a larger number, perhaps splitting it into signed 16 bit values that I can feed into the cbus "cbus_measurement_vf_send_data" function from the Cbus C++ libraries.


    Cheers,
    Paul
     
    pspeirs, May 6, 2021
    #1
    1. Advertisements

  2. pspeirs

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,218
    Likes Received:
    126
    Location:
    Adelaide, Australia
    The "cbus_measurement_vf_send_data" function just takes a 16 bit integer and scale factor and shoves it out onto the bus. So just split your 32 bit number into 2 16 bit integers and put them on seperate channels with a 0 scale factor. At the other end just read them as raw integers and put them back together again.
     
    Ashley, May 6, 2021
    #2
    1. Advertisements

  3. pspeirs

    pspeirs

    Joined:
    Nov 23, 2013
    Messages:
    159
    Likes Received:
    5
    Location:
    Sydney
    Yeah, that's what I initially thought, but I can't push a full 16 bit number (65535) in though without it being interpreted as a negative, so 0111 1111 1111 1111 would be 32767 but 1111 1111 1111 1111 would be -32767 rather than 65535.
     
    pspeirs, May 6, 2021
    #3
  4. pspeirs

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,218
    Likes Received:
    126
    Location:
    Adelaide, Australia
    Create a C union containing a 32 bit signed integer and an array of 2 16 bit signed integers. Then just put the 32 bit integer into it and read out the 2 16 bit integers.
     
    Ashley, May 6, 2021
    #4
  5. pspeirs

    pspeirs

    Joined:
    Nov 23, 2013
    Messages:
    159
    Likes Received:
    5
    Location:
    Sydney
    Still doesn't do what I need. Using the following for example, just gives me a result of -32746 which is not what I'm after obviously. It seems that bit 16 is getting a 1 which is indicating a negative number.

    My source however is an unsigned 32 bit number (I like to go big), but I get the same results.

    Only thing I can think of is to convert the 32 bit into 4 8 bit numbers which will ensure that they will be in range and send 4 measurement messages which can then be put back together at the end.

    Otherwise maybe use some fancy bit shifting on the 32 bit number to ensure that I'm only using the first 15 bits of the 16 bit numbers, even then I'd use less space with 4 8 bit numbers.

    Does that make sense, or am I just missing something obvious (wouldn't be the first time)

    Code:
        union t {
            int32_t bit32;
            int16_t bit16[2];
        };
    
        t myunion;
        myunion.bit32 = 32790;
    
     
    pspeirs, May 7, 2021
    #5
  6. pspeirs

    Ashley

    Joined:
    Dec 1, 2005
    Messages:
    1,218
    Likes Received:
    126
    Location:
    Adelaide, Australia
    How are you reading it at the other end? It doesn't matter that it thinks it's -ve when you send it if you just reverse the procedure at the other end. i.e. stick the 2 signed integers into the union and read out the 32 bit value.
     
    Ashley, May 7, 2021
    #6
  7. pspeirs

    pspeirs

    Joined:
    Nov 23, 2013
    Messages:
    159
    Likes Received:
    5
    Location:
    Sydney
    yep, OK, I see what you're saying there.
    I'm reading the value/values from the measurement objects in the SHAC, so would be using LUA for this.
     
    pspeirs, May 7, 2021
    #7
  8. pspeirs

    pspeirs

    Joined:
    Nov 23, 2013
    Messages:
    159
    Likes Received:
    5
    Location:
    Sydney
    Seems I may be able to convert back to an unsigned using the following code. I'll look into that a bit further perhaps as that may give me what I'm looking for where the following values correctly give me
    a value of 62836

    Code:
    local DIV, SUBT = math.pow(2, 15) + 1, math.pow(2, 16)
    local n = -2700
    log(n - (math.floor(n / DIV) * SUBT))
    
     
    pspeirs, May 7, 2021
    #8
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.