Feat/add scd30 (#9609)

* Merge develop into SCD30

* Add SCD30 class

* Fix logging and admin commands

* Minor cleanup and logging improvements

* Minor formatting issue

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Improvements on setTemperature

* Fix casting float-uint16_t
* Pass 100 for resetting temperature offset

* Fix issues pointed out by copilot

* Add quick reboot to set interval quicker on scd30

* Change saveState to only happen after boot and minor log changes

* Fix missing semicolon in one shot mode log

---------

Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
oscgonfer
2026-02-16 05:38:36 -06:00
committed by GitHub
co-authored by Thomas Göttgens Copilot Ben Meadors
parent 56fd9c7813
commit 57268bf4ea
9 changed files with 598 additions and 29 deletions
+16 -15
View File
@@ -205,7 +205,6 @@ uint8_t SEN5XSensor::sen5xCRC(const uint8_t *buffer)
void SEN5XSensor::sleep()
{
// TODO Check this works
idle(true);
}
@@ -230,41 +229,43 @@ bool SEN5XSensor::idle(bool checkState)
// Check if we have time, and store it
uint32_t now; // If time is RTCQualityNone, it will return zero
now = getValidTime(RTCQuality::RTCQualityDevice);
// Check if state is valid (non-zero)
if (now) {
// Check if state is valid (non-zero)
vocTime = now;
}
}
if (vocStateStable() && vocValid) {
saveState();
} else {
LOG_INFO("SEN5X: Not stopping measurement, vocState is not stable yet!");
if (!(vocStateStable() && vocValid)) {
LOG_INFO("%s: Not stopping measurement, vocState is not stable yet!", sensorName);
return true;
}
}
// Save state and prefs (on all models)
saveState();
}
if (!oneShotMode) {
LOG_INFO("SEN5X: Not stopping measurement, continuous mode!");
LOG_INFO("%s: Not stopping measurement, continuous mode!", sensorName);
return true;
} else {
LOG_INFO("%s: One shot mode enabled", sensorName);
}
// Switch to low-power based on the model
if (model == SEN50) {
if (!sendCommand(SEN5X_STOP_MEASUREMENT)) {
LOG_ERROR("SEN5X: Error stopping measurement");
LOG_ERROR("%s: Error stopping measurement", sensorName);
return false;
}
state = SEN5X_IDLE;
LOG_INFO("SEN5X: Stop measurement mode");
LOG_INFO("%s: Stop measurement mode", sensorName);
} else {
if (!sendCommand(SEN5X_START_MEASUREMENT_RHT_GAS)) {
LOG_ERROR("SEN5X: Error switching to RHT/Gas measurement");
LOG_ERROR("%s: Error switching to RHT/Gas measurement", sensorName);
return false;
}
state = SEN5X_RHTGAS_ONLY;
LOG_INFO("SEN5X: Switch to RHT/Gas only measurement mode");
LOG_INFO("%s: Switch to RHT/Gas only measurement mode", sensorName);
}
delay(200); // From Sensirion Datasheet
@@ -289,10 +290,10 @@ bool SEN5XSensor::vocStateValid()
{
if (!vocState[0] && !vocState[1] && !vocState[2] && !vocState[3] && !vocState[4] && !vocState[5] && !vocState[6] &&
!vocState[7]) {
LOG_DEBUG("SEN5X: VOC state is all 0, invalid");
LOG_DEBUG("%s: VOC state is all 0, invalid", sensorName);
return false;
} else {
LOG_DEBUG("SEN5X: VOC state is valid");
LOG_DEBUG("%s: VOC state is valid", sensorName);
return true;
}
}
@@ -618,7 +619,7 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev)
}
} else {
// TODO - Should this actually ignore? We could end up never cleaning...
LOG_INFO("SEN5X: Not enough RTCQuality, ignoring saved state. Trying again later");
LOG_INFO("SEN5X: Not enough RTCQuality, ignoring saved cleaning and VOC state");
}
idle(false);
@@ -965,4 +966,4 @@ AdminMessageHandleResult SEN5XSensor::handleAdminMessage(const meshtastic_MeshPa
return result;
}
#endif
#endif