diff --git a/include/bme680mems.h b/include/bme680mems.h index 4828a063..70dd8fec 100644 --- a/include/bme680mems.h +++ b/include/bme680mems.h @@ -5,6 +5,8 @@ #include #include "bsec_integration.h" +extern const uint8_t bsec_config_iaq[454]; + extern bmeStatus_t bme_status; // Make struct for storing gps data globally available extern TaskHandle_t BmeTask; diff --git a/include/payload.h b/include/payload.h index 91bf3778..f5872881 100644 --- a/include/payload.h +++ b/include/payload.h @@ -15,7 +15,7 @@ #define LPP_MSG_CHANNEL 28 #define LPP_HUMIDITY_CHANNEL 29 #define LPP_BAROMETER_CHANNEL 30 -#define LPP_GAS_CHANNEL 31 +#define LPP_AIR_CHANNEL 31 #endif @@ -66,8 +66,9 @@ private: void writeUint32(uint32_t i); void writeUint16(uint16_t i); void writeUint8(uint8_t i); - void writeHumidity(float humidity); - void writeTemperature(float temperature); + void writeFloat(float value); + void writeUFloat(float value); + void writePressure(float value); void writeVersion(char * version); void writeBitmap(bool a, bool b, bool c, bool d, bool e, bool f, bool g, bool h); diff --git a/lib/Bosch-BSEC/config/generic_33v_3s_4d/bsec_serialized_configurations_iaq.c b/lib/Bosch-BSEC/config/generic_33v_3s_4d/bsec_serialized_configurations_iaq.c index bce43cc3..b6007c1a 100644 --- a/lib/Bosch-BSEC/config/generic_33v_3s_4d/bsec_serialized_configurations_iaq.c +++ b/lib/Bosch-BSEC/config/generic_33v_3s_4d/bsec_serialized_configurations_iaq.c @@ -1,5 +1,5 @@ #include "bsec_serialized_configurations_iaq.h" + const uint8_t bsec_config_iaq[454] = {1,7,4,1,61,0,0,0,0,0,0,0,174,1,0,0,48,0,1,0,137,65,0,63,205,204,204,62,0,0,64,63,205,204,204,62,0,0,225,68,0,192,168,71,64,49,119,76,0,0,0,0,0,80,5,95,0,0,0,0,0,0,0,0,28,0,2,0,0,244,1,225,0,25,0,0,128,64,0,0,32,65,144,1,0,0,112,65,0,0,0,63,16,0,3,0,10,215,163,60,10,215,35,59,10,215,35,59,9,0,5,0,0,0,0,0,1,88,0,9,0,229,208,34,62,0,0,0,0,0,0,0,0,218,27,156,62,225,11,67,64,0,0,160,64,0,0,0,0,0,0,0,0,94,75,72,189,93,254,159,64,66,62,160,191,0,0,0,0,0,0,0,0,33,31,180,190,138,176,97,64,65,241,99,190,0,0,0,0,0,0,0,0,167,121,71,61,165,189,41,192,184,30,189,64,12,0,10,0,0,0,0,0,0,0,0,0,229,0,254,0,2,1,5,48,117,100,0,44,1,112,23,151,7,132,3,197,0,92,4,144,1,64,1,64,1,144,1,48,117,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,48,117,48,117,100,0,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,100,0,100,0,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,255,255,255,255,255,255,255,255,220,5,220,5,220,5,255,255,255,255,255,255,220,5,220,5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,44,1,0,0,0,0,239,79,0,0}; - diff --git a/lib/Bosch-BSEC/docs/BSEC_Binary_Size_Information.pdf b/lib/Bosch-BSEC/docs/BSEC_Binary_Size_Information.pdf deleted file mode 100644 index f6a62ed5..00000000 Binary files a/lib/Bosch-BSEC/docs/BSEC_Binary_Size_Information.pdf and /dev/null differ diff --git a/lib/Bosch-BSEC/examples/bsec_integration.c b/lib/Bosch-BSEC/examples/bsec_integration.c deleted file mode 100644 index 0dc5dc2d..00000000 --- a/lib/Bosch-BSEC/examples/bsec_integration.c +++ /dev/null @@ -1,559 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_integration.c - * - * @brief - * Private part of the example for using of BSEC library. - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ - -#include -#include -#include - -#include "bsec_integration.h" - -/**********************************************************************************************************************/ -/* local macro definitions */ -/**********************************************************************************************************************/ - -#define NUM_USED_OUTPUTS 8 - -/**********************************************************************************************************************/ -/* global variable declarations */ -/**********************************************************************************************************************/ - -/* Global sensor APIs data structure */ -static struct bme680_dev bme680_g; - -/* Global temperature offset to be subtracted */ -static float bme680_temperature_offset_g = 0.0f; - -/**********************************************************************************************************************/ -/* functions */ -/**********************************************************************************************************************/ - -/*! - * @brief Virtual sensor subscription - * Please call this function before processing of data using bsec_do_steps function - * - * @param[in] sample_rate mode to be used (either BSEC_SAMPLE_RATE_ULP or BSEC_SAMPLE_RATE_LP) - * - * @return subscription result, zero when successful - */ -static bsec_library_return_t bme680_bsec_update_subscription(float sample_rate) -{ - bsec_sensor_configuration_t requested_virtual_sensors[NUM_USED_OUTPUTS]; - uint8_t n_requested_virtual_sensors = NUM_USED_OUTPUTS; - - bsec_sensor_configuration_t required_sensor_settings[BSEC_MAX_PHYSICAL_SENSOR]; - uint8_t n_required_sensor_settings = BSEC_MAX_PHYSICAL_SENSOR; - - bsec_library_return_t status = BSEC_OK; - - /* note: Virtual sensors as desired to be added here */ - requested_virtual_sensors[0].sensor_id = BSEC_OUTPUT_IAQ; - requested_virtual_sensors[0].sample_rate = sample_rate; - requested_virtual_sensors[1].sensor_id = BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE; - requested_virtual_sensors[1].sample_rate = sample_rate; - requested_virtual_sensors[2].sensor_id = BSEC_OUTPUT_RAW_PRESSURE; - requested_virtual_sensors[2].sample_rate = sample_rate; - requested_virtual_sensors[3].sensor_id = BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY; - requested_virtual_sensors[3].sample_rate = sample_rate; - requested_virtual_sensors[4].sensor_id = BSEC_OUTPUT_RAW_GAS; - requested_virtual_sensors[4].sample_rate = sample_rate; - requested_virtual_sensors[5].sensor_id = BSEC_OUTPUT_RAW_TEMPERATURE; - requested_virtual_sensors[5].sample_rate = sample_rate; - requested_virtual_sensors[6].sensor_id = BSEC_OUTPUT_RAW_HUMIDITY; - requested_virtual_sensors[6].sample_rate = sample_rate; - requested_virtual_sensors[7].sensor_id = BSEC_OUTPUT_STATIC_IAQ; - requested_virtual_sensors[7].sample_rate = sample_rate; - - /* Call bsec_update_subscription() to enable/disable the requested virtual sensors */ - status = bsec_update_subscription(requested_virtual_sensors, n_requested_virtual_sensors, required_sensor_settings, - &n_required_sensor_settings); - - return status; -} - -/*! - * @brief Initialize the BME680 sensor and the BSEC library - * - * @param[in] sample_rate mode to be used (either BSEC_SAMPLE_RATE_ULP or BSEC_SAMPLE_RATE_LP) - * @param[in] temperature_offset device-specific temperature offset (due to self-heating) - * @param[in] bus_write pointer to the bus writing function - * @param[in] bus_read pointer to the bus reading function - * @param[in] sleep pointer to the system specific sleep function - * @param[in] state_load pointer to the system-specific state load function - * @param[in] config_load pointer to the system-specific config load function - * - * @return zero if successful, negative otherwise - */ -return_values_init bsec_iot_init(float sample_rate, float temperature_offset, bme680_com_fptr_t bus_write, - bme680_com_fptr_t bus_read, sleep_fct sleep, state_load_fct state_load, config_load_fct config_load) -{ - return_values_init ret = {BME680_OK, BSEC_OK}; - bsec_library_return_t bsec_status = BSEC_OK; - - uint8_t bsec_state[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0}; - uint8_t bsec_config[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0}; - uint8_t work_buffer[BSEC_MAX_PROPERTY_BLOB_SIZE] = {0}; - int bsec_state_len, bsec_config_len; - - /* Fixed I2C configuration */ - bme680_g.dev_id = BME680_I2C_ADDR_PRIMARY; - bme680_g.intf = BME680_I2C_INTF; - /* User configurable I2C configuration */ - bme680_g.write = bus_write; - bme680_g.read = bus_read; - bme680_g.delay_ms = sleep; - - /* Initialize BME680 API */ - ret.bme680_status = bme680_init(&bme680_g); - if (ret.bme680_status != BME680_OK) - { - return ret; - } - - /* Initialize BSEC library */ - ret.bsec_status = bsec_init(); - if (ret.bsec_status != BSEC_OK) - { - return ret; - } - - /* Load library config, if available */ - bsec_config_len = config_load(bsec_config, sizeof(bsec_config)); - if (bsec_config_len != 0) - { - ret.bsec_status = bsec_set_configuration(bsec_config, bsec_config_len, work_buffer, sizeof(work_buffer)); - if (ret.bsec_status != BSEC_OK) - { - return ret; - } - } - - /* Load previous library state, if available */ - bsec_state_len = state_load(bsec_state, sizeof(bsec_state)); - if (bsec_state_len != 0) - { - ret.bsec_status = bsec_set_state(bsec_state, bsec_state_len, work_buffer, sizeof(work_buffer)); - if (ret.bsec_status != BSEC_OK) - { - return ret; - } - } - - /* Set temperature offset */ - bme680_temperature_offset_g = temperature_offset; - - /* Call to the function which sets the library with subscription information */ - ret.bsec_status = bme680_bsec_update_subscription(sample_rate); - if (ret.bsec_status != BSEC_OK) - { - return ret; - } - - return ret; -} - -/*! - * @brief Trigger the measurement based on sensor settings - * - * @param[in] sensor_settings settings of the BME680 sensor adopted by sensor control function - * @param[in] sleep pointer to the system specific sleep function - * - * @return none - */ -static void bme680_bsec_trigger_measurement(bsec_bme_settings_t *sensor_settings, sleep_fct sleep) -{ - uint16_t meas_period; - uint8_t set_required_settings; - int8_t bme680_status = BME680_OK; - - /* Check if a forced-mode measurement should be triggered now */ - if (sensor_settings->trigger_measurement) - { - /* Set sensor configuration */ - - bme680_g.tph_sett.os_hum = sensor_settings->humidity_oversampling; - bme680_g.tph_sett.os_pres = sensor_settings->pressure_oversampling; - bme680_g.tph_sett.os_temp = sensor_settings->temperature_oversampling; - bme680_g.gas_sett.run_gas = sensor_settings->run_gas; - bme680_g.gas_sett.heatr_temp = sensor_settings->heater_temperature; /* degree Celsius */ - bme680_g.gas_sett.heatr_dur = sensor_settings->heating_duration; /* milliseconds */ - - /* Select the power mode */ - /* Must be set before writing the sensor configuration */ - bme680_g.power_mode = BME680_FORCED_MODE; - /* Set the required sensor settings needed */ - set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_GAS_SENSOR_SEL; - - /* Set the desired sensor configuration */ - bme680_status = bme680_set_sensor_settings(set_required_settings, &bme680_g); - - /* Set power mode as forced mode and trigger forced mode measurement */ - bme680_status = bme680_set_sensor_mode(&bme680_g); - - /* Get the total measurement duration so as to sleep or wait till the measurement is complete */ - bme680_get_profile_dur(&meas_period, &bme680_g); - - /* Delay till the measurement is ready. Timestamp resolution in ms */ - sleep((uint32_t)meas_period); - } - - /* Call the API to get current operation mode of the sensor */ - bme680_status = bme680_get_sensor_mode(&bme680_g); - /* When the measurement is completed and data is ready for reading, the sensor must be in BME680_SLEEP_MODE. - * Read operation mode to check whether measurement is completely done and wait until the sensor is no more - * in BME680_FORCED_MODE. */ - while (bme680_g.power_mode == BME680_FORCED_MODE) - { - /* sleep for 5 ms */ - sleep(5); - bme680_status = bme680_get_sensor_mode(&bme680_g); - } -} - -/*! - * @brief Read the data from registers and populate the inputs structure to be passed to do_steps function - * - * @param[in] time_stamp_trigger settings of the sensor returned from sensor control function - * @param[in] inputs input structure containing the information on sensors to be passed to do_steps - * @param[in] num_bsec_inputs number of inputs to be passed to do_steps - * @param[in] bsec_process_data process data variable returned from sensor_control - * - * @return none - */ -static void bme680_bsec_read_data(int64_t time_stamp_trigger, bsec_input_t *inputs, uint8_t *num_bsec_inputs, - int32_t bsec_process_data) -{ - static struct bme680_field_data data; - int8_t bme680_status = BME680_OK; - - /* We only have to read data if the previous call the bsec_sensor_control() actually asked for it */ - if (bsec_process_data) - { - bme680_status = bme680_get_sensor_data(&data, &bme680_g); - - if (data.status & BME680_NEW_DATA_MSK) - { - /* Pressure to be processed by BSEC */ - if (bsec_process_data & BSEC_PROCESS_PRESSURE) - { - /* Place presssure sample into input struct */ - inputs[*num_bsec_inputs].sensor_id = BSEC_INPUT_PRESSURE; - inputs[*num_bsec_inputs].signal = data.pressure; - inputs[*num_bsec_inputs].time_stamp = time_stamp_trigger; - (*num_bsec_inputs)++; - } - /* Temperature to be processed by BSEC */ - if (bsec_process_data & BSEC_PROCESS_TEMPERATURE) - { - /* Place temperature sample into input struct */ - inputs[*num_bsec_inputs].sensor_id = BSEC_INPUT_TEMPERATURE; - #ifdef BME680_FLOAT_POINT_COMPENSATION - inputs[*num_bsec_inputs].signal = data.temperature; - #else - inputs[*num_bsec_inputs].signal = data.temperature / 100.0f; - #endif - inputs[*num_bsec_inputs].time_stamp = time_stamp_trigger; - (*num_bsec_inputs)++; - - /* Also add optional heatsource input which will be subtracted from the temperature reading to - * compensate for device-specific self-heating (supported in BSEC IAQ solution)*/ - inputs[*num_bsec_inputs].sensor_id = BSEC_INPUT_HEATSOURCE; - inputs[*num_bsec_inputs].signal = bme680_temperature_offset_g; - inputs[*num_bsec_inputs].time_stamp = time_stamp_trigger; - (*num_bsec_inputs)++; - } - /* Humidity to be processed by BSEC */ - if (bsec_process_data & BSEC_PROCESS_HUMIDITY) - { - /* Place humidity sample into input struct */ - inputs[*num_bsec_inputs].sensor_id = BSEC_INPUT_HUMIDITY; - #ifdef BME680_FLOAT_POINT_COMPENSATION - inputs[*num_bsec_inputs].signal = data.humidity; - #else - inputs[*num_bsec_inputs].signal = data.humidity / 1000.0f; - #endif - inputs[*num_bsec_inputs].time_stamp = time_stamp_trigger; - (*num_bsec_inputs)++; - } - /* Gas to be processed by BSEC */ - if (bsec_process_data & BSEC_PROCESS_GAS) - { - /* Check whether gas_valid flag is set */ - if(data.status & BME680_GASM_VALID_MSK) - { - /* Place sample into input struct */ - inputs[*num_bsec_inputs].sensor_id = BSEC_INPUT_GASRESISTOR; - inputs[*num_bsec_inputs].signal = data.gas_resistance; - inputs[*num_bsec_inputs].time_stamp = time_stamp_trigger; - (*num_bsec_inputs)++; - } - } - } - } -} - -/*! - * @brief This function is written to process the sensor data for the requested virtual sensors - * - * @param[in] bsec_inputs input structure containing the information on sensors to be passed to do_steps - * @param[in] num_bsec_inputs number of inputs to be passed to do_steps - * @param[in] output_ready pointer to the function processing obtained BSEC outputs - * - * @return none - */ -static void bme680_bsec_process_data(bsec_input_t *bsec_inputs, uint8_t num_bsec_inputs, output_ready_fct output_ready) -{ - /* Output buffer set to the maximum virtual sensor outputs supported */ - bsec_output_t bsec_outputs[BSEC_NUMBER_OUTPUTS]; - uint8_t num_bsec_outputs = 0; - uint8_t index = 0; - - bsec_library_return_t bsec_status = BSEC_OK; - - int64_t timestamp = 0; - float iaq = 0.0f; - uint8_t iaq_accuracy = 0; - float temp = 0.0f; - float raw_temp = 0.0f; - float raw_pressure = 0.0f; - float humidity = 0.0f; - float raw_humidity = 0.0f; - float raw_gas = 0.0f; - float static_iaq = 0.0f; - uint8_t static_iaq_accuracy = 0; - float co2_equivalent = 0.0f; - uint8_t co2_accuracy = 0; - float breath_voc_equivalent = 0.0f; - uint8_t breath_voc_accuracy = 0; - float comp_gas_value = 0.0f; - uint8_t comp_gas_accuracy = 0; - float gas_percentage = 0.0f; - uint8_t gas_percentage_acccuracy = 0; - - /* Check if something should be processed by BSEC */ - if (num_bsec_inputs > 0) - { - /* Set number of outputs to the size of the allocated buffer */ - /* BSEC_NUMBER_OUTPUTS to be defined */ - num_bsec_outputs = BSEC_NUMBER_OUTPUTS; - - /* Perform processing of the data by BSEC - Note: - * The number of outputs you get depends on what you asked for during bsec_update_subscription(). This is - handled under bme680_bsec_update_subscription() function in this example file. - * The number of actual outputs that are returned is written to num_bsec_outputs. */ - bsec_status = bsec_do_steps(bsec_inputs, num_bsec_inputs, bsec_outputs, &num_bsec_outputs); - - /* Iterate through the outputs and extract the relevant ones. */ - for (index = 0; index < num_bsec_outputs; index++) - { - switch (bsec_outputs[index].sensor_id) - { - case BSEC_OUTPUT_IAQ: - iaq = bsec_outputs[index].signal; - iaq_accuracy = bsec_outputs[index].accuracy; - break; - case BSEC_OUTPUT_STATIC_IAQ: - static_iaq = bsec_outputs[index].signal; - static_iaq_accuracy = bsec_outputs[index].accuracy; - break; - case BSEC_OUTPUT_CO2_EQUIVALENT: - co2_equivalent = bsec_outputs[index].signal; - co2_accuracy = bsec_outputs[index].accuracy; - break; - case BSEC_OUTPUT_BREATH_VOC_EQUIVALENT: - breath_voc_equivalent = bsec_outputs[index].signal; - breath_voc_accuracy = bsec_outputs[index].accuracy; - break; - case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE: - temp = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_RAW_PRESSURE: - raw_pressure = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY: - humidity = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_RAW_GAS: - raw_gas = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_RAW_TEMPERATURE: - raw_temp = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_RAW_HUMIDITY: - raw_humidity = bsec_outputs[index].signal; - break; - case BSEC_OUTPUT_COMPENSATED_GAS: - comp_gas_value = bsec_outputs[index].signal; - comp_gas_accuracy = bsec_outputs[index].accuracy; - break; - case BSEC_OUTPUT_GAS_PERCENTAGE: - gas_percentage = bsec_outputs[index].signal; - gas_percentage_acccuracy = bsec_outputs[index].accuracy; - break; - default: - continue; - } - - /* Assume that all the returned timestamps are the same */ - timestamp = bsec_outputs[index].time_stamp; - } - - /* Pass the extracted outputs to the user provided output_ready() function. */ - output_ready(timestamp, iaq, iaq_accuracy, temp, humidity, raw_pressure, raw_temp, - raw_humidity, raw_gas, bsec_status, static_iaq, co2_equivalent, breath_voc_equivalent); - } -} - -/*! - * @brief Runs the main (endless) loop that queries sensor settings, applies them, and processes the measured data - * - * @param[in] sleep pointer to the system specific sleep function - * @param[in] get_timestamp_us pointer to the system specific timestamp derivation function - * @param[in] output_ready pointer to the function processing obtained BSEC outputs - * @param[in] state_save pointer to the system-specific state save function - * @param[in] save_intvl interval at which BSEC state should be saved (in samples) - * - * @return none - */ -void bsec_iot_loop(sleep_fct sleep, get_timestamp_us_fct get_timestamp_us, output_ready_fct output_ready, - state_save_fct state_save, uint32_t save_intvl) -{ - /* Timestamp variables */ - int64_t time_stamp = 0; - int64_t time_stamp_interval_ms = 0; - - /* Allocate enough memory for up to BSEC_MAX_PHYSICAL_SENSOR physical inputs*/ - bsec_input_t bsec_inputs[BSEC_MAX_PHYSICAL_SENSOR]; - - /* Number of inputs to BSEC */ - uint8_t num_bsec_inputs = 0; - - /* BSEC sensor settings struct */ - bsec_bme_settings_t sensor_settings; - - /* Save state variables */ - uint8_t bsec_state[BSEC_MAX_STATE_BLOB_SIZE]; - uint8_t work_buffer[BSEC_MAX_STATE_BLOB_SIZE]; - uint32_t bsec_state_len = 0; - uint32_t n_samples = 0; - - bsec_library_return_t bsec_status = BSEC_OK; - - while (1) - { - /* get the timestamp in nanoseconds before calling bsec_sensor_control() */ - time_stamp = get_timestamp_us() * 1000; - - /* Retrieve sensor settings to be used in this time instant by calling bsec_sensor_control */ - bsec_sensor_control(time_stamp, &sensor_settings); - - /* Trigger a measurement if necessary */ - bme680_bsec_trigger_measurement(&sensor_settings, sleep); - - /* Read data from last measurement */ - num_bsec_inputs = 0; - bme680_bsec_read_data(time_stamp, bsec_inputs, &num_bsec_inputs, sensor_settings.process_data); - - /* Time to invoke BSEC to perform the actual processing */ - bme680_bsec_process_data(bsec_inputs, num_bsec_inputs, output_ready); - - /* Increment sample counter */ - n_samples++; - - /* Retrieve and store state if the passed save_intvl */ - if (n_samples >= save_intvl) - { - bsec_status = bsec_get_state(0, bsec_state, sizeof(bsec_state), work_buffer, sizeof(work_buffer), &bsec_state_len); - if (bsec_status == BSEC_OK) - { - state_save(bsec_state, bsec_state_len); - } - n_samples = 0; - } - - - /* Compute how long we can sleep until we need to call bsec_sensor_control() next */ - /* Time_stamp is converted from microseconds to nanoseconds first and then the difference to milliseconds */ - time_stamp_interval_ms = (sensor_settings.next_call - get_timestamp_us() * 1000) / 1000000; - if (time_stamp_interval_ms > 0) - { - sleep((uint32_t)time_stamp_interval_ms); - } - } -} - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/examples/bsec_integration.h b/lib/Bosch-BSEC/examples/bsec_integration.h deleted file mode 100644 index 5155a001..00000000 --- a/lib/Bosch-BSEC/examples/bsec_integration.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_integration.h - * - * @brief - * Contains BSEC integration API - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -#ifndef __BSEC_INTEGRATION_H__ -#define __BSEC_INTEGRATION_H__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ - -/* Use the following bme680 driver: https://github.com/BoschSensortec/BME680_driver/releases/tag/bme680_v3.5.1 */ -#include "bme680.h" -/* BSEC header files are available in the inc/ folder of the release package */ -#include "bsec_interface.h" -#include "bsec_datatypes.h" - - -/**********************************************************************************************************************/ -/* type definitions */ -/**********************************************************************************************************************/ - -/* function pointer to the system specific sleep function */ -typedef void (*sleep_fct)(uint32_t t_ms); - -/* function pointer to the system specific timestamp derivation function */ -typedef int64_t (*get_timestamp_us_fct)(); - -/* function pointer to the function processing obtained BSEC outputs */ -typedef void (*output_ready_fct)(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, - float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, - float static_iaq, float co2_equivalent, float breath_voc_equivalent); - -/* function pointer to the function loading a previous BSEC state from NVM */ -typedef uint32_t (*state_load_fct)(uint8_t *state_buffer, uint32_t n_buffer); - -/* function pointer to the function saving BSEC state to NVM */ -typedef void (*state_save_fct)(const uint8_t *state_buffer, uint32_t length); - -/* function pointer to the function loading the BSEC configuration string from NVM */ -typedef uint32_t (*config_load_fct)(uint8_t *state_buffer, uint32_t n_buffer); - -/* structure definitions */ - -/* Structure with the return value from bsec_iot_init() */ -typedef struct{ - /*! Result of API execution status */ - int8_t bme680_status; - /*! Result of BSEC library */ - bsec_library_return_t bsec_status; -}return_values_init; -/**********************************************************************************************************************/ -/* function declarations */ -/**********************************************************************************************************************/ - -/*! - * @brief Initialize the BME680 sensor and the BSEC library - * - * @param[in] sample_rate mode to be used (either BSEC_SAMPLE_RATE_ULP or BSEC_SAMPLE_RATE_LP) - * @param[in] temperature_offset device-specific temperature offset (due to self-heating) - * @param[in] bus_write pointer to the bus writing function - * @param[in] bus_read pointer to the bus reading function - * @param[in] sleep pointer to the system-specific sleep function - * @param[in] state_load pointer to the system-specific state load function - * - * @return zero if successful, negative otherwise - */ -return_values_init bsec_iot_init(float sample_rate, float temperature_offset, bme680_com_fptr_t bus_write, bme680_com_fptr_t bus_read, - sleep_fct sleep, state_load_fct state_load, config_load_fct config_load); - -/*! - * @brief Runs the main (endless) loop that queries sensor settings, applies them, and processes the measured data - * - * @param[in] sleep pointer to the system-specific sleep function - * @param[in] get_timestamp_us pointer to the system-specific timestamp derivation function - * @param[in] output_ready pointer to the function processing obtained BSEC outputs - * @param[in] state_save pointer to the system-specific state save function - * @param[in] save_intvl interval at which BSEC state should be saved (in samples) - * - * @return return_values_init struct with the result of the API and the BSEC library - */ -void bsec_iot_loop(sleep_fct sleep, get_timestamp_us_fct get_timestamp_us, output_ready_fct output_ready, - state_save_fct state_save, uint32_t save_intvl); - -#ifdef __cplusplus -} -#endif - -#endif /* __BSEC_INTEGRATION_H__ */ - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/examples/bsec_iot_example.c b/lib/Bosch-BSEC/examples/bsec_iot_example.c deleted file mode 100644 index b62487b7..00000000 --- a/lib/Bosch-BSEC/examples/bsec_iot_example.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_iot_example.c - * - * @brief - * Example for using of BSEC library in a fixed configuration with the BME680 sensor. - * This works by running an endless loop in the bsec_iot_loop() function. - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ - -#include "bsec_integration.h" - -/**********************************************************************************************************************/ -/* functions */ -/**********************************************************************************************************************/ - -/*! - * @brief Write operation in either I2C or SPI - * - * param[in] dev_addr I2C or SPI device address - * param[in] reg_addr register address - * param[in] reg_data_ptr pointer to the data to be written - * param[in] data_len number of bytes to be written - * - * @return result of the bus communication function - */ -int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - // ... - // Please insert system specific function to write to the bus where BME680 is connected - // ... - return 0; -} - -/*! - * @brief Read operation in either I2C or SPI - * - * param[in] dev_addr I2C or SPI device address - * param[in] reg_addr register address - * param[out] reg_data_ptr pointer to the memory to be used to store the read data - * param[in] data_len number of bytes to be read - * - * @return result of the bus communication function - */ -int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - // ... - // Please insert system specific function to read from bus where BME680 is connected - // ... - return 0; -} - -/*! - * @brief System specific implementation of sleep function - * - * @param[in] t_ms time in milliseconds - * - * @return none - */ -void sleep(uint32_t t_ms) -{ - // ... - // Please insert system specific function sleep or delay for t_ms milliseconds - // ... -} - -/*! - * @brief Capture the system time in microseconds - * - * @return system_current_time current system timestamp in microseconds - */ -int64_t get_timestamp_us() -{ - int64_t system_current_time = 0; - // ... - // Please insert system specific function to retrieve a timestamp (in microseconds) - // ... - return system_current_time; -} - -/*! - * @brief Handling of the ready outputs - * - * @param[in] timestamp time in nanoseconds - * @param[in] iaq IAQ signal - * @param[in] iaq_accuracy accuracy of IAQ signal - * @param[in] temperature temperature signal - * @param[in] humidity humidity signal - * @param[in] pressure pressure signal - * @param[in] raw_temperature raw temperature signal - * @param[in] raw_humidity raw humidity signal - * @param[in] gas raw gas sensor signal - * @param[in] bsec_status value returned by the bsec_do_steps() call - * - * @return none - */ -void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, - float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, - float static_iaq, float co2_equivalent, float breath_voc_equivalent) -{ - // ... - // Please insert system specific code to further process or display the BSEC outputs - // ... -} - -/*! - * @brief Load previous library state from non-volatile memory - * - * @param[in,out] state_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to state_buffer - */ -uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer) -{ - // ... - // Load a previous library state from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no state was available, - // otherwise return length of loaded state string. - // ... - return 0; -} - -/*! - * @brief Save library state to non-volatile memory - * - * @param[in] state_buffer buffer holding the state to be stored - * @param[in] length length of the state string to be stored - * - * @return none - */ -void state_save(const uint8_t *state_buffer, uint32_t length) -{ - // ... - // Save the string some form of non-volatile memory, if possible. - // ... -} - -/*! - * @brief Load library config from non-volatile memory - * - * @param[in,out] config_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to config_buffer - */ -uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) -{ - // ... - // Load a library config from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no config was available, - // otherwise return length of loaded config string. - // ... - return 0; -} - -/*! - * @brief Main function which configures BSEC library and then reads and processes the data from sensor based - * on timer ticks - * - * @return result of the processing - */ -int main() -{ - return_values_init ret; - - /* Call to the function which initializes the BSEC library - * Switch on low-power mode and provide no temperature offset */ - ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 0.0f, bus_write, bus_read, sleep, state_load, config_load); - if (ret.bme680_status) - { - /* Could not intialize BME680 */ - return (int)ret.bme680_status; - } - else if (ret.bsec_status) - { - /* Could not intialize BSEC library */ - return (int)ret.bsec_status; - } - - /* Call to endless loop function which reads and processes data based on sensor settings */ - /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes */ - bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000); - - return 0; -} - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/examples/bsec_iot_example.ino b/lib/Bosch-BSEC/examples/bsec_iot_example.ino deleted file mode 100644 index 705f8f6c..00000000 --- a/lib/Bosch-BSEC/examples/bsec_iot_example.ino +++ /dev/null @@ -1,291 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_iot_example.ino - * - * @brief - * Example for using of BSEC library in a fixed configuration with the BME680 sensor. - * This works by running an endless loop in the bsec_iot_loop() function. - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ - -#include "bsec_integration.h" -#include - -/**********************************************************************************************************************/ -/* functions */ -/**********************************************************************************************************************/ - -/*! - * @brief Write operation in either Wire or SPI - * - * param[in] dev_addr Wire or SPI device address - * param[in] reg_addr register address - * param[in] reg_data_ptr pointer to the data to be written - * param[in] data_len number of bytes to be written - * - * @return result of the bus communication function - */ -int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - Wire.beginTransmission(dev_addr); - Wire.write(reg_addr); /* Set register address to start writing to */ - - /* Write the data */ - for (int index = 0; index < data_len; index++) { - Wire.write(reg_data_ptr[index]); - } - - return (int8_t)Wire.endTransmission(); -} - -/*! - * @brief Read operation in either Wire or SPI - * - * param[in] dev_addr Wire or SPI device address - * param[in] reg_addr register address - * param[out] reg_data_ptr pointer to the memory to be used to store the read data - * param[in] data_len number of bytes to be read - * - * @return result of the bus communication function - */ -int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - int8_t comResult = 0; - Wire.beginTransmission(dev_addr); - Wire.write(reg_addr); /* Set register address to start reading from */ - comResult = Wire.endTransmission(); - - delayMicroseconds(150); /* Precautionary response delay */ - Wire.requestFrom(dev_addr, (uint8_t)data_len); /* Request data */ - - int index = 0; - while (Wire.available()) /* The slave device may send less than requested (burst read) */ - { - reg_data_ptr[index] = Wire.read(); - index++; - } - - return comResult; -} - -/*! - * @brief System specific implementation of sleep function - * - * @param[in] t_ms time in milliseconds - * - * @return none - */ -void sleep(uint32_t t_ms) -{ - delay(t_ms); -} - -/*! - * @brief Capture the system time in microseconds - * - * @return system_current_time current system timestamp in microseconds - */ -int64_t get_timestamp_us() -{ - return (int64_t) millis() * 1000; -} - -/*! - * @brief Handling of the ready outputs - * - * @param[in] timestamp time in nanoseconds - * @param[in] iaq IAQ signal - * @param[in] iaq_accuracy accuracy of IAQ signal - * @param[in] temperature temperature signal - * @param[in] humidity humidity signal - * @param[in] pressure pressure signal - * @param[in] raw_temperature raw temperature signal - * @param[in] raw_humidity raw humidity signal - * @param[in] gas raw gas sensor signal - * @param[in] bsec_status value returned by the bsec_do_steps() call - * - * @return none - */ -void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, - float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, - float static_iaq, float co2_equivalent, float breath_voc_equivalent) -{ - Serial.print("["); - Serial.print(timestamp/1e6); - Serial.print("] T: "); - Serial.print(temperature); - Serial.print("| rH: "); - Serial.print(humidity); - Serial.print("| IAQ: "); - Serial.print(iaq); - Serial.print(" ("); - Serial.print(iaq_accuracy); - Serial.print("| Static IAQ: "); - Serial.print(static_iaq); - Serial.print("| CO2e: "); - Serial.print(co2_equivalent); - Serial.print("| bVOC: "); - Serial.println(breath_voc_equivalent); -} - -/*! - * @brief Load previous library state from non-volatile memory - * - * @param[in,out] state_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to state_buffer - */ -uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer) -{ - // ... - // Load a previous library state from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no state was available, - // otherwise return length of loaded state string. - // ... - return 0; -} - -/*! - * @brief Save library state to non-volatile memory - * - * @param[in] state_buffer buffer holding the state to be stored - * @param[in] length length of the state string to be stored - * - * @return none - */ -void state_save(const uint8_t *state_buffer, uint32_t length) -{ - // ... - // Save the string some form of non-volatile memory, if possible. - // ... -} - -/*! - * @brief Load library config from non-volatile memory - * - * @param[in,out] config_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to config_buffer - */ -uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) -{ - // ... - // Load a library config from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no config was available, - // otherwise return length of loaded config string. - // ... - return 0; -} - -/*! - * @brief Main function which configures BSEC library and then reads and processes the data from sensor based - * on timer ticks - * - * @return result of the processing - */ -void setup() -{ - return_values_init ret; - - /* Init I2C and serial communication */ - Wire.begin(); - Serial.begin(115200); - - /* Call to the function which initializes the BSEC library - * Switch on low-power mode and provide no temperature offset */ - ret = bsec_iot_init(BSEC_SAMPLE_RATE_LP, 5.0f, bus_write, bus_read, sleep, state_load, config_load); - if (ret.bme680_status) - { - /* Could not intialize BME680 */ - Serial.println("Error while initializing BME680"); - return; - } - else if (ret.bsec_status) - { - /* Could not intialize BSEC library */ - Serial.println("Error while initializing BSEC library"); - return; - } - - /* Call to endless loop function which reads and processes data based on sensor settings */ - /* State is saved every 10.000 samples, which means every 10.000 * 3 secs = 500 minutes */ - bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 10000); -} - -void loop() -{ -} - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.c b/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.c deleted file mode 100644 index 74507ad3..00000000 --- a/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.c +++ /dev/null @@ -1,290 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_iot_ulp_plus_example.c - * - * @brief - * Example for using of BSEC library in a fixed configuration with the BME680 sensor. - * This works by running an endless loop in the bsec_iot_loop() function. - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ -/* BSEC configuration files are available in the config/ folder of the release package. Please chose a configuration file with 3s maximum time between `bsec_sensor_control()` calls */ -#include "bsec_integration.h" - -/**********************************************************************************************************************/ -/* functions */ -/**********************************************************************************************************************/ - -/*! - * @brief Write operation in either I2C or SPI - * - * param[in] dev_addr I2C or SPI device address - * param[in] reg_addr register address - * param[in] reg_data_ptr pointer to the data to be written - * param[in] data_len number of bytes to be written - * - * @return result of the bus communication function - */ -int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - // ... - // Please insert system specific function to write to the bus where BME680 is connected - // ... - return 0; -} - -/*! - * @brief Read operation in either I2C or SPI - * - * param[in] dev_addr I2C or SPI device address - * param[in] reg_addr register address - * param[out] reg_data_ptr pointer to the memory to be used to store the read data - * param[in] data_len number of bytes to be read - * - * @return result of the bus communication function - */ -int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - // ... - // Please insert system specific function to read from bus where BME680 is connected - // ... - return 0; -} - -/*! - * @brief System specific implementation of sleep function - * - * @param[in] t_ms time in milliseconds - * - * @return none - */ -void sleep(uint32_t t_ms) -{ - // ... - // Please insert system specific function sleep or delay for t_ms milliseconds - // ... -} - -/*! - * @brief Capture the system time in microseconds - * - * @return system_current_time current system timestamp in microseconds - */ -int64_t get_timestamp_us() -{ - int64_t system_current_time = 0; - // ... - // Please insert system specific function to retrieve a timestamp (in microseconds) - // ... - return system_current_time; -} - -/*! - * @brief Handling of the ready outputs - * - * @param[in] timestamp time in nanoseconds - * @param[in] iaq IAQ signal - * @param[in] iaq_accuracy accuracy of IAQ signal - * @param[in] temperature temperature signal - * @param[in] humidity humidity signal - * @param[in] pressure pressure signal - * @param[in] raw_temperature raw temperature signal - * @param[in] raw_humidity raw humidity signal - * @param[in] gas raw gas sensor signal - * @param[in] bsec_status value returned by the bsec_do_steps() call - * - * @return none - */ -void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, - float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, - float static_iaq, float co2_equivalent, float breath_voc_equivalent) -{ - // ... - // Please insert system specific code to further process or display the BSEC outputs - // ... -} - -/*! - * @brief Load previous library state from non-volatile memory - * - * @param[in,out] state_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to state_buffer - */ -uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer) -{ - // ... - // Load a previous library state from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no state was available, - // otherwise return length of loaded state string. - // ... - return 0; -} - -/*! - * @brief Save library state to non-volatile memory - * - * @param[in] state_buffer buffer holding the state to be stored - * @param[in] length length of the state string to be stored - * - * @return none - */ -void state_save(const uint8_t *state_buffer, uint32_t length) -{ - // ... - // Save the string some form of non-volatile memory, if possible. - // ... -} - -/*! - * @brief Load library config from non-volatile memory - * - * @param[in,out] config_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to config_buffer - */ -uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) -{ - // ... - // Load a library config from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no config was available, - // otherwise return length of loaded config string. - // ... - return 0; -} - -/*! - * @brief Interrupt handler for press of a ULP plus button - * - * @return none - */ -void ulp_plus_button_press() -{ - /* We call bsec_update_subscription() in order to instruct BSEC to perform an extra measurement at the next - * possible time slot - */ - - bsec_sensor_configuration_t requested_virtual_sensors[1]; - uint8_t n_requested_virtual_sensors = 1; - bsec_sensor_configuration_t required_sensor_settings[BSEC_MAX_PHYSICAL_SENSOR]; - uint8_t n_required_sensor_settings = BSEC_MAX_PHYSICAL_SENSOR; - bsec_library_return_t status = BSEC_OK; - - /* To trigger a ULP plus, we request the IAQ virtual sensor with a specific sample rate code */ - requested_virtual_sensors[0].sensor_id = BSEC_OUTPUT_IAQ; - requested_virtual_sensors[0].sample_rate = BSEC_SAMPLE_RATE_ULP_MEASUREMENT_ON_DEMAND; - - /* Call bsec_update_subscription() to enable/disable the requested virtual sensors */ - status = bsec_update_subscription(requested_virtual_sensors, n_requested_virtual_sensors, required_sensor_settings, - &n_required_sensor_settings); - - /* The status code would tell is if the request was accepted. It will be rejected if the sensor is not already in - * ULP mode, or if the time difference between requests is too short, for example. */ -} - -/*! - * @brief Main function which configures BSEC library and then reads and processes the data from sensor based - * on timer ticks - * - * @return result of the processing - */ -int main() -{ - return_values_init ret; - // ... - // Attach a button (or other) interrupt here to the ulp_plus_button_press() handler function to - // enable this interrupt to trigger a ULP plus - // ... - - /* Call to the function which initializes the BSEC library - * Switch on ultra_low-power mode and provide no temperature offset */ - ret = bsec_iot_init(BSEC_SAMPLE_RATE_ULP, 0.0f, bus_write, bus_read, sleep, state_load, config_load); - if (ret.bme680_status) - { - /* Could not intialize BME680 or BSEC library */ - return (int)ret.bme680_status; - } - else if (ret.bsec_status) - { - /* Could not intialize BSEC library */ - return (int)ret.bsec_status; - } - /* Call to endless loop function which reads and processes data based on sensor settings */ - /* State is saved every 10.000 samples, which means every 100 * 300 secs = 500 minutes */ - bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 100); - - return 0; -} - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.ino b/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.ino deleted file mode 100644 index 7e2cff88..00000000 --- a/lib/Bosch-BSEC/examples/bsec_iot_ulp_plus_example.ino +++ /dev/null @@ -1,342 +0,0 @@ -/* - * Copyright (C) 2017 Robert Bosch. All Rights Reserved. - * - * Disclaimer - * - * Common: - * Bosch Sensortec products are developed for the consumer goods industry. They may only be used - * within the parameters of the respective valid product data sheet. Bosch Sensortec products are - * provided with the express understanding that there is no warranty of fitness for a particular purpose. - * They are not fit for use in life-sustaining, safety or security sensitive systems or any system or device - * that may lead to bodily harm or property damage if the system or device malfunctions. In addition, - * Bosch Sensortec products are not fit for use in products which interact with motor vehicle systems. - * The resale and/or use of products are at the purchasers own risk and his own responsibility. The - * examination of fitness for the intended use is the sole responsibility of the Purchaser. - * - * The purchaser shall indemnify Bosch Sensortec from all third party claims, including any claims for - * incidental, or consequential damages, arising from any product use not covered by the parameters of - * the respective valid product data sheet or not approved by Bosch Sensortec and reimburse Bosch - * Sensortec for all costs in connection with such claims. - * - * The purchaser must monitor the market for the purchased products, particularly with regard to - * product safety and inform Bosch Sensortec without delay of all security relevant incidents. - * - * Engineering Samples are marked with an asterisk (*) or (e). Samples may vary from the valid - * technical specifications of the product series. They are therefore not intended or fit for resale to third - * parties or for use in end products. Their sole purpose is internal client testing. The testing of an - * engineering sample may in no way replace the testing of a product series. Bosch Sensortec - * assumes no liability for the use of engineering samples. By accepting the engineering samples, the - * Purchaser agrees to indemnify Bosch Sensortec from all claims arising from the use of engineering - * samples. - * - * Special: - * This software module (hereinafter called "Software") and any information on application-sheets - * (hereinafter called "Information") is provided free of charge for the sole purpose to support your - * application work. The Software and Information is subject to the following terms and conditions: - * - * The Software is specifically designed for the exclusive use for Bosch Sensortec products by - * personnel who have special experience and training. Do not use this Software if you do not have the - * proper experience or training. - * - * This Software package is provided `` as is `` and without any expressed or implied warranties, - * including without limitation, the implied warranties of merchantability and fitness for a particular - * purpose. - * - * Bosch Sensortec and their representatives and agents deny any liability for the functional impairment - * of this Software in terms of fitness, performance and safety. Bosch Sensortec and their - * representatives and agents shall not be liable for any direct or indirect damages or injury, except as - * otherwise stipulated in mandatory applicable law. - * - * The Information provided is believed to be accurate and reliable. Bosch Sensortec 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 Bosch. Specifications mentioned in the Information are - * subject to change without notice. - * - * It is not allowed to deliver the source code of the Software to any third party without permission of - * Bosch Sensortec. - * - */ - -/*! - * @file bsec_iot_ulp_plus_example.ino - * - * @brief - * Example for using of BSEC library in a fixed configuration with the BME680 sensor. - * This works by running an endless loop in the bsec_iot_loop() function. - */ - -/*! - * @addtogroup bsec_examples BSEC Examples - * @brief BSEC usage examples - * @{*/ - -/**********************************************************************************************************************/ -/* header files */ -/**********************************************************************************************************************/ - -#include "bsec_integration.h" -#include "bsec_serialized_configurations_iaq.h" -#include - -/**********************************************************************************************************************/ -/* functions */ -/**********************************************************************************************************************/ - -/*! - * @brief Write operation in either Wire or SPI - * - * param[in] dev_addr Wire or SPI device address - * param[in] reg_addr register address - * param[in] reg_data_ptr pointer to the data to be written - * param[in] data_len number of bytes to be written - * - * @return result of the bus communication function - */ -int8_t bus_write(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - Wire.beginTransmission(dev_addr); - Wire.write(reg_addr); /* Set register address to start writing to */ - - /* Write the data */ - for (int index = 0; index < data_len; index++) { - Wire.write(reg_data_ptr[index]); - } - - return (int8_t)Wire.endTransmission(); -} - -/*! - * @brief Read operation in either Wire or SPI - * - * param[in] dev_addr Wire or SPI device address - * param[in] reg_addr register address - * param[out] reg_data_ptr pointer to the memory to be used to store the read data - * param[in] data_len number of bytes to be read - * - * @return result of the bus communication function - */ -int8_t bus_read(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data_ptr, uint16_t data_len) -{ - int8_t comResult = 0; - Wire.beginTransmission(dev_addr); - Wire.write(reg_addr); /* Set register address to start reading from */ - comResult = Wire.endTransmission(); - - delayMicroseconds(150); /* Precautionary response delay */ - Wire.requestFrom(dev_addr, (uint8_t)data_len); /* Request data */ - - int index = 0; - while (Wire.available()) /* The slave device may send less than requested (burst read) */ - { - reg_data_ptr[index] = Wire.read(); - index++; - } - - return comResult; -} - -/*! - * @brief System specific implementation of sleep function - * - * @param[in] t_ms time in milliseconds - * - * @return none - */ -void sleep(uint32_t t_ms) -{ - delay(t_ms); -} - -/*! - * @brief Capture the system time in microseconds - * - * @return system_current_time current system timestamp in microseconds - */ -int64_t get_timestamp_us() -{ - return (int64_t) millis() * 1000; -} - -/*! - * @brief Handling of the ready outputs - * - * @param[in] timestamp time in nanoseconds - * @param[in] iaq IAQ signal - * @param[in] iaq_accuracy accuracy of IAQ signal - * @param[in] temperature temperature signal - * @param[in] humidity humidity signal - * @param[in] pressure pressure signal - * @param[in] raw_temperature raw temperature signal - * @param[in] raw_humidity raw humidity signal - * @param[in] gas raw gas sensor signal - * @param[in] bsec_status value returned by the bsec_do_steps() call - * - * @return none - */ -void output_ready(int64_t timestamp, float iaq, uint8_t iaq_accuracy, float temperature, float humidity, - float pressure, float raw_temperature, float raw_humidity, float gas, bsec_library_return_t bsec_status, - float static_iaq, float co2_equivalent, float breath_voc_equivalent) -{ - Serial.print("["); - Serial.print(timestamp/1e6); - Serial.print("] T: "); - Serial.print(temperature); - Serial.print("| rH: "); - Serial.print(humidity); - Serial.print("| IAQ: "); - Serial.print(iaq); - Serial.print(" ("); - Serial.print(iaq_accuracy); - Serial.println(")"); -} - -/*! - * @brief Load previous library state from non-volatile memory - * - * @param[in,out] state_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to state_buffer - */ -uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer) -{ - // ... - // Load a previous library state from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no state was available, - // otherwise return length of loaded state string. - // ... - return 0; -} - -/*! - * @brief Save library state to non-volatile memory - * - * @param[in] state_buffer buffer holding the state to be stored - * @param[in] length length of the state string to be stored - * - * @return none - */ -void state_save(const uint8_t *state_buffer, uint32_t length) -{ - // ... - // Save the string some form of non-volatile memory, if possible. - // ... -} - -/*! - * @brief Load library config from non-volatile memory - * - * @param[in,out] config_buffer buffer to hold the loaded state string - * @param[in] n_buffer size of the allocated state buffer - * - * @return number of bytes copied to config_buffer - */ -uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) -{ - // ... - // Load a library config from non-volatile memory, if available. - // - // Return zero if loading was unsuccessful or no config was available, - // otherwise return length of loaded config string. - // ... - - memcpy(config_buffer, bsec_config_iaq, sizeof(bsec_config_iaq)); - return sizeof(bsec_config_iaq); -} - -/*! - * @brief Interrupt handler for press of a ULP plus button - * - * @return none - */ -void ulp_plus_button_press() -{ - /* We call bsec_update_subscription() in order to instruct BSEC to perform an extra measurement at the next - * possible time slot - */ - - bsec_sensor_configuration_t requested_virtual_sensors[1]; - uint8_t n_requested_virtual_sensors = 1; - bsec_sensor_configuration_t required_sensor_settings[BSEC_MAX_PHYSICAL_SENSOR]; - uint8_t n_required_sensor_settings = BSEC_MAX_PHYSICAL_SENSOR; - bsec_library_return_t status = BSEC_OK; - - /* To trigger a ULP plus, we request the IAQ virtual sensor with a specific sample rate code */ - requested_virtual_sensors[0].sensor_id = BSEC_OUTPUT_IAQ_ESTIMATE; - requested_virtual_sensors[0].sample_rate = BSEC_SAMPLE_RATE_ULP_MEASUREMENT_ON_DEMAND; - - /* Call bsec_update_subscription() to enable/disable the requested virtual sensors */ - status = bsec_update_subscription(requested_virtual_sensors, n_requested_virtual_sensors, required_sensor_settings, - &n_required_sensor_settings); - - /* The status code would tell is if the request was accepted. It will be rejected if the sensor is not already in - * ULP mode, or if the time difference between requests is too short, for example. */ - if (status == BSEC_OK) - { - Serial.println("ULP plus triggered sucessfully."); - } - else - { - Serial.print("ULP plus request rejected. "); - switch (status) - { - case BSEC_W_SC_MODEXCEEDULPTIMELIMIT: - Serial.println("Request came within 20 s of a previous measurement."); - break; - case BSEC_W_SC_MODINSUFFICIENTWAITTIME: - Serial.println("Request came within 20 s of a ULP plus."); - break; - case BSEC_W_SU_MODINNOULP: - Serial.println("Sensor not in ULP mode."); - break; - } - } -} - -/*! - * @brief Main function which configures BSEC library and then reads and processes the data from sensor based - * on timer ticks - * - * @return result of the processing - */ -void setup() -{ - return_values_init ret; - - /* Init I2C and serial communication */ - Wire.begin(); - Serial.begin(115200); - - /* Setup button interrupt to trigger ULP plus */ - pinMode(2, INPUT_PULLUP); - attachInterrupt(digitalPinToInterrupt(2), ulp_plus_button_press, FALLING); - - /* Call to the function which initializes the BSEC library - * Switch on ultra_low-power mode and provide no temperature offset */ - ret = bsec_iot_init(BSEC_SAMPLE_RATE_ULP, 5.0f, bus_write, bus_read, sleep, state_load, config_load); - if (ret.bme680_status) - { - /* Could not intialize BME680 */ - Serial.println("Error while initializing BME680"); - return; - } - else if (ret.bsec_status) - { - /* Could not intialize BSEC library */ - Serial.println("Error while initializing BSEC library"); - return; - } - - /* Call to endless loop function which reads and processes data based on sensor settings */ - /* State is saved every 10.000 samples, which means every 100 * 300 secs = 500 minutes */ - bsec_iot_loop(sleep, get_timestamp_us, output_ready, state_save, 100); -} - -void loop() -{ -} - -/*! @}*/ - diff --git a/lib/Bosch-BSEC/libalgobsec.a.Size.log b/lib/Bosch-BSEC/libalgobsec.a.Size.log deleted file mode 100644 index 23acb73c..00000000 --- a/lib/Bosch-BSEC/libalgobsec.a.Size.log +++ /dev/null @@ -1,2 +0,0 @@ - text data bss dec hex filename - 23795 0 1120 24915 6153 (TOTALS) diff --git a/platformio.ini b/platformio.ini index 69d42cb9..49369f08 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -;env_default = generic +env_default = generic ;env_default = ebox ;env_default = eboxtube ;env_default = heltec @@ -15,7 +15,7 @@ ;env_default = ttgov2 ;env_default = ttgov21old ;env_default = ttgov21new -env_default = ttgobeam +;env_default = ttgobeam ;env_default = lopy ;env_default = lopy4 ;env_default = fipy @@ -29,7 +29,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng [common] ; for release_version use max. 10 chars total, use any decimal format like "a.b.c" -release_version = 1.6.85 +release_version = 1.6.9 ; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running! ; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose debug_level = 0 @@ -38,12 +38,11 @@ upload_protocol = esptool ;upload_protocol = custom extra_scripts = pre:build.py keyfile = ota.conf -;platform_espressif32 = espressif32@1.5.0 platform_espressif32 = https://github.com/platformio/platform-espressif32.git#a7b1fe6 board_build.partitions = min_spiffs.csv monitor_speed = 115200 lib_deps_lora = -; MCCI LoRaWAN LMIC library@^2.2.2 +; MCCI LoRaWAN LMIC library@2.3.0 lib_deps_display = U8g2@>=2.25.0 lib_deps_rgbled = diff --git a/src/TTN/packed_decoder.js b/src/TTN/packed_decoder.js index 0571bfa0..a8f71f9e 100644 --- a/src/TTN/packed_decoder.js +++ b/src/TTN/packed_decoder.js @@ -43,7 +43,7 @@ function Decoder(bytes, port) { if (port === 7) { // BME680 sensor data - return decode(bytes, [temperature, uint16, humidity, uint16], ['temperature', 'pressure', 'humidity', 'air']); + return decode(bytes, [float, uint16, ufloat, ufloat], ['temperature', 'pressure', 'humidity', 'air']); } } @@ -116,9 +116,9 @@ var hdop = function (bytes) { }; hdop.BYTES = 2; -var temperature = function (bytes) { - if (bytes.length !== temperature.BYTES) { - throw new Error('Temperature must have exactly 2 bytes'); +var float = function (bytes) { + if (bytes.length !== float.BYTES) { + throw new Error('Float must have exactly 2 bytes'); } var isNegative = bytes[0] & 0x80; var b = ('00000000' + Number(bytes[0]).toString(2)).slice(-8) @@ -139,17 +139,27 @@ var temperature = function (bytes) { } return +(t / 100).toFixed(1); }; -temperature.BYTES = 2; +float.BYTES = 2; -var humidity = function (bytes) { - if (bytes.length !== humidity.BYTES) { - throw new Error('Humidity must have exactly 2 bytes'); +var ufloat = function (bytes) { + if (bytes.length !== ufloat.BYTES) { + throw new Error('Ufloat must have exactly 2 bytes'); } var h = bytesToInt(bytes); return +(h / 100).toFixed(1); }; -humidity.BYTES = 2; +ufloat.BYTES = 2; + +var pressure = function (bytes) { + if (bytes.length !== pressure.BYTES) { + throw new Error('Pressure must have exactly 2 bytes'); + } + + var h = bytesToInt(bytes); + return +(h / 10).toFixed(1); +}; +pressure.BYTES = 2; var bitmap = function (byte) { if (byte.length !== bitmap.BYTES) { @@ -193,8 +203,9 @@ if (typeof module === 'object' && typeof module.exports !== 'undefined') { uint16: uint16, uint32: uint32, uptime: uptime, - temperature: temperature, - humidity: humidity, + float: float, + ufloat: ufloat, + pressure: pressure, latLng: latLng, hdop: hdop, bitmap: bitmap, diff --git a/src/bme680mems.cpp b/src/bme680mems.cpp index e449a8a2..82a4b6f7 100644 --- a/src/bme680mems.cpp +++ b/src/bme680mems.cpp @@ -8,6 +8,43 @@ static const char TAG[] = "main"; bmeStatus_t bme_status; TaskHandle_t BmeTask; +// --- Bosch BSEC library configuration --- +// 3,3V supply voltage; 3s max time between sensor_control calls; 4 days +// calibration. Change this const if not applicable for your application (see +// BME680 datasheet) +const uint8_t bsec_config_iaq[454] = { + 1, 7, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 174, 1, 0, + 0, 48, 0, 1, 0, 137, 65, 0, 63, 205, 204, 204, 62, 0, 0, + 64, 63, 205, 204, 204, 62, 0, 0, 225, 68, 0, 192, 168, 71, 64, + 49, 119, 76, 0, 0, 0, 0, 0, 80, 5, 95, 0, 0, 0, 0, + 0, 0, 0, 0, 28, 0, 2, 0, 0, 244, 1, 225, 0, 25, 0, + 0, 128, 64, 0, 0, 32, 65, 144, 1, 0, 0, 112, 65, 0, 0, + 0, 63, 16, 0, 3, 0, 10, 215, 163, 60, 10, 215, 35, 59, 10, + 215, 35, 59, 9, 0, 5, 0, 0, 0, 0, 0, 1, 88, 0, 9, + 0, 229, 208, 34, 62, 0, 0, 0, 0, 0, 0, 0, 0, 218, 27, + 156, 62, 225, 11, 67, 64, 0, 0, 160, 64, 0, 0, 0, 0, 0, + 0, 0, 0, 94, 75, 72, 189, 93, 254, 159, 64, 66, 62, 160, 191, + 0, 0, 0, 0, 0, 0, 0, 0, 33, 31, 180, 190, 138, 176, 97, + 64, 65, 241, 99, 190, 0, 0, 0, 0, 0, 0, 0, 0, 167, 121, + 71, 61, 165, 189, 41, 192, 184, 30, 189, 64, 12, 0, 10, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 229, 0, 254, 0, 2, 1, 5, 48, + 117, 100, 0, 44, 1, 112, 23, 151, 7, 132, 3, 197, 0, 92, 4, + 144, 1, 64, 1, 64, 1, 144, 1, 48, 117, 48, 117, 48, 117, 48, + 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 48, 117, 100, 0, + 100, 0, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 100, 0, 48, + 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, + 100, 0, 100, 0, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, + 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, + 44, 1, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, + 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, + 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, + 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, + 255, 255, 255, 255, 255, 255, 220, 5, 220, 5, 220, 5, 255, 255, 255, + 255, 255, 255, 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 0, 0, 0, + 239, 79, 0, 0}; + // initialize BME680 sensor int bme_init(void) { @@ -22,9 +59,11 @@ int bme_init(void) { user_delay_ms, state_load, config_load); if ((int)ret.bme680_status) { - ESP_LOGE(TAG, "Could not initialize BME680, error %d", (int)ret.bme680_status); + ESP_LOGE(TAG, "Could not initialize BME680, error %d", + (int)ret.bme680_status); } else if ((int)ret.bsec_status) { - ESP_LOGE(TAG, "Could not initialize BSEC library, error %d", (int)ret.bsec_status); + ESP_LOGE(TAG, "Could not initialize BSEC library, error %d", + (int)ret.bsec_status); } else { ESP_LOGI(TAG, "BME680 sensor found and initialized"); return 1; @@ -131,13 +170,13 @@ void state_save(const uint8_t *state_buffer, uint32_t length) { * @return number of bytes copied to config_buffer */ uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer) { - // ... + // Load a library config from non-volatile memory, if available. - // // Return zero if loading was unsuccessful or no config was available, // otherwise return length of loaded config string. - // ... - return 0; + + memcpy(config_buffer, bsec_config_iaq, sizeof(bsec_config_iaq)); + return sizeof(bsec_config_iaq); } /*! diff --git a/src/lorawan.cpp b/src/lorawan.cpp index ba3e11f5..fa92d1a5 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -164,7 +164,7 @@ void onEvent(ev_t ev) { switch (ev) { case EV_SCAN_TIMEOUT: - strcpy_P(buff, PSTR("SCAN TIMEOUT")); + strcpy_P(buff, PSTR("SCAN_TIMEOUT")); break; case EV_BEACON_FOUND: @@ -210,15 +210,21 @@ void onEvent(ev_t ev) { break; case EV_TXCOMPLETE: - strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED ACK") - : PSTR("TX COMPLETE")); + strcpy_P(buff, (LMIC.txrxFlags & TXRX_ACK) ? PSTR("RECEIVED_ACK") + : PSTR("TX_COMPLETE")); sprintf(display_line6, " "); // clear previous lmic status + // if (LMIC.dataLen) { + // ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", + // LMIC.dataLen, (signed char)LMIC.rssi, (signed + // char)LMIC.snr); + // sprintf(display_line6, "RSSI %d SNR %d", (signed char)LMIC.rssi, + // (signed char)LMIC.snr); + if (LMIC.dataLen) { - ESP_LOGI(TAG, "Received %d bytes of payload, RSSI %d SNR %d", - LMIC.dataLen, (signed char)LMIC.rssi, (signed char)LMIC.snr); - sprintf(display_line6, "RSSI %d SNR %d", (signed char)LMIC.rssi, - (signed char)LMIC.snr); + ESP_LOGI(TAG, "Received %d bytes of payload, RSSI -%d SNR %d", + LMIC.dataLen, LMIC.rssi, LMIC.snr / 4); + sprintf(display_line6, "RSSI -%d SNR %d", LMIC.rssi, LMIC.snr / 4); // check if command is received on command port, then call interpreter if ((LMIC.txrxFlags & TXRX_PORT) && @@ -237,20 +243,20 @@ void onEvent(ev_t ev) { case EV_RXCOMPLETE: // data received in ping slot - strcpy_P(buff, PSTR("RX COMPLETE")); + strcpy_P(buff, PSTR("RX_COMPLETE")); break; case EV_LINK_DEAD: - strcpy_P(buff, PSTR("LINK DEAD")); + strcpy_P(buff, PSTR("LINK_DEAD")); break; case EV_LINK_ALIVE: - strcpy_P(buff, PSTR("LINK ALIVE")); + strcpy_P(buff, PSTR("LINK_ALIVE")); break; case EV_TXSTART: if (!(LMIC.opmode & OP_JOINING)) - strcpy_P(buff, PSTR("TX START")); + strcpy_P(buff, PSTR("TX_START")); break; case EV_SCAN_FOUND: @@ -262,7 +268,7 @@ void onEvent(ev_t ev) { break; default: - sprintf_P(buff, PSTR("UNKNOWN EVENT %d"), ev); + sprintf_P(buff, PSTR("UNKNOWN_EVENT_%d"), ev); break; } diff --git a/src/ota.cpp b/src/ota.cpp index ac409a0c..4f5a5e01 100644 --- a/src/ota.cpp +++ b/src/ota.cpp @@ -68,7 +68,7 @@ void start_ota_update() { ESP_LOGI(TAG, "Starting Wifi OTA update"); display(1, "**", WIFI_SSID); - WiFi.mode(WIFI_AP_STA); + WiFi.mode(WIFI_STA); WiFi.begin(WIFI_SSID, WIFI_PASS); int i = WIFI_MAX_TRY, j = OTA_MAX_TRY; diff --git a/src/payload.cpp b/src/payload.cpp index 301034f2..a00bd052 100644 --- a/src/payload.cpp +++ b/src/payload.cpp @@ -104,15 +104,16 @@ void PayloadConvert::addBME(bmeStatus_t value) { #ifdef HAS_BME int16_t temperature = (int16_t)(value.temperature); // float -> int uint16_t humidity = (uint16_t)(value.humidity); // float -> int + uint16_t pressure = (uint16_t)(value.pressure); // float -> int uint16_t iaq = (uint16_t)(value.iaq); // float -> int buffer[cursor++] = highByte(temperature); buffer[cursor++] = lowByte(temperature); - buffer[cursor++] = highByte(value.pressure); - buffer[cursor++] = lowByte(value.pressure); + buffer[cursor++] = highByte(pressure); + buffer[cursor++] = lowByte(pressure); buffer[cursor++] = highByte(humidity); buffer[cursor++] = lowByte(humidity); - buffer[cursor++] = highByte(value.iaq); - buffer[cursor++] = lowByte(value.iaq); + buffer[cursor++] = highByte(iaq); + buffer[cursor++] = lowByte(iaq); #endif } @@ -192,10 +193,10 @@ void PayloadConvert::addSensor(uint8_t buf[]) { void PayloadConvert::addBME(bmeStatus_t value) { #ifdef HAS_BME - writeTemperature(value.temperature); - writeUint16(value.pressure); - writeHumidity(value.humidity); - writeUint16(value.iaq); + writeFloat(value.temperature); + writePressure(value.pressure); + writeUFloat(value.humidity); + writeUFloat(value.iaq); #endif } @@ -232,8 +233,13 @@ void PayloadConvert::writeUint16(uint16_t i) { intToBytes(cursor, i, 2); } void PayloadConvert::writeUint8(uint8_t i) { intToBytes(cursor, i, 1); } -void PayloadConvert::writeHumidity(float humidity) { - int16_t h = (int16_t)(humidity * 100); +void PayloadConvert::writeUFloat(float value) { + int16_t h = (int16_t)(value * 100); + intToBytes(cursor, h, 2); +} + +void PayloadConvert::writePressure(float value) { + int16_t h = (int16_t)(value); intToBytes(cursor, h, 2); } @@ -241,9 +247,9 @@ void PayloadConvert::writeHumidity(float humidity) { * Uses a 16bit two's complement with two decimals, so the range is * -327.68 to +327.67 degrees */ -void PayloadConvert::writeTemperature(float temperature) { - int16_t t = (int16_t)(temperature * 100); - if (temperature < 0) { +void PayloadConvert::writeFloat(float value) { + int16_t t = (int16_t)(value * 100); + if (value < 0) { t = ~-t; t = t + 1; } @@ -371,11 +377,10 @@ void PayloadConvert::addBME(bmeStatus_t value) { // 0.1°C per bit => -3276,7 .. +3276,7 °C int16_t temperature = (int16_t)(value.temperature * 10.0); // 0.1 hPa per bit => 0 .. 6553,6 hPa - uint16_t pressure = value.pressure * 10; + uint16_t pressure = (uint16_t)(value.pressure * 10); // 0.5% per bit => 0 .. 128 %C uint8_t humidity = (uint8_t)(value.humidity * 2.0); - // 0.01 IAQ per bit => 0 .. 655,36 IAQ - uint16_t iaq = (uint16_t) value.iaq * 100; + int16_t iaq = (int16_t)(value.iaq); #if (PAYLOAD_ENCODER == 3) buffer[cursor++] = LPP_TEMPERATURE_CHANNEL; @@ -395,9 +400,9 @@ void PayloadConvert::addBME(bmeStatus_t value) { buffer[cursor++] = LPP_HUMIDITY; // 1 byte 0.5 % Unsigned buffer[cursor++] = humidity; #if (PAYLOAD_ENCODER == 3) - buffer[cursor++] = LPP_GAS_CHANNEL; + buffer[cursor++] = LPP_AIR_CHANNEL; #endif - buffer[cursor++] = LPP_ANALOG_INPUT; // 2 bytes 0.01 Signed + buffer[cursor++] = LPP_LUMINOSITY; // 2 bytes, 1.0 unsigned buffer[cursor++] = highByte(iaq); buffer[cursor++] = lowByte(iaq); #endif // HAS_BME diff --git a/src/senddata.cpp b/src/senddata.cpp index 5860c5fb..bed8d312 100644 --- a/src/senddata.cpp +++ b/src/senddata.cpp @@ -7,9 +7,20 @@ void SendPayload(uint8_t port) { MessageBuffer_t SendBuffer; // contains MessageSize, MessagePort, Message[] SendBuffer.MessageSize = payload.getSize(); - SendBuffer.MessagePort = PAYLOAD_ENCODER <= 2 - ? port - : (PAYLOAD_ENCODER == 4 ? LPP2PORT : LPP1PORT); + switch (PAYLOAD_ENCODER) { + case 1: + case 2: + SendBuffer.MessagePort = port; + break; + case 3: + SendBuffer.MessagePort = LPP1PORT; + break; + case 4: + SendBuffer.MessagePort = LPP2PORT; + break; + default: + SendBuffer.MessagePort = port; + } memcpy(SendBuffer.Message, payload.getBuffer(), payload.getSize()); // enqueue message in device's send queues diff --git a/src/sensor.cpp b/src/sensor.cpp index 53432bbc..05823f3d 100644 --- a/src/sensor.cpp +++ b/src/sensor.cpp @@ -4,25 +4,33 @@ // Local logging tag static const char TAG[] = "main"; -#define SENSORBUFFER 10 // max. size of user sensor data buffer in bytes [default=20] +#define SENSORBUFFER \ + 10 // max. size of user sensor data buffer in bytes [default=20] void sensor_init(void) { - // this function is called dureing device startup - // put your sensor initialization routines here + // this function is called during device startup + // put your user sensor initialization routines here } uint8_t sensor_mask(uint8_t sensor_no) { switch (sensor_no) { + case 0: + return (uint8_t)COUNT_DATA; case 1: return (uint8_t)SENSOR1_DATA; case 2: return (uint8_t)SENSOR2_DATA; - break; case 3: return (uint8_t)SENSOR3_DATA; case 4: return (uint8_t)SENSOR4_DATA; + case 5: + return (uint8_t)GPS_DATA; + case 6: + return (uint8_t)MEMS_DATA; + case 7: + return (uint8_t)ALARM_DATA; } }