BME280 Temperatur ausgetrickst

Der Ärger mit der Temperaturkompensation der BME280 ist endlich behoben.

An der Sensorbox ist außen ein DS18B20 dran. Der übergibt seine Temperatur an den BME, die angepasste BME Lib wandelt den Wert in uint32_t t_fine_ext um und rechnet dann bei Feuchte und Luftdruck mit der Temperatur des DS18B20 anstatt seiner eigenen Temperatur.

Alle Versuche mit ForcedMeasurement schlugen fehl. Entweder ist mein BME ein Ausnahmefall, dass die Temperatur immer so weit weg von der Realität ist, keine Ahnung.
Habe gerade keinen Ersatz zum Austausch.

BME280.h

  void setTemperature(float temperature);


  private:
    uint32_t _t_fine_ext;

BME280.cpp

/**************************************************************************/
/*!
    @brief  Initialise sensor with given parameters / settings
*/
/**************************************************************************/
bool BME280::begin(uint8_t addr) {
  _t_fine_ext = 0;
  .
  .
  .
  .
}

/**************************************************************************/
/*!
    @brief  Returns the temperature from the sensor
*/
/**************************************************************************/
float BME280::readTemperature() {

   if (_t_fine_ext > 0) {
      _t_fine = _t_fine_ext;
      return (((_t_fine_ext * 5 + 128) >> 8) / 100.F);
   }

   int32_t adc_T = read24(BME280_REGISTER_TEMPDATA);
   if (adc_T == 0x800000) // value in case temp measurement was disabled
	return -1000;

   adc_T >>= 4;

   int32_t var1, var2;
   var1 = ((((adc_T >> 3) - ((int32_t)_bme280_calib.dig_T1 << 1))) *
					((int32_t)_bme280_calib.dig_T2)) >> 11;
             
   var2 = (((((adc_T >> 4) - ((int32_t)_bme280_calib.dig_T1)) *
					((adc_T >> 4) - ((int32_t)_bme280_calib.dig_T1))) >> 12) *
					((int32_t)_bme280_calib.dig_T3)) >> 14;

   _t_fine = var1 + var2;

   return (((_t_fine * 5 + 128) >> 8) / 100.F);
}


/*!
 *  Sets a value that be used as temperature instead the buildin temperature. This adjusted
 *  temperature is used in pressure and humidity readings.
 *  @param temperature to be set as internal temperature in Celcius
 */
void BME280::setTemperature(float temperature) {
	 // convert the value in C
	 _t_fine_ext = ((int32_t(temperature * 100) << 8)) / 5;
};

Ist zwar eine Krücke, aber es funktioniert.

Wie lautet eure zustimmende Meinung?

1 Like

freddy64:
Der Ärger mit der Temperaturkompensation der BME280 ist endlich behoben.

Gab’s da Ärger?

Wie lautet eure zustimmende Meinung?

Wozu denn?

Gruß

Gregor

Die Temperaturmessung des BME280 ist die Referenztemperatur für dessen Feuchtigkeitsmessung, nicht die Umgebungstemperatur. Wenn Du die einspeist, dürfte Deine Feuchte nicht mehr stimmen.

Gruß Tommy

Die BME Lib nimmt für Feuchte und Luftdruck immer t_fine als Basis für weitere Berechnungen.

float BME280::readHumidity() {
	
  readTemperature(); // must be done first to get t_fine

  int32_t adc_H = read16(BME280_REGISTER_HUMIDDATA);
  if (adc_H == 0x8000) // value in case humidity measurement was disabled
    return 0;
        
  int32_t v_x1_u32r = (_t_fine - (int32_t)76800);

  v_x1_u32r = (((((adc_H << 14) - (((int32_t)_bme280_calib.dig_H4) << 20) -
									(((int32_t)_bme280_calib.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
									(((((((v_x1_u32r * ((int32_t)_bme280_calib.dig_H6)) >> 10) *
									(((v_x1_u32r * ((int32_t)_bme280_calib.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) +
									((int32_t)2097152)) * ((int32_t)_bme280_calib.dig_H2) + 8192) >> 14));

	 v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) *
									((int32_t)_bme280_calib.dig_H1)) >> 4));

	 v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;

	 return ((v_x1_u32r >> 12) / 1024.0F);
}

Feuchte wird mit 1%RH abweichend von einer Referenz ausgegeben. Damit kann ich leben.

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.