* Add files via upload Added ENS16x library enabling read-out of ENS160 and ENS161 sensor component (follow-up of CCS811 and iAQcore) Added ENS210 library to read out ENS210 temperature & humidity sensor * Add files via upload Add air quality sensor readout for ENS160 and ENS161 checking two possible I2C addresses (follow up sensor for CCS811 and iAQcore) Add temperature and humidity sensor readout checking two possible I2C addresses * Update BUILDS.md Add USE_ENS16x and USE_ENS210 * Update decode-status.py Add USE_ENS16x and ENS210 * Update I2CDEVICES.md Add USE_ENS16x and USE_ENS210 * Update my_user_config.h Add USE_ENS16x and USE_ENS210 * Update support_features.ino Add USE_ENS16x and USE_ENS210 * Update tasmota_configurations.h Add USE_ENS16x and ENS210 * Update tasmota_configurations_ESP32.h Add USE_ENS16x and USE_ENS210 * Update xsns_111_ens16x.ino Corrected I2X number * Update xsns_112_ens210.ino Corrected I2C number * Disable USE_ENS16x and USE_ENS210 by default * Added code size information * cut down in libs * optimize tasmota side * fix ens16x web display * final fix on alternate addresses * update code & RAM usage --------- Co-authored-by: Barbudor <barbudor@barbudor.net>
151 lines
4.1 KiB
C++
151 lines
4.1 KiB
C++
/*
|
|
xsns_99_ens210.ino - ENS210 gas and air quality sensor support for Tasmota
|
|
|
|
Copyright (C) 2021 Christoph Friese and Theo Arends
|
|
|
|
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/>.
|
|
*/
|
|
|
|
#ifdef USE_I2C
|
|
#ifdef USE_ENS210
|
|
|
|
/*********************************************************************************************\
|
|
* ENS210 - Temperature & Humidity sensor
|
|
*
|
|
* Source: ScioSense
|
|
*
|
|
* I2C Address: 0x43
|
|
\*********************************************************************************************/
|
|
|
|
#define XSNS_112 112
|
|
#define XI2C_85 85 // See I2CDEVICES.md
|
|
|
|
#define ENS210_EVERYNSECONDS 5
|
|
#define ENS210_DEVICE_NAME "EN210"
|
|
#define ENS210_LOG "E21"
|
|
|
|
#include "ScioSense_ENS210.h"
|
|
|
|
typedef struct ENS210DATA_s {
|
|
ScioSense_ENS210 *ens210;
|
|
|
|
float temperature;
|
|
float humidity;
|
|
|
|
uint8_t ready;
|
|
uint8_t tcnt;
|
|
uint8_t ecnt;
|
|
} ENS210DATA_t;
|
|
|
|
ENS210DATA_t *ENS210data = nullptr;
|
|
|
|
/********************************************************************************************/
|
|
|
|
void ens210Detect(void)
|
|
{
|
|
uint8_t i2caddr = ENS210_I2CADDR;
|
|
if (!I2cActive(i2caddr))
|
|
{
|
|
ScioSense_ENS210 *ens210 = new ScioSense_ENS210(i2caddr);
|
|
if (!ens210) {
|
|
AddLog(LOG_LEVEL_DEBUG, PSTR(ENS210_LOG ":@%02X create error!"), i2caddr);
|
|
return;
|
|
}
|
|
if (!ens210->begin()) {
|
|
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(ENS210_LOG ":@%02X begin error!"), i2caddr);
|
|
return;
|
|
}
|
|
if (!ens210->available()) {
|
|
AddLog(LOG_LEVEL_ERROR, PSTR(ENS210_LOG ":@%02X available error!"), i2caddr);
|
|
return;
|
|
}
|
|
ens210->setSingleMode(false);
|
|
ENS210data = (ENS210DATA_t *)calloc(1, sizeof(ENS210DATA_t));
|
|
if (!ENS210data) {
|
|
AddLog(LOG_LEVEL_ERROR, PSTR(ENS210_LOG ":@%02X Memory error!"), i2caddr);
|
|
return;
|
|
}
|
|
ENS210data->ens210 = ens210;
|
|
I2cSetActiveFound(i2caddr, ENS210_DEVICE_NAME);
|
|
}
|
|
}
|
|
|
|
void ens210Update(void) // Perform every n second
|
|
{
|
|
ENS210data->tcnt++;
|
|
if (ENS210data->tcnt >= ENS210_EVERYNSECONDS) {
|
|
ENS210data->tcnt = 0;
|
|
ENS210data->ready = 0;
|
|
if (ENS210data->ens210->available()) {
|
|
ENS210data->ens210->measure();
|
|
|
|
ENS210data->temperature = ENS210data->ens210->getTempCelsius();
|
|
ENS210data->humidity = ENS210data->ens210->getHumidityPercent();
|
|
ENS210data->ready = 1;
|
|
ENS210data->ecnt = 0;
|
|
} else {
|
|
// failed, count up
|
|
ENS210data->ecnt++;
|
|
if (ENS210data->ecnt > 6) {
|
|
// after 30 seconds, restart
|
|
ENS210data->ens210->begin();
|
|
if (ENS210data->ens210->available()) {
|
|
ENS210data->ens210->setSingleMode(false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ens210Show(bool json)
|
|
{
|
|
if (ENS210data->ready) {
|
|
TempHumDewShow(json, (0 == TasmotaGlobal.tele_period), ENS210_DEVICE_NAME, ENS210data->temperature, ENS210data->humidity);
|
|
}
|
|
}
|
|
|
|
/*********************************************************************************************\
|
|
* Interface
|
|
\*********************************************************************************************/
|
|
|
|
bool Xsns112(uint32_t function)
|
|
{
|
|
if (!I2cEnabled(XI2C_85)) { return false; }
|
|
|
|
bool result = false;
|
|
|
|
if (FUNC_INIT == function) {
|
|
ens210Detect();
|
|
}
|
|
else if (ENS210data) {
|
|
switch (function) {
|
|
case FUNC_EVERY_SECOND:
|
|
ens210Update();
|
|
break;
|
|
case FUNC_JSON_APPEND:
|
|
ens210Show(1);
|
|
break;
|
|
#ifdef USE_WEBSERVER
|
|
case FUNC_WEB_SENSOR:
|
|
ens210Show(0);
|
|
break;
|
|
#endif // USE_WEBSERVER
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
#endif // USE_ENS210
|
|
#endif // USE_I2C
|