BSEC integration (experimental)
This commit is contained in:
parent
8f201e066f
commit
222dfb5a95
@ -3,21 +3,30 @@
|
||||
|
||||
#include "globals.h"
|
||||
#include <Wire.h>
|
||||
#include "bme680.h"
|
||||
#include "bsec_interface.h"
|
||||
#include "bsec_datatypes.h"
|
||||
//#include "bme680_defs.h"
|
||||
//#include "bme680.c"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "bsec_integration.h"
|
||||
#include "bsec_integration.c"
|
||||
|
||||
extern bmeStatus_t
|
||||
bme_status; // Make struct for storing gps data globally available
|
||||
|
||||
void bme_init();
|
||||
int bme_init();
|
||||
bool bme_read();
|
||||
void user_delay_ms(uint32_t period);
|
||||
int64_t get_timestamp_us();
|
||||
|
||||
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data,
|
||||
uint16_t len);
|
||||
int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data,
|
||||
uint16_t len);
|
||||
|
||||
uint32_t state_load(uint8_t *state_buffer, uint32_t n_buffer);
|
||||
void state_save(const uint8_t *state_buffer, uint32_t length);
|
||||
uint32_t config_load(uint8_t *config_buffer, uint32_t n_buffer);
|
||||
|
||||
|
||||
#endif
|
@ -10,20 +10,22 @@
|
||||
#define MAC_SNIFF_WIFI 0
|
||||
#define MAC_SNIFF_BLE 1
|
||||
|
||||
/*
|
||||
typedef struct {
|
||||
unsigned frame_ctrl : 16;
|
||||
unsigned duration_id : 16;
|
||||
uint8_t addr1[6]; /* receiver address */
|
||||
uint8_t addr2[6]; /* sender address */
|
||||
uint8_t addr3[6]; /* filtering address */
|
||||
uint8_t addr1[6]; // receiver address
|
||||
uint8_t addr2[6]; // sender address
|
||||
uint8_t addr3[6]; // filtering address
|
||||
unsigned sequence_ctrl : 16;
|
||||
uint8_t addr4[6]; /* optional */
|
||||
uint8_t addr4[6]; // optional
|
||||
} wifi_ieee80211_mac_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
wifi_ieee80211_mac_hdr_t hdr;
|
||||
uint8_t payload[0]; /* network data ended with 4 bytes csum (CRC32) */
|
||||
uint8_t payload[0]; // network data ended with 4 bytes csum (CRC32)
|
||||
} wifi_ieee80211_packet_t;
|
||||
*/
|
||||
|
||||
void wifi_sniffer_init(void);
|
||||
void IRAM_ATTR wifi_sniffer_packet_handler(void *buff, wifi_promiscuous_pkt_type_t type);
|
||||
|
559
lib/Bosch-BSEC/bsec_integration.c
Normal file
559
lib/Bosch-BSEC/bsec_integration.c
Normal file
@ -0,0 +1,559 @@
|
||||
/*
|
||||
* 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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! @}*/
|
||||
|
165
lib/Bosch-BSEC/bsec_integration.h
Normal file
165
lib/Bosch-BSEC/bsec_integration.h
Normal file
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* 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__ */
|
||||
|
||||
/*! @}*/
|
||||
|
@ -9,13 +9,13 @@
|
||||
;env_default = generic
|
||||
;env_default = ebox
|
||||
;env_default = eboxtube
|
||||
;env_default = heltec
|
||||
env_default = heltec
|
||||
;env_default = heltecv2
|
||||
;env_default = ttgov1
|
||||
;env_default = ttgov2
|
||||
;env_default = ttgov21old
|
||||
;env_default = ttgov21new
|
||||
env_default = ttgobeam
|
||||
;env_default = ttgobeam
|
||||
;env_default = lopy
|
||||
;env_default = lopy4
|
||||
;env_default = fipy
|
||||
@ -32,7 +32,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
|
||||
release_version = 1.6.83
|
||||
; 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 = 3
|
||||
debug_level = 0
|
||||
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
||||
upload_protocol = esptool
|
||||
;upload_protocol = custom
|
||||
@ -59,11 +59,10 @@ lib_deps_all =
|
||||
${common.lib_deps_display}
|
||||
${common.lib_deps_rgbled}
|
||||
${common.lib_deps_gps}
|
||||
build_flags =
|
||||
-Llib/Bosch-BSEC
|
||||
-llibalgobsec.a
|
||||
-include src/hal/${PIOENV}.h
|
||||
-include src/paxcounter.conf
|
||||
build_flags_basic =
|
||||
;-include include/wifiscan.h
|
||||
-include $PROJECTSRC_DIR/hal/${PIOENV}.h
|
||||
-include $PROJECTSRC_DIR/paxcounter.conf
|
||||
-w
|
||||
;'-DARDUINO_LMIC_PROJECT_CONFIG_H="/$PROJECTSRC_DIR/lmic_config.h"'
|
||||
'-DARDUINO_LMIC_PROJECT_CONFIG_H=../../../src/lmic_config.h'
|
||||
@ -71,6 +70,12 @@ build_flags =
|
||||
'-DLOG_LOCAL_LEVEL=${common.debug_level}'
|
||||
'-DBINTRAY_PACKAGE="${PIOENV}"'
|
||||
'-DPROGVERSION="${common.release_version}"'
|
||||
build_flags_sensors =
|
||||
-Llib/Bosch-BSEC
|
||||
-llibalgobsec.a
|
||||
build_flags_all =
|
||||
${common.build_flags_basic}
|
||||
${common.build_flags_sensors}
|
||||
|
||||
[env:ebox]
|
||||
platform = ${common.platform_espressif32}
|
||||
@ -82,7 +87,7 @@ lib_deps =
|
||||
${common.lib_deps_basic}
|
||||
${common.lib_deps_lora}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -98,7 +103,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_rgbled}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -114,7 +119,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -130,7 +135,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -146,7 +151,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -162,7 +167,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -178,7 +183,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -194,7 +199,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_display}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -210,7 +215,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_gps}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_all}
|
||||
-mfix-esp32-psram-cache-issue
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
@ -227,7 +232,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_rgbled}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -235,7 +240,7 @@ monitor_speed = ${common.monitor_speed}
|
||||
[env:lopy]
|
||||
platform = ${common.platform_espressif32}
|
||||
framework = arduino
|
||||
board = esp32dev
|
||||
board = lopy4
|
||||
board_build.partitions = ${common.board_build.partitions}
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
@ -244,7 +249,7 @@ lib_deps =
|
||||
${common.lib_deps_rgbled}
|
||||
${common.lib_deps_gps}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -252,7 +257,7 @@ monitor_speed = ${common.monitor_speed}
|
||||
[env:lopy4]
|
||||
platform = ${common.platform_espressif32}
|
||||
framework = arduino
|
||||
board = esp32dev
|
||||
board = lopy4
|
||||
board_build.partitions = ${common.board_build.partitions}
|
||||
upload_speed = 921600
|
||||
lib_deps =
|
||||
@ -261,7 +266,7 @@ lib_deps =
|
||||
${common.lib_deps_rgbled}
|
||||
${common.lib_deps_gps}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
-mfix-esp32-psram-cache-issue
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
@ -278,7 +283,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_rgbled}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -294,7 +299,7 @@ lib_deps =
|
||||
${common.lib_deps_lora}
|
||||
${common.lib_deps_rgbled}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -309,7 +314,7 @@ lib_deps =
|
||||
${common.lib_deps_basic}
|
||||
${common.lib_deps_rgbled}
|
||||
build_flags =
|
||||
${common.build_flags}
|
||||
${common.build_flags_basic}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -321,7 +326,7 @@ board = featheresp32
|
||||
board_build.partitions = ${common.board_build.partitions}
|
||||
upload_speed = 921600
|
||||
lib_deps = ${common.lib_deps_all}
|
||||
build_flags = ${common.build_flags}
|
||||
build_flags = ${common.build_flags_all}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
||||
@ -333,7 +338,7 @@ board = esp32dev
|
||||
board_build.partitions = ${common.board_build.partitions}
|
||||
upload_speed = 921600
|
||||
lib_deps = ${common.lib_deps_all}
|
||||
build_flags = ${common.build_flags}
|
||||
build_flags = ${common.build_flags_all}
|
||||
upload_protocol = ${common.upload_protocol}
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
monitor_speed = ${common.monitor_speed}
|
@ -5,69 +5,27 @@
|
||||
// Local logging tag
|
||||
static const char TAG[] = "main";
|
||||
|
||||
#define NUM_USED_OUTPUTS 8
|
||||
|
||||
bmeStatus_t bme_status;
|
||||
|
||||
void bme_init(void) {
|
||||
|
||||
// initialize BME680 sensor
|
||||
int bme_init(void) {
|
||||
|
||||
return_values_init ret = {BME680_OK, BSEC_OK};
|
||||
struct bme680_dev gas_sensor;
|
||||
|
||||
Wire.begin(HAS_BME, 400000); // I2C connect to BME680 sensor with 400 KHz
|
||||
|
||||
// configure sensor for I2C communication
|
||||
gas_sensor.dev_id = BME_ADDR;
|
||||
gas_sensor.intf = BME680_I2C_INTF;
|
||||
gas_sensor.read = user_i2c_read;
|
||||
gas_sensor.write = user_i2c_write;
|
||||
gas_sensor.delay_ms = user_delay_ms;
|
||||
gas_sensor.amb_temp = 25;
|
||||
|
||||
int8_t rslt = BME680_OK;
|
||||
rslt = bme680_init(&gas_sensor);
|
||||
|
||||
if (rslt == BME680_OK) {
|
||||
ESP_LOGI(TAG, "BME680 sensor found");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "BME680 sensor not found on i2c bus");
|
||||
return;
|
||||
}
|
||||
|
||||
// configure BME680 sensor in forced mode
|
||||
|
||||
uint8_t set_required_settings;
|
||||
|
||||
/* Set the temperature, pressure and humidity settings */
|
||||
gas_sensor.tph_sett.os_hum = BME680_OS_2X;
|
||||
gas_sensor.tph_sett.os_pres = BME680_OS_4X;
|
||||
gas_sensor.tph_sett.os_temp = BME680_OS_8X;
|
||||
gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3;
|
||||
|
||||
/* Set the remaining gas sensor settings and link the heating profile */
|
||||
gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS;
|
||||
/* Create a ramp heat waveform in 3 steps */
|
||||
gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */
|
||||
gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */
|
||||
|
||||
/* Select the power mode */
|
||||
/* Must be set before writing the sensor configuration */
|
||||
gas_sensor.power_mode = BME680_FORCED_MODE;
|
||||
|
||||
/* Set the required sensor settings needed */
|
||||
set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL |
|
||||
BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;
|
||||
|
||||
/* Set the desired sensor configuration */
|
||||
rslt = bme680_set_sensor_settings(set_required_settings, &gas_sensor);
|
||||
|
||||
/* Set the power mode */
|
||||
rslt = bme680_set_sensor_mode(&gas_sensor);
|
||||
|
||||
if (rslt == BME680_OK) {
|
||||
ESP_LOGI(TAG, "BME680 sensor initialized");
|
||||
} else {
|
||||
ESP_LOGE(TAG, "BME680 initialization failed");
|
||||
return;
|
||||
/* 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, user_i2c_write, user_i2c_read,
|
||||
user_delay_ms, 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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,6 +48,15 @@ bool bme_read(void) {
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
//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);
|
||||
*/
|
||||
|
||||
int8_t user_i2c_read(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data,
|
||||
uint16_t len) {
|
||||
int8_t rslt = 0; /* Return 0 for Success, non-zero for failure */
|
||||
@ -122,6 +89,93 @@ int8_t user_i2c_write(uint8_t dev_id, uint8_t reg_addr, uint8_t *reg_data,
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/*!
|
||||
* @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. */
|
||||
}
|
||||
|
||||
void user_delay_ms(uint32_t period) { vTaskDelay(period / portTICK_PERIOD_MS); }
|
||||
|
||||
int64_t get_timestamp_us() { return (int64_t)millis() * 1000; }
|
||||
|
||||
#endif // HAS_BME
|
@ -10,13 +10,8 @@
|
||||
#define HAS_LED NOT_A_PIN // LoPy4 has no on board mono LED, we use on board RGB LED
|
||||
#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0
|
||||
|
||||
// Pins for LORA chip SPI interface, reset line and interrupt lines
|
||||
#define LORA_SCK (5) // GPIO5 - SX1276 SCK
|
||||
#define LORA_CS (17) // GPIO17 - SX1276 CS
|
||||
#define LORA_MISO (19) // GPIO19 - SX1276 MISO
|
||||
#define LORA_MOSI (27) // GPIO27 - SX1276 MOSI
|
||||
#define LORA_RST (18) // GPIO18 - SX1276 RESET
|
||||
#define LORA_IRQ (23) // LoRa IRQ
|
||||
// Pins for LORA chip SPI interface come from board file, we need some
|
||||
// additional definitions for LMIC
|
||||
#define LORA_IO1 (23) // Pin tied via diode to DIO0
|
||||
#define LORA_IO2 (23) // Pin tied via diode to DIO0
|
||||
|
||||
|
@ -19,13 +19,8 @@
|
||||
#define HAS_RGB_LED (0) // WS2812B RGB LED on GPIO0 (P2)
|
||||
#define BOARD_HAS_PSRAM // use extra 4MB extern RAM
|
||||
|
||||
// Pins for LORA chip SPI interface, reset line and interrupt lines
|
||||
#define LORA_SCK (5)
|
||||
#define LORA_CS (18)
|
||||
#define LORA_MISO (19)
|
||||
#define LORA_MOSI (27)
|
||||
#define LORA_RST LMIC_UNUSED_PIN
|
||||
#define LORA_IRQ (23) // LoRa IRQ
|
||||
// Pins for LORA chip SPI interface come from board file, we need some
|
||||
// additional definitions for LMIC
|
||||
#define LORA_IO1 (23) // Pin tied via diode to DIO0
|
||||
#define LORA_IO2 (23) // Pin tied via diode to DIO0
|
||||
|
||||
|
@ -9,9 +9,25 @@ static wifi_country_t wifi_country = {WIFI_MY_COUNTRY, WIFI_CHANNEL_MIN,
|
||||
WIFI_CHANNEL_MAX, 100,
|
||||
WIFI_COUNTRY_POLICY_MANUAL};
|
||||
|
||||
typedef struct {
|
||||
unsigned frame_ctrl : 16;
|
||||
unsigned duration_id : 16;
|
||||
uint8_t addr1[6]; // receiver address
|
||||
uint8_t addr2[6]; // sender address
|
||||
uint8_t addr3[6]; // filtering address
|
||||
unsigned sequence_ctrl : 16;
|
||||
uint8_t addr4[6]; // optional
|
||||
} wifi_ieee80211_mac_hdr_t;
|
||||
|
||||
typedef struct {
|
||||
wifi_ieee80211_mac_hdr_t hdr;
|
||||
uint8_t payload[0]; // network data ended with 4 bytes csum (CRC32)
|
||||
} wifi_ieee80211_packet_t;
|
||||
|
||||
// using IRAM_:ATTR here to speed up callback function
|
||||
IRAM_ATTR void wifi_sniffer_packet_handler(void *buff,
|
||||
wifi_promiscuous_pkt_type_t type) {
|
||||
|
||||
const wifi_promiscuous_pkt_t *ppkt = (wifi_promiscuous_pkt_t *)buff;
|
||||
const wifi_ieee80211_packet_t *ipkt =
|
||||
(wifi_ieee80211_packet_t *)ppkt->payload;
|
||||
|
Loading…
Reference in New Issue
Block a user