# 24 bit ADC output

hello
I have a 24 bit adc but there is no 3 byte data type in arduino so I just used the uint32_t which is a 32 bit unsigned int.My actual output however, is a 24 bit signed number as you can see below:

can you please help me convert the result into a correct integer so I can use it to calculate actual voltage values? I know I should divide the output by 2^24 and multiply it by the voltage reference, but it won’t be correct unless the integer is correctly converted.thanks.

P.S: here is the code that I use to retrieve the output if it matters:

``````uint32_t readData(){
Wire.write(0x10);
Wire.endTransmission();
byte dataMSB = Wire.read();
byte data = Wire.read();
byte dataLSB = Wire.read();
uint32_t data32 = dataMSB;
data32 <<= 8;
data32 |= data;
data32 <<= 8;
data32 |= dataLSB;
return data32;
}
``````

You need to sign extend your 24 bits to 32. That means look at the most significant bit of the 24 bit value and if it is 1 then make the top byte all ones.

``````if(input & 0x800 != 0) input = input | 0xF000;
``````

@OP

if(bitRead(data32, 23) == HIGH)
{
decimal value = -b23*223 + (b22*222 + … + b0*20)
}

else
{
decimal value = + (b22*222 + … + b0*20)
}

if ( data32 & 0x00800000) data32 += 0xFF000000; // Convert to negative 24-bit word (2's comp)

Which board are you using?
AVR-GCC has __int24 and __uint24 types.

If you want a signed value you can start by using ‘int32_t’ instead of ‘uint32_t’.

``````unt32_t readSigned24bitData(){
Wire.write(0x10);
Wire.endTransmission();
byte dataMSB = Wire.read();
byte data = Wire.read();
byte dataLSB = Wire.read();
int32_t data32 = dataMSB;
data32 <<= 8;
data32 |= data;
data32 <<= 8;
data32 |= dataLSB;
// Sign-extend to 32 bits
if (data32 & 0x00800000L)
data32 |= 0xFF000000;
return data32;
}
``````

Thanks everyone, I simply shifted it left by 8 bits and then right by 8 bits to extend the bit sign and it seems to work fine I think the If method is a bit faster so I will try that later on.