Skip to content

Commit

Permalink
Merge pull request #84 from arduino-libraries/update_bsec
Browse files Browse the repository at this point in the history
[rev2] Fix AirQuality readings by restructuring BSEC library
  • Loading branch information
facchinm authored Apr 4, 2024
2 parents 6b96387 + e41650a commit 1aba2ad
Show file tree
Hide file tree
Showing 17 changed files with 158 additions and 4,415 deletions.
6 changes: 1 addition & 5 deletions library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,4 @@ paragraph=Allows you to control all the components included in the Explore IoT K
category=Sensors
url=https://github.com/arduino-libraries/Arduino_MKRIoTCarrier
architectures=samd
precompiled=false
depends=Arduino_APDS9960,Arduino_BQ24195,Arduino_HTS221,Arduino_LPS22HB,Arduino_LSM6DS3,Arduino_LSM6DSOX,Adafruit BusIO,Adafruit DotStar,Adafruit GFX Library,Adafruit ST7735 and ST7789 Library,Arduino_MCHPTouch,TFT_eSPI
dot_a_linkage=true
precompiled=true
ldflags=-lalgobsec
depends=Arduino_APDS9960,Arduino_BQ24195,Arduino_HTS221,Arduino_LPS22HB,Arduino_LSM6DS3,Arduino_LSM6DSOX,Adafruit BusIO,Adafruit DotStar,Adafruit GFX Library,Adafruit ST7735 and ST7789 Library,Arduino_MCHPTouch,TFT_eSPI,BSEC Software Library
92 changes: 57 additions & 35 deletions src/AirQualityClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,31 +29,52 @@ AirQualityClass::~AirQualityClass()
{
}

/* Configure the BSEC library with information about the sensor
18v/33v = Voltage at Vdd. 1.8V or 3.3V
3s/300s = BSEC operating mode, BSEC_SAMPLE_RATE_LP or BSEC_SAMPLE_RATE_ULP
4d/28d = Operating age of the sensor in days
generic_18v_3s_4d
generic_18v_3s_28d
generic_18v_300s_4d
generic_18v_300s_28d
generic_33v_3s_4d
generic_33v_3s_28d
generic_33v_300s_4d
generic_33v_300s_28d
*/

extern "C" const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};

int AirQualityClass::begin()
{
_revision = board_revision();
if (_revision == BOARD_REVISION_2) {
if (mkr_iot_carrier_rev2::iaqSensor == nullptr) {
iaqSensor = new Bsec();
iaqSensor->begin(BME680_I2C_ADDR_PRIMARY, Wire);
iaqSensor->begin(BME68X_I2C_ADDR_LOW, Wire);
if (checkIaqSensorStatus() == STATUS_ERROR){
return 0;
}
iaqSensor->setConfig(bsec_config_iaq);

bsec_virtual_sensor_t sensorList[10] = {
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
bsec_virtual_sensor_t sensorList[13] = {
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
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_GAS_PERCENTAGE
};

iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_CONTINUOUS);
iaqSensor->updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
if (checkIaqSensorStatus() == STATUS_ERROR){
return 0;
}
Expand All @@ -68,14 +89,14 @@ int AirQualityClass::begin()

int AirQualityClass::checkIaqSensorStatus(void)
{
if (iaqSensor->status != BSEC_OK) {
if (iaqSensor->status < BSEC_OK) {
if (iaqSensor->bsecStatus != BSEC_OK) {
if (iaqSensor->bsecStatus < BSEC_OK) {
return STATUS_ERROR;
}
}

if (iaqSensor->bme680Status != BME680_OK) {
if (iaqSensor->bme680Status < BME680_OK) {
if (iaqSensor->bme68xStatus != BME68X_OK) {
if (iaqSensor->bme68xStatus < BME68X_OK) {
return STATUS_ERROR;
}
}
Expand All @@ -92,62 +113,63 @@ void AirQualityClass::end()

float AirQualityClass::readVOC()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->breathVocEquivalent;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::breathVocEquivalent;
}

float AirQualityClass::readGasResistor()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->gasResistance;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::gasResistance;
}

float AirQualityClass::readIAQ()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->iaq;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::iaq;
}

float AirQualityClass::readIAQAccuracy()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->iaqAccuracy;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::iaqAccuracy;
}

float AirQualityClass::readStaticIAQ()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->staticIaq;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::staticIaq;
}


float AirQualityClass::readCO2()
{
float reading = 0.0;
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
reading = iaqSensor->co2Equivalent;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
}
return reading;
return mkr_iot_carrier_rev2::co2Equivalent;
}

23 changes: 19 additions & 4 deletions src/Arduino_MKRIoTCarrier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,19 @@
//Touch pads values for using the case or just directly on the board
//Define on the sketch to use it
bool CARRIER_CASE = false;


mkr_iot_carrier_rev2 mkr_iot_carrier_rev2_instance;
Bsec* mkr_iot_carrier_rev2::iaqSensor;
float mkr_iot_carrier_rev2::breathVocEquivalent;
float mkr_iot_carrier_rev2::gasResistance;
float mkr_iot_carrier_rev2::iaq;
float mkr_iot_carrier_rev2::iaqAccuracy;
float mkr_iot_carrier_rev2::staticIaq;
float mkr_iot_carrier_rev2::co2Equivalent;
float mkr_iot_carrier_rev2::temperature;
float mkr_iot_carrier_rev2::pressure;
float mkr_iot_carrier_rev2::humidity;

MKRIoTCarrier::MKRIoTCarrier() {
}

Expand All @@ -34,6 +46,7 @@ int MKRIoTCarrier::begin() {
pinMode(AREF_PIN,INPUT_PULLUP);
if (digitalRead(AREF_PIN) == LOW) {
MKRIoTCarrier::_revision = BOARD_REVISION_2;
mkr_iot_carrier_rev2::iaqSensor = nullptr;
} else {
MKRIoTCarrier::_revision = BOARD_REVISION_1;
}
Expand Down Expand Up @@ -73,9 +86,11 @@ int MKRIoTCarrier::begin() {
Relay2.begin();

//Sensors
uint8_t sensorsOK = !Light.begin() << 0 | !Pressure.begin() << 1 | !IMUmodule.begin() << 2 | !Env.begin() << 3 |
(_revision == BOARD_REVISION_2 ? !AirQuality.begin() << 4 : 0);

uint8_t sensorsOK = (_revision == BOARD_REVISION_2 ? !AirQuality.begin() << 4 : 0) |
!Light.begin() << 0 |
!Pressure.begin() << 1 |
!IMUmodule.begin() << 2 |
!Env.begin() << 3;

//If some of the sensors are not connected
if(sensorsOK > 0 ){
Expand Down
44 changes: 26 additions & 18 deletions src/EnvClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,31 +30,37 @@ EnvClass::~EnvClass()
{
}

extern const uint8_t bsec_config_iaq[];

int EnvClass::begin()
{
_revision = board_revision();
if (_revision == BOARD_REVISION_2) {
if (mkr_iot_carrier_rev2::iaqSensor == nullptr) {
iaqSensor = new Bsec();
iaqSensor->begin(BME680_I2C_ADDR_PRIMARY, Wire);
iaqSensor->begin(BME68X_I2C_ADDR_LOW, Wire);
if (checkIaqSensorStatus() == STATUS_ERROR){
return 0;
}
iaqSensor->setConfig(bsec_config_iaq);

bsec_virtual_sensor_t sensorList[10] = {
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
bsec_virtual_sensor_t sensorList[13] = {
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_STATIC_IAQ,
BSEC_OUTPUT_CO2_EQUIVALENT,
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
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_GAS_PERCENTAGE
};

iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_CONTINUOUS);
iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
if (checkIaqSensorStatus() == STATUS_ERROR){
return 0;
}
Expand All @@ -73,14 +79,14 @@ int EnvClass::begin()

int EnvClass::checkIaqSensorStatus(void)
{
if (iaqSensor->status != BSEC_OK) {
if (iaqSensor->status < BSEC_OK) {
if (iaqSensor->bsecStatus != BSEC_OK) {
if (iaqSensor->bsecStatus < BSEC_OK) {
return 0;
}
}

if (iaqSensor->bme680Status != BME680_OK) {
if (iaqSensor->bme680Status < BME680_OK) {
if (iaqSensor->bme68xStatus != BME68X_OK) {
if (iaqSensor->bme68xStatus < BME68X_OK) {
return 0;
}
}
Expand All @@ -102,12 +108,13 @@ void EnvClass::end()
float EnvClass::readTemperature(int units /*= CELSIUS*/)
{
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
float reading = iaqSensor->temperature;
if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
if (units == FAHRENHEIT){
return (reading * 9.0 / 5.0) + 32.0;
return (mkr_iot_carrier_rev2::temperature * 9.0 / 5.0) + 32.0;
} else {
return reading;
return mkr_iot_carrier_rev2::temperature;
}
}
return HTS221->readTemperature(units);
Expand All @@ -116,9 +123,10 @@ float EnvClass::readTemperature(int units /*= CELSIUS*/)
float EnvClass::readHumidity()
{
if (_revision == BOARD_REVISION_2) {
while(!iaqSensor->run()){ }
return iaqSensor->humidity;

if(iaqSensor->run()){
mkr_iot_carrier_rev2::cache();
}
return mkr_iot_carrier_rev2::humidity;
}
return HTS221->readHumidity();
}
29 changes: 26 additions & 3 deletions src/MKRIoTCarrierDefines.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
//Sensor libraries
#include <Arduino_APDS9960.h> //Ambient light
#include <Arduino_LPS22HB.h> //Pressure sensor
#include "bsec/bsec.h"
#include "bsec.h"
#include <Arduino_HTS221.h> // env sensor
#include <Arduino_LSM6DSOX.h>
#include <Arduino_LSM6DS3.h>
Expand Down Expand Up @@ -62,8 +62,9 @@ namespace mkr_iot_carrier_rev1 {
};
};

namespace mkr_iot_carrier_rev2 {
static Bsec *iaqSensor = nullptr;
class mkr_iot_carrier_rev2 {
public:
static Bsec *iaqSensor;
enum relays {
RELAY1 = 1,
RELAY2 = 2,
Expand All @@ -83,8 +84,30 @@ namespace mkr_iot_carrier_rev2 {
GROVE_AN1 = A0,
GROVE_AN2 = A6,
};
static void cache() {
breathVocEquivalent = iaqSensor->breathVocEquivalent;
gasResistance = iaqSensor->gasResistance;
iaq = iaqSensor->iaq;
iaqAccuracy = iaqSensor->iaqAccuracy;
staticIaq = iaqSensor->staticIaq;
co2Equivalent = iaqSensor->co2Equivalent;
temperature = iaqSensor->temperature;
pressure = iaqSensor->pressure;
humidity = iaqSensor->humidity;
};
static float breathVocEquivalent;
static float gasResistance;
static float iaq;
static float iaqAccuracy;
static float staticIaq;
static float co2Equivalent;
static float temperature;
static float pressure;
static float humidity;
};

extern mkr_iot_carrier_rev2 mkr_iot_carrier_rev2_instance;

#define BME_SLAVE_ADDRESS 0x76

#define LSM6DSOX_ADDRESS 0x6A
Expand Down
Loading

0 comments on commit 1aba2ad

Please sign in to comment.