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
220 changes: 214 additions & 6 deletions src/helpers/sensors/EnvironmentSensorManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@ static Adafruit_AHTX0 AHTX0;
static Adafruit_BME280 BME280;
#endif

#if ENV_INCLUDE_BME680
#ifndef TELEM_BME680_ADDRESS
#define TELEM_BME680_ADDRESS 0x76 // BME680 environmental sensor I2C address
#endif
static Bsec2 BME680;
#define SAMPLING_RATE BSEC_SAMPLE_RATE_ULP
static float rawPressure = 0;
static float rawTemperature = 0;
static float compTemperature = 0;
static float rawHumidity = 0;
static float compHumidity = 0;
static float readIAQ = 0;
static float readStaticIAQ = 0;
static float readCO2 = 0;
#endif

#if ENV_INCLUDE_BMP280
#ifndef TELEM_BMP280_ADDRESS
#define TELEM_BMP280_ADDRESS 0x76 // BMP280 environmental sensor I2C address
Expand Down Expand Up @@ -109,6 +125,50 @@ bool EnvironmentSensorManager::begin() {
}
#endif

#if ENV_INCLUDE_BME680
bsecSensor sensorList[5] = {
BSEC_OUTPUT_IAQ,
// BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
// BSEC_OUTPUT_RAW_HUMIDITY,
// BSEC_OUTPUT_RAW_GAS,
// BSEC_OUTPUT_STABILIZATION_STATUS,
// BSEC_OUTPUT_RUN_IN_STATUS,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
// BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
// BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
// BSEC_OUTPUT_GAS_PERCENTAGE,
// BSEC_OUTPUT_COMPENSATED_GAS
};

if(!BME680.begin(TELEM_BME680_ADDRESS, Wire)){
checkBMEStatus(BME680);
BME680_initialized = false;
return false;
}

MESH_DEBUG_PRINTLN("Found BME680 at address: %02X", TELEM_BME680_ADDRESS);
BME680_initialized = true;

if (SAMPLING_RATE == BSEC_SAMPLE_RATE_ULP)
{
BME680.setTemperatureOffset(BSEC_SAMPLE_RATE_ULP);
}
else if (SAMPLING_RATE == BSEC_SAMPLE_RATE_LP)
{
BME680.setTemperatureOffset(TEMP_OFFSET_LP);
}

if (!BME680.updateSubscription(sensorList, ARRAY_LEN(sensorList), SAMPLING_RATE))
{
checkBMEStatus(BME680);
}

BME680.attachCallback(newDataCallback);
#endif

#if ENV_INCLUDE_BMP280
if (BMP280.begin(TELEM_BMP280_ADDRESS)) {
MESH_DEBUG_PRINTLN("Found BMP280 at address: %02X", TELEM_BMP280_ADDRESS);
Expand Down Expand Up @@ -215,6 +275,16 @@ bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, Cayen
}
#endif

#if ENV_INCLUDE_BME680
if (BME680_initialized) {
telemetry.addTemperature(TELEM_CHANNEL_SELF, compTemperature);
telemetry.addRelativeHumidity(TELEM_CHANNEL_SELF, compHumidity);
telemetry.addBarometricPressure(TELEM_CHANNEL_SELF, rawPressure);
telemetry.addGenericSensor(TELEM_CHANNEL_SELF+1, readIAQ);
telemetry.addConcentration(TELEM_CHANNEL_SELF+1, readCO2);
}
#endif

#if ENV_INCLUDE_BMP280
if (BMP280_initialized) {
telemetry.addTemperature(TELEM_CHANNEL_SELF, BMP280.readTemperature());
Expand Down Expand Up @@ -289,7 +359,6 @@ bool EnvironmentSensorManager::querySensors(uint8_t requester_permissions, Cayen
return true;
}


int EnvironmentSensorManager::getNumSettings() const {
#if ENV_INCLUDE_GPS
return gps_detected ? 1 : 0; // only show GPS setting if GPS is detected
Expand Down Expand Up @@ -329,6 +398,96 @@ bool EnvironmentSensorManager::setSettingValue(const char* name, const char* val
return false; // not supported
}

#if ENV_INCLUDE_BME680
void EnvironmentSensorManager::checkBMEStatus(Bsec2 bsec) {
if (bsec.status < BSEC_OK)
{
MESH_DEBUG_PRINTLN("BSEC error code : %f", float(bsec.status));
}
else if (bsec.status > BSEC_OK)
{
MESH_DEBUG_PRINTLN("BSEC warning code : %f", float(bsec.status));
}

if (bsec.sensor.status < BME68X_OK)
{
MESH_DEBUG_PRINTLN("BME68X error code : %f", bsec.sensor.status);
}
else if (bsec.sensor.status > BME68X_OK)
{
MESH_DEBUG_PRINTLN("BME68X warning code : %f", bsec.sensor.status);
}
}

void EnvironmentSensorManager::newDataCallback(const bme68xData data, const bsecOutputs outputs, Bsec2 bsec) {
if (!outputs.nOutputs) {
MESH_DEBUG_PRINTLN("No new data to report out");
return;
}

MESH_DEBUG_PRINTLN("BSEC outputs:\n\tTime stamp = %f", (int) (outputs.output[0].time_stamp / INT64_C(1000000)));
for (uint8_t i = 0; i < outputs.nOutputs; i++) {
const bsecData output = outputs.output[i];
switch (output.sensor_id)
{
case BSEC_OUTPUT_IAQ:
readIAQ = output.signal;
MESH_DEBUG_PRINTLN("\tIAQ = %f", output.signal);
MESH_DEBUG_PRINTLN("\tIAQ accuracy = %f", output.accuracy);
break;
case BSEC_OUTPUT_RAW_TEMPERATURE:
rawTemperature = output.signal;
MESH_DEBUG_PRINTLN("\tTemperature = %f", output.signal);
break;
case BSEC_OUTPUT_RAW_PRESSURE:
rawPressure = output.signal;
MESH_DEBUG_PRINTLN("\tPressure = %f", output.signal);
break;
case BSEC_OUTPUT_RAW_HUMIDITY:
rawHumidity = output.signal;
MESH_DEBUG_PRINTLN("\tHumidity = %f", output.signal);
break;
case BSEC_OUTPUT_RAW_GAS:
MESH_DEBUG_PRINTLN("\tGas resistance = %f", output.signal);
break;
case BSEC_OUTPUT_STABILIZATION_STATUS:
MESH_DEBUG_PRINTLN("\tStabilization status = %f", output.signal);
break;
case BSEC_OUTPUT_RUN_IN_STATUS:
MESH_DEBUG_PRINTLN("\tRun in status = %f", output.signal);
break;
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE:
compTemperature = output.signal;
MESH_DEBUG_PRINTLN("\tCompensated temperature = %f", output.signal);
break;
case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY:
compHumidity = output.signal;
MESH_DEBUG_PRINTLN("\tCompensated humidity = %f", output.signal);
break;
case BSEC_OUTPUT_STATIC_IAQ:
readStaticIAQ = output.signal;
MESH_DEBUG_PRINTLN("\tStatic IAQ = %f", output.signal);
break;
case BSEC_OUTPUT_CO2_EQUIVALENT:
readCO2 = output.signal;
MESH_DEBUG_PRINTLN("\tCO2 Equivalent = %f", output.signal);
break;
case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT:
MESH_DEBUG_PRINTLN("\tbVOC equivalent = %f", output.signal);
break;
case BSEC_OUTPUT_GAS_PERCENTAGE:
MESH_DEBUG_PRINTLN("\tGas percentage = %f", output.signal);
break;
case BSEC_OUTPUT_COMPENSATED_GAS:
MESH_DEBUG_PRINTLN("\tCompensated gas = %f", output.signal);
break;
default:
break;
}
}
}
#endif

#if ENV_INCLUDE_GPS
void EnvironmentSensorManager::initBasicGPS() {

Expand Down Expand Up @@ -474,13 +633,27 @@ void EnvironmentSensorManager::stop_gps() {

MESH_DEBUG_PRINTLN("Stop GPS is N/A on this board. Actual GPS state unchanged");
}
#endif

#ifndef ENV_INCLUDE_GPS && defined(ENV_INCLUDE_BME680) //if there is no gps but there is bme680
void EnvironmentSensorManager::loop() {
static long next_gps_update = 0;
static long next_update = 0;

if(BME680_initialized){
if (!BME680.run()){
checkBMEStatus(BME680);
}
}
next_update = millis() + 1000;
}
#endif
#if defined(ENV_INCLUDE_GPS) && defined(ENV_INCLUDE_BME680) //if there is both gps and bme680
void EnvironmentSensorManager::loop() {
static long next_update = 0;

_location->loop();

if (millis() > next_gps_update) {
if (millis() > next_update) {
if(gps_active){
#ifndef RAK_BOARD
if (_location->isValid()) {
Expand All @@ -499,11 +672,46 @@ void EnvironmentSensorManager::loop() {
node_lon = ((double)_location->getLongitude())/1000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
//else
//MESH_DEBUG_PRINTLN("No valid GPS data");
#endif
}
next_gps_update = millis() + 1000;

if(BME680_initialized){
if (!BME680.run()){
checkBMEStatus(BME680);
}
}
next_update = millis() + 1000;
}
}
#endif
#ifndef ENV_INCLUDE_BME680 && defined(ENV_INCLUDE_GPS) //if there is no bme680 but there is gps
void EnvironmentSensorManager::loop() {
static long next_update = 0;

_location->loop();

if (millis() > next_update) {
if(gps_active){
#ifndef RAK_BOARD
if (_location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
#else
if(i2cGPSFlag){
node_lat = ((double)ublox_GNSS.getLatitude())/10000000.;
node_lon = ((double)ublox_GNSS.getLongitude())/10000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
else if (serialGPSFlag && _location->isValid()) {
node_lat = ((double)_location->getLatitude())/1000000.;
node_lon = ((double)_location->getLongitude())/1000000.;
MESH_DEBUG_PRINTLN("lat %f lon %f", node_lat, node_lon);
}
#endif
}
next_update = millis() + 1000;
}
}
#endif
11 changes: 10 additions & 1 deletion src/helpers/sensors/EnvironmentSensorManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
#include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h>

#ifdef ENV_INCLUDE_BME680
#include <bsec2.h>
#endif

class EnvironmentSensorManager : public SensorManager {
protected:
int next_available_channel = TELEM_CHANNEL_SELF + 1;

bool AHTX0_initialized = false;
bool BME280_initialized = false;
bool BMP280_initialized = false;
bool BME680_initialized = false;
bool INA3221_initialized = false;
bool INA219_initialized = false;
bool SHTC3_initialized = false;
Expand All @@ -32,6 +37,10 @@ class EnvironmentSensorManager : public SensorManager {
#endif
#endif

#if ENV_INCLUDE_BME680
static void checkBMEStatus(Bsec2 bsec);
static void newDataCallback(const bme68xData data, const bsecOutputs outputs, Bsec2 bsec);
#endif

public:
#if ENV_INCLUDE_GPS
Expand All @@ -41,7 +50,7 @@ class EnvironmentSensorManager : public SensorManager {
#endif
bool begin() override;
bool querySensors(uint8_t requester_permissions, CayenneLPP& telemetry) override;
#if ENV_INCLUDE_GPS
#if ENV_INCLUDE_GPS || ENV_INCLUDE_BME680
void loop() override;
#endif
int getNumSettings() const override;
Expand Down
6 changes: 6 additions & 0 deletions variants/rak4631/platformio.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@ build_flags = ${nrf52_base.build_flags}
-D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1
-D PIN_BUZZER=WB_IO5 ;for socket D on RAK19007 and RAK19003
-D ENV_INCLUDE_GPS=1
-D ENV_INCLUDE_SHTC3=1
-D ENV_INCLUDE_LPS22HB=1
-D ENV_INCLUDE_INA219=1
-D ENV_INCLUDE_BME680=1
build_src_filter = ${nrf52_base.build_src_filter}
+<../variants/rak4631>
+<helpers/sensors>
+<helpers/ui/buzzer.cpp>
lib_deps =
${nrf52_base.lib_deps}
adafruit/Adafruit SSD1306 @ ^2.5.13
Expand All @@ -33,6 +36,9 @@ lib_deps =
arduino-libraries/Arduino_LPS22HB@^1.0.2
adafruit/Adafruit INA219@^1.2.3
sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.27
https://github.com/boschsensortec/Bosch-BSEC2-Library
https://github.com/boschsensortec/Bosch-BME68x-Library
end2endzone/NonBlockingRTTTL@^1.3.0

[env:RAK_4631_Repeater]
extends = rak4631
Expand Down