allow sensors connected to second I2C port (#2891)

This commit is contained in:
Manuel
2023-10-15 02:33:45 +02:00
committed by GitHub
parent f4b40562d3
commit 142d56c663
21 changed files with 40 additions and 33 deletions

View File

@@ -281,9 +281,10 @@ class AnalogBatteryLevel : public HasBatteryLevel
#if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO) #if defined(HAS_TELEMETRY) && !defined(ARCH_PORTDUINO)
uint16_t getINAVoltage() uint16_t getINAVoltage()
{ {
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
return ina219Sensor.getBusVoltageMv(); return ina219Sensor.getBusVoltageMv();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) { } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
return ina260Sensor.getBusVoltageMv(); return ina260Sensor.getBusVoltageMv();
} }
return 0; return 0;
@@ -294,11 +295,12 @@ class AnalogBatteryLevel : public HasBatteryLevel
if (!config.power.device_battery_ina_address) { if (!config.power.device_battery_ina_address) {
return false; return false;
} }
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219] == config.power.device_battery_ina_address) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA219].first == config.power.device_battery_ina_address) {
if (!ina219Sensor.isInitialized()) if (!ina219Sensor.isInitialized())
return ina219Sensor.runOnce() > 0; return ina219Sensor.runOnce() > 0;
return ina219Sensor.isRunning(); return ina219Sensor.isRunning();
} else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260] == config.power.device_battery_ina_address) { } else if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_INA260].first ==
config.power.device_battery_ina_address) {
if (!ina260Sensor.isInitialized()) if (!ina260Sensor.isInitialized())
return ina260Sensor.runOnce() > 0; return ina260Sensor.runOnce() > 0;
return ina260Sensor.isRunning(); return ina260Sensor.isRunning();

View File

@@ -18,6 +18,8 @@ class ScanI2CTwoWire : public ScanI2C
ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override; ScanI2C::FoundDevice find(ScanI2C::DeviceType) const override;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
bool exists(ScanI2C::DeviceType) const override; bool exists(ScanI2C::DeviceType) const override;
size_t countDevices() const override; size_t countDevices() const override;
@@ -51,6 +53,4 @@ class ScanI2CTwoWire : public ScanI2C
uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const; uint16_t getRegisterValue(const RegisterLocation &, ResponseWidth) const;
DeviceType probeOLED(ScanI2C::DeviceAddress) const; DeviceType probeOLED(ScanI2C::DeviceAddress) const;
TwoWire *fetchI2CBus(ScanI2C::DeviceAddress) const;
}; };

View File

@@ -29,6 +29,7 @@
#include "target_specific.h" #include "target_specific.h"
#include <Wire.h> #include <Wire.h>
#include <memory> #include <memory>
#include <utility>
// #include <driver/rtc_io.h> // #include <driver/rtc_io.h>
#include "mesh/eth/ethClient.h" #include "mesh/eth/ethClient.h"
@@ -122,9 +123,8 @@ uint32_t serialSinceMsec;
bool pmu_found; bool pmu_found;
// Array map of sensor types (as array index) and i2c address as value we'll find in the i2c scan // Array map of sensor types with i2c address and wire as we'll find in the i2c scan
uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = { std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1] = {};
0}; // one is enough, missing elements will be initialized to 0 anyway.
Router *router = NULL; // Users of router don't care what sort of subclass implements that API Router *router = NULL; // Users of router don't care what sort of subclass implements that API
@@ -491,7 +491,8 @@ void setup()
{ \ { \
auto found = i2cScanner->find(SCANNER_T); \ auto found = i2cScanner->find(SCANNER_T); \
if (found.type != ScanI2C::DeviceType::NONE) { \ if (found.type != ScanI2C::DeviceType::NONE) { \
nodeTelemetrySensorsMap[PB_T] = found.address.address; \ nodeTelemetrySensorsMap[PB_T].first = found.address.address; \
nodeTelemetrySensorsMap[PB_T].second = i2cScanner->fetchI2CBus(found.address); \
LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \ LOG_DEBUG("found i2c sensor %s\n", STRING(PB_T)); \
} \ } \
} }

View File

@@ -88,7 +88,7 @@ void setupModules()
#endif #endif
#if HAS_SENSOR #if HAS_SENSOR
new EnvironmentTelemetryModule(); new EnvironmentTelemetryModule();
if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I] > 0) { if (nodeTelemetrySensorsMap[meshtastic_TelemetrySensorType_PMSA003I].first > 0) {
new AirQualityTelemetryModule(); new AirQualityTelemetryModule();
} }
#endif #endif

View File

@@ -13,7 +13,7 @@ int32_t BME280Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = bme280.begin(nodeTelemetrySensorsMap[sensorType]); status = bme280.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
bme280.setSampling(Adafruit_BME280::MODE_FORCED, bme280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // Temp. oversampling Adafruit_BME280::SAMPLING_X1, // Temp. oversampling

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BME280.h> #include <Adafruit_BME280.h>
class BME280Sensor : virtual public TelemetrySensor class BME280Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_BME280 bme280; Adafruit_BME280 bme280;

View File

@@ -20,7 +20,7 @@ int32_t BME680Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
if (!bme680.begin(nodeTelemetrySensorsMap[sensorType], Wire)) if (!bme680.begin(nodeTelemetrySensorsMap[sensorType].first, *nodeTelemetrySensorsMap[sensorType].second))
checkStatus("begin"); checkStatus("begin");
if (bme680.status == BSEC_OK) { if (bme680.status == BSEC_OK) {

View File

@@ -6,7 +6,7 @@
#include "bme680_iaq_33v_3s_4d/bsec_iaq.h" #include "bme680_iaq_33v_3s_4d/bsec_iaq.h"
class BME680Sensor : virtual public TelemetrySensor class BME680Sensor : public TelemetrySensor
{ {
private: private:
Bsec2 bme680; Bsec2 bme680;

View File

@@ -13,7 +13,8 @@ int32_t BMP280Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType]); bmp280 = Adafruit_BMP280(nodeTelemetrySensorsMap[sensorType].second);
status = bmp280.begin(nodeTelemetrySensorsMap[sensorType].first);
bmp280.setSampling(Adafruit_BMP280::MODE_FORCED, bmp280.setSampling(Adafruit_BMP280::MODE_FORCED,
Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling Adafruit_BMP280::SAMPLING_X1, // Temp. oversampling

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_BMP280.h> #include <Adafruit_BMP280.h>
class BMP280Sensor : virtual public TelemetrySensor class BMP280Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_BMP280 bmp280; Adafruit_BMP280 bmp280;

View File

@@ -13,8 +13,8 @@ int32_t INA219Sensor::runOnce()
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
if (!ina219.success()) { if (!ina219.success()) {
ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType]); ina219 = Adafruit_INA219(nodeTelemetrySensorsMap[sensorType].first);
status = ina219.begin(); status = ina219.begin(nodeTelemetrySensorsMap[sensorType].second);
} else { } else {
status = ina219.success(); status = ina219.success();
} }

View File

@@ -3,7 +3,7 @@
#include "VoltageSensor.h" #include "VoltageSensor.h"
#include <Adafruit_INA219.h> #include <Adafruit_INA219.h>
class INA219Sensor : virtual public TelemetrySensor, VoltageSensor class INA219Sensor : public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA219 ina219; Adafruit_INA219 ina219;

View File

@@ -14,7 +14,7 @@ int32_t INA260Sensor::runOnce()
} }
if (!status) { if (!status) {
status = ina260.begin(nodeTelemetrySensorsMap[sensorType]); status = ina260.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
} }
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -3,7 +3,7 @@
#include "VoltageSensor.h" #include "VoltageSensor.h"
#include <Adafruit_INA260.h> #include <Adafruit_INA260.h>
class INA260Sensor : virtual public TelemetrySensor, VoltageSensor class INA260Sensor : public TelemetrySensor, VoltageSensor
{ {
private: private:
Adafruit_INA260 ina260 = Adafruit_INA260(); Adafruit_INA260 ina260 = Adafruit_INA260();

View File

@@ -13,7 +13,7 @@ int32_t LPS22HBSensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType]); status = lps22hb.begin_I2C(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -3,7 +3,7 @@
#include <Adafruit_LPS2X.h> #include <Adafruit_LPS2X.h>
#include <Adafruit_Sensor.h> #include <Adafruit_Sensor.h>
class LPS22HBSensor : virtual public TelemetrySensor class LPS22HBSensor : public TelemetrySensor
{ {
private: private:
Adafruit_LPS22 lps22hb; Adafruit_LPS22 lps22hb;

View File

@@ -12,7 +12,7 @@ int32_t MCP9808Sensor::runOnce()
if (!hasSensor()) { if (!hasSensor()) {
return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS; return DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS;
} }
status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType]); status = mcp9808.begin(nodeTelemetrySensorsMap[sensorType].first, nodeTelemetrySensorsMap[sensorType].second);
return initI2CSensor(); return initI2CSensor();
} }

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_MCP9808.h> #include <Adafruit_MCP9808.h>
class MCP9808Sensor : virtual public TelemetrySensor class MCP9808Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_MCP9808 mcp9808; Adafruit_MCP9808 mcp9808;

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_SHT31.h> #include <Adafruit_SHT31.h>
class SHT31Sensor : virtual public TelemetrySensor class SHT31Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_SHT31 sht31 = Adafruit_SHT31(); Adafruit_SHT31 sht31 = Adafruit_SHT31();

View File

@@ -2,7 +2,7 @@
#include "TelemetrySensor.h" #include "TelemetrySensor.h"
#include <Adafruit_SHTC3.h> #include <Adafruit_SHTC3.h>
class SHTC3Sensor : virtual public TelemetrySensor class SHTC3Sensor : public TelemetrySensor
{ {
private: private:
Adafruit_SHTC3 shtc3 = Adafruit_SHTC3(); Adafruit_SHTC3 shtc3 = Adafruit_SHTC3();

View File

@@ -1,9 +1,12 @@
#pragma once #pragma once
#include "../mesh/generated/meshtastic/telemetry.pb.h" #include "../mesh/generated/meshtastic/telemetry.pb.h"
#include "NodeDB.h" #include "NodeDB.h"
#include <utility>
class TwoWire;
#define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000 #define DEFAULT_SENSOR_MINIMUM_WAIT_TIME_BETWEEN_READS 1000
extern uint8_t nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1]; extern std::pair<uint8_t, TwoWire *> nodeTelemetrySensorsMap[_meshtastic_TelemetrySensorType_MAX + 1];
class TelemetrySensor class TelemetrySensor
{ {
@@ -16,7 +19,7 @@ class TelemetrySensor
} }
const char *sensorName; const char *sensorName;
meshtastic_TelemetrySensorType sensorType; meshtastic_TelemetrySensorType sensorType = meshtastic_TelemetrySensorType_SENSOR_UNSET;
unsigned status; unsigned status;
bool initialized = false; bool initialized = false;
@@ -24,9 +27,9 @@ class TelemetrySensor
{ {
if (!status) { if (!status) {
LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName); LOG_WARN("Could not connect to detected %s sensor.\n Removing from nodeTelemetrySensorsMap.\n", sensorName);
nodeTelemetrySensorsMap[sensorType] = 0; nodeTelemetrySensorsMap[sensorType].first = 0;
} else { } else {
LOG_INFO("Opened %s sensor on default i2c bus\n", sensorName); LOG_INFO("Opened %s sensor on i2c bus\n", sensorName);
setup(); setup();
} }
initialized = true; initialized = true;
@@ -35,7 +38,7 @@ class TelemetrySensor
virtual void setup(); virtual void setup();
public: public:
bool hasSensor() { return sensorType < sizeof(nodeTelemetrySensorsMap) && nodeTelemetrySensorsMap[sensorType] > 0; } bool hasSensor() { return nodeTelemetrySensorsMap[sensorType].first > 0; }
virtual int32_t runOnce() = 0; virtual int32_t runOnce() = 0;
virtual bool isInitialized() { return initialized; } virtual bool isInitialized() { return initialized; }