/** Copyright (C) 2021 Bosch Sensortec GmbH SPDX-License-Identifier: BSD-3-Clause */ /* The new sensor needs to be conditioned before the example can work reliably. You may run this example for 24hrs to let the sensor stabilize. */ /** basic.ino sketch : This is an example for illustrating the BSEC virtual outputs using BME688 Development Kit, which has been designed to work with Adafruit ESP32 Feather Board For more information visit : https://www.bosch-sensortec.com/software-tools/software/bme688-software/ */ #include #include /* Macros used */ /* Number of sensors to operate*/ #define NUM_OF_SENS 8 #define PANIC_LED LED_BUILTIN #define ERROR_DUR 1000 #define SAMPLE_RATE BSEC_SAMPLE_RATE_ULP /* Helper functions declarations */ /** @brief : This function toggles the led when a fault was detected */ void errLeds(void); /** @brief : This function checks the BSEC status, prints the respective error code. Halts in case of error @param[in] bsec : Bsec2 class object */ void checkBsecStatus(Bsec2 bsec); /** @brief : This function is called by the BSEC library when a new output is available @param[in] input : BME68X sensor data before processing @param[in] outputs : Processed BSEC BSEC output data @param[in] bsec : Instance of BSEC2 calling the callback */ void newDataCallback(const bme68xData data, const bsecOutputs outputs, Bsec2 bsec); /* Create an array of objects of the class Bsec2 */ Bsec2 envSensor[NUM_OF_SENS]; comm_mux communicationSetup[NUM_OF_SENS]; uint8_t bsecMemBlock[NUM_OF_SENS][BSEC_INSTANCE_SIZE]; uint8_t sensor = 0; /* Entry point for the example */ void setup(void) { /* Desired subscription list of BSEC2 outputs */ bsecSensor sensorList[] = { 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 }; /* Initialize the communication interfaces */ Serial.begin(115200); comm_mux_begin(Wire, SPI); pinMode(PANIC_LED, OUTPUT); delay(100); /* Valid for boards with USB-COM. Wait until the port is open */ while (!Serial) delay(10); for (uint8_t i = 0; i < NUM_OF_SENS; i++) { /* Sets the Communication interface for the sensors */ communicationSetup[i] = comm_mux_set_config(Wire, SPI, i, communicationSetup[i]); /* Assigning a chunk of memory block to the bsecInstance */ envSensor[i].allocateMemory(bsecMemBlock[i]); /* Initialize the library and interfaces */ if (!envSensor[i].begin(BME68X_SPI_INTF, comm_mux_read, comm_mux_write, comm_mux_delay, &communicationSetup[i])) { checkBsecStatus (envSensor[i]); } /* * The default offset provided has been determined by testing the sensor in LP and ULP mode on application board 3.0 * Please update the offset value after testing this on your product */ if (SAMPLE_RATE == BSEC_SAMPLE_RATE_ULP) { envSensor[i].setTemperatureOffset(TEMP_OFFSET_ULP); } else if (SAMPLE_RATE == BSEC_SAMPLE_RATE_LP) { envSensor[i].setTemperatureOffset(TEMP_OFFSET_LP); } /* Subscribe to the desired BSEC2 outputs */ if (!envSensor[i].updateSubscription(sensorList, ARRAY_LEN(sensorList), SAMPLE_RATE)) { checkBsecStatus (envSensor[i]); } /* Whenever new data is available call the newDataCallback function */ envSensor[i].attachCallback(newDataCallback); } Serial.println("BSEC library version " + \ String(envSensor[0].version.major) + "." \ + String(envSensor[0].version.minor) + "." \ + String(envSensor[0].version.major_bugfix) + "." \ + String(envSensor[0].version.minor_bugfix)); } /* Function that is looped forever */ void loop(void) { /* Call the run function often so that the library can check if it is time to read new data from the sensor and process it. */ for (sensor = 0; sensor < NUM_OF_SENS; sensor++) { if (!envSensor[sensor].run()) { checkBsecStatus(envSensor[sensor]); } } } void errLeds(void) { while (1) { digitalWrite(PANIC_LED, HIGH); delay(ERROR_DUR); digitalWrite(PANIC_LED, LOW); delay(ERROR_DUR); } } void newDataCallback(const bme68xData data, const bsecOutputs outputs, Bsec2 bsec) { if (!outputs.nOutputs) { return; } Serial.println("BSEC outputs:\n\tSensor num = " + String(sensor)); Serial.println("\tTime stamp = " + String((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: Serial.println("\tIAQ = " + String(output.signal)); Serial.println("\tIAQ accuracy = " + String((int) output.accuracy)); break; case BSEC_OUTPUT_RAW_TEMPERATURE: Serial.println("\tTemperature = " + String(output.signal)); break; case BSEC_OUTPUT_RAW_PRESSURE: Serial.println("\tPressure = " + String(output.signal)); break; case BSEC_OUTPUT_RAW_HUMIDITY: Serial.println("\tHumidity = " + String(output.signal)); break; case BSEC_OUTPUT_RAW_GAS: Serial.println("\tGas resistance = " + String(output.signal)); break; case BSEC_OUTPUT_STABILIZATION_STATUS: Serial.println("\tStabilization status = " + String(output.signal)); break; case BSEC_OUTPUT_RUN_IN_STATUS: Serial.println("\tRun in status = " + String(output.signal)); break; case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE: Serial.println("\tCompensated temperature = " + String(output.signal)); break; case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY: Serial.println("\tCompensated humidity = " + String(output.signal)); break; case BSEC_OUTPUT_STATIC_IAQ: Serial.println("\tStatic IAQ = " + String(output.signal)); break; case BSEC_OUTPUT_CO2_EQUIVALENT: Serial.println("\tCO2 Equivalent = " + String(output.signal)); break; case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT: Serial.println("\tbVOC equivalent = " + String(output.signal)); break; case BSEC_OUTPUT_GAS_PERCENTAGE: Serial.println("\tGas percentage = " + String(output.signal)); break; case BSEC_OUTPUT_COMPENSATED_GAS: Serial.println("\tCompensated gas = " + String(output.signal)); break; default: break; } } } void checkBsecStatus(Bsec2 bsec) { if (bsec.status < BSEC_OK) { Serial.println("BSEC error code : " + String(bsec.status)); errLeds(); /* Halt in case of failure */ } else if (bsec.status > BSEC_OK) { Serial.println("BSEC warning code : " + String(bsec.status)); } if (bsec.sensor.status < BME68X_OK) { Serial.println("BME68X error code : " + String(bsec.sensor.status)); errLeds(); /* Halt in case of failure */ } else if (bsec.sensor.status > BME68X_OK) { Serial.println("BME68X warning code : " + String(bsec.sensor.status)); } }