diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index af78ba9a9..78ff3a3b5 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,4 +1,5 @@ /* 6.1.0a + * Update sensor drivers to provide instant results * Add read sensor retry to DS18B20, DS18x20, DHT, SHT1X and HTU21 * Change SHT1x driver to provide better instant results * Fix DHT driver mixing values for different sensors (#1797) diff --git a/sonoff/xsns_08_htu21.ino b/sonoff/xsns_08_htu21.ino index ac56b43e8..ecb127dc6 100644 --- a/sonoff/xsns_08_htu21.ino +++ b/sonoff/xsns_08_htu21.ino @@ -227,9 +227,10 @@ void HtuDetect() void HtuEverySecond() { - if (uptime &1) { + if (92 == (uptime %100)) { HtuDetect(); - } else { + } + else if (uptime &1) { if (htu_type) { if (!HtuRead()) { AddLogMissed(htu_types, htu_valid); @@ -281,6 +282,9 @@ boolean Xsns08(byte function) if (i2c_flg) { switch (function) { + case FUNC_INIT: + HtuDetect(); + break; case FUNC_EVERY_SECOND: HtuEverySecond(); break; diff --git a/sonoff/xsns_09_bmp.ino b/sonoff/xsns_09_bmp.ino index a3769f8bc..4aac0537e 100644 --- a/sonoff/xsns_09_bmp.ino +++ b/sonoff/xsns_09_bmp.ino @@ -45,6 +45,11 @@ uint8_t bmp_type = 0; uint8_t bmp_model = 0; char bmp_name[7]; +uint8_t bmp_valid = 0; +float bmp_temperature = 0.0; +float bmp_pressure = 0.0; +float bmp_humidity = 0.0; + /*********************************************************************************************\ * BMP085 and BME180 \*********************************************************************************************/ @@ -113,21 +118,15 @@ boolean Bmp180Calibration() return true; } -double Bmp180ReadTemperature() +void Bmp180Read() { I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); delay(5); // 5ms conversion time int ut = I2cRead16(bmp_address, BMP180_REG_RESULT); - int32_t x1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; - int32_t x2 = ((int32_t)cal_mc << 11) / (x1 + (int32_t)cal_md); - bmp180_b5 = x1 + x2; - - return ((bmp180_b5 + 8) >> 4) / 10.0; -} - -double Bmp180ReadPressure() -{ - int32_t p; + int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; + int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md); + bmp180_b5 = xt1 + xt2; + bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution @@ -146,19 +145,18 @@ double Bmp180ReadPressure() uint32_t b4 = ((uint32_t)cal_ac4 * (uint32_t)(x3 + 32768)) >> 15; uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS); + int32_t p; if (b7 < 0x80000000) { p = (b7 * 2) / b4; } else { p = (b7 / b4) * 2; } - x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; - p += ((x1 + x2 + (int32_t)3791) >> 4); - return p / 100.0; // convert to mbar + bmp_pressure = p / 100.0; // convert to mbar } /*********************************************************************************************\ @@ -215,8 +213,6 @@ struct BME280CALIBDATA int8_t dig_H6; } Bme280CalibrationData; -int32_t t_fine; - boolean Bmx280Calibrate() { // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; @@ -267,62 +263,43 @@ boolean Bmx280Calibrate() return true; } -double Bme280ReadTemperature(void) +void Bme280Read(void) { - int32_t var1; - int32_t var2; - int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA); adc_T >>= 4; - var1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; - var2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) * + int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; + int32_t vart2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) * ((int32_t)Bme280CalibrationData.dig_T3)) >> 14; - t_fine = var1 + var2; + int32_t t_fine = vart1 + vart2; double T = (t_fine * 5 + 128) >> 8; - return T / 100.0; -} - -double Bme280ReadPressure(void) -{ - int64_t var1; - int64_t var2; - int64_t p; - - // Must be done first to get the t_fine variable set up - // Bme280ReadTemperature(); + bmp_temperature = T / 100.0; int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA); adc_P >>= 4; - var1 = ((int64_t)t_fine) - 128000; - var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6; + int64_t var1 = ((int64_t)t_fine) - 128000; + int64_t var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6; var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17); var2 = var2 + (((int64_t)Bme280CalibrationData.dig_P4) << 35); var1 = ((var1 * var1 * (int64_t)Bme280CalibrationData.dig_P3) >> 8) + ((var1 * (int64_t)Bme280CalibrationData.dig_P2) << 12); var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)Bme280CalibrationData.dig_P1) >> 33; if (0 == var1) { - return 0; // avoid exception caused by division by zero + return; // avoid exception caused by division by zero } - p = 1048576 - adc_P; + int64_t p = 1048576 - adc_P; p = (((p << 31) - var2) * 3125) / var1; var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); - return (double)p / 25600.0; -} + bmp_pressure = (float)p / 25600.0; + + if (BMP280_CHIPID == bmp_type) { return; } -double Bme280ReadHumidity(void) -{ int32_t v_x1_u32r; - // Must be done first to get the t_fine variable set up - // Bme280ReadTemperature(); - int32_t adc_H = I2cRead16(bmp_address, BME280_REGISTER_HUMIDDATA); - v_x1_u32r = (t_fine - ((int32_t)76800)); - v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - (((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) * @@ -332,8 +309,8 @@ double Bme280ReadHumidity(void) ((int32_t)Bme280CalibrationData.dig_H1)) >> 4)); v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; - double h = (v_x1_u32r >> 12); - return h / 1024.0; + float h = (v_x1_u32r >> 12); + bmp_humidity = h / 1024.0; } #ifdef USE_BME680 @@ -345,17 +322,14 @@ double Bme280ReadHumidity(void) struct bme680_dev gas_sensor; +float bmp_gas_resistance = 0.0; +uint8_t bme680_state = 0; + static void BmeDelayMs(uint32_t ms) { delay(ms); } -uint8_t bme680_state = 0; -float bme680_temperature; -float bme680_pressure; -float bme680_humidity; -float bme680_gas_resistance; - boolean Bme680Init() { gas_sensor.dev_id = bmp_address; @@ -400,7 +374,7 @@ boolean Bme680Init() return true; } -void Bme680PerformReading() +void Bme680Read() { int8_t rslt = BME680_OK; @@ -424,14 +398,14 @@ void Bme680PerformReading() rslt = bme680_get_sensor_data(&data, &gas_sensor); if (rslt != BME680_OK) { return; } - bme680_temperature = data.temperature / 100.0; - bme680_humidity = data.humidity / 1000.0; - bme680_pressure = data.pressure; + bmp_temperature = data.temperature / 100.0; + bmp_humidity = data.humidity / 1000.0; + bmp_pressure = data.pressure / 100.0; /* Avoid using measurements from an unstable heating setup */ if (data.status & BME680_GASM_VALID_MSK) { - bme680_gas_resistance = data.gas_resistance; + bmp_gas_resistance = data.gas_resistance / 1000.0; } else { - bme680_gas_resistance = 0; + bmp_gas_resistance = 0; } } } @@ -444,9 +418,7 @@ void Bme680PerformReading() void BmpDetect() { - if (bmp_type) { - return; - } + if (bmp_type) { return; } for (byte i = 0; i < sizeof(bmp_addresses); i++) { bmp_address = bmp_addresses[i]; @@ -456,22 +428,21 @@ void BmpDetect() } } if (bmp_type) { + bmp_model = 0; boolean success = false; switch (bmp_type) { case BMP180_CHIPID: success = Bmp180Calibration(); break; - case BMP280_CHIPID: - bmp_model = 1; // 1 - success = Bmx280Calibrate(); - break; case BME280_CHIPID: - bmp_model = 2; // 2 + bmp_model++; // 2 + case BMP280_CHIPID: + bmp_model++; // 1 success = Bmx280Calibrate(); break; #ifdef USE_BME680 case BME680_CHIPID: - bmp_model = 3; // 2 + bmp_model = 3; // 3 success = Bme680Init(); break; #endif // USE_BME680 @@ -487,54 +458,55 @@ void BmpDetect() } } +void BmpRead() +{ + switch (bmp_type) { + case BMP180_CHIPID: + Bmp180Read(); + break; + case BMP280_CHIPID: + case BME280_CHIPID: + Bme280Read(); + break; +#ifdef USE_BME680 + case BME680_CHIPID: + Bme680Read(); + break; +#endif // USE_BME680 + } + if (bmp_temperature != 0.0) { bmp_temperature = ConvertTemp(bmp_temperature); } +} + +void BmpEverySecond() +{ + if (91 == (uptime %100)) { + BmpDetect(); + } + else if (uptime &1) { + BmpRead(); + } +} + void BmpShow(boolean json) { if (bmp_type) { - float t = 0.0; - float p = 0.0; - float h = 0.0; - float g = 0.0; float bmp_sealevel = 0.0; - - switch (bmp_type) { - case BMP180_CHIPID: - t = Bmp180ReadTemperature(); - p = Bmp180ReadPressure(); - break; - case BME280_CHIPID: - h = Bme280ReadHumidity(); - case BMP280_CHIPID: - t = Bme280ReadTemperature(); - p = Bme280ReadPressure(); - break; -#ifdef USE_BME680 - case BME680_CHIPID: - t = bme680_temperature; - p = bme680_pressure / 100.0; - h = bme680_humidity; - g = bme680_gas_resistance / 1000.0; - break; -#endif // USE_BME680 - } - if (t != 0.0) { - t = ConvertTemp(t); - } - if (p != 0.0) { -// bmp_sealevel = p / pow(1.0 - ((float)Settings.altitude / 44330.0), 5.255); // pow adds 8k to the code - bmp_sealevel = (p / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; - } - char temperature[10]; - dtostrfd(t, Settings.flag2.temperature_resolution, temperature); char pressure[10]; - dtostrfd(p, Settings.flag2.pressure_resolution, pressure); char sea_pressure[10]; - dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); char humidity[10]; - dtostrfd(h, Settings.flag2.humidity_resolution, humidity); + + if (bmp_pressure != 0.0) { + bmp_sealevel = (bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; + } + + dtostrfd(bmp_temperature, Settings.flag2.temperature_resolution, temperature); + dtostrfd(bmp_pressure, Settings.flag2.pressure_resolution, pressure); + dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); + dtostrfd(bmp_humidity, Settings.flag2.humidity_resolution, humidity); #ifdef USE_BME680 char gas_resistance[10]; - dtostrfd(g, 2, gas_resistance); + dtostrfd(bmp_gas_resistance, 2, gas_resistance); #endif // USE_BME680 if (json) { @@ -555,15 +527,15 @@ void BmpShow(boolean json) if (0 == tele_period) { DomoticzTempHumPressureSensor(temperature, humidity, pressure); #ifdef USE_BME680 - if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)g); } + if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_gas_resistance); } #endif // USE_BME680 } #endif // USE_DOMOTICZ #ifdef USE_KNX if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, t); - KnxSensor(KNX_HUMIDITY, h); + KnxSensor(KNX_TEMPERATURE, bmp_temperature); + KnxSensor(KNX_HUMIDITY, bmp_humidity); } #endif // USE_KNX @@ -599,13 +571,11 @@ boolean Xsns09(byte function) if (i2c_flg) { switch (function) { + case FUNC_INIT: + BmpDetect(); + break; case FUNC_EVERY_SECOND: - if (tele_period == Settings.tele_period -2) { // Allow 2 seconds to prepare BME680 readings - BmpDetect(); - } -#ifdef USE_BME680 - Bme680PerformReading(); -#endif // USE_BME680 + BmpEverySecond(); break; case FUNC_JSON_APPEND: BmpShow(1); diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index 19cd86bb3..e845b628f 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -146,6 +146,38 @@ boolean (* const xsns_func_ptr[])(byte) PROGMEM = { // Sensor Function Pointers &Xsns32, #endif +#ifdef XSNS_33 + &Xsns33, +#endif + +#ifdef XSNS_34 + &Xsns34, +#endif + +#ifdef XSNS_35 + &Xsns35, +#endif + +#ifdef XSNS_36 + &Xsns36, +#endif + +#ifdef XSNS_37 + &Xsns37, +#endif + +#ifdef XSNS_38 + &Xsns38, +#endif + +#ifdef XSNS_39 + &Xsns39, +#endif + +#ifdef XSNS_40 + &Xsns40, +#endif + // Optional user defined sensors in range 91 - 99 #ifdef XSNS_91