Update sensor drivers

Update sensor drivers to provide instant results
This commit is contained in:
Theo Arends 2018-07-11 14:21:11 +02:00
parent 8fdcbaa8e1
commit 50ce01cd0b
4 changed files with 126 additions and 119 deletions

View File

@ -1,4 +1,5 @@
/* 6.1.0a /* 6.1.0a
* Update sensor drivers to provide instant results
* Add read sensor retry to DS18B20, DS18x20, DHT, SHT1X and HTU21 * Add read sensor retry to DS18B20, DS18x20, DHT, SHT1X and HTU21
* Change SHT1x driver to provide better instant results * Change SHT1x driver to provide better instant results
* Fix DHT driver mixing values for different sensors (#1797) * Fix DHT driver mixing values for different sensors (#1797)

View File

@ -227,9 +227,10 @@ void HtuDetect()
void HtuEverySecond() void HtuEverySecond()
{ {
if (uptime &1) { if (92 == (uptime %100)) {
HtuDetect(); HtuDetect();
} else { }
else if (uptime &1) {
if (htu_type) { if (htu_type) {
if (!HtuRead()) { if (!HtuRead()) {
AddLogMissed(htu_types, htu_valid); AddLogMissed(htu_types, htu_valid);
@ -281,6 +282,9 @@ boolean Xsns08(byte function)
if (i2c_flg) { if (i2c_flg) {
switch (function) { switch (function) {
case FUNC_INIT:
HtuDetect();
break;
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:
HtuEverySecond(); HtuEverySecond();
break; break;

View File

@ -45,6 +45,11 @@ uint8_t bmp_type = 0;
uint8_t bmp_model = 0; uint8_t bmp_model = 0;
char bmp_name[7]; 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 * BMP085 and BME180
\*********************************************************************************************/ \*********************************************************************************************/
@ -113,21 +118,15 @@ boolean Bmp180Calibration()
return true; return true;
} }
double Bmp180ReadTemperature() void Bmp180Read()
{ {
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE);
delay(5); // 5ms conversion time delay(5); // 5ms conversion time
int ut = I2cRead16(bmp_address, BMP180_REG_RESULT); int ut = I2cRead16(bmp_address, BMP180_REG_RESULT);
int32_t x1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15;
int32_t x2 = ((int32_t)cal_mc << 11) / (x1 + (int32_t)cal_md); int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md);
bmp180_b5 = x1 + x2; bmp180_b5 = xt1 + xt2;
bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0;
return ((bmp180_b5 + 8) >> 4) / 10.0;
}
double Bmp180ReadPressure()
{
int32_t p;
I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution
delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high 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 b4 = ((uint32_t)cal_ac4 * (uint32_t)(x3 + 32768)) >> 15;
uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS); uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS);
int32_t p;
if (b7 < 0x80000000) { if (b7 < 0x80000000) {
p = (b7 * 2) / b4; p = (b7 * 2) / b4;
} }
else { else {
p = (b7 / b4) * 2; p = (b7 / b4) * 2;
} }
x1 = (p >> 8) * (p >> 8); x1 = (p >> 8) * (p >> 8);
x1 = (x1 * 3038) >> 16; x1 = (x1 * 3038) >> 16;
x2 = (-7357 * p) >> 16; x2 = (-7357 * p) >> 16;
p += ((x1 + x2 + (int32_t)3791) >> 4); 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; int8_t dig_H6;
} Bme280CalibrationData; } Bme280CalibrationData;
int32_t t_fine;
boolean Bmx280Calibrate() boolean Bmx280Calibrate()
{ {
// if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false;
@ -267,62 +263,43 @@ boolean Bmx280Calibrate()
return true; return true;
} }
double Bme280ReadTemperature(void) void Bme280Read(void)
{ {
int32_t var1;
int32_t var2;
int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA); int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA);
adc_T >>= 4; adc_T >>= 4;
var1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; int32_t vart1 = ((((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 vart2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) *
((int32_t)Bme280CalibrationData.dig_T3)) >> 14; ((int32_t)Bme280CalibrationData.dig_T3)) >> 14;
t_fine = var1 + var2; int32_t t_fine = vart1 + vart2;
double T = (t_fine * 5 + 128) >> 8; double T = (t_fine * 5 + 128) >> 8;
return T / 100.0; bmp_temperature = 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();
int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA); int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA);
adc_P >>= 4; adc_P >>= 4;
var1 = ((int64_t)t_fine) - 128000; int64_t var1 = ((int64_t)t_fine) - 128000;
var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6; int64_t var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6;
var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17); var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17);
var2 = var2 + (((int64_t)Bme280CalibrationData.dig_P4) << 35); 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 = ((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; var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)Bme280CalibrationData.dig_P1) >> 33;
if (0 == var1) { 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; p = (((p << 31) - var2) * 3125) / var1;
var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25;
var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19;
p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); 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; 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); int32_t adc_H = I2cRead16(bmp_address, BME280_REGISTER_HUMIDDATA);
v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (t_fine - ((int32_t)76800));
v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) -
(((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * (((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) *
(((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) * (((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) *
@ -332,8 +309,8 @@ double Bme280ReadHumidity(void)
((int32_t)Bme280CalibrationData.dig_H1)) >> 4)); ((int32_t)Bme280CalibrationData.dig_H1)) >> 4));
v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r;
v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r;
double h = (v_x1_u32r >> 12); float h = (v_x1_u32r >> 12);
return h / 1024.0; bmp_humidity = h / 1024.0;
} }
#ifdef USE_BME680 #ifdef USE_BME680
@ -345,17 +322,14 @@ double Bme280ReadHumidity(void)
struct bme680_dev gas_sensor; struct bme680_dev gas_sensor;
float bmp_gas_resistance = 0.0;
uint8_t bme680_state = 0;
static void BmeDelayMs(uint32_t ms) static void BmeDelayMs(uint32_t ms)
{ {
delay(ms); delay(ms);
} }
uint8_t bme680_state = 0;
float bme680_temperature;
float bme680_pressure;
float bme680_humidity;
float bme680_gas_resistance;
boolean Bme680Init() boolean Bme680Init()
{ {
gas_sensor.dev_id = bmp_address; gas_sensor.dev_id = bmp_address;
@ -400,7 +374,7 @@ boolean Bme680Init()
return true; return true;
} }
void Bme680PerformReading() void Bme680Read()
{ {
int8_t rslt = BME680_OK; int8_t rslt = BME680_OK;
@ -424,14 +398,14 @@ void Bme680PerformReading()
rslt = bme680_get_sensor_data(&data, &gas_sensor); rslt = bme680_get_sensor_data(&data, &gas_sensor);
if (rslt != BME680_OK) { return; } if (rslt != BME680_OK) { return; }
bme680_temperature = data.temperature / 100.0; bmp_temperature = data.temperature / 100.0;
bme680_humidity = data.humidity / 1000.0; bmp_humidity = data.humidity / 1000.0;
bme680_pressure = data.pressure; bmp_pressure = data.pressure / 100.0;
/* Avoid using measurements from an unstable heating setup */ /* Avoid using measurements from an unstable heating setup */
if (data.status & BME680_GASM_VALID_MSK) { if (data.status & BME680_GASM_VALID_MSK) {
bme680_gas_resistance = data.gas_resistance; bmp_gas_resistance = data.gas_resistance / 1000.0;
} else { } else {
bme680_gas_resistance = 0; bmp_gas_resistance = 0;
} }
} }
} }
@ -444,9 +418,7 @@ void Bme680PerformReading()
void BmpDetect() void BmpDetect()
{ {
if (bmp_type) { if (bmp_type) { return; }
return;
}
for (byte i = 0; i < sizeof(bmp_addresses); i++) { for (byte i = 0; i < sizeof(bmp_addresses); i++) {
bmp_address = bmp_addresses[i]; bmp_address = bmp_addresses[i];
@ -456,22 +428,21 @@ void BmpDetect()
} }
} }
if (bmp_type) { if (bmp_type) {
bmp_model = 0;
boolean success = false; boolean success = false;
switch (bmp_type) { switch (bmp_type) {
case BMP180_CHIPID: case BMP180_CHIPID:
success = Bmp180Calibration(); success = Bmp180Calibration();
break; break;
case BMP280_CHIPID:
bmp_model = 1; // 1
success = Bmx280Calibrate();
break;
case BME280_CHIPID: case BME280_CHIPID:
bmp_model = 2; // 2 bmp_model++; // 2
case BMP280_CHIPID:
bmp_model++; // 1
success = Bmx280Calibrate(); success = Bmx280Calibrate();
break; break;
#ifdef USE_BME680 #ifdef USE_BME680
case BME680_CHIPID: case BME680_CHIPID:
bmp_model = 3; // 2 bmp_model = 3; // 3
success = Bme680Init(); success = Bme680Init();
break; break;
#endif // USE_BME680 #endif // USE_BME680
@ -487,54 +458,55 @@ void BmpDetect()
} }
} }
void BmpShow(boolean json) void BmpRead()
{ {
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) { switch (bmp_type) {
case BMP180_CHIPID: case BMP180_CHIPID:
t = Bmp180ReadTemperature(); Bmp180Read();
p = Bmp180ReadPressure();
break; break;
case BME280_CHIPID:
h = Bme280ReadHumidity();
case BMP280_CHIPID: case BMP280_CHIPID:
t = Bme280ReadTemperature(); case BME280_CHIPID:
p = Bme280ReadPressure(); Bme280Read();
break; break;
#ifdef USE_BME680 #ifdef USE_BME680
case BME680_CHIPID: case BME680_CHIPID:
t = bme680_temperature; Bme680Read();
p = bme680_pressure / 100.0;
h = bme680_humidity;
g = bme680_gas_resistance / 1000.0;
break; break;
#endif // USE_BME680 #endif // USE_BME680
} }
if (t != 0.0) { if (bmp_temperature != 0.0) { bmp_temperature = ConvertTemp(bmp_temperature); }
t = ConvertTemp(t); }
void BmpEverySecond()
{
if (91 == (uptime %100)) {
BmpDetect();
} }
if (p != 0.0) { else if (uptime &1) {
// bmp_sealevel = p / pow(1.0 - ((float)Settings.altitude / 44330.0), 5.255); // pow adds 8k to the code BmpRead();
bmp_sealevel = (p / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; }
}
void BmpShow(boolean json)
{
if (bmp_type) {
float bmp_sealevel = 0.0;
char temperature[10];
char pressure[10];
char sea_pressure[10];
char humidity[10];
if (bmp_pressure != 0.0) {
bmp_sealevel = (bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6;
} }
char temperature[10]; dtostrfd(bmp_temperature, Settings.flag2.temperature_resolution, temperature);
dtostrfd(t, Settings.flag2.temperature_resolution, temperature); dtostrfd(bmp_pressure, Settings.flag2.pressure_resolution, pressure);
char pressure[10];
dtostrfd(p, Settings.flag2.pressure_resolution, pressure);
char sea_pressure[10];
dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure);
char humidity[10]; dtostrfd(bmp_humidity, Settings.flag2.humidity_resolution, humidity);
dtostrfd(h, Settings.flag2.humidity_resolution, humidity);
#ifdef USE_BME680 #ifdef USE_BME680
char gas_resistance[10]; char gas_resistance[10];
dtostrfd(g, 2, gas_resistance); dtostrfd(bmp_gas_resistance, 2, gas_resistance);
#endif // USE_BME680 #endif // USE_BME680
if (json) { if (json) {
@ -555,15 +527,15 @@ void BmpShow(boolean json)
if (0 == tele_period) { if (0 == tele_period) {
DomoticzTempHumPressureSensor(temperature, humidity, pressure); DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#ifdef USE_BME680 #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_BME680
} }
#endif // USE_DOMOTICZ #endif // USE_DOMOTICZ
#ifdef USE_KNX #ifdef USE_KNX
if (0 == tele_period) { if (0 == tele_period) {
KnxSensor(KNX_TEMPERATURE, t); KnxSensor(KNX_TEMPERATURE, bmp_temperature);
KnxSensor(KNX_HUMIDITY, h); KnxSensor(KNX_HUMIDITY, bmp_humidity);
} }
#endif // USE_KNX #endif // USE_KNX
@ -599,13 +571,11 @@ boolean Xsns09(byte function)
if (i2c_flg) { if (i2c_flg) {
switch (function) { switch (function) {
case FUNC_EVERY_SECOND: case FUNC_INIT:
if (tele_period == Settings.tele_period -2) { // Allow 2 seconds to prepare BME680 readings
BmpDetect(); BmpDetect();
} break;
#ifdef USE_BME680 case FUNC_EVERY_SECOND:
Bme680PerformReading(); BmpEverySecond();
#endif // USE_BME680
break; break;
case FUNC_JSON_APPEND: case FUNC_JSON_APPEND:
BmpShow(1); BmpShow(1);

View File

@ -146,6 +146,38 @@ boolean (* const xsns_func_ptr[])(byte) PROGMEM = { // Sensor Function Pointers
&Xsns32, &Xsns32,
#endif #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 // Optional user defined sensors in range 91 - 99
#ifdef XSNS_91 #ifdef XSNS_91