
The AHTxx series of sensors, e.g. AHT20, AHT30, measure temperature and humidity. The sensor returns 20-bit values for measurements. They are to be converted to °C and %RH by the formulae given above.
All the libraries I've seen so far do the calculation in floating point. For a small MCU that doesn't have native floating point this pulls in extra library code. I wanted to see if this could be done with fixed point arithmetic.
First the humidity calculation. If we load the raw value into a 32-bit variable, multiplying by 100 will not overflow as the max value is 2^20*100. So we do this:
uint32_t l = raw * 100;
Next instead of dividing by 2^20, we divide by 2^16. This can be done by shifting right 16 bits (effectively taking the MSW of the 32-bit value).
uint16_t w = l >> 16;
Now the integer part of the humidity % is in the top 12 bits and the sixteenths of % in the bottom 4 bits. We store these separately. For display we can convert the fractional part to a number between 0 and 10000 in steps of 625, and then use as many decimal digits of that as we want (the accuracy won't be as good as 1/16th %RH or °C anyway). Even a 16-entry lookup table will suffice.
hum->frac = w & 0x0F;
hum->whole = w >> 4;
A similar calculation is applied to the temperature, except that we multiply by 200. For the temperature range of this sensor this also will not overflow 32 bits. After isolating the integral part we subtract 50. Here's a catch: If the result is negative, then we must add 1 to the integral part and subtract the fractional part from 1 (actually 0b10000 since it's in sixteenths) so that both parts are non-positive.
This has been tested with an ESP8266 module (because of the 3.3V supply requirement) driven by an Arduino sketch.
Ken Yap
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.