2017-01-28 13:41:01 +00:00
/*
2019-10-27 10:13:24 +00:00
xsns_09_bmp . ino - BMP pressure , temperature , humidity and gas sensor support for Tasmota
2017-05-13 12:02:10 +01:00
2021-01-01 12:44:04 +00:00
Copyright ( C ) 2021 Heiko Krupp and Theo Arends
2017-05-13 12:02:10 +01:00
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2017-01-28 13:41:01 +00:00
*/
# ifdef USE_I2C
# ifdef USE_BMP
/*********************************************************************************************\
2017-12-06 16:14:41 +00:00
* BMP085 , BMP180 , BMP280 , BME280 , BME680 - Pressure , Temperature , Humidity ( BME280 / BME680 ) and gas ( BME680 )
2017-01-28 13:41:01 +00:00
*
* Source : Heiko Krupp and Adafruit Industries
2017-11-11 11:33:30 +00:00
*
* I2C Address : 0x76 or 0x77
2017-01-28 13:41:01 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-11-06 16:33:51 +00:00
# define XSNS_09 9
2019-11-03 16:54:39 +00:00
# define XI2C_10 10 // See I2CDEVICES.md
2018-11-06 16:33:51 +00:00
2018-10-29 14:46:03 +00:00
# define BMP_ADDR1 0x76
# define BMP_ADDR2 0x77
2017-01-28 13:41:01 +00:00
2017-10-23 11:18:15 +01:00
# define BMP180_CHIPID 0x55
# define BMP280_CHIPID 0x58
# define BME280_CHIPID 0x60
2017-12-06 16:14:41 +00:00
# define BME680_CHIPID 0x61
2017-01-28 13:41:01 +00:00
2017-10-23 11:18:15 +01:00
# define BMP_REGISTER_CHIPID 0xD0
2017-01-28 13:41:01 +00:00
2020-01-02 20:38:18 +00:00
# define BMP_REGISTER_RESET 0xE0 // Register to reset to power on defaults (used for sleep)
# define BMP_CMND_RESET 0xB6 // I2C Parameter for RESET to put BMP into reset state
2018-10-29 14:46:03 +00:00
# define BMP_MAX_SENSORS 2
2017-11-11 11:33:30 +00:00
2018-10-29 14:46:03 +00:00
const char kBmpTypes [ ] PROGMEM = " BMP180|BMP280|BME280|BME680 " ;
2018-12-21 10:36:55 +00:00
typedef struct {
2018-10-29 14:46:03 +00:00
uint8_t bmp_address ; // I2C bus address
char bmp_name [ 7 ] ; // Sensor name - "BMPXXX"
2018-12-21 15:17:06 +00:00
uint8_t bmp_type ;
uint8_t bmp_model ;
2018-10-29 14:46:03 +00:00
# ifdef USE_BME680
2018-12-21 15:17:06 +00:00
uint8_t bme680_state ;
float bmp_gas_resistance ;
2018-10-29 14:46:03 +00:00
# endif // USE_BME680
2018-12-21 15:17:06 +00:00
float bmp_temperature ;
float bmp_pressure ;
float bmp_humidity ;
2018-12-21 10:36:55 +00:00
} bmp_sensors_t ;
uint8_t bmp_addresses [ ] = { BMP_ADDR1 , BMP_ADDR2 } ;
uint8_t bmp_count = 0 ;
uint8_t bmp_once = 1 ;
2019-03-26 17:26:50 +00:00
bmp_sensors_t * bmp_sensors = nullptr ;
2018-07-11 13:21:11 +01:00
2017-01-28 13:41:01 +00:00
/*********************************************************************************************\
* BMP085 and BME180
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-10-23 11:18:15 +01:00
# define BMP180_REG_CONTROL 0xF4
# define BMP180_REG_RESULT 0xF6
# define BMP180_TEMPERATURE 0x2E
# define BMP180_PRESSURE3 0xF4 // Max. oversampling -> OSS = 3
# define BMP180_AC1 0xAA
# define BMP180_AC2 0xAC
# define BMP180_AC3 0xAE
# define BMP180_AC4 0xB0
# define BMP180_AC5 0xB2
# define BMP180_AC6 0xB4
# define BMP180_VB1 0xB6
# define BMP180_VB2 0xB8
# define BMP180_MB 0xBA
# define BMP180_MC 0xBC
# define BMP180_MD 0xBE
# define BMP180_OSS 3
2018-12-21 10:36:55 +00:00
typedef struct {
2018-10-30 14:20:19 +00:00
int16_t cal_ac1 ;
int16_t cal_ac2 ;
int16_t cal_ac3 ;
int16_t cal_b1 ;
int16_t cal_b2 ;
int16_t cal_mc ;
int16_t cal_md ;
uint16_t cal_ac4 ;
uint16_t cal_ac5 ;
uint16_t cal_ac6 ;
2018-12-21 10:36:55 +00:00
} bmp180_cal_data_t ;
2019-03-26 17:26:50 +00:00
bmp180_cal_data_t * bmp180_cal_data = nullptr ;
2018-10-30 14:20:19 +00:00
2019-01-28 13:08:33 +00:00
bool Bmp180Calibration ( uint8_t bmp_idx )
2017-01-28 13:41:01 +00:00
{
2018-12-21 10:36:55 +00:00
if ( ! bmp180_cal_data ) {
bmp180_cal_data = ( bmp180_cal_data_t * ) malloc ( BMP_MAX_SENSORS * sizeof ( bmp180_cal_data_t ) ) ;
}
if ( ! bmp180_cal_data ) { return false ; }
2018-10-30 14:20:19 +00:00
bmp180_cal_data [ bmp_idx ] . cal_ac1 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC1 ) ;
bmp180_cal_data [ bmp_idx ] . cal_ac2 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC2 ) ;
bmp180_cal_data [ bmp_idx ] . cal_ac3 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC3 ) ;
bmp180_cal_data [ bmp_idx ] . cal_ac4 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC4 ) ;
bmp180_cal_data [ bmp_idx ] . cal_ac5 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC5 ) ;
bmp180_cal_data [ bmp_idx ] . cal_ac6 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_AC6 ) ;
bmp180_cal_data [ bmp_idx ] . cal_b1 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_VB1 ) ;
bmp180_cal_data [ bmp_idx ] . cal_b2 = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_VB2 ) ;
bmp180_cal_data [ bmp_idx ] . cal_mc = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_MC ) ;
bmp180_cal_data [ bmp_idx ] . cal_md = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_MD ) ;
2017-01-28 13:41:01 +00:00
// Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF
2018-10-30 14:20:19 +00:00
if ( ! bmp180_cal_data [ bmp_idx ] . cal_ac1 |
! bmp180_cal_data [ bmp_idx ] . cal_ac2 |
! bmp180_cal_data [ bmp_idx ] . cal_ac3 |
! bmp180_cal_data [ bmp_idx ] . cal_ac4 |
! bmp180_cal_data [ bmp_idx ] . cal_ac5 |
! bmp180_cal_data [ bmp_idx ] . cal_ac6 |
! bmp180_cal_data [ bmp_idx ] . cal_b1 |
! bmp180_cal_data [ bmp_idx ] . cal_b2 |
! bmp180_cal_data [ bmp_idx ] . cal_mc |
! bmp180_cal_data [ bmp_idx ] . cal_md ) {
2017-04-25 17:24:42 +01:00
return false ;
}
2018-10-30 14:20:19 +00:00
if ( ( bmp180_cal_data [ bmp_idx ] . cal_ac1 = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_ac2 = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_ac3 = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_ac4 = = 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_ac5 = = 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_ac6 = = 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_b1 = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_b2 = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_mc = = ( int16_t ) 0xFFFF ) |
( bmp180_cal_data [ bmp_idx ] . cal_md = = ( int16_t ) 0xFFFF ) ) {
2017-04-25 17:24:42 +01:00
return false ;
}
2017-01-28 13:41:01 +00:00
return true ;
}
2018-10-30 14:20:19 +00:00
void Bmp180Read ( uint8_t bmp_idx )
2017-01-28 13:41:01 +00:00
{
2018-12-21 10:36:55 +00:00
if ( ! bmp180_cal_data ) { return ; }
2018-10-29 14:46:03 +00:00
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_REG_CONTROL , BMP180_TEMPERATURE ) ;
2017-01-28 13:41:01 +00:00
delay ( 5 ) ; // 5ms conversion time
2018-10-29 14:46:03 +00:00
int ut = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_REG_RESULT ) ;
2018-10-30 14:20:19 +00:00
int32_t xt1 = ( ut - ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac6 ) * ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac5 ) > > 15 ;
int32_t xt2 = ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_mc < < 11 ) / ( xt1 + ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_md ) ;
2018-07-11 13:39:07 +01:00
int32_t bmp180_b5 = xt1 + xt2 ;
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_temperature = ( ( bmp180_b5 + 8 ) > > 4 ) / 10.0 ;
2017-01-28 13:41:01 +00:00
2018-10-29 14:46:03 +00:00
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_REG_CONTROL , BMP180_PRESSURE3 ) ; // Highest resolution
2017-10-23 11:18:15 +01:00
delay ( 2 + ( 4 < < BMP180_OSS ) ) ; // 26ms conversion time at ultra high resolution
2018-10-29 14:46:03 +00:00
uint32_t up = I2cRead24 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP180_REG_RESULT ) ;
2017-01-28 13:41:01 +00:00
up > > = ( 8 - BMP180_OSS ) ;
int32_t b6 = bmp180_b5 - 4000 ;
2018-10-30 14:20:19 +00:00
int32_t x1 = ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_b2 * ( ( b6 * b6 ) > > 12 ) ) > > 11 ;
int32_t x2 = ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac2 * b6 ) > > 11 ;
2017-01-28 13:41:01 +00:00
int32_t x3 = x1 + x2 ;
2018-10-30 14:20:19 +00:00
int32_t b3 = ( ( ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac1 * 4 + x3 ) < < BMP180_OSS ) + 2 ) > > 2 ;
2017-01-28 13:41:01 +00:00
2018-10-30 14:20:19 +00:00
x1 = ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac3 * b6 ) > > 13 ;
x2 = ( ( int32_t ) bmp180_cal_data [ bmp_idx ] . cal_b1 * ( ( b6 * b6 ) > > 12 ) ) > > 16 ;
2017-01-28 13:41:01 +00:00
x3 = ( ( x1 + x2 ) + 2 ) > > 2 ;
2018-10-30 14:20:19 +00:00
uint32_t b4 = ( ( uint32_t ) bmp180_cal_data [ bmp_idx ] . cal_ac4 * ( uint32_t ) ( x3 + 32768 ) ) > > 15 ;
2017-10-08 15:51:05 +01:00
uint32_t b7 = ( ( uint32_t ) up - b3 ) * ( uint32_t ) ( 50000UL > > BMP180_OSS ) ;
2017-01-28 13:41:01 +00:00
2018-07-11 13:21:11 +01:00
int32_t p ;
2017-01-28 13:41:01 +00:00
if ( b7 < 0x80000000 ) {
p = ( b7 * 2 ) / b4 ;
2017-10-08 15:51:05 +01:00
}
else {
2017-01-28 13:41:01 +00:00
p = ( b7 / b4 ) * 2 ;
}
x1 = ( p > > 8 ) * ( p > > 8 ) ;
x1 = ( x1 * 3038 ) > > 16 ;
x2 = ( - 7357 * p ) > > 16 ;
2017-10-08 15:51:05 +01:00
p + = ( ( x1 + x2 + ( int32_t ) 3791 ) > > 4 ) ;
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_pressure = ( float ) p / 100.0 ; // convert to mbar
2017-01-28 13:41:01 +00:00
}
/*********************************************************************************************\
* BMP280 and BME280
*
* Programmer : BMP280 / BME280 Datasheet and Adafruit with changes by Theo Arends
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2017-10-23 11:18:15 +01:00
# define BME280_REGISTER_CONTROLHUMID 0xF2
# define BME280_REGISTER_CONTROL 0xF4
2017-12-03 15:17:47 +00:00
# define BME280_REGISTER_CONFIG 0xF5
2017-10-23 11:18:15 +01:00
# define BME280_REGISTER_PRESSUREDATA 0xF7
# define BME280_REGISTER_TEMPDATA 0xFA
# define BME280_REGISTER_HUMIDDATA 0xFD
# define BME280_REGISTER_DIG_T1 0x88
# define BME280_REGISTER_DIG_T2 0x8A
# define BME280_REGISTER_DIG_T3 0x8C
# define BME280_REGISTER_DIG_P1 0x8E
# define BME280_REGISTER_DIG_P2 0x90
# define BME280_REGISTER_DIG_P3 0x92
# define BME280_REGISTER_DIG_P4 0x94
# define BME280_REGISTER_DIG_P5 0x96
# define BME280_REGISTER_DIG_P6 0x98
# define BME280_REGISTER_DIG_P7 0x9A
# define BME280_REGISTER_DIG_P8 0x9C
# define BME280_REGISTER_DIG_P9 0x9E
# define BME280_REGISTER_DIG_H1 0xA1
# define BME280_REGISTER_DIG_H2 0xE1
# define BME280_REGISTER_DIG_H3 0xE3
# define BME280_REGISTER_DIG_H4 0xE4
# define BME280_REGISTER_DIG_H5 0xE5
# define BME280_REGISTER_DIG_H6 0xE7
2017-01-28 13:41:01 +00:00
2018-12-21 10:36:55 +00:00
typedef struct {
2017-01-28 13:41:01 +00:00
uint16_t dig_T1 ;
2017-10-23 11:18:15 +01:00
int16_t dig_T2 ;
int16_t dig_T3 ;
2017-01-28 13:41:01 +00:00
uint16_t dig_P1 ;
2017-10-23 11:18:15 +01:00
int16_t dig_P2 ;
int16_t dig_P3 ;
int16_t dig_P4 ;
int16_t dig_P5 ;
int16_t dig_P6 ;
int16_t dig_P7 ;
int16_t dig_P8 ;
int16_t dig_P9 ;
int16_t dig_H2 ;
int16_t dig_H4 ;
int16_t dig_H5 ;
2018-10-30 14:20:19 +00:00
uint8_t dig_H1 ;
uint8_t dig_H3 ;
2017-10-23 11:18:15 +01:00
int8_t dig_H6 ;
2018-12-21 10:36:55 +00:00
} Bme280CalibrationData_t ;
2019-03-26 17:26:50 +00:00
Bme280CalibrationData_t * Bme280CalibrationData = nullptr ;
2017-01-28 13:41:01 +00:00
2019-01-28 13:08:33 +00:00
bool Bmx280Calibrate ( uint8_t bmp_idx )
2017-01-28 13:41:01 +00:00
{
2017-10-18 17:22:34 +01:00
// if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false;
2018-12-21 10:36:55 +00:00
if ( ! Bme280CalibrationData ) {
Bme280CalibrationData = ( Bme280CalibrationData_t * ) malloc ( BMP_MAX_SENSORS * sizeof ( Bme280CalibrationData_t ) ) ;
}
if ( ! Bme280CalibrationData ) { return false ; }
2018-10-30 14:20:19 +00:00
Bme280CalibrationData [ bmp_idx ] . dig_T1 = I2cRead16LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_T1 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_T2 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_T2 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_T3 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_T3 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P1 = I2cRead16LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P1 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P2 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P2 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P3 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P3 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P4 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P4 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P5 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P5 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P6 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P6 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P7 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P7 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P8 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P8 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_P9 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_P9 ) ;
2018-10-29 14:46:03 +00:00
if ( BME280_CHIPID = = bmp_sensors [ bmp_idx ] . bmp_type ) { // #1051
2018-10-30 14:20:19 +00:00
Bme280CalibrationData [ bmp_idx ] . dig_H1 = I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H1 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_H2 = I2cReadS16_LE ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H2 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_H3 = I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H3 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_H4 = ( I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H4 ) < < 4 ) | ( I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H4 + 1 ) & 0xF ) ;
Bme280CalibrationData [ bmp_idx ] . dig_H5 = ( I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H5 + 1 ) < < 4 ) | ( I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H5 ) > > 4 ) ;
Bme280CalibrationData [ bmp_idx ] . dig_H6 = ( int8_t ) I2cRead8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_DIG_H6 ) ;
2018-10-29 14:46:03 +00:00
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_CONTROL , 0x00 ) ; // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27)
2017-12-03 15:17:47 +00:00
// Set before CONTROL_meas (DS 5.4.3)
2018-10-29 14:46:03 +00:00
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_CONTROLHUMID , 0x01 ) ; // 1x oversampling
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_CONFIG , 0xA0 ) ; // 1sec standby between measurements (to limit self heating), IIR filter off
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_CONTROL , 0x27 ) ; // 1x oversampling, normal mode
2017-12-03 15:17:47 +00:00
} else {
2018-10-29 14:46:03 +00:00
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_CONTROL , 0xB7 ) ; // 16x oversampling, normal mode (Adafruit)
2017-12-03 15:17:47 +00:00
}
2017-01-28 13:41:01 +00:00
return true ;
}
2018-10-30 14:20:19 +00:00
void Bme280Read ( uint8_t bmp_idx )
2017-01-28 13:41:01 +00:00
{
2018-12-21 10:36:55 +00:00
if ( ! Bme280CalibrationData ) { return ; }
2018-10-29 14:46:03 +00:00
int32_t adc_T = I2cRead24 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_TEMPDATA ) ;
2017-01-28 13:41:01 +00:00
adc_T > > = 4 ;
2018-10-30 14:20:19 +00:00
int32_t vart1 = ( ( ( ( adc_T > > 3 ) - ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_T1 < < 1 ) ) ) * ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_T2 ) ) > > 11 ;
int32_t vart2 = ( ( ( ( ( adc_T > > 4 ) - ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_T1 ) ) * ( ( adc_T > > 4 ) - ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_T1 ) ) ) > > 12 ) *
( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_T3 ) ) > > 14 ;
2018-07-11 13:21:11 +01:00
int32_t t_fine = vart1 + vart2 ;
2018-07-11 13:39:07 +01:00
float T = ( t_fine * 5 + 128 ) > > 8 ;
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_temperature = T / 100.0 ;
2017-01-28 13:41:01 +00:00
2018-10-29 14:46:03 +00:00
int32_t adc_P = I2cRead24 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_PRESSUREDATA ) ;
2017-01-28 13:41:01 +00:00
adc_P > > = 4 ;
2018-07-11 13:21:11 +01:00
int64_t var1 = ( ( int64_t ) t_fine ) - 128000 ;
2018-10-30 14:20:19 +00:00
int64_t var2 = var1 * var1 * ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P6 ;
var2 = var2 + ( ( var1 * ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P5 ) < < 17 ) ;
var2 = var2 + ( ( ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P4 ) < < 35 ) ;
var1 = ( ( var1 * var1 * ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P3 ) > > 8 ) + ( ( var1 * ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P2 ) < < 12 ) ;
var1 = ( ( ( ( ( int64_t ) 1 ) < < 47 ) + var1 ) ) * ( ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P1 ) > > 33 ;
2017-04-25 17:24:42 +01:00
if ( 0 = = var1 ) {
2018-07-11 13:21:11 +01:00
return ; // avoid exception caused by division by zero
2017-01-28 13:41:01 +00:00
}
2018-07-11 13:21:11 +01:00
int64_t p = 1048576 - adc_P ;
2017-01-28 13:41:01 +00:00
p = ( ( ( p < < 31 ) - var2 ) * 3125 ) / var1 ;
2018-10-30 14:20:19 +00:00
var1 = ( ( ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P9 ) * ( p > > 13 ) * ( p > > 13 ) ) > > 25 ;
var2 = ( ( ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P8 ) * p ) > > 19 ;
p = ( ( p + var1 + var2 ) > > 8 ) + ( ( ( int64_t ) Bme280CalibrationData [ bmp_idx ] . dig_P7 ) < < 4 ) ;
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_pressure = ( float ) p / 25600.0 ;
2017-01-28 13:41:01 +00:00
2018-10-29 14:46:03 +00:00
if ( BMP280_CHIPID = = bmp_sensors [ bmp_idx ] . bmp_type ) { return ; }
2017-01-28 13:41:01 +00:00
2018-10-29 14:46:03 +00:00
int32_t adc_H = I2cRead16 ( bmp_sensors [ bmp_idx ] . bmp_address , BME280_REGISTER_HUMIDDATA ) ;
2018-07-11 13:39:07 +01:00
int32_t v_x1_u32r = ( t_fine - ( ( int32_t ) 76800 ) ) ;
2018-10-30 14:20:19 +00:00
v_x1_u32r = ( ( ( ( ( adc_H < < 14 ) - ( ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H4 ) < < 20 ) -
( ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H5 ) * v_x1_u32r ) ) + ( ( int32_t ) 16384 ) ) > > 15 ) *
( ( ( ( ( ( ( v_x1_u32r * ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H6 ) ) > > 10 ) *
( ( ( v_x1_u32r * ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H3 ) ) > > 11 ) + ( ( int32_t ) 32768 ) ) ) > > 10 ) +
( ( int32_t ) 2097152 ) ) * ( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H2 ) + 8192 ) > > 14 ) ) ;
2017-01-28 13:41:01 +00:00
v_x1_u32r = ( v_x1_u32r - ( ( ( ( ( v_x1_u32r > > 15 ) * ( v_x1_u32r > > 15 ) ) > > 7 ) *
2018-10-30 14:20:19 +00:00
( ( int32_t ) Bme280CalibrationData [ bmp_idx ] . dig_H1 ) ) > > 4 ) ) ;
2017-01-28 13:41:01 +00:00
v_x1_u32r = ( v_x1_u32r < 0 ) ? 0 : v_x1_u32r ;
v_x1_u32r = ( v_x1_u32r > 419430400 ) ? 419430400 : v_x1_u32r ;
2018-07-11 13:21:11 +01:00
float h = ( v_x1_u32r > > 12 ) ;
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_humidity = h / 1024.0 ;
2017-01-28 13:41:01 +00:00
}
2017-12-06 16:14:41 +00:00
# ifdef USE_BME680
2017-01-28 13:41:01 +00:00
/*********************************************************************************************\
2018-07-04 17:41:00 +01:00
* BME680 support by Bosch https : //github.com/BoschSensortec/BME680_driver
2017-01-28 13:41:01 +00:00
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2018-07-04 17:41:00 +01:00
# include <bme680.h>
2019-03-26 17:26:50 +00:00
struct bme680_dev * gas_sensor = nullptr ;
2018-07-04 17:41:00 +01:00
static void BmeDelayMs ( uint32_t ms )
{
delay ( ms ) ;
}
2019-01-28 13:08:33 +00:00
bool Bme680Init ( uint8_t bmp_idx )
2018-07-04 17:41:00 +01:00
{
2018-12-21 10:36:55 +00:00
if ( ! gas_sensor ) {
gas_sensor = ( bme680_dev * ) malloc ( BMP_MAX_SENSORS * sizeof ( bme680_dev ) ) ;
}
if ( ! gas_sensor ) { return false ; }
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . dev_id = bmp_sensors [ bmp_idx ] . bmp_address ;
gas_sensor [ bmp_idx ] . intf = BME680_I2C_INTF ;
gas_sensor [ bmp_idx ] . read = & I2cReadBuffer ;
gas_sensor [ bmp_idx ] . write = & I2cWriteBuffer ;
gas_sensor [ bmp_idx ] . delay_ms = BmeDelayMs ;
2018-07-04 17:41:00 +01:00
/* amb_temp can be set to 25 prior to configuring the gas sensor
* or by performing a few temperature readings without operating the gas sensor .
*/
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . amb_temp = 25 ;
2018-07-04 17:41:00 +01:00
int8_t rslt = BME680_OK ;
2018-10-30 14:20:19 +00:00
rslt = bme680_init ( & gas_sensor [ bmp_idx ] ) ;
2018-07-04 17:41:00 +01:00
if ( rslt ! = BME680_OK ) { return false ; }
/* Set the temperature, pressure and humidity settings */
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . tph_sett . os_hum = BME680_OS_2X ;
gas_sensor [ bmp_idx ] . tph_sett . os_pres = BME680_OS_4X ;
gas_sensor [ bmp_idx ] . tph_sett . os_temp = BME680_OS_8X ;
gas_sensor [ bmp_idx ] . tph_sett . filter = BME680_FILTER_SIZE_3 ;
2018-07-04 17:41:00 +01:00
/* Set the remaining gas sensor settings and link the heating profile */
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . gas_sett . run_gas = BME680_ENABLE_GAS_MEAS ;
2018-07-04 17:41:00 +01:00
/* Create a ramp heat waveform in 3 steps */
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . gas_sett . heatr_temp = 320 ; /* degree Celsius */
gas_sensor [ bmp_idx ] . gas_sett . heatr_dur = 150 ; /* milliseconds */
2018-07-04 17:41:00 +01:00
/* Select the power mode */
/* Must be set before writing the sensor configuration */
2018-10-30 14:20:19 +00:00
gas_sensor [ bmp_idx ] . power_mode = BME680_FORCED_MODE ;
2018-07-04 17:41:00 +01:00
/* Set the required sensor settings needed */
uint8_t set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL ;
/* Set the desired sensor configuration */
2018-10-30 14:20:19 +00:00
rslt = bme680_set_sensor_settings ( set_required_settings , & gas_sensor [ bmp_idx ] ) ;
2018-07-04 17:41:00 +01:00
if ( rslt ! = BME680_OK ) { return false ; }
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bme680_state = 0 ;
2018-07-04 17:41:00 +01:00
return true ;
}
2017-01-28 13:41:01 +00:00
2018-10-30 14:20:19 +00:00
void Bme680Read ( uint8_t bmp_idx )
2017-01-28 13:41:01 +00:00
{
2018-12-21 10:36:55 +00:00
if ( ! gas_sensor ) { return ; }
2018-07-04 17:41:00 +01:00
int8_t rslt = BME680_OK ;
2018-10-29 14:46:03 +00:00
if ( BME680_CHIPID = = bmp_sensors [ bmp_idx ] . bmp_type ) {
if ( 0 = = bmp_sensors [ bmp_idx ] . bme680_state ) {
2018-07-04 17:41:00 +01:00
/* Trigger the next measurement if you would like to read data out continuously */
2018-10-30 14:20:19 +00:00
rslt = bme680_set_sensor_mode ( & gas_sensor [ bmp_idx ] ) ;
2018-07-04 17:41:00 +01:00
if ( rslt ! = BME680_OK ) { return ; }
/* Get the total measurement duration so as to sleep or wait till the
* measurement is complete */
// uint16_t meas_period;
2018-10-30 14:20:19 +00:00
// bme680_get_profile_dur(&meas_period, &gas_sensor[bmp_idx]);
2018-07-04 17:41:00 +01:00
// delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bme680_state = 1 ;
2018-07-04 17:41:00 +01:00
} else {
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bme680_state = 0 ;
2018-07-04 17:41:00 +01:00
struct bme680_field_data data ;
2018-10-30 14:20:19 +00:00
rslt = bme680_get_sensor_data ( & data , & gas_sensor [ bmp_idx ] ) ;
2018-07-04 17:41:00 +01:00
if ( rslt ! = BME680_OK ) { return ; }
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_temperature = data . temperature / 100.0 ;
bmp_sensors [ bmp_idx ] . bmp_humidity = data . humidity / 1000.0 ;
bmp_sensors [ bmp_idx ] . bmp_pressure = data . pressure / 100.0 ;
2018-07-04 17:41:00 +01:00
/* Avoid using measurements from an unstable heating setup */
if ( data . status & BME680_GASM_VALID_MSK ) {
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_gas_resistance = data . gas_resistance / 1000.0 ;
2018-07-04 17:41:00 +01:00
} else {
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_idx ] . bmp_gas_resistance = 0 ;
2018-07-04 17:41:00 +01:00
}
}
2017-10-08 15:51:05 +01:00
}
2018-07-04 17:41:00 +01:00
return ;
2017-01-28 13:41:01 +00:00
}
2017-12-06 16:14:41 +00:00
# endif // USE_BME680
2017-01-28 13:41:01 +00:00
2017-11-04 15:36:51 +00:00
/********************************************************************************************/
2018-11-14 13:32:09 +00:00
void BmpDetect ( void )
2017-01-28 13:41:01 +00:00
{
2018-12-21 15:17:06 +00:00
int bmp_sensor_size = BMP_MAX_SENSORS * sizeof ( bmp_sensors_t ) ;
2018-12-21 10:36:55 +00:00
if ( ! bmp_sensors ) {
2018-12-21 15:17:06 +00:00
bmp_sensors = ( bmp_sensors_t * ) malloc ( bmp_sensor_size ) ;
2018-12-21 10:36:55 +00:00
}
if ( ! bmp_sensors ) { return ; }
2018-12-21 15:17:06 +00:00
memset ( bmp_sensors , 0 , bmp_sensor_size ) ; // Init defaults to 0
2018-12-21 10:36:55 +00:00
2019-06-30 15:44:36 +01:00
for ( uint32_t i = 0 ; i < BMP_MAX_SENSORS ; i + + ) {
2019-11-06 16:48:38 +00:00
if ( I2cActive ( bmp_addresses [ i ] ) ) { continue ; }
2018-10-29 14:46:03 +00:00
uint8_t bmp_type = I2cRead8 ( bmp_addresses [ i ] , BMP_REGISTER_CHIPID ) ;
2017-11-11 11:33:30 +00:00
if ( bmp_type ) {
2018-10-29 14:46:03 +00:00
bmp_sensors [ bmp_count ] . bmp_address = bmp_addresses [ i ] ;
bmp_sensors [ bmp_count ] . bmp_type = bmp_type ;
bmp_sensors [ bmp_count ] . bmp_model = 0 ;
2019-01-28 13:08:33 +00:00
bool success = false ;
2018-10-29 14:46:03 +00:00
switch ( bmp_type ) {
case BMP180_CHIPID :
2018-10-30 14:20:19 +00:00
success = Bmp180Calibration ( bmp_count ) ;
2018-10-29 14:46:03 +00:00
break ;
case BME280_CHIPID :
bmp_sensors [ bmp_count ] . bmp_model + + ; // 2
case BMP280_CHIPID :
bmp_sensors [ bmp_count ] . bmp_model + + ; // 1
2018-10-30 14:20:19 +00:00
success = Bmx280Calibrate ( bmp_count ) ;
2018-10-29 14:46:03 +00:00
break ;
2018-10-30 14:20:19 +00:00
# ifdef USE_BME680
case BME680_CHIPID :
bmp_sensors [ bmp_count ] . bmp_model = 3 ; // 3
success = Bme680Init ( bmp_count ) ;
break ;
# endif // USE_BME680
2018-10-29 14:46:03 +00:00
}
if ( success ) {
GetTextIndexed ( bmp_sensors [ bmp_count ] . bmp_name , sizeof ( bmp_sensors [ bmp_count ] . bmp_name ) , bmp_sensors [ bmp_count ] . bmp_model , kBmpTypes ) ;
2019-11-09 17:34:22 +00:00
I2cSetActiveFound ( bmp_sensors [ bmp_count ] . bmp_address , bmp_sensors [ bmp_count ] . bmp_name ) ;
2018-10-29 14:46:03 +00:00
bmp_count + + ;
}
2017-11-11 11:33:30 +00:00
}
2017-01-28 13:41:01 +00:00
}
2018-10-29 14:46:03 +00:00
}
2018-11-14 13:32:09 +00:00
void BmpRead ( void )
2018-10-29 14:46:03 +00:00
{
2019-06-30 15:44:36 +01:00
for ( uint32_t bmp_idx = 0 ; bmp_idx < bmp_count ; bmp_idx + + ) {
2018-10-29 14:46:03 +00:00
switch ( bmp_sensors [ bmp_idx ] . bmp_type ) {
2017-11-11 11:33:30 +00:00
case BMP180_CHIPID :
2018-10-30 14:20:19 +00:00
Bmp180Read ( bmp_idx ) ;
2017-11-11 11:33:30 +00:00
break ;
2018-07-11 13:21:11 +01:00
case BMP280_CHIPID :
2018-10-29 14:46:03 +00:00
case BME280_CHIPID :
2018-10-30 14:20:19 +00:00
Bme280Read ( bmp_idx ) ;
2017-12-06 16:14:41 +00:00
break ;
2018-10-30 14:20:19 +00:00
# ifdef USE_BME680
case BME680_CHIPID :
Bme680Read ( bmp_idx ) ;
break ;
# endif // USE_BME680
2017-11-11 11:33:30 +00:00
}
2017-01-28 13:41:01 +00:00
}
2018-07-11 13:21:11 +01:00
}
2017-12-06 16:14:41 +00:00
2019-01-28 13:08:33 +00:00
void BmpShow ( bool json )
2018-07-11 13:21:11 +01:00
{
2019-06-30 15:44:36 +01:00
for ( uint32_t bmp_idx = 0 ; bmp_idx < bmp_count ; bmp_idx + + ) {
2018-10-29 14:46:03 +00:00
if ( bmp_sensors [ bmp_idx ] . bmp_type ) {
2020-10-29 09:34:44 +00:00
float bmp_sealevel = ConvertPressureForSeaLevel ( bmp_sensors [ bmp_idx ] . bmp_pressure ) ;
2018-11-04 15:55:12 +00:00
float bmp_temperature = ConvertTemp ( bmp_sensors [ bmp_idx ] . bmp_temperature ) ;
float bmp_pressure = ConvertPressure ( bmp_sensors [ bmp_idx ] . bmp_pressure ) ;
2018-10-29 14:46:03 +00:00
2018-12-21 15:17:06 +00:00
char name [ 10 ] ;
2019-03-08 18:24:02 +00:00
strlcpy ( name , bmp_sensors [ bmp_idx ] . bmp_name , sizeof ( name ) ) ;
2018-10-29 14:46:03 +00:00
if ( bmp_count > 1 ) {
2019-05-17 13:23:21 +01:00
snprintf_P ( name , sizeof ( name ) , PSTR ( " %s%c%02X " ) , name , IndexSeparator ( ) , bmp_sensors [ bmp_idx ] . bmp_address ) ; // BMXXXX-XX
2018-10-29 14:46:03 +00:00
}
2018-07-11 13:21:11 +01:00
2018-12-21 15:17:06 +00:00
char temperature [ 33 ] ;
2018-11-04 15:55:12 +00:00
dtostrfd ( bmp_temperature , Settings . flag2 . temperature_resolution , temperature ) ;
2018-12-21 15:17:06 +00:00
char pressure [ 33 ] ;
2018-11-04 15:55:12 +00:00
dtostrfd ( bmp_pressure , Settings . flag2 . pressure_resolution , pressure ) ;
2018-12-21 15:17:06 +00:00
char sea_pressure [ 33 ] ;
2018-10-29 14:46:03 +00:00
dtostrfd ( bmp_sealevel , Settings . flag2 . pressure_resolution , sea_pressure ) ;
2020-03-18 10:23:00 +00:00
float bmp_humidity = ConvertHumidity ( bmp_sensors [ bmp_idx ] . bmp_humidity ) ;
2018-12-21 15:17:06 +00:00
char humidity [ 33 ] ;
2020-03-18 10:23:00 +00:00
dtostrfd ( bmp_humidity , Settings . flag2 . humidity_resolution , humidity ) ;
float f_dewpoint = CalcTempHumToDew ( bmp_temperature , bmp_humidity ) ;
2020-03-17 10:10:39 +00:00
char dewpoint [ 33 ] ;
dtostrfd ( f_dewpoint , Settings . flag2 . temperature_resolution , dewpoint ) ;
2017-12-06 16:14:41 +00:00
# ifdef USE_BME680
2018-12-21 15:17:06 +00:00
char gas_resistance [ 33 ] ;
2018-10-29 14:46:03 +00:00
dtostrfd ( bmp_sensors [ bmp_idx ] . bmp_gas_resistance , 2 , gas_resistance ) ;
2017-12-06 16:14:41 +00:00
# endif // USE_BME680
2017-11-04 15:36:51 +00:00
2018-10-29 14:46:03 +00:00
if ( json ) {
2020-03-17 10:10:39 +00:00
char json_humidity [ 80 ] ;
snprintf_P ( json_humidity , sizeof ( json_humidity ) , PSTR ( " , \" " D_JSON_HUMIDITY " \" :%s, \" " D_JSON_DEWPOINT " \" :%s " ) , humidity , dewpoint ) ;
2018-10-29 14:46:03 +00:00
char json_sealevel [ 40 ] ;
snprintf_P ( json_sealevel , sizeof ( json_sealevel ) , PSTR ( " , \" " D_JSON_PRESSUREATSEALEVEL " \" :%s " ) , sea_pressure ) ;
2017-12-06 16:14:41 +00:00
# ifdef USE_BME680
2018-10-29 14:46:03 +00:00
char json_gas [ 40 ] ;
snprintf_P ( json_gas , sizeof ( json_gas ) , PSTR ( " , \" " D_JSON_GAS " \" :%s " ) , gas_resistance ) ;
2019-03-23 16:57:31 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ \" " D_JSON_TEMPERATURE " \" :%s%s, \" " D_JSON_PRESSURE " \" :%s%s%s} " ) ,
2018-10-29 14:46:03 +00:00
name ,
temperature ,
( bmp_sensors [ bmp_idx ] . bmp_model > = 2 ) ? json_humidity : " " ,
pressure ,
( Settings . altitude ! = 0 ) ? json_sealevel : " " ,
2018-12-21 15:17:06 +00:00
( bmp_sensors [ bmp_idx ] . bmp_model > = 3 ) ? json_gas : " " ) ;
2017-12-06 16:14:41 +00:00
# else
2019-03-23 16:57:31 +00:00
ResponseAppend_P ( PSTR ( " , \" %s \" :{ \" " D_JSON_TEMPERATURE " \" :%s%s, \" " D_JSON_PRESSURE " \" :%s%s} " ) ,
name , temperature , ( bmp_sensors [ bmp_idx ] . bmp_model > = 2 ) ? json_humidity : " " , pressure , ( Settings . altitude ! = 0 ) ? json_sealevel : " " ) ;
2017-12-06 16:14:41 +00:00
# endif // USE_BME680
2018-10-29 14:46:03 +00:00
2017-11-04 15:36:51 +00:00
# ifdef USE_DOMOTICZ
2020-10-29 12:37:09 +00:00
if ( ( 0 = = TasmotaGlobal . tele_period ) & & ( 0 = = bmp_idx ) ) { // We want the same first sensor to report to Domoticz in case a read is missed
2020-03-18 10:23:00 +00:00
DomoticzTempHumPressureSensor ( bmp_temperature , bmp_humidity , bmp_pressure ) ;
2018-04-27 17:06:19 +01:00
# ifdef USE_BME680
2018-10-29 14:46:03 +00:00
if ( bmp_sensors [ bmp_idx ] . bmp_model > = 3 ) { DomoticzSensor ( DZ_AIRQUALITY , ( uint32_t ) bmp_sensors [ bmp_idx ] . bmp_gas_resistance ) ; }
2018-04-27 17:06:19 +01:00
# endif // USE_BME680
2018-10-29 14:46:03 +00:00
}
2018-10-30 14:20:19 +00:00
# endif // USE_DOMOTICZ
2018-04-18 16:28:45 +01:00
# ifdef USE_KNX
2020-10-29 12:37:09 +00:00
if ( 0 = = TasmotaGlobal . tele_period ) {
2018-11-04 15:55:12 +00:00
KnxSensor ( KNX_TEMPERATURE , bmp_temperature ) ;
2020-03-18 10:23:00 +00:00
KnxSensor ( KNX_HUMIDITY , bmp_humidity ) ;
2018-10-29 14:46:03 +00:00
}
2018-04-18 16:28:45 +01:00
# endif // USE_KNX
2017-11-04 15:36:51 +00:00
# ifdef USE_WEBSERVER
2018-10-29 14:46:03 +00:00
} else {
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( HTTP_SNS_TEMP , name , temperature , TempUnit ( ) ) ;
2018-10-29 14:46:03 +00:00
if ( bmp_sensors [ bmp_idx ] . bmp_model > = 2 ) {
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( HTTP_SNS_HUM , name , humidity ) ;
2020-03-17 10:10:39 +00:00
WSContentSend_PD ( HTTP_SNS_DEW , name , dewpoint , TempUnit ( ) ) ;
2018-10-29 14:46:03 +00:00
}
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( HTTP_SNS_PRESSURE , name , pressure , PressureUnit ( ) . c_str ( ) ) ;
2018-10-29 14:46:03 +00:00
if ( Settings . altitude ! = 0 ) {
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( HTTP_SNS_SEAPRESSURE , name , sea_pressure , PressureUnit ( ) . c_str ( ) ) ;
2018-10-29 14:46:03 +00:00
}
2017-12-06 16:14:41 +00:00
# ifdef USE_BME680
2018-10-29 14:46:03 +00:00
if ( bmp_sensors [ bmp_idx ] . bmp_model > = 3 ) {
2019-03-19 16:31:43 +00:00
WSContentSend_PD ( PSTR ( " {s}%s " D_GAS " {m}%s " D_UNIT_KILOOHM " {e} " ) , name , gas_resistance ) ;
2018-10-29 14:46:03 +00:00
}
2017-12-06 16:14:41 +00:00
# endif // USE_BME680
2019-03-19 16:31:43 +00:00
2018-10-30 14:20:19 +00:00
# endif // USE_WEBSERVER
2018-10-29 14:46:03 +00:00
}
2017-10-08 15:51:05 +01:00
}
2017-01-28 13:41:01 +00:00
}
}
2017-11-03 17:07:25 +00:00
2020-01-02 20:38:18 +00:00
# ifdef USE_DEEPSLEEP
void BMP_EnterSleep ( void )
{
2020-09-14 11:26:32 +01:00
if ( DeepSleepEnabled ( ) ) {
for ( uint32_t bmp_idx = 0 ; bmp_idx < bmp_count ; bmp_idx + + ) {
switch ( bmp_sensors [ bmp_idx ] . bmp_type ) {
case BMP180_CHIPID :
case BMP280_CHIPID :
case BME280_CHIPID :
I2cWrite8 ( bmp_sensors [ bmp_idx ] . bmp_address , BMP_REGISTER_RESET , BMP_CMND_RESET ) ;
break ;
default :
break ;
}
2020-01-02 20:38:18 +00:00
}
}
}
# endif // USE_DEEPSLEEP
2017-11-03 17:07:25 +00:00
/*********************************************************************************************\
* Interface
\ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2019-01-28 13:08:33 +00:00
bool Xsns09 ( uint8_t function )
2017-11-03 17:07:25 +00:00
{
2019-11-04 09:38:05 +00:00
if ( ! I2cEnabled ( XI2C_10 ) ) { return false ; }
2019-11-03 16:54:39 +00:00
2019-01-28 13:08:33 +00:00
bool result = false ;
2017-11-03 17:07:25 +00:00
2019-11-11 16:32:44 +00:00
if ( FUNC_INIT = = function ) {
BmpDetect ( ) ;
}
else if ( bmp_count ) {
switch ( function ) {
case FUNC_EVERY_SECOND :
BmpRead ( ) ;
break ;
case FUNC_JSON_APPEND :
BmpShow ( 1 ) ;
break ;
2017-11-03 17:07:25 +00:00
# ifdef USE_WEBSERVER
2019-11-11 16:32:44 +00:00
case FUNC_WEB_SENSOR :
BmpShow ( 0 ) ;
break ;
2018-10-30 14:20:19 +00:00
# endif // USE_WEBSERVER
2020-01-02 20:38:18 +00:00
# ifdef USE_DEEPSLEEP
case FUNC_SAVE_BEFORE_RESTART :
BMP_EnterSleep ( ) ;
break ;
2020-01-02 20:51:15 +00:00
# endif // USE_DEEPSLEEP
2019-11-11 16:32:44 +00:00
}
2017-11-03 17:07:25 +00:00
}
return result ;
}
2018-10-30 14:20:19 +00:00
# endif // USE_BMP
# endif // USE_I2C