# Receiving a 24-bit Number

I have a sensor hooked up to the I2C lines of Arduino. The sensor outputs a 24-bit number and is read with the following code.

``````  uint8_t pMMSB = Wire.read();

long p_dout = pMMSB << 16 | pMLSB << 8 | pLMSB; //3 Byte (24 bits) Varible
``````

Using this code I get a p_dout value of around -31000. I decided to print out the MMSB, MLSB, LMSB, and got the following.

pMMSB = 171 (10101011)
pMLSB = 136 (10001000)
pLMSB = 100 (01100100)

I put the 3 bytes together and got 11241572 (10101011-10001000-01100100), which is the correct value I should be getting from my sensor! I have tried long, double, unsigned long, float, but nothing gives me the correct value I should be seeing. How do I read a 24-bit value with Arduino?

I thought storing the variable as a 32-bit long would do the trick, but apparently not.

cast the shift 16

``````uint32_t p_dout = (uint32_t)pMMSB << 16 | pMLSB << 8 | pLMSB; //3 Byte (24 bits) Varible
``````

cast the shift 16

No, that is not enough. The shift 8 needs to be specified as unsigned. The automatic integer promotion(signed) from the bit shift <<8 is creating the negative values.

``````void setup() {
Serial.begin(115200);
byte pMMSB = 171;//(10101011)
byte pMLSB = 136;//(10001000)
byte pLMSB = 100;//(01100100)

int32_t p_dout = (int32_t)pMMSB << 16 | (uint16_t)pMLSB << 8 | pLMSB;
//int32_t p_dout = (int32_t)pMMSB << 16 | pMLSB << 8 | pLMSB;

Serial.println(p_dout);
Serial.println(p_dout,BIN);
}

void loop() {}
``````

the safest is to use unsigned integers and to cast all variables before shifting to the ultimate format`uint32_t p_dout = (uint32_t)pMMSB << 16 | (uint32_t)pMLSB << 8 | pLMSB;`