Rescan I2C on AQ module init (#10593)
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
#include "Router.h"
|
#include "Router.h"
|
||||||
#include "TransmitHistory.h"
|
#include "TransmitHistory.h"
|
||||||
#include "UnitConversions.h"
|
#include "UnitConversions.h"
|
||||||
|
#include "detect/ScanI2CTwoWire.h"
|
||||||
#include "graphics/ScreenFonts.h"
|
#include "graphics/ScreenFonts.h"
|
||||||
#include "graphics/SharedUIDisplay.h"
|
#include "graphics/SharedUIDisplay.h"
|
||||||
#include "graphics/images.h"
|
#include "graphics/images.h"
|
||||||
@@ -41,12 +42,13 @@ void AirQualityTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
|||||||
if (!moduleConfig.telemetry.air_quality_enabled && !AIR_QUALITY_TELEMETRY_MODULE_ENABLE) {
|
if (!moduleConfig.telemetry.air_quality_enabled && !AIR_QUALITY_TELEMETRY_MODULE_ENABLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_INFO("Air Quality Telemetry adding I2C devices...");
|
LOG_INFO("Air Quality Telemetry adding I2C devices...");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Uncomment the preferences below if you want to use the module
|
Uncomment the preferences below if you want to use the module
|
||||||
without having to configure it from the PythonAPI or WebUI.
|
without having to configure it from the PythonAPI or WebUI.
|
||||||
Note: this was previously on runOnce, which didnt take effect
|
Note: this was previously on runOnce, which didn't take effect
|
||||||
as other modules already had already been initialized (screen)
|
as other modules already had already been initialized (screen)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -54,6 +56,52 @@ void AirQualityTelemetryModule::i2cScanFinished(ScanI2C *i2cScanner)
|
|||||||
// moduleConfig.telemetry.air_quality_screen_enabled = 1;
|
// moduleConfig.telemetry.air_quality_screen_enabled = 1;
|
||||||
// moduleConfig.telemetry.air_quality_interval = 15;
|
// moduleConfig.telemetry.air_quality_interval = 15;
|
||||||
|
|
||||||
|
// Add here supported sensors in the Air Quality module
|
||||||
|
// These sensors will be scanned twice, once in the first scan,
|
||||||
|
// and secondly in the first run of the module
|
||||||
|
if (!supportedSensors.count(PMSA003I_ADDR))
|
||||||
|
supportedSensors[PMSA003I_ADDR] = ScanI2C::DeviceType::PMSA003I;
|
||||||
|
if (!supportedSensors.count(SEN5X_ADDR))
|
||||||
|
supportedSensors[SEN5X_ADDR] = ScanI2C::DeviceType::SEN5X;
|
||||||
|
#if __has_include(<SensirionI2cScd4x.h>)
|
||||||
|
if (!supportedSensors.count(SCD4X_ADDR))
|
||||||
|
supportedSensors[SCD4X_ADDR] = ScanI2C::DeviceType::SCD4X;
|
||||||
|
#endif
|
||||||
|
#if __has_include(<SensirionI2cSfa3x.h>)
|
||||||
|
if (!supportedSensors.count(SFA30_ADDR))
|
||||||
|
supportedSensors[SFA30_ADDR] = ScanI2C::DeviceType::SFA30;
|
||||||
|
#endif
|
||||||
|
#if __has_include(<SensirionI2cScd30.h>)
|
||||||
|
if (!supportedSensors.count(SCD30_ADDR))
|
||||||
|
supportedSensors[SCD30_ADDR] = ScanI2C::DeviceType::SCD30;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!firstTime) {
|
||||||
|
// Re-scan for late comming sensors
|
||||||
|
LOG_INFO("Re-scanning supported sensors...");
|
||||||
|
|
||||||
|
for (const auto &[address, type] : supportedSensors) {
|
||||||
|
|
||||||
|
if (!i2cScanner->exists(type)) {
|
||||||
|
LOG_INFO("Re-scanning on address 0x%x", address);
|
||||||
|
uint8_t array_address[1] = {address};
|
||||||
|
#if defined(I2C_SDA1) || (defined(NRF52840_XXAA) && (WIRE_INTERFACES_COUNT == 2))
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, array_address, sizeof(array_address));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(I2C_SDA)
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, array_address, sizeof(array_address));
|
||||||
|
#elif defined(ARCH_PORTDUINO)
|
||||||
|
if (portduino_config.i2cdev != "") {
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, array_address, sizeof(array_address));
|
||||||
|
}
|
||||||
|
#elif HAS_WIRE
|
||||||
|
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, array_address, sizeof(array_address));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// order by priority of metrics/values (low top, high bottom)
|
// order by priority of metrics/values (low top, high bottom)
|
||||||
addSensor<PMSA003ISensor>(i2cScanner, ScanI2C::DeviceType::PMSA003I);
|
addSensor<PMSA003ISensor>(i2cScanner, ScanI2C::DeviceType::PMSA003I);
|
||||||
addSensor<SEN5XSensor>(i2cScanner, ScanI2C::DeviceType::SEN5X);
|
addSensor<SEN5XSensor>(i2cScanner, ScanI2C::DeviceType::SEN5X);
|
||||||
@@ -94,6 +142,12 @@ int32_t AirQualityTelemetryModule::runOnce()
|
|||||||
if (moduleConfig.telemetry.air_quality_enabled) {
|
if (moduleConfig.telemetry.air_quality_enabled) {
|
||||||
LOG_INFO("Air quality Telemetry: init");
|
LOG_INFO("Air quality Telemetry: init");
|
||||||
|
|
||||||
|
#if !MESHTASTIC_EXCLUDE_I2C
|
||||||
|
// Re-scan I2C bus
|
||||||
|
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
|
||||||
|
i2cScanFinished(i2cScanner.get());
|
||||||
|
#endif
|
||||||
|
|
||||||
// check if we have at least one sensor
|
// check if we have at least one sensor
|
||||||
if (!sensors.empty()) {
|
if (!sensors.empty()) {
|
||||||
result = DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
result = DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
#if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
#if !MESHTASTIC_EXCLUDE_AIR_QUALITY_SENSOR
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "BaseTelemetryModule.h"
|
#include "BaseTelemetryModule.h"
|
||||||
|
#include <map>
|
||||||
|
|
||||||
#ifndef AIR_QUALITY_TELEMETRY_MODULE_ENABLE
|
#ifndef AIR_QUALITY_TELEMETRY_MODULE_ENABLE
|
||||||
#define AIR_QUALITY_TELEMETRY_MODULE_ENABLE 0
|
#define AIR_QUALITY_TELEMETRY_MODULE_ENABLE 0
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
#include "../mesh/generated/meshtastic/telemetry.pb.h"
|
||||||
#include "NodeDB.h"
|
#include "NodeDB.h"
|
||||||
#include "ProtobufModule.h"
|
#include "ProtobufModule.h"
|
||||||
|
#include "detect/ScanI2C.h"
|
||||||
#include "detect/ScanI2CConsumer.h"
|
#include "detect/ScanI2CConsumer.h"
|
||||||
#include <OLEDDisplay.h>
|
#include <OLEDDisplay.h>
|
||||||
#include <OLEDDisplayUi.h>
|
#include <OLEDDisplayUi.h>
|
||||||
@@ -69,6 +70,9 @@ class AirQualityTelemetryModule : private concurrency::OSThread,
|
|||||||
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
uint32_t sendToPhoneIntervalMs = SECONDS_IN_MINUTE * 1000; // Send to phone every minute
|
||||||
// uint32_t sendToPhoneIntervalMs = 1000; // Send to phone every minute
|
// uint32_t sendToPhoneIntervalMs = 1000; // Send to phone every minute
|
||||||
uint32_t lastSentToPhone = 0;
|
uint32_t lastSentToPhone = 0;
|
||||||
|
|
||||||
|
// Map for supported sensors to re-scan
|
||||||
|
std::map<uint8_t, ScanI2C::DeviceType> supportedSensors;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -11,6 +11,15 @@ static std::forward_list<TelemetrySensor *> sensors;
|
|||||||
template <typename T> void addSensor(const ScanI2C *i2cScanner, ScanI2C::DeviceType type)
|
template <typename T> void addSensor(const ScanI2C *i2cScanner, ScanI2C::DeviceType type)
|
||||||
{
|
{
|
||||||
ScanI2C::FoundDevice dev = i2cScanner->find(type);
|
ScanI2C::FoundDevice dev = i2cScanner->find(type);
|
||||||
|
// Avoid adding the same device twice
|
||||||
|
if (dev.type != ScanI2C::DeviceType::NONE) {
|
||||||
|
for (const TelemetrySensor *_sensor : sensors) {
|
||||||
|
if ((_sensor->_address == dev.address.address) && (_sensor->_port == dev.address.port)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dev.type != ScanI2C::DeviceType::NONE || type == ScanI2C::DeviceType::NONE) {
|
if (dev.type != ScanI2C::DeviceType::NONE || type == ScanI2C::DeviceType::NONE) {
|
||||||
TelemetrySensor *sensor = new T();
|
TelemetrySensor *sensor = new T();
|
||||||
#if WIRE_INTERFACES_COUNT > 1
|
#if WIRE_INTERFACES_COUNT > 1
|
||||||
|
|||||||
@@ -34,10 +34,7 @@ class PMSA003ISensor : public TelemetrySensor
|
|||||||
uint32_t pmMeasureStarted = 0;
|
uint32_t pmMeasureStarted = 0;
|
||||||
|
|
||||||
uint8_t buffer[PMSA003I_FRAME_LENGTH]{};
|
uint8_t buffer[PMSA003I_FRAME_LENGTH]{};
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
#ifdef PMSA003I_I2C_CLOCK_SPEED
|
#ifdef PMSA003I_I2C_CLOCK_SPEED
|
||||||
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
|
||||||
ReClockI2C reClockI2C;
|
ReClockI2C reClockI2C;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,10 +13,7 @@ class SCD30Sensor : public TelemetrySensor
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SensirionI2cScd30 scd30;
|
SensirionI2cScd30 scd30;
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
#ifdef SCD30_I2C_CLOCK_SPEED
|
#ifdef SCD30_I2C_CLOCK_SPEED
|
||||||
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
|
||||||
ReClockI2C reClockI2C;
|
ReClockI2C reClockI2C;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ class SCD4XSensor : public TelemetrySensor
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SensirionI2cScd4x scd4x;
|
SensirionI2cScd4x scd4x;
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
#ifdef SCD4X_I2C_CLOCK_SPEED
|
#ifdef SCD4X_I2C_CLOCK_SPEED
|
||||||
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
|
||||||
ReClockI2C reClockI2C;
|
ReClockI2C reClockI2C;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -61,10 +61,7 @@ struct _SEN5XMeasurements {
|
|||||||
class SEN5XSensor : public TelemetrySensor
|
class SEN5XSensor : public TelemetrySensor
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
#ifdef SEN5X_I2C_CLOCK_SPEED
|
#ifdef SEN5X_I2C_CLOCK_SPEED
|
||||||
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
|
||||||
ReClockI2C reClockI2C;
|
ReClockI2C reClockI2C;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,7 @@ class SFA30Sensor : public TelemetrySensor
|
|||||||
uint32_t measureStarted = 0;
|
uint32_t measureStarted = 0;
|
||||||
|
|
||||||
SensirionI2cSfa3x sfa30;
|
SensirionI2cSfa3x sfa30;
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
#ifdef SFA30_I2C_CLOCK_SPEED
|
#ifdef SFA30_I2C_CLOCK_SPEED
|
||||||
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
|
||||||
ReClockI2C reClockI2C;
|
ReClockI2C reClockI2C;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,6 @@ class SHTXXSensor : public TelemetrySensor
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
SHTSensor sht;
|
SHTSensor sht;
|
||||||
TwoWire *_bus{};
|
|
||||||
uint8_t _address{};
|
|
||||||
SHTSensor::SHTAccuracy accuracy{};
|
SHTSensor::SHTAccuracy accuracy{};
|
||||||
bool setAccuracy(SHTSensor::SHTAccuracy newAccuracy);
|
bool setAccuracy(SHTSensor::SHTAccuracy newAccuracy);
|
||||||
|
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ class TelemetrySensor
|
|||||||
}
|
}
|
||||||
|
|
||||||
const char *sensorName;
|
const char *sensorName;
|
||||||
|
// TODO: Rename?
|
||||||
|
uint8_t _address = 0;
|
||||||
|
TwoWire *_bus{};
|
||||||
|
ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C;
|
||||||
|
|
||||||
// TODO: delete after migration
|
// TODO: delete after migration
|
||||||
bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
|
bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user