Re-add I2C scan, fix frame.

This commit is contained in:
Tom Fifield 2024-10-19 13:00:25 +11:00
parent 318da220dc
commit 8faf4665b0
5 changed files with 71 additions and 32 deletions

View File

@ -41,6 +41,12 @@ ScanI2C::FoundDevice ScanI2C::firstAccelerometer() const
return firstOfOrNONE(7, types); return firstOfOrNONE(7, types);
} }
ScanI2C::FoundDevice ScanI2C::firstAQI() const
{
ScanI2C::DeviceType types[] = {PMSA0031, SCD4X};
return firstOfOrNONE(2, types);
}
ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const ScanI2C::FoundDevice ScanI2C::find(ScanI2C::DeviceType) const
{ {
return DEVICE_NONE; return DEVICE_NONE;

View File

@ -115,6 +115,8 @@ class ScanI2C
FoundDevice firstAccelerometer() const; FoundDevice firstAccelerometer() const;
FoundDevice firstAQI() const;
virtual FoundDevice find(DeviceType) const; virtual FoundDevice find(DeviceType) const;
virtual bool exists(DeviceType) const; virtual bool exists(DeviceType) const;

View File

@ -150,6 +150,8 @@ ScanI2C::DeviceAddress rtc_found = ScanI2C::ADDRESS_NONE;
ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE; ScanI2C::DeviceAddress accelerometer_found = ScanI2C::ADDRESS_NONE;
// The I2C address of the RGB LED (if found) // The I2C address of the RGB LED (if found)
ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE); ScanI2C::FoundDevice rgb_found = ScanI2C::FoundDevice(ScanI2C::DeviceType::NONE, ScanI2C::ADDRESS_NONE);
/// The I2C address of our Air Quality Indicator (if found)
ScanI2C::DeviceAddress aqi_found = ScanI2C::ADDRESS_NONE;
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) #if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL)
ATECCX08A atecc; ATECCX08A atecc;
@ -532,6 +534,9 @@ void setup()
pmu_found = i2cScanner->exists(ScanI2C::DeviceType::PMU_AXP192_AXP2101); pmu_found = i2cScanner->exists(ScanI2C::DeviceType::PMU_AXP192_AXP2101);
auto aqiInfo = i2cScanner->firstAQI();
aqi_found = aqiInfo.type != ScanI2C::DeviceType::NONE ? screenInfo.address : ScanI2C::ADDRESS_NONE;
/* /*
* There are a bunch of sensors that have no further logic than to be found and stuffed into the * There are a bunch of sensors that have no further logic than to be found and stuffed into the
* nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field * nodeTelemetrySensorsMap singleton. This wraps that logic in a temporary scope to declare the temporary field
@ -1187,4 +1192,4 @@ void loop()
mainDelay.delay(delayMsec); mainDelay.delay(delayMsec);
} }
} }
#endif #endif

View File

@ -33,6 +33,7 @@ extern uint8_t kb_model;
extern ScanI2C::DeviceAddress rtc_found; extern ScanI2C::DeviceAddress rtc_found;
extern ScanI2C::DeviceAddress accelerometer_found; extern ScanI2C::DeviceAddress accelerometer_found;
extern ScanI2C::FoundDevice rgb_found; extern ScanI2C::FoundDevice rgb_found;
extern ScanI2C::DeviceAddress aqi_found;
extern bool eink_found; extern bool eink_found;
extern bool pmu_found; extern bool pmu_found;

View File

@ -40,7 +40,6 @@ int32_t AirQualityTelemetryModule::runOnce()
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.
*/ */
// moduleConfig.telemetry.air_quality_enabled = 1; // moduleConfig.telemetry.air_quality_enabled = 1;
if (!(moduleConfig.telemetry.air_quality_enabled)) { if (!(moduleConfig.telemetry.air_quality_enabled)) {
@ -55,34 +54,54 @@ int32_t AirQualityTelemetryModule::runOnce()
if (moduleConfig.telemetry.air_quality_enabled) { if (moduleConfig.telemetry.air_quality_enabled) {
LOG_INFO("Air quality Telemetry: Initializing"); LOG_INFO("Air quality Telemetry: Initializing");
if (aqi_found.address == 0x00) {
LOG_DEBUG("Rescanning for I2C AQI Sensor");
uint8_t i2caddr_scan[] = {PMSA0031_ADDR, SCD4X_ADDR};
uint8_t i2caddr_asize = 2;
auto i2cScanner = std::unique_ptr<ScanI2CTwoWire>(new ScanI2CTwoWire());
#if WIRE_INTERFACES_COUNT == 2
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE1, i2caddr_scan, i2caddr_asize);
#endif
i2cScanner->scanPort(ScanI2C::I2CPort::WIRE, i2caddr_scan, i2caddr_asize);
auto aqi_info = i2cScanner->firstAQI();
if (aqi_info.type != ScanI2C::DeviceType::NONE) {
aqi_found = aqi_info.address;
}
if (aqi_found.address == 0x00) {
return disable();
}
}
if (scd4xSensor.hasSensor()) if (scd4xSensor.hasSensor())
result = scd4xSensor.runOnce(); result = scd4xSensor.runOnce();
if (pmsa0031Sensor.hasSensor()) if (pmsa0031Sensor.hasSensor())
result = pmsa0031Sensor.runOnce(); result = pmsa0031Sensor.runOnce();
} return result;
return result;
} else {
// if we somehow got to a second run of this module with measurement disabled, then just wait forever
if (!moduleConfig.telemetry.air_quality_enabled)
return disable();
if (((lastSentToMesh == 0) || } else {
!Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled( // if we somehow got to a second run of this module with measurement disabled, then just wait forever
moduleConfig.telemetry.air_quality_interval, if (!moduleConfig.telemetry.air_quality_enabled)
default_telemetry_broadcast_interval_secs, numOnlineNodes))) && return disable();
airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
airTime->isTxAllowedAirUtil()) { if (((lastSentToMesh == 0) ||
sendTelemetry(); !Throttle::isWithinTimespanMs(lastSentToMesh, Default::getConfiguredOrDefaultMsScaled(
lastSentToMesh = millis(); moduleConfig.telemetry.air_quality_interval,
} else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) && default_telemetry_broadcast_interval_secs, numOnlineNodes))) &&
(service->isToPhoneQueueEmpty())) { airTime->isTxAllowedChannelUtil(config.device.role != meshtastic_Config_DeviceConfig_Role_SENSOR) &&
// Just send to phone when it's not our time to send to mesh yet airTime->isTxAllowedAirUtil()) {
// Only send while queue is empty (phone assumed connected) sendTelemetry();
sendTelemetry(NODENUM_BROADCAST, true); lastSentToMesh = millis();
lastSentToPhone = millis(); } else if (((lastSentToPhone == 0) || !Throttle::isWithinTimespanMs(lastSentToPhone, sendToPhoneIntervalMs)) &&
(service->isToPhoneQueueEmpty())) {
// Just send to phone when it's not our time to send to mesh yet
// Only send while queue is empty (phone assumed connected)
sendTelemetry(NODENUM_BROADCAST, true);
lastSentToPhone = millis();
}
} }
return min(sendToPhoneIntervalMs, result);
} }
return min(sendToPhoneIntervalMs, result);
} }
bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t) bool AirQualityTelemetryModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshtastic_Telemetry *t)
@ -141,20 +160,26 @@ void AirQualityTelemetryModule::drawFrame(OLEDDisplay *display, OLEDDisplayUiSta
// Display "Env. From: ..." on its own // Display "Env. From: ..." on its own
display->drawString(x, y, "AQ. From: " + String(lastSender) + "(" + String(agoSecs) + "s)"); display->drawString(x, y, "AQ. From: " + String(lastSender) + "(" + String(agoSecs) + "s)");
// Continue with the remaining details if (lastMeasurement.variant.air_quality_metrics.has_pm10_standard) {
/*display->drawString(x, y += _fontHeight(FONT_SMALL),
"Temp/Hum: " + last_temp + " / " +
String(lastMeasurement.variant.environment_metrics.relative_humidity, 0) + "%");*/
/*if (lastMeasurement.variant.environment_metrics.barometric_pressure != 0) {
display->drawString(x, y += _fontHeight(FONT_SMALL), display->drawString(x, y += _fontHeight(FONT_SMALL),
"Press: " + String(lastMeasurement.variant.environment_metrics.barometric_pressure, 0) + "hPA"); "PM1.0(Standard): " + String(lastMeasurement.variant.air_quality_metrics.pm10_standard, 0));
}*/ }
if (lastMeasurement.variant.air_quality_metrics.has_pm25_standard) {
display->drawString(x, y += _fontHeight(FONT_SMALL),
"PM2.5(Standard): " + String(lastMeasurement.variant.air_quality_metrics.pm25_standard, 0));
}
if (lastMeasurement.variant.air_quality_metrics.has_pm10_environmental) {
display->drawString(x, y += _fontHeight(FONT_SMALL),
"PM10.0(Standard): " + String(lastMeasurement.variant.air_quality_metrics.pm100_standard, 0));
}
if (lastMeasurement.variant.air_quality_metrics.has_co2) {
display->drawString(x, y += _fontHeight(FONT_SMALL),
"CO2: " + String(lastMeasurement.variant.air_quality_metrics.co2, 0) + " ppm");
}
} }
bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m) bool AirQualityTelemetryModule::getAirQualityTelemetry(meshtastic_Telemetry *m)
{ {
// XXX
bool valid = true; bool valid = true;
bool hasSensor = false; bool hasSensor = false;
m->time = getTime(); m->time = getTime();