Output Consistency

TucsonDon

Member
I am using a MikroElektronika Temp-Hum 3 click to measure temp & humidity, and having an issue with getting a consistent display.

C:
void ReadOutsideTemp(void)
{
int Temp;
unsigned int Hum;
uint8_t RawTempHum[4];
Temp = RawTempHum[1] << 8 | RawTempHum[0];
Hum = RawTempHum[3] << 8 | RawTempHum[2];
Temp = (Temp / 2^16)*165 - 40;
Hum = (Hum / 2^16)*100;
if (SysConfigbits.TempFormat == ON) Temp = (Temp * 9 / 5) + 32; //change from °C to °F
SysTemp.Out = Temp;     //for lcd display
SysTemp.RH = Hum;   //for lcd display

TempDisplay(); //display on LCD
}
I have the hdc2010 configured for:
Temp-14 bit
Hum-14 bit
auto sample 1 every minute w/ an IOC on RB1 for DRDY

temp is from -120° to 120° and humidity can display from 0 - 220% and changes with every display update
how can I display a more accurate and consistent reading[/code]

Attachments

• 1.5 MB Views: 2
Last edited:

ronsimpson

Well-Known Member
Try averaging the last 10 readings.
----edited----
How bad is the noise. +/-1 number?

Last edited:

TucsonDon

Member
I tried to average and that didn't work. I have work the formula using both the programmer and scientific calculator and think the issue is how I am implementing the exponents.
This is what I have:

C:
int Temp;
float THResult;

THResult = (Temp / 2^16)*165 - 40;
the formula is from the hdc2010 data sheet.

rjenkinsgb

Well-Known Member
the formula is from the hdc2010 data sheet.
All the values should be floats (or be cast to floats) for that to be guaranteed work properly as shown.

See if this works differently?

C:
int Temp;
float THResult;

THResult = ((float) Temp / 65536.0) * 165.0 - 40.0;
I'd probably use a long for storage and keep the results shifted by eg. 8 bits more than the raw values. That allows integer maths with fractional precision.

DrG

Active Member

Hum = (Hum / 2^16)*100;

Run it using:

Hum /= 65536;
Hum *= 100;

Same for Temp:

Temp = (Temp / 2^16)*165 - 40;

Use:
temp /= 65536;
temp *= 165;
temp -= 40;

See if you get a different result. Then, change both to floats.
Also, and I am too lazy to go look, but don't you have to mask the unused bits first?

Of course, I could be wrong.

DrG

Active Member
All the variables should be floats (or be cast to floats) for that to work properly as shown.

I'd probably use a long for storage and keep the results shifted by eg. 8 bits more than the raw values. That allows integer maths with fractional precision.
Beat me by a minute. Also, there is no good reason to use 2^16 instead of the constant.

DrG

Active Member
Also, and I am too lazy to go look, but don't you have to mask the unused bits first?
Now, I see from the data sheet, "The humidity register is a 16-bit result register in binary format (the 2 LSBs D1 and D0 are always 0).", so no, you don't need any masking on humidity.

To add to what has already been said in #4 and working with your code, this should be more accurate.
C:
void ReadOutsideTemp(void)
{
uint16_t Temp, Hum;
uint8_t RawTempHum[4];
float fTemp, fHum;

Temp = RawTempHum[1] << 8 | RawTempHum[0];
Hum = RawTempHum[3] << 8 | RawTempHum[2];
//Temp = (Temp / 2^16)*165 - 40;
//Hum = (Hum / 2^16)*100;
fTemp = ((float)Temp / 65536.0) * 165.0 - 40.0;
fHum = ((float)Hum / 65536.0) * 100.0;
if (SysConfigbits.TempFormat == ON) fTemp = (fTemp * 9 / 5) + 32; //change from °C to °F
SysTemp.Out = fTemp;     //for lcd display
SysTemp.RH = fHum;   //for lcd display
TempDisplay(); //display on LCD
}

TucsonDon

Member
rjenkinsgb & DrG thanks for your input. I got it to work with:
C:
void ReadOutsideTemp(void)
{
uint8_t RawTempHum[4];
int Temp = 0;
int Hum = 0;
double THResult = 0;
Temp = RawTempHum[1] << 8 | RawTempHum[0];
Hum = RawTempHum[3] << 8 | RawTempHum[2];

THResult = (double)(Temp / (pow (2,16)))*165 - 40;
SysTemp.Out = (float)THResult;

THResult = 0;
THResult = (double)(Hum / (pow (2,16)))*100;
SysTemp.RH = (float)THResult;

TempDisplay();
}
once I figured out the pow function from math.h it started to work.

DrG

Active Member
Terrific. I am glad you got it working and I don't want to belabor this point, but why use
(pow (2,16)) instead of the constant 65536.0? I know the data sheet uses 2^16 and you may want to follow that strictly, but is there another reason?

TucsonDon

Member
DrG I used it because of the datasheet, and because of my inexperience it was the easiest for me to figure out.

DrG

Active Member
DrG I used it because of the datasheet, and because of my inexperience it was the easiest for me to figure out.
I get that, thanks for answering.