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
* 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)

View File

@ -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;

View File

@ -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 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) {
case BMP180_CHIPID:
t = Bmp180ReadTemperature();
p = Bmp180ReadPressure();
Bmp180Read();
break;
case BME280_CHIPID:
h = Bme280ReadHumidity();
case BMP280_CHIPID:
t = Bme280ReadTemperature();
p = Bme280ReadPressure();
case BME280_CHIPID:
Bme280Read();
break;
#ifdef USE_BME680
case BME680_CHIPID:
t = bme680_temperature;
p = bme680_pressure / 100.0;
h = bme680_humidity;
g = bme680_gas_resistance / 1000.0;
Bme680Read();
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;
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 bmp_sealevel = 0.0;
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_EVERY_SECOND:
if (tele_period == Settings.tele_period -2) { // Allow 2 seconds to prepare BME680 readings
case FUNC_INIT:
BmpDetect();
}
#ifdef USE_BME680
Bme680PerformReading();
#endif // USE_BME680
break;
case FUNC_EVERY_SECOND:
BmpEverySecond();
break;
case FUNC_JSON_APPEND:
BmpShow(1);

View File

@ -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