From 03cd543127317f3984fea0cdc3149421128824ca Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Fri, 12 Jun 2020 12:38:52 +0200 Subject: [PATCH] Add support for HP303B Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) --- RELEASENOTES.md | 1 + tasmota/CHANGELOG.md | 1 + tasmota/my_user_config.h | 1 + tasmota/tasmota_configurations.h | 1 + tasmota/xsns_73_hp303b.ino | 114 ++++++++++++++++--------------- 5 files changed, 62 insertions(+), 56 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index ab01ddaa4..c1637501c 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -77,3 +77,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add support for up to eight MCP9808 temperature sensors by device111 (#8594) - Add support for BL0940 energy monitor as used in Blitzwolf BW-SHP10 (#8175) - Add initial support for Telegram bot (#8619) +- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 9033a2bba..0c6ef82bd 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -3,6 +3,7 @@ ### 8.3.1.3 20200611 - Add initial support for Telegram bot (#8619) +- Add support for HP303B Temperature and Pressure sensor by Robert Jaakke (#8638) ### 8.3.1.2 20200522 diff --git a/tasmota/my_user_config.h b/tasmota/my_user_config.h index ea2e6eefe..d6a140663 100644 --- a/tasmota/my_user_config.h +++ b/tasmota/my_user_config.h @@ -527,6 +527,7 @@ // #define USE_VEML6075 // [I2cDriver49] Enable VEML6075 UVA/UVB/UVINDEX Sensor (I2C address 0x10) (+2k1 code) // #define USE_VEML7700 // [I2cDriver50] Enable VEML7700 Ambient Light sensor (I2C addresses 0x10) (+4k5 code) // #define USE_MCP9808 // [I2cDriver51] Enable MCP9808 temperature sensor (I2C addresses 0x18 - 0x1F) (+0k9 code) +// #define USE_HP303B // [I2cDriver52] Enable HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) // #define USE_DISPLAY // Add I2C Display Support (+2k code) #define USE_DISPLAY_MODES1TO5 // Enable display mode 1 to 5 in addition to mode 0 diff --git a/tasmota/tasmota_configurations.h b/tasmota/tasmota_configurations.h index 811076d8f..ff81e486d 100644 --- a/tasmota/tasmota_configurations.h +++ b/tasmota/tasmota_configurations.h @@ -155,6 +155,7 @@ //#define USE_TASMOTA_SLAVE // Add support for Arduino Uno/Pro Mini via serial interface including flashing (+2k3 code, 44 mem) //#define USE_OPENTHERM // Add support for OpenTherm (+15k code) //#define USE_MCP9808 // Add support for MCP9808 temperature sensor (+0k9 code) +//#define USE_HP303B // Add support for HP303B temperature and pressure sensor (I2C address 0x76 or 0x77) (+6k2 code) #define USE_ENERGY_SENSOR // Add energy sensors (-14k code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) diff --git a/tasmota/xsns_73_hp303b.ino b/tasmota/xsns_73_hp303b.ino index 1be0a1606..0d9363409 100644 --- a/tasmota/xsns_73_hp303b.ino +++ b/tasmota/xsns_73_hp303b.ino @@ -16,58 +16,57 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + #ifdef USE_I2C #ifdef USE_HP303B /*********************************************************************************************\ - * HP303B - Gas (TVOC - Total Volatile Organic Compounds) and Air Quality (CO2) + * HP303B - Pressure and temperature sensor * * Source: Lolin LOLIN_HP303B_Library * * I2C Address: 0x77 or 0x76 \*********************************************************************************************/ -#define XSNS_73 73 -#define XI2C_52 52 // See I2CDEVICES.md +#define XSNS_73 73 +#define XI2C_52 52 // See I2CDEVICES.md + +#define HP303B_MAX_SENSORS 2 +#define HP303B_START_ADDRESS 0x76 #include // HP303B Object LOLIN_HP303B HP303BSensor = LOLIN_HP303B(); -#define HP303B_MAX_SENSORS 2 -#define HP303B_START_ADDRESS 0x76 - struct { -char types[7] = "HP303B"; -uint8_t count = 0; -int16_t oversampling = 7; + int16_t oversampling = 7; + char types[7] = "HP303B"; + uint8_t count = 0; } hp303b_cfg; struct BHP303B { - uint8_t address; - uint8_t valid = 0; float temperature = NAN; float pressure = NAN; + uint8_t address; + uint8_t valid = 0; } hp303b_sensor[HP303B_MAX_SENSORS]; + /*********************************************************************************************/ -bool HP303B_Read(uint8_t hp303b_idx) -{ +bool HP303B_Read(uint32_t hp303b_idx) { if (hp303b_sensor[hp303b_idx].valid) { hp303b_sensor[hp303b_idx].valid--; } float t; + if (HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { + return false; + } + float p; - int16_t ret; - - ret = HP303BSensor.measureTempOnce(t, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); - if (ret != 0) - return false; - - ret = HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling); - if (ret != 0) + if (HP303BSensor.measurePressureOnce(p, hp303b_sensor[hp303b_idx].address, hp303b_cfg.oversampling) != 0) { return false; + } hp303b_sensor[hp303b_idx].temperature = (float)ConvertTemp(t); - hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p) / 100; //conversion to hPa + hp303b_sensor[hp303b_idx].pressure = (float)ConvertPressure(p / 100); // Conversion to hPa hp303b_sensor[hp303b_idx].valid = SENSOR_MAX_MISS; return true; @@ -75,14 +74,11 @@ bool HP303B_Read(uint8_t hp303b_idx) /********************************************************************************************/ -void HP303B_Detect(void) -{ - for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) - { - if (!I2cSetDevice(HP303B_START_ADDRESS + i )) { continue; } +void HP303B_Detect(void) { + for (uint32_t i = 0; i < HP303B_MAX_SENSORS; i++) { + if (!I2cSetDevice(HP303B_START_ADDRESS + i)) { continue; } - if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) - { + if (HP303BSensor.begin(HP303B_START_ADDRESS + i)) { hp303b_sensor[hp303b_cfg.count].address = HP303B_START_ADDRESS + i; I2cSetActiveFound(hp303b_sensor[hp303b_cfg.count].address, hp303b_cfg.types); hp303b_cfg.count++; @@ -90,50 +86,58 @@ void HP303B_Detect(void) } } -void HP303B_EverySecond(void) -{ +void HP303B_EverySecond(void) { for (uint32_t i = 0; i < hp303b_cfg.count; i++) { if (uptime &1) { - if (!HP303B_Read(i)) { - AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); + if (!HP303B_Read(i)) { + AddLogMissed(hp303b_cfg.types, hp303b_sensor[i].valid); + } } } - } } -void HP303B_Show(bool json) -{ +void HP303B_Show(bool json) { for (uint32_t i = 0; i < hp303b_cfg.count; i++) { - char sensor_name[12]; - strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); - if (hp303b_cfg.count > 1) { - snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c0x%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-0x76, HP303B-0x77 - } + if (hp303b_sensor[i].valid) { + char sensor_name[12]; + strlcpy(sensor_name, hp303b_cfg.types, sizeof(sensor_name)); + if (hp303b_cfg.count > 1) { + snprintf_P(sensor_name, sizeof(sensor_name), PSTR("%s%c%02X"), sensor_name, IndexSeparator(), hp303b_sensor[i].address); // HP303B-76, HP303B-77 + } + + float sealevel = 0.0; + if (hp303b_sensor[i].pressure != 0.0) { + sealevel = (hp303b_sensor[i].pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; + sealevel = ConvertPressure(sealevel); + } - if (hp303b_sensor[i].valid) - { char str_temperature[33]; dtostrfd(hp303b_sensor[i].temperature, Settings.flag2.temperature_resolution, str_temperature); char str_pressure[33]; dtostrfd(hp303b_sensor[i].pressure, Settings.flag2.pressure_resolution, str_pressure); + char sea_pressure[33]; + dtostrfd(sealevel, Settings.flag2.pressure_resolution, sea_pressure); - if (json) - { + if (json) { ResponseAppend_P(PSTR(",\"%s\":{\"" D_JSON_TEMPERATURE "\":%s,\"" D_JSON_PRESSURE "\":%s"), sensor_name, str_temperature, str_pressure); + if (Settings.altitude != 0) { + ResponseAppend_P(PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); + } ResponseJsonEnd(); - #ifdef USE_DOMOTICZ +#ifdef USE_DOMOTICZ // Domoticz and knx only support one temp sensor if ((0 == tele_period) && (0 == i)) { DomoticzSensor(DZ_TEMP, hp303b_sensor[i].temperature); } - #endif // USE_DOMOTICZ - #ifdef USE_WEBSERVER - } - else - { +#endif // USE_DOMOTICZ +#ifdef USE_WEBSERVER + } else { WSContentSend_PD(HTTP_SNS_TEMP, sensor_name, str_temperature, TempUnit()); WSContentSend_PD(HTTP_SNS_PRESSURE, sensor_name, str_pressure, PressureUnit().c_str()); - #endif // USE_WEBSERVER + if (Settings.altitude != 0) { + WSContentSend_PD(HTTP_SNS_SEAPRESSURE, sensor_name, sea_pressure, PressureUnit().c_str()); + } +#endif // USE_WEBSERVER } } } @@ -152,10 +156,8 @@ bool Xsns73(uint8_t function) if (FUNC_INIT == function) { HP303B_Detect(); } - else if (hp303b_cfg.count) - { - switch (function) - { + else if (hp303b_cfg.count) { + switch (function) { case FUNC_EVERY_SECOND: HP303B_EverySecond(); break;