UncleRus / esp-idf-lib

Component library for ESP32-xx and ESP8266

Home Page:https://esp-idf-lib.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

error in bme680_convert_temperature() when temperature is below 0

ashelman-ec opened this issue · comments

The issue

For temperatures below 0C, the conversion from raw to fixed results in incorrect temperatures of approximately -250C, likely due to some overflow error. Since bme680_convert_temperature() also has the side-effect of setting cd->t_fine, which is used in the calculations of humidity and pressure, those are also affected (humidity will jump to 100%, and pressure will increase significantly).

Bosch BME680 datasheet and their code repository are now using an updated formula, reference:

A fix was verified using Bosch's updated code, see logs below.

Which SDK are you using?

esp-idf

Which version of SDK are you using?

v5.0

Which build target have you used?

  • esp32
  • esp32s2
  • esp32s3
  • esp32c2
  • esp8266
  • other

Component causing the issue

bme680

Anything in the logs that might be useful for us?

=== Logs with library code ===
D (161433) bme680: Started measurement
D (161583) bme680: Raw data: 415070 338646 24157 664 7
D (161583) bme680: Fixed point sensor values: -24677/100 deg.C, 100000/1000 %, 117044 Pa, 56560 Ohm
D (161583) bme680: Floating point sensor values: -246.77 deg.C, 100.00 %, 1170.44 hPa, 56560.00 Ohm
D (163933) bme680: Started measurement
D (164083) bme680: Raw data: 416786 339178 24369 698 7
D (164083) bme680: Fixed point sensor values: -24622/100 deg.C, 100000/1000 %, 116935 Pa, 55295 Ohm
D (164083) bme680: Floating point sensor values: -246.22 deg.C, 100.00 %, 1169.35 hPa, 55295.00 Ohm
D (166433) bme680: Started measurement
D (166583) bme680: Raw data: 419006 339858 24634 753 7
D (166583) bme680: Fixed point sensor values: 23/100 deg.C, 67794/1000 %, 101771 Pa, 53364 Ohm
D (166583) bme680: Floating point sensor values: 0.23 deg.C, 67.79 %, 1017.71 hPa, 53364.00 Ohm
D (168933) bme680: Started measurement
D (169083) bme680: Raw data: 421011 340469 24891 815 7
D (169083) bme680: Fixed point sensor values: 87/100 deg.C, 69601/1000 %, 101773 Pa, 51344 Ohm
D (169083) bme680: Floating point sensor values: 0.87 deg.C, 69.60 %, 1017.73 hPa, 51344.00 Ohm

=== Logs AFTER FIX ===
[ logs are from preliminary code change that just compared the values but didn't store the temperature
  result. But since calculating the "new" result had the side effect of storing the new t_fine,
  humidity & pressure are displayed correctly ]
[ "old" is original code from repository ]
[ "new" is the correct result by using the updated code below ]

D (813933) bme680: Started measurement
D (814083) bme680: Raw data: 418505 338897 22903 320 7
D (814083) bme680: Fixed point sensor values: 8/100 deg.C, 56505/1000 %, 101909 Pa, 73594 Ohm
D (814083) bme680: Floating point sensor values: 0.08 deg.C, 56.51 %, 1019.09 hPa, 73594.00 Ohm
D (816433) bme680: Started measurement
D (816583) bme680: Raw data: 418356 338853 22910 310 7
D (816583) bme680: Fixed point sensor values: 3/100 deg.C, 56541/1000 %, 101909 Pa, 74244 Ohm
D (816583) bme680: Floating point sensor values: 0.03 deg.C, 56.54 %, 1019.09 hPa, 74244.00 Ohm
D (818933) bme680: Started measurement
D (819083) bme680: Raw data: 418204 338808 22920 313 7
W (819083) bme680: Calculated temp does not match: old = -24578, new = -2
D (819083) bme680: Fixed point sensor values: -24578/100 deg.C, 56619/1000 %, 101909 Pa, 74048 Ohm
D (819093) bme680: Floating point sensor values: -245.78 deg.C, 56.62 %, 1019.09 hPa, 74048.00 Ohm
D (821433) bme680: Started measurement
D (821583) bme680: Raw data: 418039 338761 22927 314 7
W (821583) bme680: Calculated temp does not match: old = -24583, new = -7
D (821583) bme680: Fixed point sensor values: -24583/100 deg.C, 56650/1000 %, 101907 Pa, 73983 Ohm
D (821593) bme680: Floating point sensor values: -245.83 deg.C, 56.65 %, 1019.07 hPa, 73983.00 Ohm

Additional information or context

Corrected code:

static int16_t bme680_convert_temperature(bme680_t *dev, uint32_t raw_temperature)
{
    bme680_calib_data_t *cd = &dev->calib_data;

    int64_t var1;
    int64_t var2;
    int64_t var3;
    int16_t temperature;

    var1 = ((int32_t)raw_temperature >> 3) - ((int32_t)cd->par_t1 << 1);
    var2 = (var1 * (int32_t)cd->par_t2) >> 11;
    var3 = ((var1 >> 1) * (var1 >> 1)) >> 12;
    var3 = ((var3) * ((int32_t)cd->par_t3 << 4)) >> 14;
    cd->t_fine = (int32_t)(var2 + var3);
    temperature = (int16_t)(((cd->t_fine * 5) + 128) >> 8);

    return temperature;
}

Confirmation

  • This report is not a question nor a request for drivers.

Thank you!

That was an impressively fast response, speaking for the quality of this repository!