mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-04 03:18:10 +10:00
* Add SEN6X * Adds new SENXX class for SEN5X and SEN6X * Adds CO2 sensor calibration class to be shared among othre CO2 sensors * Make existing CO2 sensor draw from CO2Sensor class * Minor coment for CO2 sensor class * Move away from getRTC in SENXX class to keep track of time changes. * Change all sensors to millis for tracking time, instead of using getRTC * Add comments regarding VOC state * Avoid storing non-valid RTC Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Avoid CO2 sensor warm-up time to be below PM measured started Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix limits in CO2 sensor calibration Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Add pragma once on headers * Avoid non-working ASC commands Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * Fix data poll * Move pm measure started before warmup check * Make cleaning non-blocking * Restore previous state if cleaning fails. Fix data ready condition. * Fix CO2 sensor checks for calibration --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
173 lines
4.5 KiB
C++
173 lines
4.5 KiB
C++
#include "configuration.h"
|
|
|
|
#if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include(<SensirionI2cSfa3x.h>)
|
|
|
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
|
#include "SFA30Sensor.h"
|
|
|
|
SFA30Sensor::SFA30Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SFA30, "SFA30"){};
|
|
|
|
bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
|
|
{
|
|
LOG_INFO("Init sensor: %s", sensorName);
|
|
|
|
_bus = bus;
|
|
_address = dev->address.address;
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
_port = dev->address.port;
|
|
reClockI2C.setup(_bus, _port);
|
|
reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED);
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
sfa30.begin(*_bus, _address);
|
|
delay(20);
|
|
|
|
if (this->isError(sfa30.deviceReset())) {
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
return false;
|
|
}
|
|
|
|
state = State::IDLE;
|
|
if (this->isError(sfa30.startContinuousMeasurement())) {
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
return false;
|
|
}
|
|
|
|
LOG_INFO("%s starting measurement", sensorName);
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
status = 1;
|
|
state = State::ACTIVE;
|
|
measureStarted = millis();
|
|
LOG_INFO("%s Enabled", sensorName);
|
|
|
|
initI2CSensor();
|
|
return true;
|
|
};
|
|
|
|
bool SFA30Sensor::isError(uint16_t response)
|
|
{
|
|
if (response == SFA30_NO_ERROR)
|
|
return false;
|
|
|
|
// TODO - Check error to char conversion
|
|
LOG_ERROR("%s: %u", sensorName, response);
|
|
return true;
|
|
}
|
|
|
|
void SFA30Sensor::sleep()
|
|
{
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED);
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
// Note - not recommended for this sensor on a periodic basis
|
|
if (this->isError(sfa30.stopMeasurement())) {
|
|
LOG_ERROR("%s: Can't stop measurement", sensorName);
|
|
};
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
LOG_DEBUG("%s: stop measurement", sensorName);
|
|
state = State::IDLE;
|
|
measureStarted = 0;
|
|
}
|
|
|
|
uint32_t SFA30Sensor::wakeUp()
|
|
{
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED);
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
LOG_DEBUG("Waking %s", sensorName);
|
|
if (this->isError(sfa30.startContinuousMeasurement())) {
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
return 0;
|
|
}
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
state = State::ACTIVE;
|
|
measureStarted = millis();
|
|
return SFA30_WARMUP_MS;
|
|
}
|
|
|
|
int32_t SFA30Sensor::wakeUpTimeMs()
|
|
{
|
|
return SFA30_WARMUP_MS;
|
|
}
|
|
|
|
bool SFA30Sensor::canSleep()
|
|
{
|
|
// Sleep is disabled in this sensor because readings are not tested with periodic sleep
|
|
// with such low power consumption, prefered to keep it active
|
|
return false;
|
|
}
|
|
|
|
bool SFA30Sensor::isActive()
|
|
{
|
|
return state == State::ACTIVE;
|
|
}
|
|
|
|
int32_t SFA30Sensor::pendingForReadyMs()
|
|
{
|
|
uint32_t sinceHchoMeasureStarted = millis() - measureStarted;
|
|
LOG_DEBUG("%s: Since measure started: %ums", sensorName, sinceHchoMeasureStarted);
|
|
|
|
if (sinceHchoMeasureStarted < SFA30_WARMUP_MS) {
|
|
LOG_INFO("%s: not enough time passed since starting measurement", sensorName);
|
|
return SFA30_WARMUP_MS - sinceHchoMeasureStarted;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
bool SFA30Sensor::getMetrics(meshtastic_Telemetry *measurement)
|
|
{
|
|
float hcho = 0.0;
|
|
float humidity = 0.0;
|
|
float temperature = 0.0;
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED);
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
if (this->isError(sfa30.readMeasuredValues(hcho, humidity, temperature))) {
|
|
LOG_WARN("%s: No values", sensorName);
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
return false;
|
|
}
|
|
|
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
|
reClockI2C.restoreClock();
|
|
#endif /* SFA30_I2C_CLOCK_SPEED */
|
|
|
|
measurement->variant.air_quality_metrics.has_form_temperature = true;
|
|
measurement->variant.air_quality_metrics.has_form_humidity = true;
|
|
measurement->variant.air_quality_metrics.has_form_formaldehyde = true;
|
|
|
|
measurement->variant.air_quality_metrics.form_temperature = temperature;
|
|
measurement->variant.air_quality_metrics.form_humidity = humidity;
|
|
measurement->variant.air_quality_metrics.form_formaldehyde = hcho;
|
|
|
|
LOG_DEBUG("Got %s readings: hcho=%.2f, hcho_temp=%.2f, hcho_hum=%.2f", sensorName, hcho, temperature, humidity);
|
|
|
|
return true;
|
|
}
|
|
#endif
|