Sensirion / embedded-i2c-sht4x

Embedded driver for the SHT4x sensor family.
BSD 3-Clause "New" or "Revised" License
8 stars 6 forks source link

Humidity is way to high #4

Closed Exeu closed 1 month ago

Exeu commented 1 month ago

Hi,

i am currently using this in a stm32wb project. So the sensor is hooked up correctly and i am able to communicate with it.

But for some reason the Humidity the sensor reports is 30% higher than what it should be.

Sensor is the following: sht41-ad1f-r2

I am using the following code:

int16_t sht4x_measure_high_precision(int32_t* temperature, int32_t* humidity) {
    int16_t local_error = NO_ERROR;
    uint16_t temperature_ticks;
    uint16_t humidity_ticks;

    local_error =
        sht4x_measure_high_precision_ticks(&temperature_ticks, &humidity_ticks);
    if (local_error != NO_ERROR) {
        return local_error;
    }
    *temperature = (float)(temperature_ticks) / 65535.0f * 175.0f - 45.0f;                   /* convert raw temperature */
    *humidity = (((float)(humidity_ticks) / 65535.0f) * 125.0f - 6.0f);

    /*
    *temperature = convert_ticks_to_celsius(temperature_ticks);
    *humidity = convert_ticks_to_percent_rh(humidity_ticks);
    */

    return local_error;
}

The temperature is around 23 degrees (which matches). But the humidity gets read out with 86% (58% should be)

Regardless how often i read it is always that high.

As you can see i already used the formula coming from the data-sheet instead of this milli rh stuff. In the end both are returning the same rh.

This is how i call the lib:

  sht4x_init(SHT40_I2C_ADDR_44);

  sht4x_soft_reset();
  sensirion_hal_sleep_us(10000);
  uint32_t serial_number = 0;
  error = sht4x_serial_number(&serial_number);
  if (error != NO_ERROR) {
    printf("error executing serial_number(): %i\n", error);
    //return error;
  }
  printf("serial_number: %u\n", serial_number);

  int32_t temperature_milli_degC = 0;
  int32_t humidity_milli_RH = 0;
  uint16_t repetition = 0;
  for (repetition = 0; repetition < 500; repetition++) {
    sensirion_hal_sleep_us(20000);
    error = sht4x_measure_high_precision(&temperature_milli_degC,
                                           &humidity_milli_RH);
    if (error != NO_ERROR) {
      printf("error executing measure_lowest_precision_ticks(): %i\n",
             error);
      continue;
    }
    printf("Temperature milli °C: %li ", temperature_milli_degC);
    printf("Humidity milli percent RH: %i\n", humidity_milli_RH);
  }

Maybe i am doing something wrong or its a falsy sensor.. But i dunno.

Exeu commented 1 month ago

Hmm... maybe i need this conversion stuff for absolute humidity? https://github.com/Sensirion/embedded-sht/blob/master/utils/sensirion_humidity_conversion.c

I am a bit confused with this. Coming from an SHTC3. Applying the conversion function on the value i got with the example above it boils down to be a good match, but i dont get why.

So value from sensor (wich should be RH?) is: ~80% -> Wrong Taking this value now and put it into the "absolute Hum" function -> 46% -> Right.

Exeu commented 1 month ago

Tested another sensor. But same readings

psachs commented 1 month ago

Hi, since you tested with two different sensors I don't think there is anything wrong with the sensors itself.

The embedded driver does not include floating point operations, since a lot of embedded targets don't support floating point. If you prefer output as floating point you can also read the temperature and humidity as ticks and convert them to floating point using the following functions (taken from the Rasperry pi driver: https://github.com/Sensirion/raspberry-pi-i2c-sht4x/blob/master/sht4x_i2c.c#L53C1-L66C2

float sht4x_signal_temperature(uint16_t temperature_ticks) {
    float temperature = 0.0;
    temperature = (float)(temperature_ticks);
    temperature = ((temperature * 175.0) / 65535.0) - 45.0;
    return temperature;
}

float sht4x_signal_humidity(uint16_t humidity_ticks) {
    float humidity = 0.0;
    humidity = (float)(humidity_ticks);
    humidity = ((humidity * 125.0) / 65535.0) - 6.0;
    return humidity;
}

Since I don't know your environment and your reference I can't really verify if your relative humidity is wrong or not. E.g. during rain, resp. in humid conditions a relative humidity of ~80% is possible.

Another possibility is, that there is a numerical issue with your platform. If you can log the raw ticks you can convert them to relative humidity and temperature using your computer (e.g. calculator). If you get the same values, this would rule out any numerical issue.

Converting the relative humidity to absolute humidity is not what you want to do. They are not the same. Absolute humidity is in g/m³ and expresses the actual amount of water vapor per unit volume (e.g. m³). The relative humidity is in percent and is the percentage of the amount of moisture the air can hold.

Best regards, Pascal

Exeu commented 1 month ago

@psachs thank you for the heads up! I will try those things you mentioned and report back here.

To my environment: Its just normal room environment, sunny day quite warm and dry. So the rel hum. is around 45%.

Exeu commented 1 month ago

I now used the formula from above. Same results.

Then i calculated the hum using:

(47109 * 125) / 65535 - 6

So the raw sensor output was: uint16_t ticks = 47109 Also doing it manually i get the same result. The humidity is around 30% higher than it really is.

fyi @psachs

psachs commented 1 month ago

Hi @Exeu

The formula and conversion is correct. In that case the ~83% relative humidity is what the sensor is measuring on your platform. I am not sure how this is possible in a rather dry environment. I assume your humidity signal is changing when you e.g. lightly blow on it and is not constant at 47109 ticks.

I never saw any similar issue before where the humidity signal is off by that much.

Best regards, Pascal

Exeu commented 1 month ago

@psachs you won't believe me but: I now put the same code on my second board featuring the same sensor. And this one is spitting out now the values i expect.

So it may is really a faulty sensor then. I don't know why this sensor was reading the same values as the other one in the beginning -> But now it seems to work (maybe i had there the wrong calculation)..

With this sensor i get now around 44% hum instead of 80 :)

I am quite happy currently (since this took me two days of debugging now)! Thank you for the help and nice support, highly appreciated :)

psachs commented 1 month ago

Hi @Exeu

Great to hear that you get things working. If you think the sensor has problems there is one more thing you can try: Use the heater for a couple minutes (e.g. 5minutes) as follows:

int32_t temperature = 0;
int32_t humidity = 0;
for (int i = 0; i < 300; i++) {
    if (temperature < 100000) {
        // only active the heater if the temperature is below 100°C to ensure the sensor does not overheat.
        sht4x_activate_highest_heater_power_short(*temperature, *humidity);
    }
    sensirion_hal_sleep_us(100000); // sleep for 100ms
}

If the SHT41 sensor is contaminated (e.g. due to storage or shipping) the heater could fix the issue.

Best regards, Pascal

Exeu commented 1 month ago

I will try that. Thank you for the hint :)