1

I need to do a math to convert a 16-bit value received from sensor to real relative humidity value. It's calculated with following formula:

formula rh=-6+125*(Srh/2^16)

Given this in floating point math that would be:

uint16_t buf = 0x7C80; // Example
float rh = ((float)buf*125 / 65536)-6;

But I want to avoid floating point math as my platform are "FPUless".

What are the most effective way to calculate & store RH in integer math here? Considering it's humidity the actual value should be between 0 and 100% but sometimes approximation could lead that rh could be slightly less than 0 or higher than 100 (if I would leave that float, I could just do something like if (rh<0) rh=0; else if (rh>100) rh=100;) and I care only about last 2 digits after decimal point (%.2f).

Currently I've solved this like this:

int16_t rhint = ((uint32_t)buf*12500 / 65536)-600;

And working with rhint / 100; rhint % 100. But probably there are more effective way?

NStorm
  • 140
  • 7
  • 1
    Whats wrong with current implementation (If the care is taken that `rhint` is divided by 100 or whatever is scaled to)? – WedaPashi May 10 '18 at 09:39
  • @WedaPashi, I don't like it works with 32-bit value to multiply it only to divide it back to 16-bit boundaries. I think there are might be a better solution probably using only 2x 8-bit variables achieved with div&mod. – NStorm May 10 '18 at 09:43
  • What is the maximum value that you can read from the sensor? Is it 0xFFFF? – jwdonahue May 10 '18 at 10:00
  • @jwdonahue 0xFFF0 theoretically as it's 12-bit value actually. – NStorm May 10 '18 at 10:13
  • Is a 32 bits CPU or a 16 bits ? If it's a 32 bits CPU, your solution is fine. But you could also simply do that `rhint = ((uint32_t)buf*125 - 65536 * 6` – benjarobin May 10 '18 at 10:23
  • But practially as we speaking of % value, which can't go above 100 it's somewhere around 0xD9F0. – NStorm May 10 '18 at 10:24

1 Answers1

0

You could avoid the large intermediate term by writing the right hand side as

-6 + (128 - 4 + 1) * S / 65536

Which becomes

-6 + S / 512 - S / 16384 + S / 65536

You might be able to drop the last term, and possibly the penultimate one too depending on how precise you want the basis point truncation to be.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483