understanding a bitwise calculation

Hi,

I'm reading some code that performs bitwise operations on an int and stores them in an array. I've worked out the binary representation of each step and included this beside the code.

uint8_t buff[16];

uint8_t * get_reading() {
    memset(buff, 0, sizeof(buff));
    int reading = 423; // 0000000110100111 

    buff[0] = 'B';
    buff[1] = 'V';
    buff[2] = reading&0xff; // 10100111
    buff[3] = (reading>>8)&0xff; //00000001
    buff[4] = (reading>>16)&0xff; //00000000
    buff[5] = (reading>>24)&0xff; ////00000000
    
    *blen = 6;
    return (&buff[0]);
}

On another computer, the array buff is received as a message and displayed in hex as [42,56,da,1,0,0]

Why question is, how could you figure out what the original number was from the hex number. I get that 42 and 56 are the acii equivalent of 'B' and 'V. But how do you get the number 423 from 'da' '1' '0' '0'?

Thanks

ultrasonicbananna: But how do you get the number 423 from 'da' '1' '0' '0'?

From the programmer's manual.

How do you figure you can get 32 bits of byte data from a 16-bit int value?

Regards,
Ray L.

Are you on a 32 bit computer?

On a standard arduino your reading variable as an int will be indeed 2 bytes as you properly represent in binary

What the bitwise Magic do is split your reading integer into 4 bytes from the least significant part to the most significant

On a standard arduino the buff[4] and buff[5] would always be zero because an int is not that big

Once you have “serialized” (that’s how it’s called) your value and send it across the wire you get 6 bytes on the other side and indeed 42 and 56 are the B and V

You will notice that 0xDA is your B10100111 (binary) that was put in buff[2] and 0x1 is your B00000001 that was put in buff[3] and same for the 2 zeros

what you need to do is basically rebuild the int by shifting the bytes in the other direction into an int - let’s call it R - on a 16 bit integer system

Conceptually you do

R = (buff[3] << 8 ) + buff[2];

If you have a 32 bit system on the receiving end then you do

R =(buff[5] << 24) +(buff[4] << 16) + (buff[3] << 8 ) + buff[2];

(Conceptually because you probably need to cast buff[ x ] into an int before you shift the bits right) so more something like

R = (int) buff[5];
R <<=8;
R += (int) buff[4];
R <<=8;
Etc

)

(Assuming buff is the array on the receiving system which holds the values in the order your printed them 0x42, 0x56, 0xDA, 0x01, 0x00, 0x00)

You will notice that 0xDA is your B10100111 (binary)

Well, except it's not... A7

@wetfw - oops I quickly assumed it was and did not check as the other bytes were correct :-)

423 is indeed 0000 0001 1010 0111

which means indeed sending 0xA7 and 0x01

so the question is (besides how do you rebuild the number) why does he get 0xDA instead of 0xA7 while everything else is received correctly

0xDA is 1101 1010 0xA7 is 1010 0111

I would double check for repeatability of the error and also quality of Tx and Rx, baud rates, translation from 5v to 3.3V etc...

Hi J-M-L,

Thanks for your very helpful reply. The code is for a 32 bit mcu.

Sorry, I mistyped the number, it was actually 474, apologies for the confusion.

Thanks C

Hi J-M-L,

Just processing this further - this might be an open ended question but would you know why you would split the reading integer into 4 bytes? Is this a logical thing to do on a 32 bit mcu?

Thanks

Thats because an int in a 32 bit MCU is usually represented with 32 bits rather than 16 on standard Arduino