Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Output Consistency

Status
Not open for further replies.

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];
    i2c1_readDataBlock(TempHum, TempL, RawTempHum, 4);      //read click board
    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

  • hdc2010.pdf
    1.5 MB · Views: 156
Last edited:
Try averaging the last 10 readings.
----edited----
How bad is the noise. +/-1 number?
 
Last edited:
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.
 
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.
 
Instead of using:

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

Run it using:

Hum /= 65536;
Hum *= 100;

Same for Temp:

Instead of :

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.
 
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.
 
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;
 
  i2c1_readDataBlock(TempHum, TempL, RawTempHum, 4);      //read click board
  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
}
 
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;
i2c1_readDataBlock(TempHum, TempL, RawTempHum, 4);      //read click board
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.
 
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?
 
DrG I used it because of the datasheet, and because of my inexperience it was the easiest for me to figure out.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top