Skip to content

Commit 1aba2ad

Browse files
authored
Merge pull request #84 from arduino-libraries/update_bsec
[rev2] Fix AirQuality readings by restructuring BSEC library
2 parents 6b96387 + e41650a commit 1aba2ad

17 files changed

+158
-4415
lines changed

library.properties

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,4 @@ paragraph=Allows you to control all the components included in the Explore IoT K
77
category=Sensors
88
url=https://github.com/arduino-libraries/Arduino_MKRIoTCarrier
99
architectures=samd
10-
precompiled=false
11-
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
12-
dot_a_linkage=true
13-
precompiled=true
14-
ldflags=-lalgobsec
10+
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

src/AirQualityClass.cpp

+57-35
Original file line numberDiff line numberDiff line change
@@ -29,31 +29,52 @@ AirQualityClass::~AirQualityClass()
2929
{
3030
}
3131

32+
/* Configure the BSEC library with information about the sensor
33+
18v/33v = Voltage at Vdd. 1.8V or 3.3V
34+
3s/300s = BSEC operating mode, BSEC_SAMPLE_RATE_LP or BSEC_SAMPLE_RATE_ULP
35+
4d/28d = Operating age of the sensor in days
36+
generic_18v_3s_4d
37+
generic_18v_3s_28d
38+
generic_18v_300s_4d
39+
generic_18v_300s_28d
40+
generic_33v_3s_4d
41+
generic_33v_3s_28d
42+
generic_33v_300s_4d
43+
generic_33v_300s_28d
44+
*/
45+
46+
extern "C" const uint8_t bsec_config_iaq[] = {
47+
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
48+
};
49+
3250
int AirQualityClass::begin()
3351
{
3452
_revision = board_revision();
3553
if (_revision == BOARD_REVISION_2) {
3654
if (mkr_iot_carrier_rev2::iaqSensor == nullptr) {
3755
iaqSensor = new Bsec();
38-
iaqSensor->begin(BME680_I2C_ADDR_PRIMARY, Wire);
56+
iaqSensor->begin(BME68X_I2C_ADDR_LOW, Wire);
3957
if (checkIaqSensorStatus() == STATUS_ERROR){
4058
return 0;
4159
}
60+
iaqSensor->setConfig(bsec_config_iaq);
4261

43-
bsec_virtual_sensor_t sensorList[10] = {
44-
BSEC_OUTPUT_RAW_TEMPERATURE,
45-
BSEC_OUTPUT_RAW_PRESSURE,
46-
BSEC_OUTPUT_RAW_HUMIDITY,
47-
BSEC_OUTPUT_RAW_GAS,
62+
bsec_virtual_sensor_t sensorList[13] = {
4863
BSEC_OUTPUT_IAQ,
4964
BSEC_OUTPUT_STATIC_IAQ,
5065
BSEC_OUTPUT_CO2_EQUIVALENT,
5166
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
67+
BSEC_OUTPUT_RAW_TEMPERATURE,
68+
BSEC_OUTPUT_RAW_PRESSURE,
69+
BSEC_OUTPUT_RAW_HUMIDITY,
70+
BSEC_OUTPUT_RAW_GAS,
71+
BSEC_OUTPUT_STABILIZATION_STATUS,
72+
BSEC_OUTPUT_RUN_IN_STATUS,
5273
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
5374
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
75+
BSEC_OUTPUT_GAS_PERCENTAGE
5476
};
55-
56-
iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_CONTINUOUS);
77+
iaqSensor->updateSubscription(sensorList, 13, BSEC_SAMPLE_RATE_LP);
5778
if (checkIaqSensorStatus() == STATUS_ERROR){
5879
return 0;
5980
}
@@ -68,14 +89,14 @@ int AirQualityClass::begin()
6889

6990
int AirQualityClass::checkIaqSensorStatus(void)
7091
{
71-
if (iaqSensor->status != BSEC_OK) {
72-
if (iaqSensor->status < BSEC_OK) {
92+
if (iaqSensor->bsecStatus != BSEC_OK) {
93+
if (iaqSensor->bsecStatus < BSEC_OK) {
7394
return STATUS_ERROR;
7495
}
7596
}
7697

77-
if (iaqSensor->bme680Status != BME680_OK) {
78-
if (iaqSensor->bme680Status < BME680_OK) {
98+
if (iaqSensor->bme68xStatus != BME68X_OK) {
99+
if (iaqSensor->bme68xStatus < BME68X_OK) {
79100
return STATUS_ERROR;
80101
}
81102
}
@@ -92,62 +113,63 @@ void AirQualityClass::end()
92113

93114
float AirQualityClass::readVOC()
94115
{
95-
float reading = 0.0;
96116
if (_revision == BOARD_REVISION_2) {
97-
while(!iaqSensor->run()){ }
98-
reading = iaqSensor->breathVocEquivalent;
117+
if(iaqSensor->run()){
118+
mkr_iot_carrier_rev2::cache();
119+
}
99120
}
100-
return reading;
121+
return mkr_iot_carrier_rev2::breathVocEquivalent;
101122
}
102123

103124
float AirQualityClass::readGasResistor()
104125
{
105-
float reading = 0.0;
106126
if (_revision == BOARD_REVISION_2) {
107-
while(!iaqSensor->run()){ }
108-
reading = iaqSensor->gasResistance;
127+
if(iaqSensor->run()){
128+
mkr_iot_carrier_rev2::cache();
129+
}
109130
}
110-
return reading;
131+
return mkr_iot_carrier_rev2::gasResistance;
111132
}
112133

113134
float AirQualityClass::readIAQ()
114135
{
115-
float reading = 0.0;
116136
if (_revision == BOARD_REVISION_2) {
117-
while(!iaqSensor->run()){ }
118-
reading = iaqSensor->iaq;
137+
if(iaqSensor->run()){
138+
mkr_iot_carrier_rev2::cache();
139+
}
119140
}
120-
return reading;
141+
return mkr_iot_carrier_rev2::iaq;
121142
}
122143

123144
float AirQualityClass::readIAQAccuracy()
124145
{
125-
float reading = 0.0;
126146
if (_revision == BOARD_REVISION_2) {
127-
while(!iaqSensor->run()){ }
128-
reading = iaqSensor->iaqAccuracy;
147+
if(iaqSensor->run()){
148+
mkr_iot_carrier_rev2::cache();
149+
}
129150
}
130-
return reading;
151+
return mkr_iot_carrier_rev2::iaqAccuracy;
131152
}
132153

133154
float AirQualityClass::readStaticIAQ()
134155
{
135-
float reading = 0.0;
136156
if (_revision == BOARD_REVISION_2) {
137-
while(!iaqSensor->run()){ }
138-
reading = iaqSensor->staticIaq;
157+
if(iaqSensor->run()){
158+
mkr_iot_carrier_rev2::cache();
159+
}
139160
}
140-
return reading;
161+
return mkr_iot_carrier_rev2::staticIaq;
141162
}
142163

143164

144165
float AirQualityClass::readCO2()
145166
{
146167
float reading = 0.0;
147168
if (_revision == BOARD_REVISION_2) {
148-
while(!iaqSensor->run()){ }
149-
reading = iaqSensor->co2Equivalent;
169+
if(iaqSensor->run()){
170+
mkr_iot_carrier_rev2::cache();
171+
}
150172
}
151-
return reading;
173+
return mkr_iot_carrier_rev2::co2Equivalent;
152174
}
153175

src/Arduino_MKRIoTCarrier.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,19 @@
2323
//Touch pads values for using the case or just directly on the board
2424
//Define on the sketch to use it
2525
bool CARRIER_CASE = false;
26-
26+
27+
mkr_iot_carrier_rev2 mkr_iot_carrier_rev2_instance;
28+
Bsec* mkr_iot_carrier_rev2::iaqSensor;
29+
float mkr_iot_carrier_rev2::breathVocEquivalent;
30+
float mkr_iot_carrier_rev2::gasResistance;
31+
float mkr_iot_carrier_rev2::iaq;
32+
float mkr_iot_carrier_rev2::iaqAccuracy;
33+
float mkr_iot_carrier_rev2::staticIaq;
34+
float mkr_iot_carrier_rev2::co2Equivalent;
35+
float mkr_iot_carrier_rev2::temperature;
36+
float mkr_iot_carrier_rev2::pressure;
37+
float mkr_iot_carrier_rev2::humidity;
38+
2739
MKRIoTCarrier::MKRIoTCarrier() {
2840
}
2941

@@ -34,6 +46,7 @@ int MKRIoTCarrier::begin() {
3446
pinMode(AREF_PIN,INPUT_PULLUP);
3547
if (digitalRead(AREF_PIN) == LOW) {
3648
MKRIoTCarrier::_revision = BOARD_REVISION_2;
49+
mkr_iot_carrier_rev2::iaqSensor = nullptr;
3750
} else {
3851
MKRIoTCarrier::_revision = BOARD_REVISION_1;
3952
}
@@ -73,9 +86,11 @@ int MKRIoTCarrier::begin() {
7386
Relay2.begin();
7487

7588
//Sensors
76-
uint8_t sensorsOK = !Light.begin() << 0 | !Pressure.begin() << 1 | !IMUmodule.begin() << 2 | !Env.begin() << 3 |
77-
(_revision == BOARD_REVISION_2 ? !AirQuality.begin() << 4 : 0);
78-
89+
uint8_t sensorsOK = (_revision == BOARD_REVISION_2 ? !AirQuality.begin() << 4 : 0) |
90+
!Light.begin() << 0 |
91+
!Pressure.begin() << 1 |
92+
!IMUmodule.begin() << 2 |
93+
!Env.begin() << 3;
7994

8095
//If some of the sensors are not connected
8196
if(sensorsOK > 0 ){

src/EnvClass.cpp

+26-18
Original file line numberDiff line numberDiff line change
@@ -30,31 +30,37 @@ EnvClass::~EnvClass()
3030
{
3131
}
3232

33+
extern const uint8_t bsec_config_iaq[];
34+
3335
int EnvClass::begin()
3436
{
3537
_revision = board_revision();
3638
if (_revision == BOARD_REVISION_2) {
3739
if (mkr_iot_carrier_rev2::iaqSensor == nullptr) {
3840
iaqSensor = new Bsec();
39-
iaqSensor->begin(BME680_I2C_ADDR_PRIMARY, Wire);
41+
iaqSensor->begin(BME68X_I2C_ADDR_LOW, Wire);
4042
if (checkIaqSensorStatus() == STATUS_ERROR){
4143
return 0;
4244
}
45+
iaqSensor->setConfig(bsec_config_iaq);
4346

44-
bsec_virtual_sensor_t sensorList[10] = {
45-
BSEC_OUTPUT_RAW_TEMPERATURE,
46-
BSEC_OUTPUT_RAW_PRESSURE,
47-
BSEC_OUTPUT_RAW_HUMIDITY,
48-
BSEC_OUTPUT_RAW_GAS,
47+
bsec_virtual_sensor_t sensorList[13] = {
4948
BSEC_OUTPUT_IAQ,
5049
BSEC_OUTPUT_STATIC_IAQ,
5150
BSEC_OUTPUT_CO2_EQUIVALENT,
5251
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
52+
BSEC_OUTPUT_RAW_TEMPERATURE,
53+
BSEC_OUTPUT_RAW_PRESSURE,
54+
BSEC_OUTPUT_RAW_HUMIDITY,
55+
BSEC_OUTPUT_RAW_GAS,
56+
BSEC_OUTPUT_STABILIZATION_STATUS,
57+
BSEC_OUTPUT_RUN_IN_STATUS,
5358
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
5459
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
60+
BSEC_OUTPUT_GAS_PERCENTAGE
5561
};
5662

57-
iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_CONTINUOUS);
63+
iaqSensor->updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
5864
if (checkIaqSensorStatus() == STATUS_ERROR){
5965
return 0;
6066
}
@@ -73,14 +79,14 @@ int EnvClass::begin()
7379

7480
int EnvClass::checkIaqSensorStatus(void)
7581
{
76-
if (iaqSensor->status != BSEC_OK) {
77-
if (iaqSensor->status < BSEC_OK) {
82+
if (iaqSensor->bsecStatus != BSEC_OK) {
83+
if (iaqSensor->bsecStatus < BSEC_OK) {
7884
return 0;
7985
}
8086
}
8187

82-
if (iaqSensor->bme680Status != BME680_OK) {
83-
if (iaqSensor->bme680Status < BME680_OK) {
88+
if (iaqSensor->bme68xStatus != BME68X_OK) {
89+
if (iaqSensor->bme68xStatus < BME68X_OK) {
8490
return 0;
8591
}
8692
}
@@ -102,12 +108,13 @@ void EnvClass::end()
102108
float EnvClass::readTemperature(int units /*= CELSIUS*/)
103109
{
104110
if (_revision == BOARD_REVISION_2) {
105-
while(!iaqSensor->run()){ }
106-
float reading = iaqSensor->temperature;
111+
if(iaqSensor->run()){
112+
mkr_iot_carrier_rev2::cache();
113+
}
107114
if (units == FAHRENHEIT){
108-
return (reading * 9.0 / 5.0) + 32.0;
115+
return (mkr_iot_carrier_rev2::temperature * 9.0 / 5.0) + 32.0;
109116
} else {
110-
return reading;
117+
return mkr_iot_carrier_rev2::temperature;
111118
}
112119
}
113120
return HTS221->readTemperature(units);
@@ -116,9 +123,10 @@ float EnvClass::readTemperature(int units /*= CELSIUS*/)
116123
float EnvClass::readHumidity()
117124
{
118125
if (_revision == BOARD_REVISION_2) {
119-
while(!iaqSensor->run()){ }
120-
return iaqSensor->humidity;
121-
126+
if(iaqSensor->run()){
127+
mkr_iot_carrier_rev2::cache();
128+
}
129+
return mkr_iot_carrier_rev2::humidity;
122130
}
123131
return HTS221->readHumidity();
124132
}

src/MKRIoTCarrierDefines.h

+26-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
//Sensor libraries
1010
#include <Arduino_APDS9960.h> //Ambient light
1111
#include <Arduino_LPS22HB.h> //Pressure sensor
12-
#include "bsec/bsec.h"
12+
#include "bsec.h"
1313
#include <Arduino_HTS221.h> // env sensor
1414
#include <Arduino_LSM6DSOX.h>
1515
#include <Arduino_LSM6DS3.h>
@@ -62,8 +62,9 @@ namespace mkr_iot_carrier_rev1 {
6262
};
6363
};
6464

65-
namespace mkr_iot_carrier_rev2 {
66-
static Bsec *iaqSensor = nullptr;
65+
class mkr_iot_carrier_rev2 {
66+
public:
67+
static Bsec *iaqSensor;
6768
enum relays {
6869
RELAY1 = 1,
6970
RELAY2 = 2,
@@ -83,8 +84,30 @@ namespace mkr_iot_carrier_rev2 {
8384
GROVE_AN1 = A0,
8485
GROVE_AN2 = A6,
8586
};
87+
static void cache() {
88+
breathVocEquivalent = iaqSensor->breathVocEquivalent;
89+
gasResistance = iaqSensor->gasResistance;
90+
iaq = iaqSensor->iaq;
91+
iaqAccuracy = iaqSensor->iaqAccuracy;
92+
staticIaq = iaqSensor->staticIaq;
93+
co2Equivalent = iaqSensor->co2Equivalent;
94+
temperature = iaqSensor->temperature;
95+
pressure = iaqSensor->pressure;
96+
humidity = iaqSensor->humidity;
97+
};
98+
static float breathVocEquivalent;
99+
static float gasResistance;
100+
static float iaq;
101+
static float iaqAccuracy;
102+
static float staticIaq;
103+
static float co2Equivalent;
104+
static float temperature;
105+
static float pressure;
106+
static float humidity;
86107
};
87108

109+
extern mkr_iot_carrier_rev2 mkr_iot_carrier_rev2_instance;
110+
88111
#define BME_SLAVE_ADDRESS 0x76
89112

90113
#define LSM6DSOX_ADDRESS 0x6A

0 commit comments

Comments
 (0)