first fully functional integration (experimental)
This commit is contained in:
parent
eb5dac2dea
commit
76600a86b1
@ -89,6 +89,7 @@ extern uint8_t volatile channel; // wifi channel rotation counter
|
|||||||
extern uint16_t volatile macs_total, macs_wifi, macs_ble,
|
extern uint16_t volatile macs_total, macs_wifi, macs_ble,
|
||||||
batt_voltage; // display values
|
batt_voltage; // display values
|
||||||
extern hw_timer_t *channelSwitch, *sendCycle, *displaytimer;
|
extern hw_timer_t *channelSwitch, *sendCycle, *displaytimer;
|
||||||
|
extern SemaphoreHandle_t I2Caccess;
|
||||||
|
|
||||||
extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
|
extern std::set<uint16_t, std::less<uint16_t>, Mallocator<uint16_t>> macs;
|
||||||
extern std::array<uint64_t, 0xff>::iterator it;
|
extern std::array<uint64_t, 0xff>::iterator it;
|
||||||
|
@ -103,7 +103,7 @@
|
|||||||
/** BME680 configuration macros */
|
/** BME680 configuration macros */
|
||||||
/** Enable or un-comment the macro to provide floating point data output */
|
/** Enable or un-comment the macro to provide floating point data output */
|
||||||
#ifndef BME680_FLOAT_POINT_COMPENSATION
|
#ifndef BME680_FLOAT_POINT_COMPENSATION
|
||||||
/* #define BME680_FLOAT_POINT_COMPENSATION */
|
//#define BME680_FLOAT_POINT_COMPENSATION
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/** BME680 General config */
|
/** BME680 General config */
|
||||||
|
@ -47,14 +47,13 @@
|
|||||||
|
|
||||||
#include "bsec.h"
|
#include "bsec.h"
|
||||||
|
|
||||||
TwoWire* Bsec::wireObj = NULL;
|
TwoWire *Bsec::wireObj = NULL;
|
||||||
SPIClass* Bsec::spiObj = NULL;
|
SPIClass *Bsec::spiObj = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*/
|
*/
|
||||||
Bsec::Bsec()
|
Bsec::Bsec() {
|
||||||
{
|
|
||||||
nextCall = 0;
|
nextCall = 0;
|
||||||
version.major = 0;
|
version.major = 0;
|
||||||
version.minor = 0;
|
version.minor = 0;
|
||||||
@ -72,8 +71,8 @@ Bsec::Bsec()
|
|||||||
/**
|
/**
|
||||||
* @brief Function to initialize the BSEC library and the BME680 sensor
|
* @brief Function to initialize the BSEC library and the BME680 sensor
|
||||||
*/
|
*/
|
||||||
void Bsec::begin(uint8_t devId, enum bme680_intf intf, bme680_com_fptr_t read, bme680_com_fptr_t write, bme680_delay_fptr_t idleTask)
|
void Bsec::begin(uint8_t devId, enum bme680_intf intf, bme680_com_fptr_t read,
|
||||||
{
|
bme680_com_fptr_t write, bme680_delay_fptr_t idleTask) {
|
||||||
_bme680.dev_id = devId;
|
_bme680.dev_id = devId;
|
||||||
_bme680.intf = intf;
|
_bme680.intf = intf;
|
||||||
_bme680.read = read;
|
_bme680.read = read;
|
||||||
@ -88,8 +87,7 @@ void Bsec::begin(uint8_t devId, enum bme680_intf intf, bme680_com_fptr_t read, b
|
|||||||
/**
|
/**
|
||||||
* @brief Function to initialize the BSEC library and the BME680 sensor
|
* @brief Function to initialize the BSEC library and the BME680 sensor
|
||||||
*/
|
*/
|
||||||
void Bsec::begin(uint8_t i2cAddr, TwoWire &i2c)
|
void Bsec::begin(uint8_t i2cAddr, TwoWire &i2c) {
|
||||||
{
|
|
||||||
_bme680.dev_id = i2cAddr;
|
_bme680.dev_id = i2cAddr;
|
||||||
_bme680.intf = BME680_I2C_INTF;
|
_bme680.intf = BME680_I2C_INTF;
|
||||||
_bme680.read = Bsec::i2cRead;
|
_bme680.read = Bsec::i2cRead;
|
||||||
@ -107,8 +105,7 @@ void Bsec::begin(uint8_t i2cAddr, TwoWire &i2c)
|
|||||||
/**
|
/**
|
||||||
* @brief Function to initialize the BSEC library and the BME680 sensor
|
* @brief Function to initialize the BSEC library and the BME680 sensor
|
||||||
*/
|
*/
|
||||||
void Bsec::begin(uint8_t chipSelect, SPIClass &spi)
|
void Bsec::begin(uint8_t chipSelect, SPIClass &spi) {
|
||||||
{
|
|
||||||
_bme680.dev_id = chipSelect;
|
_bme680.dev_id = chipSelect;
|
||||||
_bme680.intf = BME680_SPI_INTF;
|
_bme680.intf = BME680_SPI_INTF;
|
||||||
_bme680.read = Bsec::spiTransfer;
|
_bme680.read = Bsec::spiTransfer;
|
||||||
@ -128,8 +125,7 @@ void Bsec::begin(uint8_t chipSelect, SPIClass &spi)
|
|||||||
/**
|
/**
|
||||||
* @brief Common code for the begin function
|
* @brief Common code for the begin function
|
||||||
*/
|
*/
|
||||||
void Bsec::beginCommon(void)
|
void Bsec::beginCommon(void) {
|
||||||
{
|
|
||||||
status = bsec_init();
|
status = bsec_init();
|
||||||
|
|
||||||
getVersion();
|
getVersion();
|
||||||
@ -140,8 +136,8 @@ void Bsec::beginCommon(void)
|
|||||||
/**
|
/**
|
||||||
* @brief Function that sets the desired sensors and the sample rates
|
* @brief Function that sets the desired sensors and the sample rates
|
||||||
*/
|
*/
|
||||||
void Bsec::updateSubscription(bsec_virtual_sensor_t sensorList[], uint8_t nSensors, float sampleRate)
|
void Bsec::updateSubscription(bsec_virtual_sensor_t sensorList[],
|
||||||
{
|
uint8_t nSensors, float sampleRate) {
|
||||||
bsec_sensor_configuration_t virtualSensors[BSEC_NUMBER_OUTPUTS],
|
bsec_sensor_configuration_t virtualSensors[BSEC_NUMBER_OUTPUTS],
|
||||||
sensorSettings[BSEC_MAX_PHYSICAL_SENSOR];
|
sensorSettings[BSEC_MAX_PHYSICAL_SENSOR];
|
||||||
uint8_t nVirtualSensors = 0, nSensorSettings = BSEC_MAX_PHYSICAL_SENSOR;
|
uint8_t nVirtualSensors = 0, nSensorSettings = BSEC_MAX_PHYSICAL_SENSOR;
|
||||||
@ -152,15 +148,16 @@ void Bsec::updateSubscription(bsec_virtual_sensor_t sensorList[], uint8_t nSenso
|
|||||||
nVirtualSensors++;
|
nVirtualSensors++;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = bsec_update_subscription(virtualSensors, nVirtualSensors, sensorSettings, &nSensorSettings);
|
status = bsec_update_subscription(virtualSensors, nVirtualSensors,
|
||||||
|
sensorSettings, &nSensorSettings);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Callback from the user to trigger reading of data from the BME680, process and store outputs
|
* @brief Callback from the user to trigger reading of data from the BME680,
|
||||||
|
* process and store outputs
|
||||||
*/
|
*/
|
||||||
bool Bsec::run(void)
|
bool Bsec::run(void) {
|
||||||
{
|
|
||||||
bool newData = false;
|
bool newData = false;
|
||||||
/* Check if the time has arrived to call do_steps() */
|
/* Check if the time has arrived to call do_steps() */
|
||||||
int64_t callTimeMs = getTimeMs();
|
int64_t callTimeMs = getTimeMs();
|
||||||
@ -175,7 +172,8 @@ bool Bsec::run(void)
|
|||||||
if (status < BSEC_OK)
|
if (status < BSEC_OK)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
nextCall = bme680Settings.next_call / INT64_C(1000000); // Convert from ns to ms
|
nextCall =
|
||||||
|
bme680Settings.next_call / INT64_C(1000000); // Convert from ns to ms
|
||||||
|
|
||||||
bme680Status = setBme680Config(bme680Settings);
|
bme680Status = setBme680Config(bme680Settings);
|
||||||
if (bme680Status != BME680_OK) {
|
if (bme680Status != BME680_OK) {
|
||||||
@ -200,33 +198,34 @@ bool Bsec::run(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to get the state of the algorithm to save to non-volatile memory
|
* @brief Function to get the state of the algorithm to save to non-volatile
|
||||||
|
* memory
|
||||||
*/
|
*/
|
||||||
void Bsec::getState(uint8_t *state)
|
void Bsec::getState(uint8_t *state) {
|
||||||
{
|
|
||||||
uint8_t workBuffer[BSEC_MAX_STATE_BLOB_SIZE];
|
uint8_t workBuffer[BSEC_MAX_STATE_BLOB_SIZE];
|
||||||
uint32_t n_serialized_state = BSEC_MAX_STATE_BLOB_SIZE;
|
uint32_t n_serialized_state = BSEC_MAX_STATE_BLOB_SIZE;
|
||||||
status = bsec_get_state(0, state, BSEC_MAX_STATE_BLOB_SIZE, workBuffer, BSEC_MAX_STATE_BLOB_SIZE, &n_serialized_state);
|
status = bsec_get_state(0, state, BSEC_MAX_STATE_BLOB_SIZE, workBuffer,
|
||||||
|
BSEC_MAX_STATE_BLOB_SIZE, &n_serialized_state);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to set the state of the algorithm from non-volatile memory
|
* @brief Function to set the state of the algorithm from non-volatile memory
|
||||||
*/
|
*/
|
||||||
void Bsec::setState(uint8_t *state)
|
void Bsec::setState(uint8_t *state) {
|
||||||
{
|
|
||||||
uint8_t workBuffer[BSEC_MAX_STATE_BLOB_SIZE];
|
uint8_t workBuffer[BSEC_MAX_STATE_BLOB_SIZE];
|
||||||
|
|
||||||
status = bsec_set_state(state, BSEC_MAX_STATE_BLOB_SIZE, workBuffer, BSEC_MAX_STATE_BLOB_SIZE);
|
status = bsec_set_state(state, BSEC_MAX_STATE_BLOB_SIZE, workBuffer,
|
||||||
|
BSEC_MAX_STATE_BLOB_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to set the configuration of the algorithm from memory
|
* @brief Function to set the configuration of the algorithm from memory
|
||||||
*/
|
*/
|
||||||
void Bsec::setConfig(const uint8_t *state)
|
void Bsec::setConfig(const uint8_t *state) {
|
||||||
{
|
|
||||||
uint8_t workBuffer[BSEC_MAX_PROPERTY_BLOB_SIZE];
|
uint8_t workBuffer[BSEC_MAX_PROPERTY_BLOB_SIZE];
|
||||||
|
|
||||||
status = bsec_set_configuration(state, BSEC_MAX_PROPERTY_BLOB_SIZE, workBuffer, sizeof(workBuffer));
|
status = bsec_set_configuration(state, BSEC_MAX_PROPERTY_BLOB_SIZE,
|
||||||
|
workBuffer, sizeof(workBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Private functions */
|
/* Private functions */
|
||||||
@ -234,16 +233,13 @@ void Bsec::setConfig(const uint8_t *state)
|
|||||||
/**
|
/**
|
||||||
* @brief Get the version of the BSEC library
|
* @brief Get the version of the BSEC library
|
||||||
*/
|
*/
|
||||||
void Bsec::getVersion(void)
|
void Bsec::getVersion(void) { bsec_get_version(&version); }
|
||||||
{
|
|
||||||
bsec_get_version(&version);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Read data from the BME680 and process it
|
* @brief Read data from the BME680 and process it
|
||||||
*/
|
*/
|
||||||
bool Bsec::readProcessData(int64_t currTimeNs, bsec_bme_settings_t bme680Settings)
|
bool Bsec::readProcessData(int64_t currTimeNs,
|
||||||
{
|
bsec_bme_settings_t bme680Settings) {
|
||||||
bme680Status = bme680_get_sensor_data(&_data, &_bme680);
|
bme680Status = bme680_get_sensor_data(&_data, &_bme680);
|
||||||
if (bme680Status != BME680_OK) {
|
if (bme680Status != BME680_OK) {
|
||||||
return false;
|
return false;
|
||||||
@ -255,10 +251,15 @@ bool Bsec::readProcessData(int64_t currTimeNs, bsec_bme_settings_t bme680Setting
|
|||||||
if (_data.status & BME680_NEW_DATA_MSK) {
|
if (_data.status & BME680_NEW_DATA_MSK) {
|
||||||
if (bme680Settings.process_data & BSEC_PROCESS_TEMPERATURE) {
|
if (bme680Settings.process_data & BSEC_PROCESS_TEMPERATURE) {
|
||||||
inputs[nInputs].sensor_id = BSEC_INPUT_TEMPERATURE;
|
inputs[nInputs].sensor_id = BSEC_INPUT_TEMPERATURE;
|
||||||
|
#ifdef BME680_FLOAT_POINT_COMPENSATION
|
||||||
inputs[nInputs].signal = _data.temperature;
|
inputs[nInputs].signal = _data.temperature;
|
||||||
|
#else
|
||||||
|
inputs[nInputs].signal = _data.temperature / 100.0f;
|
||||||
|
#endif
|
||||||
inputs[nInputs].time_stamp = currTimeNs;
|
inputs[nInputs].time_stamp = currTimeNs;
|
||||||
nInputs++;
|
nInputs++;
|
||||||
/* Temperature offset from the real temperature due to external heat sources */
|
/* Temperature offset from the real temperature due to external heat
|
||||||
|
* sources */
|
||||||
inputs[nInputs].sensor_id = BSEC_INPUT_HEATSOURCE;
|
inputs[nInputs].sensor_id = BSEC_INPUT_HEATSOURCE;
|
||||||
inputs[nInputs].signal = _tempOffset;
|
inputs[nInputs].signal = _tempOffset;
|
||||||
inputs[nInputs].time_stamp = currTimeNs;
|
inputs[nInputs].time_stamp = currTimeNs;
|
||||||
@ -266,7 +267,11 @@ bool Bsec::readProcessData(int64_t currTimeNs, bsec_bme_settings_t bme680Setting
|
|||||||
}
|
}
|
||||||
if (bme680Settings.process_data & BSEC_PROCESS_HUMIDITY) {
|
if (bme680Settings.process_data & BSEC_PROCESS_HUMIDITY) {
|
||||||
inputs[nInputs].sensor_id = BSEC_INPUT_HUMIDITY;
|
inputs[nInputs].sensor_id = BSEC_INPUT_HUMIDITY;
|
||||||
|
#ifdef BME680_FLOAT_POINT_COMPENSATION
|
||||||
inputs[nInputs].signal = _data.humidity;
|
inputs[nInputs].signal = _data.humidity;
|
||||||
|
#else
|
||||||
|
inputs[nInputs].signal = _data.humidity / 1000.0f;
|
||||||
|
#endif
|
||||||
inputs[nInputs].time_stamp = currTimeNs;
|
inputs[nInputs].time_stamp = currTimeNs;
|
||||||
nInputs++;
|
nInputs++;
|
||||||
}
|
}
|
||||||
@ -295,7 +300,8 @@ bool Bsec::readProcessData(int64_t currTimeNs, bsec_bme_settings_t bme680Setting
|
|||||||
zeroOutputs();
|
zeroOutputs();
|
||||||
|
|
||||||
if (nOutputs > 0) {
|
if (nOutputs > 0) {
|
||||||
outputTimestamp = _outputs[0].time_stamp / 1000000; // Convert from ns to ms
|
outputTimestamp =
|
||||||
|
_outputs[0].time_stamp / 1000000; // Convert from ns to ms
|
||||||
|
|
||||||
for (uint8_t i = 0; i < nOutputs; i++) {
|
for (uint8_t i = 0; i < nOutputs; i++) {
|
||||||
switch (_outputs[i].sensor_id) {
|
switch (_outputs[i].sensor_id) {
|
||||||
@ -361,24 +367,22 @@ bool Bsec::readProcessData(int64_t currTimeNs, bsec_bme_settings_t bme680Setting
|
|||||||
/**
|
/**
|
||||||
* @brief Set the BME680 sensor's configuration
|
* @brief Set the BME680 sensor's configuration
|
||||||
*/
|
*/
|
||||||
int8_t Bsec::setBme680Config(bsec_bme_settings_t bme680Settings)
|
int8_t Bsec::setBme680Config(bsec_bme_settings_t bme680Settings) {
|
||||||
{
|
|
||||||
_bme680.gas_sett.run_gas = bme680Settings.run_gas;
|
_bme680.gas_sett.run_gas = bme680Settings.run_gas;
|
||||||
_bme680.tph_sett.os_hum = bme680Settings.humidity_oversampling;
|
_bme680.tph_sett.os_hum = bme680Settings.humidity_oversampling;
|
||||||
_bme680.tph_sett.os_temp = bme680Settings.temperature_oversampling;
|
_bme680.tph_sett.os_temp = bme680Settings.temperature_oversampling;
|
||||||
_bme680.tph_sett.os_pres = bme680Settings.pressure_oversampling;
|
_bme680.tph_sett.os_pres = bme680Settings.pressure_oversampling;
|
||||||
_bme680.gas_sett.heatr_temp = bme680Settings.heater_temperature;
|
_bme680.gas_sett.heatr_temp = bme680Settings.heater_temperature;
|
||||||
_bme680.gas_sett.heatr_dur = bme680Settings.heating_duration;
|
_bme680.gas_sett.heatr_dur = bme680Settings.heating_duration;
|
||||||
uint16_t desired_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL
|
uint16_t desired_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL |
|
||||||
| BME680_GAS_SENSOR_SEL;
|
BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL;
|
||||||
return bme680_set_sensor_settings(desired_settings, &_bme680);
|
return bme680_set_sensor_settings(desired_settings, &_bme680);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Function to zero the outputs
|
* @brief Function to zero the outputs
|
||||||
*/
|
*/
|
||||||
void Bsec::zeroOutputs(void)
|
void Bsec::zeroOutputs(void) {
|
||||||
{
|
|
||||||
temperature = 0.0f;
|
temperature = 0.0f;
|
||||||
pressure = 0.0f;
|
pressure = 0.0f;
|
||||||
humidity = 0.0f;
|
humidity = 0.0f;
|
||||||
@ -404,8 +408,7 @@ void Bsec::zeroOutputs(void)
|
|||||||
/**
|
/**
|
||||||
* @brief Function to calculate an int64_t timestamp in milliseconds
|
* @brief Function to calculate an int64_t timestamp in milliseconds
|
||||||
*/
|
*/
|
||||||
int64_t Bsec::getTimeMs(void)
|
int64_t Bsec::getTimeMs(void) {
|
||||||
{
|
|
||||||
int64_t timeMs = millis();
|
int64_t timeMs = millis();
|
||||||
|
|
||||||
if (lastTime > timeMs) { // An overflow occured
|
if (lastTime > timeMs) { // An overflow occured
|
||||||
@ -419,8 +422,7 @@ int64_t Bsec::getTimeMs(void)
|
|||||||
/**
|
/**
|
||||||
@brief Task that delays for a ms period of time
|
@brief Task that delays for a ms period of time
|
||||||
*/
|
*/
|
||||||
void Bsec::delay_ms(uint32_t period)
|
void Bsec::delay_ms(uint32_t period) {
|
||||||
{
|
|
||||||
// Wait for a period amount of ms
|
// Wait for a period amount of ms
|
||||||
// The system may simply idle, sleep or even perform background tasks
|
// The system may simply idle, sleep or even perform background tasks
|
||||||
delay(period);
|
delay(period);
|
||||||
@ -429,15 +431,15 @@ void Bsec::delay_ms(uint32_t period)
|
|||||||
/**
|
/**
|
||||||
@brief Callback function for reading registers over I2C
|
@brief Callback function for reading registers over I2C
|
||||||
*/
|
*/
|
||||||
int8_t Bsec::i2cRead(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t length)
|
int8_t Bsec::i2cRead(uint8_t devId, uint8_t regAddr, uint8_t *regData,
|
||||||
{
|
uint16_t length) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
int8_t rslt = 0;
|
int8_t rslt = 0;
|
||||||
if(Bsec::wireObj) {
|
if (Bsec::wireObj) {
|
||||||
Bsec::wireObj->beginTransmission(devId);
|
Bsec::wireObj->beginTransmission(devId);
|
||||||
Bsec::wireObj->write(regAddr);
|
Bsec::wireObj->write(regAddr);
|
||||||
rslt = Bsec::wireObj->endTransmission();
|
rslt = Bsec::wireObj->endTransmission();
|
||||||
Bsec::wireObj->requestFrom((int) devId, (int) length);
|
Bsec::wireObj->requestFrom((int)devId, (int)length);
|
||||||
for (i = 0; (i < length) && Bsec::wireObj->available(); i++) {
|
for (i = 0; (i < length) && Bsec::wireObj->available(); i++) {
|
||||||
regData[i] = Bsec::wireObj->read();
|
regData[i] = Bsec::wireObj->read();
|
||||||
}
|
}
|
||||||
@ -450,11 +452,11 @@ int8_t Bsec::i2cRead(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t
|
|||||||
/**
|
/**
|
||||||
* @brief Callback function for writing registers over I2C
|
* @brief Callback function for writing registers over I2C
|
||||||
*/
|
*/
|
||||||
int8_t Bsec::i2cWrite(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t length)
|
int8_t Bsec::i2cWrite(uint8_t devId, uint8_t regAddr, uint8_t *regData,
|
||||||
{
|
uint16_t length) {
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
int8_t rslt = 0;
|
int8_t rslt = 0;
|
||||||
if(Bsec::wireObj) {
|
if (Bsec::wireObj) {
|
||||||
Bsec::wireObj->beginTransmission(devId);
|
Bsec::wireObj->beginTransmission(devId);
|
||||||
Bsec::wireObj->write(regAddr);
|
Bsec::wireObj->write(regAddr);
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
@ -471,15 +473,17 @@ int8_t Bsec::i2cWrite(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t
|
|||||||
/**
|
/**
|
||||||
* @brief Callback function for reading and writing registers over SPI
|
* @brief Callback function for reading and writing registers over SPI
|
||||||
*/
|
*/
|
||||||
int8_t Bsec::spiTransfer(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint16_t length)
|
int8_t Bsec::spiTransfer(uint8_t devId, uint8_t regAddr, uint8_t *regData,
|
||||||
{
|
uint16_t length) {
|
||||||
int8_t rslt = 0;
|
int8_t rslt = 0;
|
||||||
if(Bsec::spiObj) {
|
if (Bsec::spiObj) {
|
||||||
Bsec::spiObj->beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0)); // Can be upto 10MHz
|
Bsec::spiObj->beginTransaction(
|
||||||
|
SPISettings(4000000, MSBFIRST, SPI_MODE0)); // Can be upto 10MHz
|
||||||
|
|
||||||
digitalWrite(devId, LOW);
|
digitalWrite(devId, LOW);
|
||||||
|
|
||||||
Bsec::spiObj->transfer(regAddr); // Write the register address, ignore the return
|
Bsec::spiObj->transfer(
|
||||||
|
regAddr); // Write the register address, ignore the return
|
||||||
for (uint16_t i = 0; i < length; i++)
|
for (uint16_t i = 0; i < length; i++)
|
||||||
regData[i] = Bsec::spiObj->transfer(regData[i]);
|
regData[i] = Bsec::spiObj->transfer(regData[i]);
|
||||||
|
|
||||||
@ -489,5 +493,6 @@ int8_t Bsec::spiTransfer(uint8_t devId, uint8_t regAddr, uint8_t *regData, uint1
|
|||||||
rslt = -1;
|
rslt = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return rslt;;
|
return rslt;
|
||||||
|
;
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ description = Paxcounter is a proof-of-concept ESP32 device for metering passeng
|
|||||||
release_version = 1.7.03
|
release_version = 1.7.03
|
||||||
; DEBUG LEVEL: For production run set to 0, otherwise device will leak RAM while running!
|
; 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
|
; 0=None, 1=Error, 2=Warn, 3=Info, 4=Debug, 5=Verbose
|
||||||
debug_level = 4
|
debug_level = 3
|
||||||
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
; UPLOAD MODE: select esptool to flash via USB/UART, select custom to upload to cloud for OTA
|
||||||
upload_protocol = esptool
|
upload_protocol = esptool
|
||||||
;upload_protocol = custom
|
;upload_protocol = custom
|
||||||
|
@ -7,13 +7,29 @@ static const char TAG[] = "main";
|
|||||||
|
|
||||||
bmeStatus_t bme_status;
|
bmeStatus_t bme_status;
|
||||||
TaskHandle_t BmeTask;
|
TaskHandle_t BmeTask;
|
||||||
float bme_offset = (float)BME_TEMP_OFFSET;
|
|
||||||
|
|
||||||
Bsec iaqSensor;
|
Bsec iaqSensor;
|
||||||
|
|
||||||
|
bsec_virtual_sensor_t sensorList[10] = {
|
||||||
|
BSEC_OUTPUT_RAW_TEMPERATURE,
|
||||||
|
BSEC_OUTPUT_RAW_PRESSURE,
|
||||||
|
BSEC_OUTPUT_RAW_HUMIDITY,
|
||||||
|
BSEC_OUTPUT_RAW_GAS,
|
||||||
|
BSEC_OUTPUT_IAQ,
|
||||||
|
BSEC_OUTPUT_STATIC_IAQ,
|
||||||
|
BSEC_OUTPUT_CO2_EQUIVALENT,
|
||||||
|
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
|
||||||
|
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
|
||||||
|
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
||||||
|
};
|
||||||
|
|
||||||
// initialize BME680 sensor
|
// initialize BME680 sensor
|
||||||
int bme_init(void) {
|
int bme_init(void) {
|
||||||
|
|
||||||
|
// block i2c bus access
|
||||||
|
if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) ==
|
||||||
|
pdTRUE) {
|
||||||
|
|
||||||
Wire.begin(HAS_BME);
|
Wire.begin(HAS_BME);
|
||||||
iaqSensor.begin(BME_ADDR, Wire);
|
iaqSensor.begin(BME_ADDR, Wire);
|
||||||
|
|
||||||
@ -30,19 +46,7 @@ int bme_init(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bsec_virtual_sensor_t sensorList[10] = {
|
iaqSensor.setTemperatureOffset((float)BME_TEMP_OFFSET);
|
||||||
BSEC_OUTPUT_RAW_TEMPERATURE,
|
|
||||||
BSEC_OUTPUT_RAW_PRESSURE,
|
|
||||||
BSEC_OUTPUT_RAW_HUMIDITY,
|
|
||||||
BSEC_OUTPUT_RAW_GAS,
|
|
||||||
BSEC_OUTPUT_IAQ,
|
|
||||||
BSEC_OUTPUT_STATIC_IAQ,
|
|
||||||
BSEC_OUTPUT_CO2_EQUIVALENT,
|
|
||||||
BSEC_OUTPUT_BREATH_VOC_EQUIVALENT,
|
|
||||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE,
|
|
||||||
BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY,
|
|
||||||
};
|
|
||||||
|
|
||||||
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP);
|
||||||
|
|
||||||
if (checkIaqSensorStatus())
|
if (checkIaqSensorStatus())
|
||||||
@ -52,15 +56,14 @@ int bme_init(void) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
iaqSensor.setTemperatureOffset(bme_offset);
|
xSemaphoreGive(I2Caccess); // release i2c bus access
|
||||||
|
|
||||||
if (checkIaqSensorStatus())
|
} else {
|
||||||
ESP_LOGI(TAG, "Ttemperature offset initialized succesful");
|
ESP_LOGE(TAG, "I2c bus busy - BME680 initialization error");
|
||||||
else {
|
|
||||||
ESP_LOGE(TAG, "Temperature offset initialization error");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
} // bme_init()
|
||||||
|
|
||||||
// Helper function definitions
|
// Helper function definitions
|
||||||
int checkIaqSensorStatus(void) {
|
int checkIaqSensorStatus(void) {
|
||||||
@ -83,7 +86,7 @@ int checkIaqSensorStatus(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return rslt;
|
return rslt;
|
||||||
}
|
} // checkIaqSensorStatus()
|
||||||
|
|
||||||
// loop function which reads and processes data based on sensor settings
|
// loop function which reads and processes data based on sensor settings
|
||||||
void bme_loop(void *pvParameters) {
|
void bme_loop(void *pvParameters) {
|
||||||
@ -92,6 +95,11 @@ void bme_loop(void *pvParameters) {
|
|||||||
|
|
||||||
#ifdef HAS_BME
|
#ifdef HAS_BME
|
||||||
while (checkIaqSensorStatus()) {
|
while (checkIaqSensorStatus()) {
|
||||||
|
|
||||||
|
// block i2c bus access
|
||||||
|
if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) ==
|
||||||
|
pdTRUE) {
|
||||||
|
|
||||||
if (iaqSensor.run()) { // If new data is available
|
if (iaqSensor.run()) { // If new data is available
|
||||||
bme_status.raw_temperature = iaqSensor.rawTemperature;
|
bme_status.raw_temperature = iaqSensor.rawTemperature;
|
||||||
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
bme_status.raw_humidity = iaqSensor.rawHumidity;
|
||||||
@ -103,6 +111,9 @@ void bme_loop(void *pvParameters) {
|
|||||||
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
bme_status.iaq_accuracy = iaqSensor.iaqAccuracy;
|
||||||
bme_status.gas = iaqSensor.gasResistance;
|
bme_status.gas = iaqSensor.gasResistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
xSemaphoreGive(I2Caccess); // release i2c bus access
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ESP_LOGE(TAG, "BME task ended");
|
ESP_LOGE(TAG, "BME task ended");
|
||||||
|
@ -52,7 +52,12 @@ void doHousekeeping() {
|
|||||||
// read battery voltage into global variable
|
// read battery voltage into global variable
|
||||||
#ifdef HAS_BATTERY_PROBE
|
#ifdef HAS_BATTERY_PROBE
|
||||||
batt_voltage = read_voltage();
|
batt_voltage = read_voltage();
|
||||||
ESP_LOGI(TAG, "Measured Voltage: %dmV", batt_voltage);
|
ESP_LOGI(TAG, "Voltage: %dmV", batt_voltage);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// display BME sensor data if present
|
||||||
|
#ifdef HAS_BME
|
||||||
|
ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f", bme_status.temperature, bme_status.iaq);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// check free heap memory
|
// check free heap memory
|
||||||
|
@ -98,6 +98,10 @@ void init_display(const char *Productname, const char *Version) {
|
|||||||
|
|
||||||
void refreshtheDisplay() {
|
void refreshtheDisplay() {
|
||||||
|
|
||||||
|
// block i2c bus access
|
||||||
|
if (xSemaphoreTake(I2Caccess, (DISPLAYREFRESH_MS / portTICK_PERIOD_MS)) ==
|
||||||
|
pdTRUE) {
|
||||||
|
|
||||||
// set display on/off according to current device configuration
|
// set display on/off according to current device configuration
|
||||||
if (DisplayState != cfg.screenon) {
|
if (DisplayState != cfg.screenon) {
|
||||||
DisplayState = cfg.screenon;
|
DisplayState = cfg.screenon;
|
||||||
@ -114,7 +118,8 @@ void refreshtheDisplay() {
|
|||||||
// update counter (lines 0-1)
|
// update counter (lines 0-1)
|
||||||
snprintf(
|
snprintf(
|
||||||
buff, sizeof(buff), "PAX:%-4d",
|
buff, sizeof(buff), "PAX:%-4d",
|
||||||
(int)macs.size()); // convert 16-bit MAC counter to decimal counter value
|
(int)
|
||||||
|
macs.size()); // convert 16-bit MAC counter to decimal counter value
|
||||||
u8x8.draw2x2String(0, 0,
|
u8x8.draw2x2String(0, 0,
|
||||||
buff); // display number on unique macs total Wifi + BLE
|
buff); // display number on unique macs total Wifi + BLE
|
||||||
|
|
||||||
@ -188,6 +193,9 @@ void refreshtheDisplay() {
|
|||||||
|
|
||||||
#endif // HAS_LORA
|
#endif // HAS_LORA
|
||||||
|
|
||||||
|
xSemaphoreGive(I2Caccess); // release i2c bus access
|
||||||
|
}
|
||||||
|
|
||||||
} // refreshDisplay()
|
} // refreshDisplay()
|
||||||
|
|
||||||
#endif // HAS_DISPLAY
|
#endif // HAS_DISPLAY
|
@ -19,10 +19,10 @@
|
|||||||
// user defined sensors
|
// user defined sensors
|
||||||
//#define HAS_SENSORS 1 // comment out if device has user defined sensors
|
//#define HAS_SENSORS 1 // comment out if device has user defined sensors
|
||||||
|
|
||||||
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
//#define MY_OLED_SDA (21)
|
#define MY_OLED_SDA (21)
|
||||||
//#define MY_OLED_SCL (22)
|
#define MY_OLED_SCL (22)
|
||||||
//#define MY_OLED_RST (NOT_A_PIN)
|
#define MY_OLED_RST U8X8_PIN_NONE
|
||||||
//#define DISPLAY_FLIP 1 // use if display is rotated
|
//#define DISPLAY_FLIP 1 // use if display is rotated
|
||||||
|
|
||||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||||
|
@ -22,7 +22,7 @@
|
|||||||
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
//#define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C
|
||||||
//#define MY_OLED_SDA (21)
|
//#define MY_OLED_SDA (21)
|
||||||
//#define MY_OLED_SCL (22)
|
//#define MY_OLED_SCL (22)
|
||||||
//#define MY_OLED_RST (NOT_A_PIN)
|
//#define MY_OLED_RST U8X8_PIN_NONE
|
||||||
//#define DISPLAY_FLIP 1 // use if display is rotated
|
//#define DISPLAY_FLIP 1 // use if display is rotated
|
||||||
|
|
||||||
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
#define HAS_LORA 1 // comment out if device shall not send data via LoRa
|
||||||
|
18
src/main.cpp
18
src/main.cpp
@ -35,11 +35,14 @@ IDLE 0 0 ESP32 arduino scheduler -> runs wifi sniffer
|
|||||||
looptask 1 1 arduino core -> runs the LMIC LoRa stack
|
looptask 1 1 arduino core -> runs the LMIC LoRa stack
|
||||||
irqhandler 1 1 executes tasks triggered by irq
|
irqhandler 1 1 executes tasks triggered by irq
|
||||||
gpsloop 1 2 reads data from GPS via serial or i2c
|
gpsloop 1 2 reads data from GPS via serial or i2c
|
||||||
bmeloop 1 0 reads data from BME sensor via i2c
|
bmeloop 1 1 reads data from BME sensor via i2c
|
||||||
IDLE 1 0 ESP32 arduino scheduler
|
IDLE 1 0 ESP32 arduino scheduler
|
||||||
|
|
||||||
Low priority numbers denote low priority tasks.
|
Low priority numbers denote low priority tasks.
|
||||||
|
|
||||||
|
Tasks using i2c bus all must have same priority, because using mutex semaphore
|
||||||
|
(irqhandler, bmeloop)
|
||||||
|
|
||||||
ESP32 hardware timers
|
ESP32 hardware timers
|
||||||
==========================
|
==========================
|
||||||
0 Trigger display refresh
|
0 Trigger display refresh
|
||||||
@ -60,6 +63,7 @@ uint16_t volatile macs_total = 0, macs_wifi = 0, macs_ble = 0,
|
|||||||
hw_timer_t *channelSwitch = NULL, *sendCycle = NULL, *homeCycle = NULL,
|
hw_timer_t *channelSwitch = NULL, *sendCycle = NULL, *homeCycle = NULL,
|
||||||
*displaytimer = NULL; // irq tasks
|
*displaytimer = NULL; // irq tasks
|
||||||
TaskHandle_t irqHandlerTask, wifiSwitchTask;
|
TaskHandle_t irqHandlerTask, wifiSwitchTask;
|
||||||
|
SemaphoreHandle_t I2Caccess;
|
||||||
|
|
||||||
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
|
// container holding unique MAC address hashes with Memory Alloctor using PSRAM,
|
||||||
// if present
|
// if present
|
||||||
@ -78,6 +82,14 @@ void setup() {
|
|||||||
|
|
||||||
char features[100] = "";
|
char features[100] = "";
|
||||||
|
|
||||||
|
if (I2Caccess == NULL) // Check that semaphore has not already been created
|
||||||
|
{
|
||||||
|
I2Caccess = xSemaphoreCreateMutex(); // Create a mutex semaphore we will use
|
||||||
|
// to manage the i2c bus
|
||||||
|
if ((I2Caccess) != NULL)
|
||||||
|
xSemaphoreGive((I2Caccess)); // Flag the i2c bus available for use
|
||||||
|
}
|
||||||
|
|
||||||
// disable brownout detection
|
// disable brownout detection
|
||||||
#ifdef DISABLE_BROWNOUT
|
#ifdef DISABLE_BROWNOUT
|
||||||
// register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4
|
// register with brownout is at address DR_REG_RTCCNTL_BASE + 0xd4
|
||||||
@ -343,11 +355,11 @@ void setup() {
|
|||||||
"bmeloop", // name of task
|
"bmeloop", // name of task
|
||||||
4096, // stack size of task
|
4096, // stack size of task
|
||||||
(void *)1, // parameter of the task
|
(void *)1, // parameter of the task
|
||||||
0, // priority of the task
|
//0, // priority of the task
|
||||||
|
1, // priority of the task
|
||||||
&BmeTask, // task handle
|
&BmeTask, // task handle
|
||||||
1); // CPU core
|
1); // CPU core
|
||||||
}
|
}
|
||||||
delay(2000); // time for initializing i2c sensor
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start timer triggered interrupts
|
// start timer triggered interrupts
|
||||||
|
Loading…
Reference in New Issue
Block a user