Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/helpers/SensorManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <CayenneLPP.h>
#include "sensors/LocationProvider.h"
#include <Wire.h>

#define TELEM_PERM_BASE 0x01 // 'base' permission includes battery
#define TELEM_PERM_LOCATION 0x02
Expand All @@ -15,6 +16,7 @@ class SensorManager {
double node_altitude; // altitude in meters

SensorManager() { node_lat = 0; node_lon = 0; node_altitude = 0; }
virtual bool i2c_probe(TwoWire& wire, uint8_t addr) { return false; }
virtual bool begin() { return false; }
virtual bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) { return false; }
virtual void loop() { }
Expand Down
133 changes: 78 additions & 55 deletions src/helpers/sensors/EnvironmentSensorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@
#endif

#ifdef ENV_INCLUDE_BME680
#ifndef TELEM_BME680_ADDRESS
#define TELEM_BME680_ADDRESS 0x76
#if defined(TELEM_BME680_ADDRESS)
uint8_t TELEM_BME680_ADDRESSES[] = { TELEM_BME680_ADDRESS };
#else
uint8_t TELEM_BME680_ADDRESSES[] = { 0x76, 0x77 }; // Known I2C addresses for BME680
#endif
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
#include <Adafruit_BME680.h>
Expand All @@ -28,17 +30,21 @@ static Adafruit_AHTX0 AHTX0;
#endif

#if ENV_INCLUDE_BME280
#ifndef TELEM_BME280_ADDRESS
#define TELEM_BME280_ADDRESS 0x76 // BME280 environmental sensor I2C address
#if defined(TELEM_BME280_ADDRESS)
uint8_t TELEM_BME280_ADDRESSES[] = { TELEM_BME280_ADDRESS };
#else
uint8_t TELEM_BME280_ADDRESSES[] = { 0x76, 0x77 }; // Known I2C addresses for BME280
#endif
#define TELEM_BME280_SEALEVELPRESSURE_HPA (1013.25) // Athmospheric pressure at sea level
#include <Adafruit_BME280.h>
static Adafruit_BME280 BME280;
#endif

#if ENV_INCLUDE_BMP280
#ifndef TELEM_BMP280_ADDRESS
#define TELEM_BMP280_ADDRESS 0x76 // BMP280 environmental sensor I2C address
#if defined(TELEM_BMP280_ADDRESS)
uint8_t TELEM_BMP280_ADDRESSES[] = { TELEM_BMP280_ADDRESS };
#else
uint8_t TELEM_BMP280_ADDRESSES[] = { 0x76, 0x77 }; // Known I2C addresses for BMP280
#endif
#define TELEM_BMP280_SEALEVELPRESSURE_HPA (1013.25) // Athmospheric pressure at sea level
#include <Adafruit_BMP280.h>
Expand Down Expand Up @@ -161,6 +167,12 @@ class RAK12500LocationProvider : public LocationProvider {
static RAK12500LocationProvider RAK12500_provider;
#endif

bool EnvironmentSensorManager::i2c_probe(TwoWire &wire, uint8_t addr) {
wire.beginTransmission(addr);
uint8_t error = wire.endTransmission();
return (error == 0); // If found i2c device, the error is 0
}

bool EnvironmentSensorManager::begin() {
#if ENV_INCLUDE_GPS
#ifdef RAK_WISBLOCK_GPS
Expand All @@ -182,7 +194,7 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_AHTX0
if (AHTX0.begin(TELEM_WIRE, 0, TELEM_AHTX_ADDRESS)) {
if (i2c_probe(*TELEM_WIRE, TELEM_AHTX_ADDRESS) && AHTX0.begin(TELEM_WIRE, 0, TELEM_AHTX_ADDRESS)) {
MESH_DEBUG_PRINTLN("Found AHT10/AHT20 at address: %02X", TELEM_AHTX_ADDRESS);
AHTX0_initialized = true;
} else {
Expand All @@ -192,46 +204,55 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_BME680
if (BME680.begin(TELEM_BME680_ADDRESS)) {
MESH_DEBUG_PRINTLN("Found BME680 at address: %02X", TELEM_BME680_ADDRESS);
BME680_initialized = true;
} else {
BME680_initialized = false;
MESH_DEBUG_PRINTLN("BME680 was not found at I2C address %02X", TELEM_BME680_ADDRESS);
for (size_t i = 0; i < sizeof(TELEM_BME680_ADDRESSES) / sizeof(TELEM_BME680_ADDRESSES[0]); i++) {
if (i2c_probe(*TELEM_WIRE, TELEM_BME680_ADDRESSES[i]) && BME680.begin(TELEM_BME680_ADDRESSES[i], TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found BME680 at address: %02X", TELEM_BME680_ADDRESSES[i]);
BME680_initialized = true;
break;
} else {
BME680_initialized = false;
MESH_DEBUG_PRINTLN("BME680 was not found at I2C address %02X", TELEM_BME680_ADDRESSES[i]);
}
}
#endif

#if ENV_INCLUDE_BME280
if (BME280.begin(TELEM_BME280_ADDRESS, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found BME280 at address: %02X", TELEM_BME280_ADDRESS);
MESH_DEBUG_PRINTLN("BME sensor ID: %02X", BME280.sensorID());
// Reduce self-heating: single-shot conversions, light oversampling, long standby.
BME280.setSampling(Adafruit_BME280::MODE_FORCED,
for (size_t i = 0; i < sizeof(TELEM_BME280_ADDRESSES) / sizeof(TELEM_BME280_ADDRESSES[0]); i++) {
if (i2c_probe(*TELEM_WIRE, TELEM_BME280_ADDRESSES[i]) && BME280.begin(TELEM_BME280_ADDRESSES[i], TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found BME280 at address: %02X", TELEM_BME280_ADDRESSES[i]);
MESH_DEBUG_PRINTLN("BME sensor ID: %02X", BME280.sensorID());
// Reduce self-heating: single-shot conversions, light oversampling, long standby.
BME280.setSampling(Adafruit_BME280::MODE_FORCED,
Adafruit_BME280::SAMPLING_X1, // temperature
Adafruit_BME280::SAMPLING_X1, // pressure
Adafruit_BME280::SAMPLING_X1, // humidity
Adafruit_BME280::FILTER_OFF,
Adafruit_BME280::STANDBY_MS_1000);
BME280_initialized = true;
} else {
BME280_initialized = false;
MESH_DEBUG_PRINTLN("BME280 was not found at I2C address %02X", TELEM_BME280_ADDRESS);
BME280_initialized = true;
break;
} else {
BME280_initialized = false;
MESH_DEBUG_PRINTLN("BME280 was not found at I2C address %02X", TELEM_BME280_ADDRESSES[i]);
}
}
#endif
#endif

#if ENV_INCLUDE_BMP280
if (BMP280.begin(TELEM_BMP280_ADDRESS)) {
MESH_DEBUG_PRINTLN("Found BMP280 at address: %02X", TELEM_BMP280_ADDRESS);
MESH_DEBUG_PRINTLN("BMP sensor ID: %02X", BMP280.sensorID());
BMP280_initialized = true;
} else {
BMP280_initialized = false;
MESH_DEBUG_PRINTLN("BMP280 was not found at I2C address %02X", TELEM_BMP280_ADDRESS);
}
#endif
for (size_t i = 0; i < sizeof(TELEM_BMP280_ADDRESSES) / sizeof(TELEM_BMP280_ADDRESSES[0]); i++) {
if (i2c_probe(*TELEM_WIRE, TELEM_BMP280_ADDRESSES[i]) && BMP280.begin(TELEM_BMP280_ADDRESSES[i])) {
MESH_DEBUG_PRINTLN("Found BMP280 at address: %02X", TELEM_BMP280_ADDRESSES[i]);
MESH_DEBUG_PRINTLN("BMP sensor ID: %02X", BMP280.sensorID());
BMP280_initialized = true;
break;
} else {
BMP280_initialized = false;
MESH_DEBUG_PRINTLN("BMP280 was not found at I2C address %02X", TELEM_BMP280_ADDRESSES[i]);
}
}
#endif

#if ENV_INCLUDE_SHTC3
if (SHTC3.begin(TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, 0x70) && SHTC3.begin(TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found sensor: SHTC3");
SHTC3_initialized = true;
} else {
Expand All @@ -242,21 +263,23 @@ bool EnvironmentSensorManager::begin() {


#if ENV_INCLUDE_SHT4X
SHT4X.begin(*TELEM_WIRE, TELEM_SHT4X_ADDRESS);
uint32_t serialNumber = 0;
int16_t sht4x_error;
sht4x_error = SHT4X.serialNumber(serialNumber);
if (sht4x_error == 0) {
MESH_DEBUG_PRINTLN("Found SHT4X at address: %02X", TELEM_SHT4X_ADDRESS);
SHT4X_initialized = true;
} else {
SHT4X_initialized = false;
MESH_DEBUG_PRINTLN("SHT4X was not found at I2C address %02X", TELEM_SHT4X_ADDRESS);
if (i2c_probe(*TELEM_WIRE, TELEM_SHT4X_ADDRESS)) {
SHT4X.begin(*TELEM_WIRE, TELEM_SHT4X_ADDRESS);
uint32_t serialNumber = 0;
int16_t sht4x_error;
sht4x_error = SHT4X.serialNumber(serialNumber);
if (sht4x_error == 0) {
MESH_DEBUG_PRINTLN("Found SHT4X at address: %02X", TELEM_SHT4X_ADDRESS);
SHT4X_initialized = true;
} else {
SHT4X_initialized = false;
MESH_DEBUG_PRINTLN("SHT4X was not found at I2C address %02X", TELEM_SHT4X_ADDRESS);
}
}
#endif

#if ENV_INCLUDE_LPS22HB
if (LPS22HB.begin()) {
if (i2c_probe(*TELEM_WIRE, 0x5C) && LPS22HB.begin()) {
MESH_DEBUG_PRINTLN("Found sensor: LPS22HB");
LPS22HB_initialized = true;
} else {
Expand All @@ -266,7 +289,7 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_INA3221
if (INA3221.begin(TELEM_INA3221_ADDRESS, TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, TELEM_INA3221_ADDRESS) && INA3221.begin(TELEM_INA3221_ADDRESS, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found INA3221 at address: %02X", TELEM_INA3221_ADDRESS);
MESH_DEBUG_PRINTLN("%04X %04X", INA3221.getDieID(), INA3221.getManufacturerID());

Expand All @@ -281,7 +304,7 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_INA219
if (INA219.begin(TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, TELEM_INA219_ADDRESS) && INA219.begin(TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found INA219 at address: %02X", TELEM_INA219_ADDRESS);
INA219_initialized = true;
} else {
Expand All @@ -291,17 +314,17 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_INA260
if (INA260.begin(TELEM_INA260_ADDRESS, TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, TELEM_INA260_ADDRESS) && INA260.begin(TELEM_INA260_ADDRESS, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found INA260 at address: %02X", TELEM_INA260_ADDRESS);
INA260_initialized = true;
} else {
INA260_initialized = false;
MESH_DEBUG_PRINTLN("INA260 was not found at I2C address %02X", TELEM_INA260_ADDRESS);
MESH_DEBUG_PRINTLN("INA260 was not found at I2C address %02X", TELEM_INA219_ADDRESS);
}
#endif

#if ENV_INCLUDE_INA226
if (INA226.begin()) {
if (i2c_probe(*TELEM_WIRE, TELEM_INA226_ADDRESS) && INA226.begin()) {
MESH_DEBUG_PRINTLN("Found INA226 at address: %02X", TELEM_INA226_ADDRESS);
INA226.setMaxCurrentShunt(TELEM_INA226_MAX_AMP, TELEM_INA226_SHUNT_VALUE);
INA226_initialized = true;
Expand All @@ -312,7 +335,7 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_MLX90614
if (MLX90614.begin(TELEM_MLX90614_ADDRESS, TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, TELEM_MLX90614_ADDRESS) && MLX90614.begin(TELEM_MLX90614_ADDRESS, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found MLX90614 at address: %02X", TELEM_MLX90614_ADDRESS);
MLX90614_initialized = true;
} else {
Expand All @@ -322,7 +345,7 @@ bool EnvironmentSensorManager::begin() {
#endif

#if ENV_INCLUDE_VL53L0X
if (VL53L0X.begin(TELEM_VL53L0X_ADDRESS, false, TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, TELEM_VL53L0X_ADDRESS) && VL53L0X.begin(TELEM_VL53L0X_ADDRESS, false, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found VL53L0X at address: %02X", TELEM_VL53L0X_ADDRESS);
VL53L0X_initialized = true;
} else {
Expand All @@ -334,7 +357,7 @@ bool EnvironmentSensorManager::begin() {
#if ENV_INCLUDE_BMP085
// First argument is MODE (aka oversampling)
// choose ULTRALOWPOWER
if (BMP085.begin(0, TELEM_WIRE)) {
if (i2c_probe(*TELEM_WIRE, 0x77) && BMP085.begin(0, TELEM_WIRE)) {
MESH_DEBUG_PRINTLN("Found sensor BMP085");
BMP085_initialized = true;
} else {
Expand All @@ -345,7 +368,7 @@ bool EnvironmentSensorManager::begin() {

#if ENV_INCLUDE_RAK12035
RAK12035.setup(*TELEM_WIRE);
if (RAK12035.begin(TELEM_RAK12035_ADDRESS)) {
if (i2c_probe(*TELEM_WIRE, TELEM_RAK12035_ADDRESS) && RAK12035.begin(TELEM_RAK12035_ADDRESS)) {
MESH_DEBUG_PRINTLN("Found sensor RAK12035 at address: %02X", TELEM_RAK12035_ADDRESS);
RAK12035_initialized = true;
} else {
Expand Down Expand Up @@ -716,7 +739,7 @@ bool EnvironmentSensorManager::gpsIsAwake(uint8_t ioPin){
gps_detected = true;
return true;
}

pinMode(ioPin, INPUT);
MESH_DEBUG_PRINTLN("GPS did not init with this IO pin... try the next");
return false;
Expand Down Expand Up @@ -759,7 +782,7 @@ void EnvironmentSensorManager::loop() {

#if ENV_INCLUDE_GPS
if (gps_active) {
_location->loop();
_location->loop();
}
if (millis() > next_gps_update) {

Expand Down
1 change: 1 addition & 0 deletions src/helpers/sensors/EnvironmentSensorManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ class EnvironmentSensorManager : public SensorManager {
#else
EnvironmentSensorManager(){};
#endif
bool i2c_probe(TwoWire& wire, uint8_t addr) override;
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
#if ENV_INCLUDE_GPS
Expand Down