mirror of
https://github.com/airgradienthq/arduino.git
synced 2025-07-21 20:52:08 +02:00
Fix capitalize folder and file name ignored
This commit is contained in:
251
src/Sgp41/Sgp41.cpp
Normal file
251
src/Sgp41/Sgp41.cpp
Normal file
@ -0,0 +1,251 @@
|
||||
#include "Sgp41.h"
|
||||
#include "../Libraries/SensirionSGP41/src/SensirionI2CSgp41.h"
|
||||
#include "../Libraries/Sensirion_Gas_Index_Algorithm/src/NOxGasIndexAlgorithm.h"
|
||||
#include "../Libraries/Sensirion_Gas_Index_Algorithm/src/VOCGasIndexAlgorithm.h"
|
||||
|
||||
#define sgpSensor() ((SensirionI2CSgp41 *)(this->_sensor))
|
||||
#define vocAlgorithm() ((VOCGasIndexAlgorithm *)(this->_vocAlgorithm))
|
||||
#define noxAlgorithm() ((NOxGasIndexAlgorithm *)(this->_noxAlgorithm))
|
||||
|
||||
/**
|
||||
* @brief Construct a new Sgp 4 1:: Sgp 4 1 object
|
||||
*
|
||||
* @param type Board type @ref BoardType
|
||||
*/
|
||||
Sgp41::Sgp41(BoardType type) : _boardType(type) {}
|
||||
|
||||
/**
|
||||
* @brief Sensor intialize, if initialize fail, other function call always
|
||||
* return false or invalid valid
|
||||
*
|
||||
* @param wire TwoWire instance
|
||||
* @return true Success
|
||||
* @return false Failure
|
||||
*/
|
||||
bool Sgp41::begin(TwoWire &wire) {
|
||||
/** Ignore next step if initialized */
|
||||
if (this->_isBegin) {
|
||||
AgLog("Initialized, call end() then try again");
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Check that board has supported this sensor */
|
||||
if (this->boardSupported() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Init algorithm */
|
||||
_vocAlgorithm = new VOCGasIndexAlgorithm();
|
||||
_noxAlgorithm = new NOxGasIndexAlgorithm();
|
||||
|
||||
/** Init sensor */
|
||||
this->_sensor = new SensirionI2CSgp41();
|
||||
sgpSensor()->begin(wire);
|
||||
|
||||
uint16_t testResult;
|
||||
if (sgpSensor()->executeSelfTest(testResult) != 0) {
|
||||
return false;
|
||||
}
|
||||
if (testResult != 0xD400) {
|
||||
AgLog("Self-test failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
/** Create task */
|
||||
xTaskCreate(
|
||||
[](void *param) {
|
||||
Sgp41 *sgp = static_cast<Sgp41 *>(param);
|
||||
sgp->_handle();
|
||||
},
|
||||
"sgp_poll", 2048, this, 5, &pollTask);
|
||||
#else
|
||||
conditioningPeriod = millis();
|
||||
conditioningCount = 0;
|
||||
#endif
|
||||
|
||||
this->_isBegin = true;
|
||||
AgLog("Initialize");
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(ESP8266)
|
||||
bool Sgp41::begin(TwoWire &wire, Stream &stream) {
|
||||
this->_debugStream = &stream;
|
||||
return this->begin(wire);
|
||||
}
|
||||
void Sgp41::handle(void) {
|
||||
uint32_t ms = (uint32_t)(millis() - conditioningPeriod);
|
||||
if (ms >= 1000) {
|
||||
conditioningPeriod = millis();
|
||||
if (onConditioning) {
|
||||
if (_noxConditioning() == false) {
|
||||
AgLog("SGP on conditioning failed");
|
||||
}
|
||||
conditioningCount++;
|
||||
if (conditioningCount >= 10) {
|
||||
onConditioning = false;
|
||||
}
|
||||
} else {
|
||||
uint16_t srawVoc, srawNox;
|
||||
if (getRawSignal(srawVoc, srawNox)) {
|
||||
nox = noxAlgorithm()->process(srawNox);
|
||||
tvoc = vocAlgorithm()->process(srawVoc);
|
||||
AgLog("Polling SGP41 success: tvoc: %d, nox: %d", tvoc, nox);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
/**
|
||||
* @brief Handle the sensor conditioning and run time udpate value, This method
|
||||
* must not call, it's called on private task
|
||||
*/
|
||||
void Sgp41::_handle(void) {
|
||||
/** NOx conditionning */
|
||||
uint16_t err;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
if (_noxConditioning() == false) {
|
||||
AgLog("SGP on conditioning failed");
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
onConditioning = false;
|
||||
AgLog("Conditioning finish");
|
||||
|
||||
uint16_t srawVoc, srawNox;
|
||||
for (;;) {
|
||||
vTaskDelay(pdMS_TO_TICKS(1000));
|
||||
if (getRawSignal(srawVoc, srawNox)) {
|
||||
tvocRaw = srawVoc;
|
||||
nox = noxAlgorithm()->process(srawNox);
|
||||
tvoc = vocAlgorithm()->process(srawVoc);
|
||||
AgLog("Polling SGP41 success: tvoc: %d, nox: %d", tvoc, nox);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief De-Initialize sensor
|
||||
*/
|
||||
void Sgp41::end(void) {
|
||||
if (this->_isBegin == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef ESP32
|
||||
vTaskDelete(pollTask);
|
||||
#else
|
||||
_debugStream = nullptr;
|
||||
#endif
|
||||
bsp = NULL;
|
||||
this->_isBegin = false;
|
||||
delete sgpSensor();
|
||||
delete vocAlgorithm();
|
||||
delete noxAlgorithm();
|
||||
|
||||
AgLog("De-initialize");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get TVOC index
|
||||
*
|
||||
* @return int -1 if invalid
|
||||
*/
|
||||
int Sgp41::getTvocIndex(void) {
|
||||
if (onConditioning) {
|
||||
return -1;
|
||||
}
|
||||
return tvoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get NOX index
|
||||
*
|
||||
* @return int -1 if invalid
|
||||
*/
|
||||
int Sgp41::getNoxIndex(void) {
|
||||
if (onConditioning) {
|
||||
return -1;
|
||||
}
|
||||
return nox;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check that board has supported sensor
|
||||
*
|
||||
* @return true Supported
|
||||
* @return false Not-supported
|
||||
*/
|
||||
bool Sgp41::boardSupported(void) {
|
||||
if (this->bsp == nullptr) {
|
||||
this->bsp = getBoardDef(this->_boardType);
|
||||
}
|
||||
|
||||
if ((this->bsp == nullptr) || (this->bsp->I2C.supported == false)) {
|
||||
AgLog("Board not supported");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get raw signal
|
||||
*
|
||||
* @param raw_voc Raw VOC output
|
||||
* @param row_nox Raw NOx output
|
||||
* @param defaultRh
|
||||
* @param defaultT
|
||||
* @return true Success
|
||||
* @return false Failure
|
||||
*/
|
||||
bool Sgp41::getRawSignal(uint16_t &raw_voc, uint16_t &row_nox,
|
||||
uint16_t defaultRh, uint16_t defaultT) {
|
||||
if (this->isBegin() == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sgpSensor()->measureRawSignals(defaultRh, defaultT, raw_voc, row_nox) ==
|
||||
0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Check that sensor is initialized
|
||||
*
|
||||
* @return true Initialized
|
||||
* @return false Not-initialized
|
||||
*/
|
||||
bool Sgp41::isBegin(void) {
|
||||
if (this->_isBegin) {
|
||||
return true;
|
||||
}
|
||||
AgLog("Sensor not-initialized");
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle nox conditioning process
|
||||
*
|
||||
* @return true Success
|
||||
* @return false Failure
|
||||
*/
|
||||
bool Sgp41::_noxConditioning(void) {
|
||||
uint16_t err;
|
||||
uint16_t srawVoc;
|
||||
err = sgpSensor()->executeConditioning(defaultRh, defaultT, srawVoc);
|
||||
return (err == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get TVOC raw value
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
int Sgp41::getTvocRaw(void) { return tvocRaw; }
|
Reference in New Issue
Block a user