Skip to content

Commit

Permalink
Merge pull request #49 from BoschSensortec/experimental/multi-instanc…
Browse files Browse the repository at this point in the history
…e-support

Merged Experimental/multi instance support to master
  • Loading branch information
Bosch Sensortec authored Jan 23, 2020
2 parents 7101334 + be6042c commit c5503e0
Show file tree
Hide file tree
Showing 15 changed files with 1,209 additions and 770 deletions.
61 changes: 26 additions & 35 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,33 @@ The binaries and includes for the core BSEC library in this repository are licen

The Arduino wrapper and BME680 Sensor API are licensed under the following license.

Copyright (C) 2017 - 2019 Bosch Sensortec GmbH
Copyright (c) 2020 Bosch Sensortec GmbH. All rights reserved.

BSD-3-Clause

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

Neither the name of the copyright holder nor the names of the
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE

The information provided is believed to be accurate and reliable.
The copyright holder assumes no responsibility
for the consequences of use
of such information nor for any infringement of patents or
other rights of third parties which may result from its use.
No license is granted by implication or otherwise under any patent or
patent rights of the copyright holder.
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,4 +184,4 @@ The current list of tested boards include,
| Esp32 | Sparkfun ESP32 Thing | v1.0.3-rc1 | https://github.com/espressif/arduino-esp32 |
| Esp8266 | Adafruit Feather HUZZAH | Upstream of v2.5.1 SHA-1 hash 625c3a62c4991347e8298fb5e4021bc6f6df7099 | https://github.com/esp8266/Arduino |

## Copyright (C) 2017 - 2019 Bosch Sensortec GmbH
## Copyright (C) 2020 Bosch Sensortec GmbH. All rights reserved.
29 changes: 15 additions & 14 deletions examples/basic_config_state/basic_config_state.ino
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
#include <EEPROM.h>
#include "bsec.h"
/* 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
*/
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
*/
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};

#define STATE_SAVE_PERIOD UINT32_C(360 * 60 * 1000) // 360 minutes - 4 times a day
Expand Down Expand Up @@ -114,6 +114,7 @@ void checkIaqSensorStatus(void)
Serial.println(output);
}
}
iaqSensor.status = BSEC_OK;
}

void errLeds(void)
Expand Down Expand Up @@ -180,4 +181,4 @@ void updateState(void)
EEPROM.write(0, BSEC_MAX_STATE_BLOB_SIZE);
EEPROM.commit();
}
}
}
235 changes: 235 additions & 0 deletions examples/basic_config_state_multi/basic_config_state_multi.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,235 @@
#include <EEPROM.h>
#include "bsec.h"
/* 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
*/
const uint8_t bsec_config_iaq[] = {
#include "config/generic_33v_3s_4d/bsec_iaq.txt"
};

#define STATE_SAVE_PERIOD UINT32_C(300000) // 360 minutes - 4 times a day
#define N_SENSORS 2

// Helper functions declarations
void checkIaqSensorStatus(void);
void errLeds(void);
void loadState(void);
void updateState(void);

// Create objects of the class Bsec
Bsec iaqSensor1, iaqSensor2;
uint8_t bsecState1[BSEC_MAX_STATE_BLOB_SIZE], bsecState2[BSEC_MAX_STATE_BLOB_SIZE];
uint16_t stateUpdateCounter = 0;

String output;

// Entry point for the example
void setup(void)
{
EEPROM.begin((N_SENSORS * BSEC_MAX_STATE_BLOB_SIZE) + 1); // 1st address for the length of one state
Serial.begin(115200);
Wire.begin();

iaqSensor1.begin(BME680_I2C_ADDR_PRIMARY, Wire);
iaqSensor2.begin(BME680_I2C_ADDR_SECONDARY, Wire);
output = "\nBSEC library version " + String(iaqSensor1.version.major) + "." + String(iaqSensor1.version.minor) + "." + String(iaqSensor1.version.major_bugfix) + "." + String(iaqSensor1.version.minor_bugfix);
Serial.println(output);
checkIaqSensorStatus();

iaqSensor1.setConfig(bsec_config_iaq);
iaqSensor2.setConfig(bsec_config_iaq);
checkIaqSensorStatus();

loadState();

bsec_virtual_sensor_t sensorList[7] = {
BSEC_OUTPUT_RAW_TEMPERATURE,
BSEC_OUTPUT_RAW_PRESSURE,
BSEC_OUTPUT_RAW_HUMIDITY,
BSEC_OUTPUT_RAW_GAS,
BSEC_OUTPUT_IAQ,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
};

iaqSensor1.updateSubscription(sensorList, 7, BSEC_SAMPLE_RATE_LP);
iaqSensor2.updateSubscription(sensorList, 7, BSEC_SAMPLE_RATE_LP);
checkIaqSensorStatus();

// Print the header
output = "Sensor, Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%]";
Serial.println(output);
}

// Function that is looped forever
void loop(void)
{
unsigned long time_trigger = millis();
if (iaqSensor1.run()) { // If new data is available
output = "1, " + String(time_trigger);
output += ", " + String(iaqSensor1.rawTemperature);
output += ", " + String(iaqSensor1.pressure);
output += ", " + String(iaqSensor1.rawHumidity);
output += ", " + String(iaqSensor1.gasResistance);
output += ", " + String(iaqSensor1.iaq);
output += ", " + String(iaqSensor1.iaqAccuracy);
output += ", " + String(iaqSensor1.temperature);
output += ", " + String(iaqSensor1.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}

time_trigger = millis();
if (iaqSensor2.run()) { // If new data is available
output = "2, " + String(time_trigger);
output += ", " + String(iaqSensor2.rawTemperature);
output += ", " + String(iaqSensor2.pressure);
output += ", " + String(iaqSensor2.rawHumidity);
output += ", " + String(iaqSensor2.gasResistance);
output += ", " + String(iaqSensor2.iaq);
output += ", " + String(iaqSensor2.iaqAccuracy);
output += ", " + String(iaqSensor2.temperature);
output += ", " + String(iaqSensor2.humidity);
Serial.println(output);
updateState();
} else {
checkIaqSensorStatus();
}
}

// Helper function definitions
void checkIaqSensorStatus(void)
{
if (iaqSensor1.status != BSEC_OK) {
if (iaqSensor1.status < BSEC_OK) {
output = "BSEC1 error code : " + String(iaqSensor1.status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor1.status);
Serial.println(output);
}
}

if (iaqSensor1.bme680Status != BME680_OK) {
if (iaqSensor1.bme680Status < BME680_OK) {
output = "BME6801 error code : " + String(iaqSensor1.bme680Status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor1.bme680Status);
Serial.println(output);
}
}
iaqSensor1.status = BSEC_OK;

if (iaqSensor2.status != BSEC_OK) {
if (iaqSensor2.status < BSEC_OK) {
output = "BSEC error code : " + String(iaqSensor2.status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BSEC warning code : " + String(iaqSensor2.status);
Serial.println(output);
}
}

if (iaqSensor2.bme680Status != BME680_OK) {
if (iaqSensor2.bme680Status < BME680_OK) {
output = "BME680 error code : " + String(iaqSensor2.bme680Status);
Serial.println(output);
for (;;)
errLeds(); /* Halt in case of failure */
} else {
output = "BME680 warning code : " + String(iaqSensor2.bme680Status);
Serial.println(output);
}
}
iaqSensor2.status = BSEC_OK;
}

void errLeds(void)
{
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, HIGH);
delay(100);
digitalWrite(LED_BUILTIN, LOW);
delay(100);
}

void loadState(void)
{
if (EEPROM.read(0) == BSEC_MAX_STATE_BLOB_SIZE) {
// Existing state in EEPROM
Serial.println("Reading state from EEPROM");

for (uint8_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE; i++) {
bsecState1[i] = EEPROM.read(i + 1);
bsecState2[i] = EEPROM.read(i + 1 + BSEC_MAX_STATE_BLOB_SIZE);
Serial.println(String(bsecState1[i], HEX) + ", " + String(bsecState2[i], HEX));
}

iaqSensor1.setState(bsecState1);
iaqSensor2.setState(bsecState2);
checkIaqSensorStatus();
} else {
// Erase the EEPROM with zeroes
Serial.println("Erasing EEPROM");

for (uint16_t i = 0; i < (N_SENSORS * BSEC_MAX_STATE_BLOB_SIZE) + 1; i++) {
EEPROM.write(i, 0);
}

EEPROM.commit();
}
}

void updateState(void)
{
bool update = false;
/* Set a trigger to save the state. Here, the state is saved every STATE_SAVE_PERIOD with the first state being saved once the algorithm achieves full calibration, i.e. iaqAccuracy = 3 */
if (stateUpdateCounter == 0) {
if ((iaqSensor1.iaqAccuracy >= 3) || (iaqSensor2.iaqAccuracy >= 3)) {
update = true;
stateUpdateCounter++;
}
} else {
/* Update every STATE_SAVE_PERIOD milliseconds */
if ((stateUpdateCounter * STATE_SAVE_PERIOD) < millis()) {
update = true;
stateUpdateCounter++;
}
}

if (update) {
iaqSensor1.getState(bsecState1);
iaqSensor2.getState(bsecState2);
checkIaqSensorStatus();

Serial.println("Writing state(s) to EEPROM");

for (uint16_t i = 0; i < BSEC_MAX_STATE_BLOB_SIZE ; i++) {
EEPROM.write(i + 1, bsecState1[i]);
EEPROM.write(i + 1 + BSEC_MAX_STATE_BLOB_SIZE, bsecState2[i]);
Serial.println(String(bsecState1[i], HEX) + ", " + String(bsecState2[i], HEX));
}

EEPROM.write(0, BSEC_MAX_STATE_BLOB_SIZE);
EEPROM.commit();
}
}
Loading

0 comments on commit c5503e0

Please sign in to comment.