From b7ec5cd35a5e2ed59e76854c8dc36d86fa32ab84 Mon Sep 17 00:00:00 2001 From: oscgonfer Date: Tue, 26 May 2026 09:55:32 +0200 Subject: [PATCH] Refurbish ReClockI2C API * Make ReClockI2C API class * Use new API in AirQualityTelemetry module * Minor changes on some logs --- src/detect/ReClockI2C.h | 98 ++++++++++ src/detect/reClockI2C.cpp | 44 ----- src/detect/reClockI2C.h | 14 -- src/modules/Telemetry/AirQualityTelemetry.cpp | 4 +- .../Telemetry/Sensor/PMSA003ISensor.cpp | 46 +++-- src/modules/Telemetry/Sensor/PMSA003ISensor.h | 4 + src/modules/Telemetry/Sensor/SCD30Sensor.cpp | 78 ++++---- src/modules/Telemetry/Sensor/SCD30Sensor.h | 4 + src/modules/Telemetry/Sensor/SCD4XSensor.cpp | 112 +++++------ src/modules/Telemetry/Sensor/SCD4XSensor.h | 6 +- src/modules/Telemetry/Sensor/SEN5XSensor.cpp | 177 +++++++++--------- src/modules/Telemetry/Sensor/SEN5XSensor.h | 4 + src/modules/Telemetry/Sensor/SFA30Sensor.cpp | 61 +++--- src/modules/Telemetry/Sensor/SFA30Sensor.h | 4 + variants/esp32/esp32-common.ini | 2 +- 15 files changed, 338 insertions(+), 320 deletions(-) create mode 100644 src/detect/ReClockI2C.h delete mode 100644 src/detect/reClockI2C.cpp delete mode 100644 src/detect/reClockI2C.h diff --git a/src/detect/ReClockI2C.h b/src/detect/ReClockI2C.h new file mode 100644 index 000000000..90cc859cb --- /dev/null +++ b/src/detect/ReClockI2C.h @@ -0,0 +1,98 @@ +#pragma once + +#ifndef RECLOCK_I2C_ +#define RECLOCK_I2C_ + +#include "../graphics/Screen.h" +#include "ScanI2CTwoWire.h" +#include +#include + +/* Class to set and restore the I2C clock temporarily on a i2cBus + See https://github.com/arduino/Arduino/issues/11457 + Currently, only ESP32 can getClock() + While all cores can setClock() + https://github.com/sandeepmistry/arduino-nRF5/blob/master/libraries/Wire/Wire.h#L50 + https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Wire/src/Wire.h#L60 + https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/Wire/src/Wire.h#L103 + For cases when I2C speed is different to the ones defined by sensors (see defines in sensor classes) + we need to reclock I2C and set it back to the previous stablished speed. + Only for cases where we can know it (ESP32 or known screen) we can do this. +*/ + +extern graphics::Screen *screen; + +class ReClockI2C +{ + public: + void setup(TwoWire *i2cBus, ScanI2C::I2CPort port) + { + this->i2cBus = i2cBus; + this->port = port; + this->previousClock = 0; + } + + bool setClock(uint32_t desiredClock) + { + uint32_t currentClock = this->getClock(); + + if (currentClock) { + LOG_DEBUG("Current I2C frequency: %uHz", currentClock); + } + + if (currentClock != desiredClock) { + LOG_DEBUG("Changing I2C clock to %uHz", desiredClock); + this->i2cBus->setClock(desiredClock); + // If the clock is 0Hz, we still store it + // We'll check in restoreClock function + setPreviousClock(currentClock); + LOG_DEBUG("Stored previous clock I2C clock: %uHz", this->previousClock); + return true; + } + + LOG_DEBUG("I2C clock was already %uHz. Skipping", desiredClock); + return false; + } + + bool restoreClock() + { + if (this->previousClock) { + LOG_DEBUG("Restoring I2C clock to %uHz", this->previousClock); + i2cBus->setClock(this->previousClock); + return true; + } + LOG_DEBUG("I2C clock was unknown. Not restored"); + return false; + } + + private: + TwoWire *i2cBus{}; + ScanI2C::I2CPort port{}; + uint32_t previousClock = 0; + + void setPreviousClock(uint32_t clock) { this->previousClock = clock; } + + uint32_t getClock() + { + +#ifdef CAN_GET_I2C_CLOCK + return this->i2cBus->getClock(); +#elif HAS_SCREEN + if (screen) { + // If we get a non-zero response here, the screen has set a speed + uint32_t screenClock = 0; + ScanI2C::I2CPort screenPort = ScanI2C::I2CPort::NO_I2C; + screenClock = screen->getI2cFrequency(); + screenPort = screen->getI2CPort(); + // Check if i2c port is the same, and that we got a screenClock back (0 means the screen didn't set it) + if (screenClock && (screenPort == this->port)) { + LOG_DEBUG("Screen defined I2C frequency: %uHz", screenClock); + return screenClock; + } + } +#endif + return 0; + } +}; + +#endif diff --git a/src/detect/reClockI2C.cpp b/src/detect/reClockI2C.cpp deleted file mode 100644 index df81a7e23..000000000 --- a/src/detect/reClockI2C.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "reClockI2C.h" -#include "ScanI2CTwoWire.h" - -/* See https://github.com/arduino/Arduino/issues/11457 - Currently, only ESP32 can getClock() - While all cores can setClock() - https://github.com/sandeepmistry/arduino-nRF5/blob/master/libraries/Wire/Wire.h#L50 - https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Wire/src/Wire.h#L60 - https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/Wire/src/Wire.h#L103 - For cases when I2C speed is different to the ones defined by sensors (see defines in sensor classes) - we need to reclock I2C and set it back to the previous stablished speed. - Only for cases where we can know it (ESP32 or known screen) we can do this. -*/ - -uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, ScanI2C::I2CPort port) -{ - - uint32_t currentClock = 0; - uint32_t screenClock = 0; - ScanI2C::I2CPort screenPort = ScanI2C::I2CPort::NO_I2C; - - // Assume that if we can't getClock, or there is no screen, we can set the clock speed at will -#ifdef CAN_RECLOCK_I2C - currentClock = i2cBus->getClock(); - LOG_DEBUG("Current I2C frequency: %uHz", currentClock); -#elif HAS_SCREEN - if (screen) { - // If we get a non-zero response here, the screen has set a speed - screenClock = screen->getI2cFrequency(); - screenPort = screen->getI2CPort(); - // Check if i2c port is the same, and that we got a screenClock back (0 means the screen didn't set it) - if (screenClock && (screenPort == port)) - currentClock = screenClock; - LOG_DEBUG("Screen defined I2C frequency: %uHz", screenClock); - } -#endif - - if (currentClock != desiredClock) { - LOG_DEBUG("Changing I2C clock to %uHz", desiredClock); - i2cBus->setClock(desiredClock); - } - - return currentClock; -} diff --git a/src/detect/reClockI2C.h b/src/detect/reClockI2C.h deleted file mode 100644 index b28525414..000000000 --- a/src/detect/reClockI2C.h +++ /dev/null @@ -1,14 +0,0 @@ - -#ifndef RECLOCK_I2C_ -#define RECLOCK_I2C_ - -#include "../graphics/Screen.h" -#include "ScanI2CTwoWire.h" -#include -#include - -uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, ScanI2C::I2CPort port); - -extern graphics::Screen *screen; - -#endif diff --git a/src/modules/Telemetry/AirQualityTelemetry.cpp b/src/modules/Telemetry/AirQualityTelemetry.cpp index 3d7cb7351..a50ea8e57 100644 --- a/src/modules/Telemetry/AirQualityTelemetry.cpp +++ b/src/modules/Telemetry/AirQualityTelemetry.cpp @@ -110,10 +110,10 @@ int32_t AirQualityTelemetryModule::runOnce() } // Wake up the sensors that need it - LOG_INFO("Waking up sensors..."); uint32_t lastTelemetry = transmitHistory ? transmitHistory->getLastSentToMeshMillis(TX_HISTORY_KEY_AIR_QUALITY_TELEMETRY) : 0; for (TelemetrySensor *sensor : sensors) { + LOG_DEBUG("Checking if %s needs to wake up", sensor->sensorName); if (!sensor->canSleep()) { LOG_DEBUG("%s sensor doesn't have sleep feature. Skipping", sensor->sensorName); } else if (((lastTelemetry == 0) || !Throttle::isWithinTimespanMs(lastTelemetry - sensor->wakeUpTimeMs(), @@ -154,8 +154,8 @@ int32_t AirQualityTelemetryModule::runOnce() } // Send to sleep sensors that consume power - LOG_DEBUG("Sending sensors to sleep"); for (TelemetrySensor *sensor : sensors) { + LOG_DEBUG("Checking if %s can be sent to sleep", sensor->sensorName); if (sensor->isActive() && sensor->canSleep()) { if (sensor->wakeUpTimeMs() < (int32_t)Default::getConfiguredOrDefaultMsScaled(moduleConfig.telemetry.air_quality_interval, diff --git a/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp b/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp index c6711fc5a..357545f27 100644 --- a/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp +++ b/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp @@ -2,7 +2,6 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR -#include "../detect/reClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "PMSA003ISensor.h" #include "TelemetrySensor.h" @@ -13,31 +12,36 @@ PMSA003ISensor::PMSA003ISensor() : TelemetrySensor(meshtastic_TelemetrySensorTyp bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { - LOG_INFO("Init sensor: %s", sensorName); + LOG_INFO("%s: Init sensor", sensorName); #ifdef PMSA003I_ENABLE_PIN pinMode(PMSA003I_ENABLE_PIN, OUTPUT); #endif + // TODO PMS5003I sometimes get late to the party... + _bus = bus; _address = dev->address.address; - _port = dev->address.port; - #ifdef PMSA003I_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, _port); + _port = dev->address.port; + reClockI2C.setup(_bus, _port); + + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); + reClockI2C.setClock(PMSA003I_I2C_CLOCK_SPEED); #endif /* PMSA003I_I2C_CLOCK_SPEED */ _bus->beginTransmission(_address); if (_bus->endTransmission() != 0) { LOG_WARN("%s not found on I2C at 0x12", sensorName); +#ifdef PMSA003I_I2C_CLOCK_SPEED + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); +#endif /* PMSA003I_I2C_CLOCK_SPEED */ return false; } #ifdef PMSA003I_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* PMSA003I_I2C_CLOCK_SPEED */ status = 1; @@ -55,13 +59,17 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement) } #ifdef PMSA003I_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); + reClockI2C.setClock(PMSA003I_I2C_CLOCK_SPEED); #endif /* PMSA003I_I2C_CLOCK_SPEED */ _bus->requestFrom(_address, (uint8_t)PMSA003I_FRAME_LENGTH); if (_bus->available() < PMSA003I_FRAME_LENGTH) { - LOG_WARN("%s read failed: incomplete data (%d bytes)", sensorName, _bus->available()); + LOG_WARN("%s: read failed: incomplete data (%d bytes)", sensorName, _bus->available()); +#ifdef PMSA003I_I2C_CLOCK_SPEED + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); +#endif /* PMSA003I_I2C_CLOCK_SPEED */ return false; } @@ -70,14 +78,12 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement) } #ifdef PMSA003I_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* PMSA003I_I2C_CLOCK_SPEED */ if (buffer[0] != 0x42 || buffer[1] != 0x4D) { - LOG_WARN("%s frame header invalid: 0x%02X 0x%02X", sensorName, buffer[0], buffer[1]); + LOG_WARN("%s: frame header invalid: 0x%02X 0x%02X", sensorName, buffer[0], buffer[1]); return false; } @@ -133,7 +139,7 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement) measurement->variant.air_quality_metrics.has_particles_100um = true; measurement->variant.air_quality_metrics.particles_100um = read16(buffer, 26); - LOG_DEBUG("Got %s readings: pM1p0_standard=%u, pM2p5_standard=%u, pM10p0_standard=%u", sensorName, + LOG_DEBUG("%s: Got readings: pM1p0_standard=%u, pM2p5_standard=%u, pM10p0_standard=%u", sensorName, measurement->variant.air_quality_metrics.pm10_standard, measurement->variant.air_quality_metrics.pm25_standard, measurement->variant.air_quality_metrics.pm100_standard); @@ -192,7 +198,7 @@ void PMSA003ISensor::sleep() uint32_t PMSA003ISensor::wakeUp() { #ifdef PMSA003I_ENABLE_PIN - LOG_INFO("Waking up %s", sensorName); + LOG_INFO("%s: Waking up", sensorName); digitalWrite(PMSA003I_ENABLE_PIN, HIGH); state = State::ACTIVE; pmMeasureStarted = getTime(); diff --git a/src/modules/Telemetry/Sensor/PMSA003ISensor.h b/src/modules/Telemetry/Sensor/PMSA003ISensor.h index ed01a188d..ce7bba4bb 100644 --- a/src/modules/Telemetry/Sensor/PMSA003ISensor.h +++ b/src/modules/Telemetry/Sensor/PMSA003ISensor.h @@ -2,6 +2,7 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR +#include "../detect/ReClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "RTC.h" #include "TelemetrySensor.h" @@ -35,7 +36,10 @@ class PMSA003ISensor : public TelemetrySensor uint8_t buffer[PMSA003I_FRAME_LENGTH]{}; TwoWire *_bus{}; uint8_t _address{}; +#ifdef PMSA003I_I2C_CLOCK_SPEED ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + ReClockI2C reClockI2C; +#endif }; #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/SCD30Sensor.cpp b/src/modules/Telemetry/Sensor/SCD30Sensor.cpp index b9c7617ad..a752b105d 100644 --- a/src/modules/Telemetry/Sensor/SCD30Sensor.cpp +++ b/src/modules/Telemetry/Sensor/SCD30Sensor.cpp @@ -2,7 +2,6 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() -#include "../detect/reClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "SCD30Sensor.h" @@ -12,15 +11,16 @@ SCD30Sensor::SCD30Sensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SCD3 bool SCD30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { - LOG_INFO("Init sensor: %s", sensorName); + LOG_INFO("%s: Init sensor", sensorName); _bus = bus; _address = dev->address.address; - _port = dev->address.port; - #ifdef SCD30_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); + _port = dev->address.port; + reClockI2C.setup(_bus, _port); + + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD30_I2C_CLOCK_SPEED); #endif /* SCD30_I2C_CLOCK_SPEED */ scd30.begin(*_bus, _address); @@ -28,10 +28,8 @@ bool SCD30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (!startMeasurement()) { LOG_ERROR("%s: Failed to start periodic measurement", sensorName); #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ return false; } @@ -41,10 +39,8 @@ bool SCD30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) } #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ if (state == SCD30_MEASUREMENT) { @@ -63,31 +59,27 @@ bool SCD30Sensor::getMetrics(meshtastic_Telemetry *measurement) float co2, temperature, humidity; #ifdef SCD30_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD30_I2C_CLOCK_SPEED); #endif /* SCD30_I2C_CLOCK_SPEED */ if (scd30.readMeasurementData(co2, temperature, humidity) != SCD30_NO_ERROR) { - LOG_ERROR("SCD30: Failed to read measurement data."); + LOG_ERROR("%s: Failed to read measurement data", sensorName); #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ return false; } #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ if (co2 == 0) { - LOG_ERROR("SCD30: Invalid CO₂ reading."); + LOG_ERROR("%s: Invalid CO₂ reading", sensorName); return false; } @@ -98,7 +90,7 @@ bool SCD30Sensor::getMetrics(meshtastic_Telemetry *measurement) measurement->variant.air_quality_metrics.co2_temperature = temperature; measurement->variant.air_quality_metrics.co2_humidity = humidity; - LOG_DEBUG("Got %s readings: co2=%u, co2_temp=%.2f, co2_hum=%.2f", sensorName, (uint32_t)co2, temperature, humidity); + LOG_DEBUG("%s: Got readings: co2=%u, co2_temp=%.2f, co2_hum=%.2f", sensorName, (uint32_t)co2, temperature, humidity); return true; } @@ -285,7 +277,7 @@ bool SCD30Sensor::setTemperature(float tempReference) tempOffset = (temperature - tempReference); if (tempOffset < 0) { - LOG_ERROR("%s temperature offset is only positive", sensorName); + LOG_ERROR("%s: temperature offset is only positive", sensorName); return false; } @@ -375,17 +367,15 @@ bool SCD30Sensor::isActive() uint32_t SCD30Sensor::wakeUp() { #ifdef SCD30_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD30_I2C_CLOCK_SPEED); #endif /* SCD30_I2C_CLOCK_SPEED */ startMeasurement(); #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ return 0; @@ -398,17 +388,15 @@ uint32_t SCD30Sensor::wakeUp() void SCD30Sensor::sleep() { #ifdef SCD30_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD30_I2C_CLOCK_SPEED); #endif /* SCD30_I2C_CLOCK_SPEED */ stopMeasurement(); #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ } @@ -433,8 +421,8 @@ AdminMessageHandleResult SCD30Sensor::handleAdminMessage(const meshtastic_MeshPa AdminMessageHandleResult result; #ifdef SCD30_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD30_I2C_CLOCK_SPEED); #endif /* SCD30_I2C_CLOCK_SPEED */ switch (request->which_payload_variant) { @@ -491,10 +479,8 @@ AdminMessageHandleResult SCD30Sensor::handleAdminMessage(const meshtastic_MeshPa } #ifdef SCD30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD30_I2C_CLOCK_SPEED */ return result; diff --git a/src/modules/Telemetry/Sensor/SCD30Sensor.h b/src/modules/Telemetry/Sensor/SCD30Sensor.h index 067b9b73b..64ca73420 100644 --- a/src/modules/Telemetry/Sensor/SCD30Sensor.h +++ b/src/modules/Telemetry/Sensor/SCD30Sensor.h @@ -2,6 +2,7 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() +#include "../detect/ReClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "TelemetrySensor.h" #include @@ -14,7 +15,10 @@ class SCD30Sensor : public TelemetrySensor SensirionI2cScd30 scd30; TwoWire *_bus{}; uint8_t _address{}; +#ifdef SCD30_I2C_CLOCK_SPEED ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + ReClockI2C reClockI2C; +#endif bool performFRC(uint16_t targetCO2); bool setASC(bool ascEnabled); diff --git a/src/modules/Telemetry/Sensor/SCD4XSensor.cpp b/src/modules/Telemetry/Sensor/SCD4XSensor.cpp index d5f88312b..aa9ac9165 100644 --- a/src/modules/Telemetry/Sensor/SCD4XSensor.cpp +++ b/src/modules/Telemetry/Sensor/SCD4XSensor.cpp @@ -2,7 +2,6 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() -#include "../detect/reClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "SCD4XSensor.h" @@ -18,8 +17,11 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _address = dev->address.address; #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + _port = dev->address.port; + reClockI2C.setup(_bus, _port); + + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ scd4x.begin(*_bus, _address); @@ -30,10 +32,8 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) // Stop periodic measurement if (!stopMeasurement()) { #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } @@ -46,10 +46,8 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (!powerUp()) { LOG_ERROR("%s: Error trying to execute powerUp()", sensorName); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } @@ -58,10 +56,8 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (!getASC(ascActive)) { LOG_ERROR("%s: Unable to check if ASC is enabled", sensorName); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } @@ -70,19 +66,15 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (!startMeasurement()) { LOG_ERROR("%s: Couldn't start measurement", sensorName); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ if (state == SCD4X_MEASUREMENT) { @@ -108,18 +100,16 @@ bool SCD4XSensor::getMetrics(meshtastic_Telemetry *measurement) float temperature, humidity; #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ bool dataReady; error = scd4x.getDataReadyStatus(dataReady); if (error != SCD4X_NO_ERROR || !dataReady) { #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ LOG_ERROR("SCD4X: Data is not ready"); return false; @@ -128,10 +118,8 @@ bool SCD4XSensor::getMetrics(meshtastic_Telemetry *measurement) error = scd4x.readMeasurement(co2, temperature, humidity); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ LOG_DEBUG("Got %s readings: co2=%u, co2_temp=%.2f, co2_hum%.2f", sensorName, co2, temperature, humidity); @@ -646,16 +634,14 @@ bool SCD4XSensor::powerDown() } #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ if (!stopMeasurement()) { #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } @@ -663,19 +649,15 @@ bool SCD4XSensor::powerDown() if (scd4x.powerDown() != SCD4X_NO_ERROR) { LOG_ERROR("%s: Error trying to execute sleep()", sensorName); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ state = SCD4X_OFF; @@ -723,26 +705,22 @@ uint32_t SCD4XSensor::wakeUp() { #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ if (startMeasurement()) { co2MeasureStarted = getTime(); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return SCD4X_WARMUP_MS; } #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return 0; @@ -755,17 +733,15 @@ uint32_t SCD4XSensor::wakeUp() void SCD4XSensor::sleep() { #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ stopMeasurement(); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ } @@ -806,8 +782,8 @@ AdminMessageHandleResult SCD4XSensor::handleAdminMessage(const meshtastic_MeshPa AdminMessageHandleResult result; #ifdef SCD4X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); + LOG_INFO("%s: attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SCD4X_I2C_CLOCK_SPEED); #endif /* SCD4X_I2C_CLOCK_SPEED */ // TODO: potentially add selftest command? @@ -911,10 +887,8 @@ AdminMessageHandleResult SCD4XSensor::handleAdminMessage(const meshtastic_MeshPa this->startMeasurement(); #ifdef SCD4X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SCD4X_I2C_CLOCK_SPEED */ return result; diff --git a/src/modules/Telemetry/Sensor/SCD4XSensor.h b/src/modules/Telemetry/Sensor/SCD4XSensor.h index 76d36dda8..03ff4abc2 100644 --- a/src/modules/Telemetry/Sensor/SCD4XSensor.h +++ b/src/modules/Telemetry/Sensor/SCD4XSensor.h @@ -2,13 +2,14 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() +#include "../detect/ReClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "RTC.h" #include "TelemetrySensor.h" #include // Max speed 400kHz -#define SCD4X_I2C_CLOCK_SPEED 100000 +#define SCD4X_I2C_CLOCK_SPEED 400000 #define SCD4X_WARMUP_MS 5000 class SCD4XSensor : public TelemetrySensor @@ -17,7 +18,10 @@ class SCD4XSensor : public TelemetrySensor SensirionI2cScd4x scd4x; TwoWire *_bus{}; uint8_t _address{}; +#ifdef SCD4X_I2C_CLOCK_SPEED ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + ReClockI2C reClockI2C; +#endif bool performFRC(uint32_t targetCO2); bool setASCBaseline(uint32_t targetCO2); diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp index 4dd9b5db6..ab14215b6 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp @@ -2,7 +2,6 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR -#include "../detect/reClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "FSCommon.h" #include "SEN5XSensor.h" @@ -18,7 +17,7 @@ SEN5XSensor::SEN5XSensor() : TelemetrySensor(meshtastic_TelemetrySensorType_SEN5 bool SEN5XSensor::getVersion() { if (!sendCommand(SEN5X_GET_FIRMWARE_VERSION)) { - LOG_ERROR("SEN5X: Error sending version command"); + LOG_ERROR("%s: Error sending version command", sensorName); return false; } delay(20); // From Sensirion Datasheet @@ -26,7 +25,7 @@ bool SEN5XSensor::getVersion() uint8_t versionBuffer[12]{}; size_t charNumber = readBuffer(&versionBuffer[0], 3); if (charNumber == 0) { - LOG_ERROR("SEN5X: Error getting data ready flag value"); + LOG_ERROR("%s: Error getting data ready flag value", sensorName); return false; } @@ -34,9 +33,9 @@ bool SEN5XSensor::getVersion() hardwareVer = versionBuffer[3] + (versionBuffer[4] / 10); protocolVer = versionBuffer[5] + (versionBuffer[6] / 10); - LOG_INFO("SEN5X Firmware Version: %0.2f", firmwareVer); - LOG_INFO("SEN5X Hardware Version: %0.2f", hardwareVer); - LOG_INFO("SEN5X Protocol Version: %0.2f", protocolVer); + LOG_INFO("%s: Firmware Version: %0.2f", sensorName, firmwareVer); + LOG_INFO("%s: Hardware Version: %0.2f", sensorName, hardwareVer); + LOG_INFO("%s: Protocol Version: %0.2f", sensorName, protocolVer); return true; } @@ -44,7 +43,7 @@ bool SEN5XSensor::getVersion() bool SEN5XSensor::findModel() { if (!sendCommand(SEN5X_GET_PRODUCT_NAME)) { - LOG_ERROR("SEN5X: Error asking for product name"); + LOG_ERROR("%s: Error asking for product name", sensorName); return false; } delay(50); // From Sensirion Datasheet @@ -53,7 +52,7 @@ bool SEN5XSensor::findModel() uint8_t name[nameSize]; size_t charNumber = readBuffer(&name[0], nameSize); if (charNumber == 0) { - LOG_ERROR("SEN5X: Error getting device name"); + LOG_ERROR("%s: Error getting device name", sensorName); return false; } @@ -61,15 +60,15 @@ bool SEN5XSensor::findModel() switch (name[4]) { case 48: model = SEN50; - LOG_INFO("SEN5X: found sensor model SEN50"); + LOG_INFO("%s: found sensor model SEN50", sensorName); break; case 52: model = SEN54; - LOG_INFO("SEN5X: found sensor model SEN54"); + LOG_INFO("%s: found sensor model SEN54", sensorName); break; case 53: model = SEN55; - LOG_INFO("SEN5X: found sensor model SEN55"); + LOG_INFO("%s: found sensor model SEN55", sensorName); break; } @@ -134,8 +133,8 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum } #ifdef SEN5X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, _port); + LOG_DEBUG("%s: Attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SEN5X_I2C_CLOCK_SPEED); #endif /* SEN5X_I2C_CLOCK_SPEED */ // Transmit the data @@ -147,19 +146,17 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum uint8_t i2c_error = _bus->endTransmission(); #ifdef SEN5X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_DEBUG("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SEN5X_I2C_CLOCK_SPEED */ if (writtenBytes != bufferSize) { - LOG_ERROR("SEN5X: Error writting on I2C bus"); + LOG_ERROR("%s: Error writting on I2C bus", sensorName); return false; } if (i2c_error != 0) { - LOG_ERROR("SEN5X: Error on I2C communication: %x", i2c_error); + LOG_ERROR("%s: Error on I2C communication: %x", sensorName, i2c_error); return false; } return true; @@ -168,13 +165,17 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum uint8_t SEN5XSensor::readBuffer(uint8_t *buffer, uint8_t byteNumber) { #ifdef SEN5X_I2C_CLOCK_SPEED - LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, _port); + LOG_DEBUG("%s: Attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); + reClockI2C.setClock(SEN5X_I2C_CLOCK_SPEED); #endif /* SEN5X_I2C_CLOCK_SPEED */ size_t readBytes = _bus->requestFrom(_address, byteNumber); if (readBytes != byteNumber) { - LOG_ERROR("SEN5X: Error reading I2C bus"); + LOG_ERROR("%s: Error reading I2C bus", sensorName); +#ifdef SEN5X_I2C_CLOCK_SPEED + LOG_DEBUG("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); +#endif /* SEN5X_I2C_CLOCK_SPEED */ return 0; } @@ -186,7 +187,11 @@ uint8_t SEN5XSensor::readBuffer(uint8_t *buffer, uint8_t byteNumber) uint8_t recvCRC = _bus->read(); uint8_t calcCRC = sen5xCRC(&buffer[i - 2]); if (recvCRC != calcCRC) { - LOG_ERROR("SEN5X: Checksum error while receiving msg"); + LOG_ERROR("%s: Checksum error while receiving msg", sensorName); +#ifdef SEN5X_I2C_CLOCK_SPEED + LOG_DEBUG("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); +#endif /* SEN5X_I2C_CLOCK_SPEED */ return 0; } readBytes -= 3; @@ -194,10 +199,8 @@ uint8_t SEN5XSensor::readBuffer(uint8_t *buffer, uint8_t byteNumber) } #ifdef SEN5X_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_DEBUG("%s: restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SEN5X_I2C_CLOCK_SPEED */ return receivedBytes; @@ -326,24 +329,24 @@ bool SEN5XSensor::vocStateToSensor() } if (!vocStateValid()) { - LOG_INFO("SEN5X: VOC state is invalid, not sending"); + LOG_INFO("%s: VOC state is invalid, not sending", sensorName); return true; } if (!sendCommand(SEN5X_STOP_MEASUREMENT)) { - LOG_ERROR("SEN5X: Error stoping measurement"); + LOG_ERROR("%s: Error stoping measurement", sensorName); return false; } delay(200); // From Sensirion Datasheet - LOG_DEBUG("SEN5X: Sending VOC state to sensor"); + LOG_DEBUG("%s: Sending VOC state to sensor", sensorName); LOG_DEBUG("[%u, %u, %u, %u, %u, %u, %u, %u]", vocState[0], vocState[1], vocState[2], vocState[3], vocState[4], vocState[5], vocState[6], vocState[7]); // Note: send command already takes into account the CRC // buffer size increment needed if (!sendCommand(SEN5X_RW_VOCS_STATE, vocState, SEN5X_VOC_STATE_BUFFER_SIZE)) { - LOG_ERROR("SEN5X: Error sending VOC's state command'"); + LOG_ERROR("%s: Error sending VOC's state command'", sensorName); return false; } @@ -356,10 +359,10 @@ bool SEN5XSensor::vocStateFromSensor() return true; } - LOG_INFO("SEN5X: Getting VOC state from sensor"); + LOG_INFO("%s: Getting VOC state from sensor", sensorName); // Ask VOCs state from the sensor if (!sendCommand(SEN5X_RW_VOCS_STATE)) { - LOG_ERROR("SEN5X: Error sending VOC's state command'"); + LOG_ERROR("%s: Error sending VOC's state command'", sensorName); return false; } @@ -371,13 +374,13 @@ bool SEN5XSensor::vocStateFromSensor() delay(20); // From Sensirion Datasheet if (receivedNumber == 0) { - LOG_DEBUG("SEN5X: Error getting VOC's state"); + LOG_DEBUG("%s: Error getting VOC's state", sensorName); return false; } // Print the state (if debug is on) - LOG_DEBUG("SEN5X: VOC state retrieved from sensor: [%u, %u, %u, %u, %u, %u, %u, %u]", vocState[0], vocState[1], vocState[2], - vocState[3], vocState[4], vocState[5], vocState[6], vocState[7]); + LOG_DEBUG("%s: VOC state retrieved from sensor: [%u, %u, %u, %u, %u, %u, %u, %u]", sensorName, vocState[0], vocState[1], + vocState[2], vocState[3], vocState[4], vocState[5], vocState[6], vocState[7]); return true; } @@ -389,11 +392,11 @@ bool SEN5XSensor::loadState() auto file = FSCom.open(sen5XStateFileName, FILE_O_READ); bool okay = false; if (file) { - LOG_INFO("%s state read from %s", sensorName, sen5XStateFileName); + LOG_INFO("%s: state read from %s", sensorName, sen5XStateFileName); pb_istream_t stream = {&readcb, &file, meshtastic_SEN5XState_size}; if (!pb_decode(&stream, &meshtastic_SEN5XState_msg, &sen5xstate)) { - LOG_ERROR("Error: can't decode protobuf %s", PB_GET_ERROR(&stream)); + LOG_ERROR("%s: can't decode protobuf %s", sensorName, PB_GET_ERROR(&stream)); } else { lastCleaning = sen5xstate.last_cleaning_time; lastCleaningValid = sen5xstate.last_cleaning_valid; @@ -425,12 +428,12 @@ bool SEN5XSensor::loadState() } file.close(); } else { - LOG_INFO("No %s state found (File: %s)", sensorName, sen5XStateFileName); + LOG_INFO("%s: No state found (File: %s)", sensorName, sen5XStateFileName); } spiLock->unlock(); return okay; #else - LOG_ERROR("SEN5X: ERROR - Filesystem not implemented"); + LOG_ERROR("%s: Filesystem not implemented", sensorName); #endif } @@ -463,7 +466,7 @@ bool SEN5XSensor::saveState() pb_ostream_t stream = {&writecb, static_cast(&file), meshtastic_SEN5XState_size}; if (!pb_encode(&stream, &meshtastic_SEN5XState_msg, &sen5xstate)) { - LOG_ERROR("Error: can't encode protobuf %s", PB_GET_ERROR(&stream)); + LOG_ERROR("%s: can't encode protobuf %s", sensorName, PB_GET_ERROR(&stream)); } else { okay = true; } @@ -475,7 +478,7 @@ bool SEN5XSensor::saveState() return okay; #else - LOG_ERROR("%s: ERROR - Filesystem not implemented", sensorName); + LOG_ERROR("%s: Filesystem not implemented", sensorName); #endif } @@ -487,10 +490,10 @@ bool SEN5XSensor::isActive() uint32_t SEN5XSensor::wakeUp() { - LOG_DEBUG("SEN5X: Waking up sensor"); + LOG_DEBUG("%s: Waking up sensor", sensorName); if (!sendCommand(SEN5X_START_MEASUREMENT)) { - LOG_ERROR("SEN5X: Error starting measurement"); + LOG_ERROR("%s: Error starting measurement", sensorName); // TODO - what should this return?? Something actually on the default interval? return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; } @@ -502,7 +505,7 @@ uint32_t SEN5XSensor::wakeUp() pmMeasureStarted = getTime(); state = SEN5X_MEASUREMENT; if (state == SEN5X_MEASUREMENT) - LOG_INFO("SEN5X: Started measurement mode"); + LOG_INFO("%s: Started measurement mode", sensorName); return SEN5X_WARMUP_MS_1; } @@ -511,7 +514,7 @@ bool SEN5XSensor::vocStateStable() uint32_t now; now = getTime(); uint32_t sinceFirstMeasureStarted = (now - rhtGasMeasureStarted); - LOG_DEBUG("sinceFirstMeasureStarted: %us", sinceFirstMeasureStarted); + LOG_DEBUG("%s: sinceFirstMeasureStarted: %us", sensorName, sinceFirstMeasureStarted); return sinceFirstMeasureStarted > SEN5X_VOC_STATE_WARMUP_S; } @@ -523,25 +526,25 @@ bool SEN5XSensor::startCleaning() // Note that cleaning command can only be run when the sensor is in measurement mode if (!sendCommand(SEN5X_START_MEASUREMENT)) { - LOG_ERROR("SEN5X: Error starting measurment mode"); + LOG_ERROR("%s: Error starting measurment mode", sensorName); return false; } delay(50); // From Sensirion Datasheet if (!sendCommand(SEN5X_START_FAN_CLEANING)) { - LOG_ERROR("SEN5X: Error starting fan cleaning"); + LOG_ERROR("%s: Error starting fan cleaning", sensorName); return false; } delay(20); // From Sensirion Datasheet // This message will be always printed so the user knows the device it's not hung - LOG_INFO("SEN5X: Started fan cleaning it will take 10 seconds..."); + LOG_INFO("%s: Started fan cleaning it will take 10 seconds...", sensorName); uint16_t started = millis(); while (millis() - started < 10500) { delay(500); } - LOG_INFO("SEN5X: Cleaning done!!"); + LOG_INFO("%s: Cleaning done", sensorName); // Save timestamp in flash so we know when a week has passed uint32_t now; @@ -558,22 +561,25 @@ bool SEN5XSensor::startCleaning() bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) { state = SEN5X_NOT_DETECTED; - LOG_INFO("Init sensor: %s", sensorName); + LOG_INFO("%s: Init sensor", sensorName); _bus = bus; _address = dev->address.address; +#ifdef SEN5X_I2C_CLOCK_SPEED _port = dev->address.port; + reClockI2C.setup(_bus, _port); +#endif /* SEN5X_I2C_CLOCK_SPEED */ delay(50); // without this there is an error on the deviceReset function if (!sendCommand(SEN5X_RESET)) { - LOG_ERROR("SEN5X: Error reseting device"); + LOG_ERROR("%s: error reseting device", sensorName); return false; } delay(200); // From Sensirion Datasheet if (!findModel()) { - LOG_ERROR("SEN5X: error finding sensor model"); + LOG_ERROR("%s: error finding sensor model", sensorName); return false; } @@ -581,7 +587,7 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (!getVersion()) return false; if (firmwareVer < 2) { - LOG_ERROR("SEN5X: error firmware is too old and will not work with this implementation"); + LOG_ERROR("%s: firmware is too old and will not work with this implementation", sensorName); return false; } delay(200); // From Sensirion Datasheet @@ -606,11 +612,12 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (passed > ONE_WEEK_IN_SECONDS && (now > SEN5X_VOC_VALID_DATE)) { // If current date greater than 01/01/2018 (validity check) - LOG_INFO("SEN5X: More than a week (%us) since last cleaning in epoch (%us). Trigger, cleaning...", passed, - lastCleaning); + LOG_INFO("%s: More than a week (%us) since last cleaning in epoch (%us). Trigger, cleaning...", sensorName, + passed, lastCleaning); startCleaning(); } else { - LOG_INFO("SEN5X: Cleaning not needed (%ds passed). Last cleaning date (in epoch): %us", passed, lastCleaning); + LOG_INFO("%s: Cleaning not needed (%ds passed). Last cleaning date (in epoch): %us", sensorName, passed, + lastCleaning); } } else { // We assume the device has just been updated or it is new, @@ -619,29 +626,29 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) // Otherwise, we will never trigger cleaning in some cases lastCleaning = now; lastCleaningValid = true; - LOG_INFO("SEN5X: No valid last cleaning date found, saving it now: %us", lastCleaning); + LOG_INFO("%s: No valid last cleaning date found, saving it now: %us", sensorName, lastCleaning); saveState(); } if (model != SEN50) { if (!vocValid) { - LOG_INFO("SEN5X: No valid VOC's state found"); + LOG_INFO("%s: No valid VOC's state found", sensorName); } else { // Check if state is recent if (vocStateRecent(now)) { // If current date greater than 01/01/2018 (validity check) // Send it to the sensor - LOG_INFO("SEN5X: VOC state is valid and recent"); + LOG_INFO("%s: VOC state is valid and recent", sensorName); vocStateToSensor(); } else { - LOG_INFO("SEN5X: VOC state is too old or date is invalid"); - LOG_DEBUG("SEN5X: vocTime %u, Passed %u, and now %u", vocTime, passed, now); + LOG_INFO("%s: VOC state is too old or date is invalid", sensorName); + LOG_DEBUG("%s: vocTime %u, Passed %u, and now %u", sensorName, vocTime, passed, now); } } } } else { // TODO - Should this actually ignore? We could end up never cleaning... - LOG_INFO("SEN5X: Not enough RTCQuality, ignoring saved cleaning and VOC state"); + LOG_INFO("%s: Not enough RTCQuality, ignoring saved cleaning and VOC state", sensorName); } idle(false); @@ -654,16 +661,16 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) bool SEN5XSensor::readValues() { if (!sendCommand(SEN5X_READ_VALUES)) { - LOG_ERROR("SEN5X: Error sending read command"); + LOG_ERROR("%s: Error sending read command", sensorName); return false; } - LOG_DEBUG("SEN5X: Reading PM Values"); + LOG_DEBUG("%s: Reading PM Values", sensorName); delay(20); // From Sensirion Datasheet uint8_t dataBuffer[16]{}; size_t receivedNumber = readBuffer(&dataBuffer[0], 24); if (receivedNumber == 0) { - LOG_ERROR("SEN5X: Error getting values"); + LOG_ERROR("%s: Error getting values", sensorName); return false; } @@ -688,16 +695,16 @@ bool SEN5XSensor::readValues() sen5xmeasurement.vocIndex = !isnan(int_vocIndex) ? int_vocIndex / 10.0f : FLT_MAX; sen5xmeasurement.noxIndex = !isnan(int_noxIndex) ? int_noxIndex / 10.0f : FLT_MAX; - LOG_DEBUG("Got %s readings: pM1p0=%u, pM2p5=%u, pM4p0=%u, pM10p0=%u", sensorName, sen5xmeasurement.pM1p0, + LOG_DEBUG("%s: Got readings: pM1p0=%u, pM2p5=%u, pM4p0=%u, pM10p0=%u", sensorName, sen5xmeasurement.pM1p0, sen5xmeasurement.pM2p5, sen5xmeasurement.pM4p0, sen5xmeasurement.pM10p0); if (model != SEN50) { - LOG_DEBUG("Got %s readings: humidity=%.2f, temperature=%.2f, vocIndex=%.2f", sensorName, sen5xmeasurement.humidity, + LOG_DEBUG("%s: Got readings: humidity=%.2f, temperature=%.2f, vocIndex=%.2f", sensorName, sen5xmeasurement.humidity, sen5xmeasurement.temperature, sen5xmeasurement.vocIndex); } if (model == SEN55) { - LOG_DEBUG("Got %s readings: noxIndex=%.2f", sensorName, sen5xmeasurement.noxIndex); + LOG_DEBUG("%s: Got readings: noxIndex=%.2f", sensorName, sen5xmeasurement.noxIndex); } return true; @@ -706,17 +713,17 @@ bool SEN5XSensor::readValues() bool SEN5XSensor::readPNValues(bool cumulative) { if (!sendCommand(SEN5X_READ_PM_VALUES)) { - LOG_ERROR("SEN5X: Error sending read command"); + LOG_ERROR("%s: Error sending read command", sensorName); return false; } - LOG_DEBUG("SEN5X: Reading PN Values"); + LOG_DEBUG("%s: Reading PN Values", sensorName); delay(20); // From Sensirion Datasheet uint8_t dataBuffer[20]{}; size_t receivedNumber = readBuffer(&dataBuffer[0], 30); if (receivedNumber == 0) { - LOG_ERROR("SEN5X: Error getting PN values"); + LOG_ERROR("%s: Error getting PN values", sensorName); return false; } @@ -750,7 +757,7 @@ bool SEN5XSensor::readPNValues(bool cumulative) sen5xmeasurement.pN1p0 -= sen5xmeasurement.pN0p5; } - LOG_DEBUG("Got %s readings: pN0p5=%u, pN1p0=%u, pN2p5=%u, pN4p0=%u, pN10p0=%u, tSize=%.2f", sensorName, + LOG_DEBUG("%s: Got readings: pN0p5=%u, pN1p0=%u, pN2p5=%u, pN4p0=%u, pN10p0=%u, tSize=%.2f", sensorName, sen5xmeasurement.pN0p5, sen5xmeasurement.pN1p0, sen5xmeasurement.pN2p5, sen5xmeasurement.pN4p0, sen5xmeasurement.pN10p0, sen5xmeasurement.tSize); @@ -764,7 +771,7 @@ uint8_t SEN5XSensor::getMeasurements() // Try to get new data if (!sendCommand(SEN5X_READ_DATA_READY)) { - LOG_ERROR("SEN5X: Error sending command data ready flag"); + LOG_ERROR("%s: Error sending command data ready flag", sensorName); return 2; } delay(20); // From Sensirion Datasheet @@ -772,7 +779,7 @@ uint8_t SEN5XSensor::getMeasurements() uint8_t dataReadyBuffer[3]; size_t charNumber = readBuffer(&dataReadyBuffer[0], 3); if (charNumber == 0) { - LOG_ERROR("SEN5X: Error getting device version value"); + LOG_ERROR("%s: Error getting device version value", sensorName); return 2; } @@ -780,17 +787,17 @@ uint8_t SEN5XSensor::getMeasurements() uint32_t sinceLastDataPollMs = (now - lastDataPoll) * 1000; // Check if data is ready, and if since last time we requested is less than SEN5X_POLL_INTERVAL if (!dataReady && (sinceLastDataPollMs > SEN5X_POLL_INTERVAL)) { - LOG_INFO("SEN5X: Data is not ready"); + LOG_INFO("%s: Data is not ready", sensorName); return 1; } if (!readValues()) { - LOG_ERROR("SEN5X: Error getting readings"); + LOG_ERROR("%s: Error getting readings", sensorName); return 2; } if (!readPNValues(false)) { - LOG_ERROR("SEN5X: Error getting PN readings"); + LOG_ERROR("%s: Error getting PN readings", sensorName); return 2; } @@ -809,13 +816,13 @@ int32_t SEN5XSensor::pendingForReadyMs() uint32_t now; now = getTime(); uint32_t sincePmMeasureStarted = (now - pmMeasureStarted) * 1000; - LOG_DEBUG("SEN5X: Since measure started: %ums", sincePmMeasureStarted); + LOG_DEBUG("%s: Since measure started: %ums", sensorName, sincePmMeasureStarted); switch (state) { case SEN5X_MEASUREMENT: { if (sincePmMeasureStarted < SEN5X_WARMUP_MS_1) { - LOG_INFO("SEN5X: not enough time passed since starting measurement"); + LOG_INFO("%s: not enough time passed since starting measurement", sensorName); return SEN5X_WARMUP_MS_1 - sincePmMeasureStarted; } @@ -829,7 +836,7 @@ int32_t SEN5XSensor::pendingForReadyMs() // If the reading is low (the tyhreshold is in #/cm3) and second warmUp hasn't passed we return to come back later if ((sen5xmeasurement.pN4p0 / 100) < SEN5X_PN4P0_CONC_THD && sincePmMeasureStarted < SEN5X_WARMUP_MS_2) { - LOG_INFO("SEN5X: Concentration is low, we will ask again in the second warm up period"); + LOG_INFO("%s: Concentration is low, we will ask again in the second warm up period", sensorName); state = SEN5X_MEASUREMENT_2; // Report how many seconds are pending to cover the first warm up period return SEN5X_WARMUP_MS_2 - sincePmMeasureStarted; @@ -851,9 +858,9 @@ int32_t SEN5XSensor::pendingForReadyMs() bool SEN5XSensor::getMetrics(meshtastic_Telemetry *measurement) { - LOG_INFO("SEN5X: Attempting to get metrics"); + LOG_INFO("%s: Attempting to get metrics", sensorName); if (!isActive()) { - LOG_INFO("SEN5X: not in measurement mode"); + LOG_INFO("%s: not in measurement mode", sensorName); return false; } @@ -943,9 +950,9 @@ void SEN5XSensor::setMode(bool setOneShot) { oneShotMode = setOneShot; if (oneShotMode) { - LOG_INFO("%s setting mode to one shot mode", sensorName); + LOG_INFO("%s: setting mode to one shot mode", sensorName); } else { - LOG_INFO("%s setting mode to continuous mode", sensorName); + LOG_INFO("%s: setting mode to continuous mode", sensorName); } } diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.h b/src/modules/Telemetry/Sensor/SEN5XSensor.h index 22b1c5846..a6608d30c 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.h +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.h @@ -2,6 +2,7 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR +#include "../detect/ReClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "RTC.h" #include "TelemetrySensor.h" @@ -62,7 +63,10 @@ class SEN5XSensor : public TelemetrySensor private: TwoWire *_bus{}; uint8_t _address{}; +#ifdef SEN5X_I2C_CLOCK_SPEED ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + ReClockI2C reClockI2C; +#endif bool getVersion(); float firmwareVer = -1; diff --git a/src/modules/Telemetry/Sensor/SFA30Sensor.cpp b/src/modules/Telemetry/Sensor/SFA30Sensor.cpp index 7c8a08544..286d9fd47 100644 --- a/src/modules/Telemetry/Sensor/SFA30Sensor.cpp +++ b/src/modules/Telemetry/Sensor/SFA30Sensor.cpp @@ -2,7 +2,6 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() -#include "../detect/reClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "SFA30Sensor.h" @@ -14,11 +13,13 @@ bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _bus = bus; _address = dev->address.address; - _port = dev->address.port; #ifdef SFA30_I2C_CLOCK_SPEED + _port = dev->address.port; + reClockI2C.setup(_bus, _port); + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); + reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED); #endif /* SFA30_I2C_CLOCK_SPEED */ sfa30.begin(*_bus, _address); @@ -26,10 +27,8 @@ bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) if (this->isError(sfa30.deviceReset())) { #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ return false; } @@ -37,10 +36,8 @@ bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) state = State::IDLE; if (this->isError(sfa30.startContinuousMeasurement())) { #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ return false; } @@ -48,10 +45,8 @@ bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) LOG_INFO("%s starting measurement", sensorName); #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ status = 1; @@ -77,7 +72,7 @@ void SFA30Sensor::sleep() { #ifdef SFA30_I2C_CLOCK_SPEED LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); + reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED); #endif /* SFA30_I2C_CLOCK_SPEED */ // Note - not recommended for this sensor on a periodic basis @@ -86,10 +81,8 @@ void SFA30Sensor::sleep() }; #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ LOG_INFO("%s: stop measurement", sensorName); @@ -101,25 +94,21 @@ uint32_t SFA30Sensor::wakeUp() { #ifdef SFA30_I2C_CLOCK_SPEED LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); + reClockI2C.setClock(SFA30_I2C_CLOCK_SPEED); #endif /* SFA30_I2C_CLOCK_SPEED */ LOG_INFO("Waking up %s", sensorName); if (this->isError(sfa30.startContinuousMeasurement())) { #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ return 0; } #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ state = State::ACTIVE; @@ -166,25 +155,21 @@ bool SFA30Sensor::getMetrics(meshtastic_Telemetry *measurement) #ifdef SFA30_I2C_CLOCK_SPEED LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); + 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 - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ return false; } #ifdef SFA30_I2C_CLOCK_SPEED - if (currentClock) { - LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); - reClockI2C(currentClock, _bus, _port); - } + LOG_INFO("%s restoring clock speed", sensorName); + reClockI2C.restoreClock(); #endif /* SFA30_I2C_CLOCK_SPEED */ measurement->variant.air_quality_metrics.has_form_temperature = true; diff --git a/src/modules/Telemetry/Sensor/SFA30Sensor.h b/src/modules/Telemetry/Sensor/SFA30Sensor.h index 038a70e1e..299a9fdf0 100644 --- a/src/modules/Telemetry/Sensor/SFA30Sensor.h +++ b/src/modules/Telemetry/Sensor/SFA30Sensor.h @@ -2,6 +2,7 @@ #if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR && __has_include() +#include "../detect/ReClockI2C.h" #include "../mesh/generated/meshtastic/telemetry.pb.h" #include "RTC.h" #include "TelemetrySensor.h" @@ -21,7 +22,10 @@ class SFA30Sensor : public TelemetrySensor SensirionI2cSfa3x sfa30; TwoWire *_bus{}; uint8_t _address{}; +#ifdef SFA30_I2C_CLOCK_SPEED ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + ReClockI2C reClockI2C; +#endif bool isError(uint16_t response); diff --git a/variants/esp32/esp32-common.ini b/variants/esp32/esp32-common.ini index a94defff2..a910d50c9 100644 --- a/variants/esp32/esp32-common.ini +++ b/variants/esp32/esp32-common.ini @@ -56,7 +56,7 @@ build_flags = -DLIBPAX_BLE -DHAS_UDP_MULTICAST=1 ;-DDEBUG_HEAP - -DCAN_RECLOCK_I2C + -DCAN_GET_I2C_CLOCK lib_deps = ${arduino_base.lib_deps}