first commit
This commit is contained in:
commit
5893b00dd2
1669 changed files with 1982740 additions and 0 deletions
|
|
@ -0,0 +1,232 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2021 Bosch Sensortec GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* bme688_dev_kit.ino :
|
||||
* This is an example to log data using the BME688 development
|
||||
* kit which has been designed to work with Adafruit ESP32 Feather Board
|
||||
* For more information visit :
|
||||
* https://www.bosch-sensortec.com/software-tools/software/bme688-software/
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "bme68xLibrary.h"
|
||||
#include "commMux.h"
|
||||
|
||||
#include <SdFat.h>
|
||||
#include <Esp.h>
|
||||
|
||||
/* Macros used in BME68x_datalogger module */
|
||||
#define N_KIT_SENS 8
|
||||
#define SD_PIN_CS 33
|
||||
#define PANIC_LED LED_BUILTIN
|
||||
#define PANIC_DUR 1000
|
||||
/* measurement duration */
|
||||
#define MEAS_DUR 140
|
||||
#define LOG_FILE_NAME "/BME688_Datalogger_Log.csv"
|
||||
|
||||
/* Declaration of variables */
|
||||
Bme68x bme[N_KIT_SENS];
|
||||
commMux commSetup[N_KIT_SENS];
|
||||
uint8_t lastMeasindex[N_KIT_SENS] = {0};
|
||||
bme68xData sensorData[N_KIT_SENS] = {0};
|
||||
String logHeader;
|
||||
uint32_t lastLogged = 0;
|
||||
|
||||
static SdFat sd;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sensor and hardware settings
|
||||
* Initializes the SD card module
|
||||
*/
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
/* Initiate SPI communication */
|
||||
commMuxBegin(Wire, SPI);
|
||||
pinMode(PANIC_LED, OUTPUT);
|
||||
delay(100);
|
||||
|
||||
/* Setting SD Card */
|
||||
if (!sd.begin(SD_PIN_CS, SPI_EIGHTH_SPEED)) {
|
||||
Serial.println("SD Card not found");
|
||||
panicLeds();
|
||||
} else {
|
||||
sd.remove(LOG_FILE_NAME);
|
||||
File file;
|
||||
|
||||
if (!file.open(LOG_FILE_NAME, (O_RDWR | O_CREAT))) {
|
||||
Serial.println("Failed to open file for writing");
|
||||
panicLeds();
|
||||
}
|
||||
/* Parameters for logging in the file */
|
||||
logHeader = "TimeStamp(ms),Sensor Index,Temperature(deg "
|
||||
"C),Pressure(Pa),Humidity(%),Gas Resistance(ohm),Gas "
|
||||
"Index,Meas Index,idac,Status,Gas Valid,Heater Stable";
|
||||
|
||||
if (file.println(logHeader)) {
|
||||
Serial.println(logHeader);
|
||||
file.close();
|
||||
} else {
|
||||
panicLeds();
|
||||
}
|
||||
logHeader = "";
|
||||
}
|
||||
|
||||
/* Communication interface set for all the 8 sensors in the development kit */
|
||||
for (uint8_t i = 0; i < N_KIT_SENS; i++) {
|
||||
commSetup[i] = commMuxSetConfig(Wire, SPI, i, commSetup[i]);
|
||||
bme[i].begin(BME68X_SPI_INTF, commMuxRead, commMuxWrite, commMuxDelay,
|
||||
&commSetup[i]);
|
||||
if(bme[i].checkStatus()) {
|
||||
Serial.println("Initializing sensor " + String(i) + " failed with error " + bme[i].statusString());
|
||||
panicLeds();
|
||||
}
|
||||
}
|
||||
|
||||
/* Setting the default heater profile configuration */
|
||||
for (uint8_t i = 0; i < N_KIT_SENS; i++) {
|
||||
bme[i].setTPH();
|
||||
|
||||
/* Heater temperature in degree Celsius as per the suggested heater profile
|
||||
*/
|
||||
uint16_t tempProf[10] = {320, 100, 100, 100, 200, 200, 200, 320, 320, 320};
|
||||
/* Multiplier to the shared heater duration */
|
||||
uint16_t mulProf[10] = {5, 2, 10, 30, 5, 5, 5, 5, 5, 5};
|
||||
/* Shared heating duration in milliseconds */
|
||||
uint16_t sharedHeatrDur =
|
||||
MEAS_DUR - (bme[i].getMeasDur(BME68X_PARALLEL_MODE) / INT64_C(1000));
|
||||
|
||||
bme[i].setHeaterProf(tempProf, mulProf, sharedHeatrDur, 10);
|
||||
|
||||
/* Parallel mode of sensor operation */
|
||||
bme[i].setOpMode(BME68X_PARALLEL_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
uint8_t nFieldsLeft = 0;
|
||||
int16_t indexDiff;
|
||||
bool newLogdata = false;
|
||||
/* Control loop for data acquisition - checks if the data is available */
|
||||
if ((millis() - lastLogged) >= MEAS_DUR) {
|
||||
|
||||
lastLogged = millis();
|
||||
for (uint8_t i = 0; i < N_KIT_SENS; i++) {
|
||||
if (bme[i].fetchData()) {
|
||||
do {
|
||||
nFieldsLeft = bme[i].getData(sensorData[i]);
|
||||
/* Check if new data is received */
|
||||
if (sensorData[i].status & BME68X_NEW_DATA_MSK) {
|
||||
/* Inspect miss of data index */
|
||||
indexDiff =
|
||||
(int16_t)sensorData[i].meas_index - (int16_t)lastMeasindex[i];
|
||||
if (indexDiff > 1) {
|
||||
|
||||
Serial.println("Skip I:" + String(i) +
|
||||
", DIFF:" + String(indexDiff) +
|
||||
", MI:" + String(sensorData[i].meas_index) +
|
||||
", LMI:" + String(lastMeasindex[i]) +
|
||||
", S:" + String(sensorData[i].status, HEX));
|
||||
panicLeds();
|
||||
}
|
||||
lastMeasindex[i] = sensorData[i].meas_index;
|
||||
|
||||
logHeader += millis();
|
||||
logHeader += ",";
|
||||
logHeader += i;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].temperature;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].pressure;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].humidity;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].gas_resistance;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].gas_index;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].meas_index;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].idac;
|
||||
logHeader += ",";
|
||||
logHeader += String(sensorData[i].status, HEX);
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].status & BME68X_GASM_VALID_MSK;
|
||||
logHeader += ",";
|
||||
logHeader += sensorData[i].status & BME68X_HEAT_STAB_MSK;
|
||||
logHeader += "\r\n";
|
||||
newLogdata = true;
|
||||
}
|
||||
} while (nFieldsLeft);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newLogdata) {
|
||||
newLogdata = false;
|
||||
|
||||
digitalWrite(PANIC_LED, HIGH);
|
||||
|
||||
appendFile(logHeader);
|
||||
logHeader = "";
|
||||
|
||||
digitalWrite(PANIC_LED, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Configuring the sensor with digital pin 13 as
|
||||
* an output and toggles it at one second pace
|
||||
*/
|
||||
static void panicLeds(void) {
|
||||
while (1) {
|
||||
digitalWrite(PANIC_LED, HIGH);
|
||||
delay(PANIC_DUR);
|
||||
digitalWrite(PANIC_LED, LOW);
|
||||
delay(PANIC_DUR);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Writing the sensor data to the log file(csv)
|
||||
* @param sensorData
|
||||
*/
|
||||
static void writeFile(String sensorData) {
|
||||
|
||||
File file;
|
||||
|
||||
if (!file.open(LOG_FILE_NAME, (O_RDWR | O_AT_END))) {
|
||||
Serial.println("Failed to open file for writing");
|
||||
panicLeds();
|
||||
}
|
||||
if (file.print(sensorData)) {
|
||||
Serial.print(sensorData);
|
||||
} else {
|
||||
Serial.println("Write failed");
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
/*!
|
||||
* @brief Appending the sensor data into the log file(csv)
|
||||
* @param sensorData
|
||||
*/
|
||||
static void appendFile(String sensorData) {
|
||||
File file;
|
||||
|
||||
if (!file.open(LOG_FILE_NAME, (O_RDWR | O_AT_END))) {
|
||||
Serial.println("Failed to open file for appending");
|
||||
panicLeds();
|
||||
}
|
||||
if (file.print(sensorData)) {
|
||||
Serial.print(sensorData);
|
||||
} else {
|
||||
Serial.println("Write append");
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/**
|
||||
Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
|
||||
|
||||
BSD-3-Clause
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@file commMux.cpp
|
||||
@date 11 Jan 2023
|
||||
@version 1.2.40408
|
||||
|
||||
*/
|
||||
|
||||
#include "commMux.h"
|
||||
|
||||
#define CLOCK_FREQUENCY 400000
|
||||
#define COMM_SPEED 8000000
|
||||
|
||||
const uint8_t I2C_EXPANDER_ADDR = 0x20;
|
||||
const uint8_t I2C_EXPANDER_OUTPUT_REG_ADDR = 0x01;
|
||||
const uint8_t I2C_EXPANDER_OUTPUT_DESELECT = 0xFF;
|
||||
const uint8_t I2C_EXPANDER_CONFIG_REG_ADDR = 0x03;
|
||||
const uint8_t I2C_EXPANDER_CONFIG_REG_MASK = 0x00;
|
||||
|
||||
/**
|
||||
* @brief Function to configure the communication across sensors
|
||||
*/
|
||||
commMux commMuxSetConfig(TwoWire &wireobj, SPIClass &spiobj, uint8_t idx, commMux &comm)
|
||||
{
|
||||
comm.select = ((0x01 << idx) ^ 0xFF);
|
||||
comm.spiobj = &spiobj;
|
||||
comm.wireobj = &wireobj;
|
||||
|
||||
return comm;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to trigger the communication
|
||||
*/
|
||||
void commMuxBegin(TwoWire &wireobj, SPIClass &spiobj)
|
||||
{
|
||||
wireobj.begin();
|
||||
wireobj.setClock(CLOCK_FREQUENCY);
|
||||
wireobj.beginTransmission(I2C_EXPANDER_ADDR);
|
||||
wireobj.write(I2C_EXPANDER_CONFIG_REG_ADDR);
|
||||
wireobj.write(I2C_EXPANDER_CONFIG_REG_MASK);
|
||||
wireobj.endTransmission();
|
||||
|
||||
spiobj.begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to set the ship select pin of the SPI
|
||||
*/
|
||||
static void setChipSelect(TwoWire *wireobj, uint8_t mask)
|
||||
{
|
||||
// send I2C-Expander device address
|
||||
wireobj->beginTransmission(I2C_EXPANDER_ADDR);
|
||||
// send I2C-Expander output register address
|
||||
wireobj->write(I2C_EXPANDER_OUTPUT_REG_ADDR);
|
||||
// send mask to set output level of GPIO pins
|
||||
wireobj->write(mask);
|
||||
// end communication
|
||||
wireobj->endTransmission();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to write the sensor data to the register
|
||||
*/
|
||||
int8_t commMuxWrite(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr)
|
||||
{
|
||||
commMux *comm = (commMux*) intf_ptr;
|
||||
uint32_t i;
|
||||
|
||||
if (comm)
|
||||
{
|
||||
setChipSelect(comm->wireobj, comm->select);
|
||||
|
||||
comm->spiobj->beginTransaction(SPISettings(COMM_SPEED, MSBFIRST, SPI_MODE0));
|
||||
comm->spiobj->transfer(reg_addr);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
comm->spiobj->transfer(reg_data[i]);
|
||||
}
|
||||
comm->spiobj->endTransaction();
|
||||
|
||||
setChipSelect(comm->wireobj, I2C_EXPANDER_OUTPUT_DESELECT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to read the sensor data from the register
|
||||
*/
|
||||
int8_t commMuxRead(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr)
|
||||
{
|
||||
commMux *comm = (commMux*) intf_ptr;
|
||||
uint32_t i;
|
||||
|
||||
if (comm)
|
||||
{
|
||||
setChipSelect(comm->wireobj, comm->select);
|
||||
|
||||
comm->spiobj->beginTransaction(SPISettings(COMM_SPEED, MSBFIRST, SPI_MODE0));
|
||||
comm->spiobj->transfer(reg_addr);
|
||||
for (i = 0; i < length; i++)
|
||||
{
|
||||
reg_data[i] = comm->spiobj->transfer(0xFF);
|
||||
}
|
||||
comm->spiobj->endTransaction();
|
||||
|
||||
setChipSelect(comm->wireobj, I2C_EXPANDER_OUTPUT_DESELECT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Function to maintain a delay between communication
|
||||
*/
|
||||
void commMuxDelay(uint32_t period_us, void *intf_ptr)
|
||||
{
|
||||
(void) intf_ptr;
|
||||
delayMicroseconds(period_us);
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
Copyright (c) 2021 Bosch Sensortec GmbH. All rights reserved.
|
||||
|
||||
BSD-3-Clause
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
3. Neither the name of the copyright holder nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
@file commMux.h
|
||||
@date 11 Jan 2023
|
||||
@version 1.2.40408
|
||||
|
||||
*/
|
||||
#ifndef COMM_MUX_H
|
||||
#define COMM_MUX_H
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "Wire.h"
|
||||
#include "SPI.h"
|
||||
|
||||
/**
|
||||
* Datatype working as an interface descriptor
|
||||
*/
|
||||
typedef struct {
|
||||
TwoWire *wireobj;
|
||||
SPIClass *spiobj;
|
||||
uint8_t select;
|
||||
} commMux;
|
||||
|
||||
/**
|
||||
* @brief Function to configure the communication across sensors
|
||||
* @param wireobj : The TwoWire object
|
||||
* @param spiobj : The SPIClass object
|
||||
* @param idx : Selected sensor for communication interface
|
||||
* @param comm : Structure for selected sensor
|
||||
* @return : Structure holding the communication setup
|
||||
*/
|
||||
commMux commMuxSetConfig(TwoWire &wireobj, SPIClass &spiobj, uint8_t idx, commMux &comm);
|
||||
|
||||
/**
|
||||
* @brief Function to trigger the communication
|
||||
* @param wireobj : The TwoWire object
|
||||
* @param spiobj : The SPIClass object
|
||||
*/
|
||||
void commMuxBegin(TwoWire &wireobj, SPIClass &spiobj);
|
||||
|
||||
/**
|
||||
* @brief Function to write the sensor data to the register
|
||||
* @param reg_addr : Address of the register
|
||||
* @param reg_data : Pointer to the data to be written
|
||||
* @param length : length of the register data
|
||||
* @param intf_ptr : Pointer to the interface descriptor
|
||||
* @return 0 if successful, non-zero otherwise
|
||||
*/
|
||||
int8_t commMuxWrite(uint8_t reg_addr, const uint8_t *reg_data, uint32_t length, void *intf_ptr);
|
||||
|
||||
/**
|
||||
* @brief Function to read the sensor data from the register
|
||||
* @param reg_addr : Address of the register
|
||||
* @param reg_data : Pointer to the data to be read from the sensor
|
||||
* @param length : length of the register data
|
||||
* @param intf_ptr : Pointer to the interface descriptor
|
||||
* @return 0 if successful, non-zero otherwise
|
||||
*/
|
||||
int8_t commMuxRead(uint8_t reg_addr, uint8_t *reg_data, uint32_t length, void *intf_ptr);
|
||||
|
||||
/**
|
||||
* @brief Function to maintain a delay between communication
|
||||
* @param period_us : Time delay in micro secs
|
||||
* @param intf_ptr : Pointer to the interface descriptor
|
||||
*/
|
||||
void commMuxDelay(uint32_t period_us, void *intf_ptr);
|
||||
|
||||
#endif /* COMM_MUX_H */
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* Copyright (C) 2021 Bosch Sensortec GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "bme68xLibrary.h"
|
||||
|
||||
#ifndef PIN_CS
|
||||
#define PIN_CS SS
|
||||
#endif
|
||||
|
||||
Bme68x bme;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sensor and hardware settings
|
||||
*/
|
||||
void setup(void)
|
||||
{
|
||||
SPI.begin();
|
||||
Serial.begin(115200);
|
||||
|
||||
while (!Serial)
|
||||
delay(10);
|
||||
|
||||
/* initializes the sensor based on SPI library */
|
||||
bme.begin(PIN_CS, SPI);
|
||||
|
||||
if(bme.checkStatus())
|
||||
{
|
||||
if (bme.checkStatus() == BME68X_ERROR)
|
||||
{
|
||||
Serial.println("Sensor error:" + bme.statusString());
|
||||
return;
|
||||
}
|
||||
else if (bme.checkStatus() == BME68X_WARNING)
|
||||
{
|
||||
Serial.println("Sensor Warning:" + bme.statusString());
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the default configuration for temperature, pressure and humidity */
|
||||
bme.setTPH();
|
||||
|
||||
/* Set the heater configuration to 300 deg C for 100ms for Forced mode */
|
||||
bme.setHeaterProf(300, 100);
|
||||
|
||||
Serial.println("TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%), Gas resistance(ohm), Status");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
bme68xData data;
|
||||
|
||||
bme.setOpMode(BME68X_FORCED_MODE);
|
||||
delayMicroseconds(bme.getMeasDur());
|
||||
|
||||
if (bme.fetchData())
|
||||
{
|
||||
bme.getData(data);
|
||||
Serial.print(String(millis()) + ", ");
|
||||
Serial.print(String(data.temperature) + ", ");
|
||||
Serial.print(String(data.pressure) + ", ");
|
||||
Serial.print(String(data.humidity) + ", ");
|
||||
Serial.print(String(data.gas_resistance) + ", ");
|
||||
Serial.println(data.status, HEX);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 3.16.0)
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(forced_mode_idf)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
; PlatformIO Project Configuration File
|
||||
;
|
||||
; Build options: build flags, source filter
|
||||
; Upload options: custom upload port, speed and extra flags
|
||||
; Library options: dependencies, extra library storages
|
||||
; Advanced options: extra scripting
|
||||
;
|
||||
; Please visit documentation for the other options and examples
|
||||
; https://docs.platformio.org/page/projectconf.html
|
||||
|
||||
[env:esp32dev]
|
||||
platform = espressif32@6.6.0
|
||||
board = esp32dev
|
||||
framework = espidf
|
||||
platform_packages =
|
||||
platformio/framework-espidf@~3.50201.0
|
||||
lib_deps =
|
||||
../../
|
||||
https://github.com/natanaeljr/esp32-I2Cbus
|
||||
monitor_speed = 115200
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# This file was automatically generated for projects
|
||||
# without default 'CMakeLists.txt' file.
|
||||
|
||||
FILE(GLOB_RECURSE app_sources ${CMAKE_SOURCE_DIR}/src/*.*)
|
||||
|
||||
idf_component_register(SRCS ${app_sources})
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/**
|
||||
* Copyright (C) 2021 Bosch Sensortec GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "esp_log.h"
|
||||
#include "esp_timer.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "bme68xLibrary.h"
|
||||
#include "I2Cbus.hpp"
|
||||
|
||||
#define BME688_ADD 0x77
|
||||
|
||||
static const char* TAG = "main";
|
||||
|
||||
Bme68x bme;
|
||||
|
||||
int8_t read_bytes_wrapper(uint8_t a_register, uint8_t *data, uint32_t len, void *intfPtr) {
|
||||
return static_cast<I2C_t *>(intfPtr)->readBytes(BME688_ADD, a_register, len, data)==ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
int8_t write_bytes_wrapper(uint8_t a_register, const uint8_t *data, uint32_t len,
|
||||
void *intfPtr) {
|
||||
return static_cast<I2C_t *>(intfPtr)->writeBytes(BME688_ADD, a_register, len, data)==ESP_OK ? 0 : -1;
|
||||
}
|
||||
|
||||
uint32_t IRAM_ATTR millis() { return (uint32_t) (esp_timer_get_time() / 1000ULL); }
|
||||
void IRAM_ATTR delay(uint32_t ms) { vTaskDelay(ms / portTICK_PERIOD_MS); }
|
||||
uint32_t IRAM_ATTR micros() { return (uint32_t) esp_timer_get_time(); }
|
||||
|
||||
void delay_microseconds_safe(uint32_t us) { // avoids CPU locks that could trigger WDT or affect WiFi/BT stability
|
||||
uint32_t start = micros();
|
||||
|
||||
const uint32_t lag = 5000; // microseconds, specifies the maximum time for a CPU busy-loop.
|
||||
// it must be larger than the worst-case duration of a delay(1) call (hardware tasks)
|
||||
// 5ms is conservative, it could be reduced when exact BT/WiFi stack delays are known
|
||||
if (us > lag) {
|
||||
delay((us - lag) / 1000UL); // note: in disabled-interrupt contexts delay() won't actually sleep
|
||||
while (micros() - start < us - lag)
|
||||
delay(1); // in those cases, this loop allows to yield for BT/WiFi stack tasks
|
||||
}
|
||||
while (micros() - start < us) // fine delay the remaining usecs
|
||||
;
|
||||
}
|
||||
|
||||
void delay_us(uint32_t period, void *intfPtr) {
|
||||
delay_microseconds_safe(period);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Initializes the sensor and hardware settings
|
||||
*/
|
||||
void setup(void)
|
||||
{
|
||||
i2c0.begin(GPIO_NUM_3,GPIO_NUM_0);
|
||||
|
||||
/* initializes the sensor based on I2C library */
|
||||
bme.begin(BME68X_I2C_INTF, read_bytes_wrapper, write_bytes_wrapper, delay_us, (void *) &i2c0);
|
||||
|
||||
if(bme.checkStatus())
|
||||
{
|
||||
if (bme.checkStatus() == BME68X_ERROR)
|
||||
{
|
||||
ESP_LOGI(TAG, "Sensor error: %d", bme.status);
|
||||
return;
|
||||
}
|
||||
else if (bme.checkStatus() == BME68X_WARNING)
|
||||
{
|
||||
ESP_LOGI(TAG, "Sensor Warning: %d", bme.status);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the default configuration for temperature, pressure and humidity */
|
||||
bme.setTPH();
|
||||
|
||||
/* Set the heater configuration to 300 deg C for 100ms for Forced mode */
|
||||
bme.setHeaterProf(300, 100);
|
||||
|
||||
ESP_LOGI(TAG, "TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%%), Gas resistance(ohm), Status");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
bme68xData data;
|
||||
|
||||
bme.setOpMode(BME68X_FORCED_MODE);
|
||||
delay_microseconds_safe(bme.getMeasDur());
|
||||
|
||||
if (bme.fetchData())
|
||||
{
|
||||
bme.getData(data);
|
||||
ESP_LOGI(TAG, "%lu, %f, %f, %f, %f, %d", millis(), data.temperature, data.pressure, data.humidity, data.gas_resistance, data.status);
|
||||
}
|
||||
}
|
||||
|
||||
void loop_task(void *pv_params) {
|
||||
setup();
|
||||
while (true) {
|
||||
loop();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void app_main()
|
||||
{
|
||||
ESP_LOGI(TAG, "starting");
|
||||
xTaskCreate(loop_task, "loopTask", 8192, nullptr, 1, NULL);
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* Copyright (C) 2021 Bosch Sensortec GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "bme68xLibrary.h"
|
||||
|
||||
#define NEW_GAS_MEAS (BME68X_GASM_VALID_MSK | BME68X_HEAT_STAB_MSK | BME68X_NEW_DATA_MSK)
|
||||
#define MEAS_DUR 140
|
||||
|
||||
#ifndef PIN_CS
|
||||
#define PIN_CS SS
|
||||
#endif
|
||||
|
||||
Bme68x bme;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sensor and hardware settings
|
||||
*/
|
||||
void setup(void)
|
||||
{
|
||||
SPI.begin();
|
||||
Serial.begin(115200);
|
||||
|
||||
while (!Serial)
|
||||
delay(10);
|
||||
|
||||
/* initializes the sensor based on SPI library */
|
||||
bme.begin(PIN_CS, SPI);
|
||||
|
||||
if(bme.checkStatus())
|
||||
{
|
||||
if (bme.checkStatus() == BME68X_ERROR)
|
||||
{
|
||||
Serial.println("Sensor error:" + bme.statusString());
|
||||
return;
|
||||
}
|
||||
else if (bme.checkStatus() == BME68X_WARNING)
|
||||
{
|
||||
Serial.println("Sensor Warning:" + bme.statusString());
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the default configuration for temperature, pressure and humidity */
|
||||
bme.setTPH();
|
||||
|
||||
/* Heater temperature in degree Celsius */
|
||||
uint16_t tempProf[10] = { 320, 100, 100, 100, 200, 200, 200, 320, 320,
|
||||
320 };
|
||||
/* Multiplier to the shared heater duration */
|
||||
uint16_t mulProf[10] = { 5, 2, 10, 30, 5, 5, 5, 5, 5, 5 };
|
||||
/* Shared heating duration in milliseconds */
|
||||
uint16_t sharedHeatrDur = MEAS_DUR - (bme.getMeasDur(BME68X_PARALLEL_MODE) / 1000);
|
||||
|
||||
bme.setHeaterProf(tempProf, mulProf, sharedHeatrDur, 10);
|
||||
bme.setOpMode(BME68X_PARALLEL_MODE);
|
||||
|
||||
Serial.println("TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%), Gas resistance(ohm), Status, Gas index");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
bme68xData data;
|
||||
uint8_t nFieldsLeft = 0;
|
||||
|
||||
/* data being fetched for every 140ms */
|
||||
delay(MEAS_DUR);
|
||||
|
||||
if (bme.fetchData())
|
||||
{
|
||||
do
|
||||
{
|
||||
nFieldsLeft = bme.getData(data);
|
||||
if (data.status == NEW_GAS_MEAS)
|
||||
{
|
||||
Serial.print(String(millis()) + ", ");
|
||||
Serial.print(String(data.temperature) + ", ");
|
||||
Serial.print(String(data.pressure) + ", ");
|
||||
Serial.print(String(data.humidity) + ", ");
|
||||
Serial.print(String(data.gas_resistance) + ", ");
|
||||
Serial.print(String(data.status, HEX) + ", ");
|
||||
Serial.println(data.gas_index);
|
||||
}
|
||||
} while (nFieldsLeft);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/**
|
||||
* Copyright (C) 2021 Bosch Sensortec GmbH
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Arduino.h"
|
||||
#include "bme68xLibrary.h"
|
||||
|
||||
#define NEW_GAS_MEAS (BME68X_GASM_VALID_MSK | BME68X_HEAT_STAB_MSK | BME68X_NEW_DATA_MSK)
|
||||
|
||||
#ifndef PIN_CS
|
||||
#define PIN_CS SS
|
||||
#endif
|
||||
|
||||
Bme68x bme;
|
||||
|
||||
/**
|
||||
* @brief Initializes the sensor and hardware settings
|
||||
*/
|
||||
void setup(void)
|
||||
{
|
||||
SPI.begin();
|
||||
Serial.begin(115200);
|
||||
|
||||
while (!Serial)
|
||||
delay(10);
|
||||
|
||||
/* Initializes the sensor based on SPI library */
|
||||
bme.begin(PIN_CS, SPI);
|
||||
|
||||
if(bme.checkStatus())
|
||||
{
|
||||
if (bme.checkStatus() == BME68X_ERROR)
|
||||
{
|
||||
Serial.println("Sensor error:" + bme.statusString());
|
||||
return;
|
||||
}
|
||||
else if (bme.checkStatus() == BME68X_WARNING)
|
||||
{
|
||||
Serial.println("Sensor Warning:" + bme.statusString());
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the default configuration for temperature, pressure and humidity */
|
||||
bme.setTPH();
|
||||
|
||||
/* Heater temperature in degree Celsius */
|
||||
uint16_t tempProf[10] = { 100, 200, 320 };
|
||||
/* Heating duration in milliseconds */
|
||||
uint16_t durProf[10] = { 150, 150, 150 };
|
||||
|
||||
bme.setSeqSleep(BME68X_ODR_250_MS);
|
||||
bme.setHeaterProf(tempProf, durProf, 3);
|
||||
bme.setOpMode(BME68X_SEQUENTIAL_MODE);
|
||||
|
||||
Serial.println("TimeStamp(ms), Temperature(deg C), Pressure(Pa), Humidity(%), Gas resistance(ohm), Status, Gas index");
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
bme68xData data;
|
||||
uint8_t nFieldsLeft = 0;
|
||||
|
||||
delay(150);
|
||||
|
||||
if (bme.fetchData())
|
||||
{
|
||||
do
|
||||
{
|
||||
nFieldsLeft = bme.getData(data);
|
||||
//if (data.status == NEW_GAS_MEAS)
|
||||
{
|
||||
Serial.print(String(millis()) + ", ");
|
||||
Serial.print(String(data.temperature) + ", ");
|
||||
Serial.print(String(data.pressure) + ", ");
|
||||
Serial.print(String(data.humidity) + ", ");
|
||||
Serial.print(String(data.gas_resistance) + ", ");
|
||||
Serial.print(String(data.status, HEX) + ", ");
|
||||
Serial.println(data.gas_index);
|
||||
if(data.gas_index == 2) /* Sequential mode sleeps after this measurement */
|
||||
delay(250);
|
||||
}
|
||||
} while (nFieldsLeft);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue