From 91cc9dba0c0600ad6050343a22f3f45b43d95c83 Mon Sep 17 00:00:00 2001 From: Gregor Wolf Date: Fri, 8 Mar 2019 18:13:51 +0100 Subject: [PATCH] Support for BME280 --- include/bme280.h | 17 ++++++++++++ include/cyclic.h | 6 ++++- include/globals.h | 6 ++++- platformio.ini | 6 ++--- src/bme280.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++ src/bme680mems.cpp | 10 +++---- src/cyclic.cpp | 14 ++++++++-- src/hal/generic.h | 5 ++-- src/hal/heltec.h | 5 ++-- src/hal/heltecv2.h | 5 ++-- src/hal/octopus32.h | 5 ++-- src/hal/ttgobeam.h | 5 ++-- src/hal/ttgov21new.h | 6 +++++ src/main.cpp | 23 +++++++++++++--- src/rcommand.cpp | 2 +- 15 files changed, 151 insertions(+), 27 deletions(-) create mode 100644 include/bme280.h create mode 100644 src/bme280.cpp diff --git a/include/bme280.h b/include/bme280.h new file mode 100644 index 00000000..c4c5c4a8 --- /dev/null +++ b/include/bme280.h @@ -0,0 +1,17 @@ +#ifndef _BME280_H +#define _BME280_H + +#include "globals.h" +#include +#include +#include +#include "../lib/Bosch-BSEC/src/bsec.h" + +extern bmeStatus_t + bme_status; // Make struct for storing gps data globally available +extern TaskHandle_t Bme280Task; + +int bme280_init(); +void bme280_loop(void *pvParameters); + +#endif \ No newline at end of file diff --git a/include/cyclic.h b/include/cyclic.h index ffdee8f5..77853bb6 100644 --- a/include/cyclic.h +++ b/include/cyclic.h @@ -7,10 +7,14 @@ #include "spislave.h" #include -#ifdef HAS_BME +#ifdef HAS_BME680 #include "bme680mems.h" #endif +#ifdef HAS_BME280 +#include "bme280.h" +#endif + extern Ticker housekeeper; void housekeeping(void); diff --git a/include/globals.h b/include/globals.h index 24c83580..724c4ef5 100644 --- a/include/globals.h +++ b/include/globals.h @@ -151,8 +151,12 @@ extern time_t userUTCTime; #include "sensor.h" #endif -#ifdef HAS_BME +#ifdef HAS_BME680 #include "bme680mems.h" #endif +#ifdef HAS_BME280 +#include "bme280.h" +#endif + #endif \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 47ca6e73..79765a6c 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,7 +6,7 @@ ; ---> SELECT TARGET PLATFORM HERE! <--- [platformio] -env_default = generic +;env_default = generic ;env_default = ebox ;env_default = eboxtube ;env_default = heltec @@ -14,7 +14,7 @@ env_default = generic ;env_default = ttgov1 ;env_default = ttgov2 ;env_default = ttgov21old -;env_default = ttgov21new +env_default = ttgov21new ;env_default = ttgobeam ;env_default = ttgofox ;env_default = lopy @@ -202,7 +202,7 @@ lib_deps = ${common.lib_deps_lora} ${common.lib_deps_display} build_flags = - ${common.build_flags_basic} + ${common.build_flags_all} upload_protocol = ${common.upload_protocol} extra_scripts = ${common.extra_scripts} monitor_speed = ${common.monitor_speed} diff --git a/src/bme280.cpp b/src/bme280.cpp new file mode 100644 index 00000000..d2af49e3 --- /dev/null +++ b/src/bme280.cpp @@ -0,0 +1,63 @@ +#ifdef HAS_BME280 + +#include "bme280.h" + +// Local logging tag +static const char TAG[] = __FILE__; + +bmeStatus_t bme_status; +TaskHandle_t Bme280Task; + +#define SEALEVELPRESSURE_HPA (1013.25) + +Adafruit_BME280 bme; // I2C +//Adafruit_BME280 bme(BME_CS); // hardware SPI +//Adafruit_BME280 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI + +// initialize BME280 sensor +int bme280_init(void) { + + bool status; + // return = 0 -> error / return = 1 -> success + + // block i2c bus access + if (I2C_MUTEX_LOCK()) { + status = bme.begin(BME280_ADDR); + if (!status) { + ESP_LOGE(TAG, "BME280 sensor not found"); + goto error; + } + ESP_LOGI(TAG, "BME280 sensor found and initialized"); + } else { + ESP_LOGE(TAG, "I2c bus busy - BME280 initialization error"); + goto error; + } + + I2C_MUTEX_UNLOCK(); // release i2c bus access + return 1; + +error: + I2C_MUTEX_UNLOCK(); // release i2c bus access + return 0; + +} // bme_init() + +// loop function which reads and processes data based on sensor settings +void bme280_loop(void *pvParameters) { +#ifdef HAS_BME280 + while (1) { + if (I2C_MUTEX_LOCK()) { + bme_status.temperature = bme.readTemperature(); + bme_status.pressure = (bme.readPressure() / 100.0); // conversion Pa -> hPa + // bme.readAltitude(SEALEVELPRESSURE_HPA); + bme_status.humidity = bme.readHumidity(); + I2C_MUTEX_UNLOCK(); + } + } +#endif + ESP_LOGE(TAG, "BME task ended"); + vTaskDelete(Bme280Task); // should never be reached + +} // bme_loop() + +#endif // HAS_BME280 \ No newline at end of file diff --git a/src/bme680mems.cpp b/src/bme680mems.cpp index d0679507..8f28c389 100644 --- a/src/bme680mems.cpp +++ b/src/bme680mems.cpp @@ -1,4 +1,4 @@ -#ifdef HAS_BME +#ifdef HAS_BME680 #include "bme680mems.h" @@ -34,8 +34,8 @@ int bme_init(void) { // block i2c bus access if (I2C_MUTEX_LOCK()) { - Wire.begin(HAS_BME); - iaqSensor.begin(BME_ADDR, Wire); + Wire.begin(HAS_BME680); + iaqSensor.begin(BME680_ADDR, Wire); ESP_LOGI(TAG, "BSEC v%d.%d.%d.%d", iaqSensor.version.major, iaqSensor.version.minor, iaqSensor.version.major_bugfix, @@ -103,7 +103,7 @@ void bme_loop(void *pvParameters) { configASSERT(((uint32_t)pvParameters) == 1); // FreeRTOS check -#ifdef HAS_BME +#ifdef HAS_BME680 while (1) { // block i2c bus access if (I2C_MUTEX_LOCK()) { @@ -168,4 +168,4 @@ void updateState(void) { } } -#endif // HAS_BME \ No newline at end of file +#endif // HAS_BME680 \ No newline at end of file diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 8899d05b..63234d84 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -36,10 +36,14 @@ void doHousekeeping() { ESP_LOGD(TAG, "Gpsloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(GpsTask), eTaskGetState(GpsTask)); #endif -#ifdef HAS_BME +#ifdef HAS_BME680 ESP_LOGD(TAG, "Bmeloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(BmeTask), eTaskGetState(BmeTask)); #endif +#ifdef HAS_BME280 + ESP_LOGD(TAG, "Bme280loop %d bytes left | Taskstate = %d", + uxTaskGetStackHighWaterMark(Bme280Task), eTaskGetState(Bme280Task)); +#endif #ifdef HAS_DCF77 ESP_LOGD(TAG, "Clockloop %d bytes left | Taskstate = %d", uxTaskGetStackHighWaterMark(ClockTask), eTaskGetState(ClockTask)); @@ -58,11 +62,17 @@ void doHousekeeping() { #endif // display BME sensor data -#ifdef HAS_BME +#ifdef HAS_BME680 ESP_LOGI(TAG, "BME680 Temp: %.2f°C | IAQ: %.2f | IAQacc: %d", bme_status.temperature, bme_status.iaq, bme_status.iaq_accuracy); #endif +// display BME280 sensor data +#ifdef HAS_BME280 + ESP_LOGI(TAG, "BME680 Temp: %.2f°C | Humidity: %.2f | Pressure: %.0f", + bme_status.temperature, bme_status.humidity, bme_status.pressure); +#endif + // check free heap memory if (ESP.getMinFreeHeap() <= MEM_LOW) { ESP_LOGI(TAG, diff --git a/src/hal/generic.h b/src/hal/generic.h index 0ca56b04..07a629d3 100644 --- a/src/hal/generic.h +++ b/src/hal/generic.h @@ -18,8 +18,9 @@ // enable only if device has these sensors, otherwise comment these lines // BME680 sensor on I2C bus -#define HAS_BME GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL -#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND +#define HAS_BME 1 // Enable BME sensors in general +#define HAS_BME680 GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL +#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND // user defined sensors //#define HAS_SENSORS 1 // comment out if device has user defined sensors diff --git a/src/hal/heltec.h b/src/hal/heltec.h index f8ab5b8e..4c3f3051 100644 --- a/src/hal/heltec.h +++ b/src/hal/heltec.h @@ -7,8 +7,9 @@ // Hardware related definitions for Heltec V2 LoRa-32 Board -//#define HAS_BME GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL -//#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND +//#define HAS_BME 1 // Enable BME sensors in general +//#define HAS_BME680 GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL +//#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 diff --git a/src/hal/heltecv2.h b/src/hal/heltecv2.h index 7cb9145c..596b571f 100644 --- a/src/hal/heltecv2.h +++ b/src/hal/heltecv2.h @@ -7,8 +7,9 @@ // Hardware related definitions for Heltec V2 LoRa-32 Board -//#define HAS_BME GPIO_NUM_4, GPIO_NUM_15 // SDA, SCL -//#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND +//#define HAS_BME 1 // Enable BME sensors in general +//#define HAS_BME680 GPIO_NUM_4, GPIO_NUM_15 // SDA, SCL +//#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 diff --git a/src/hal/octopus32.h b/src/hal/octopus32.h index 288c286b..ad4fbb07 100644 --- a/src/hal/octopus32.h +++ b/src/hal/octopus32.h @@ -12,8 +12,9 @@ #define DISABLE_BROWNOUT 1 // comment out if you want to keep brownout feature // Octopus32 has a pre-populated BME680 on i2c addr 0x76 -#define HAS_BME GPIO_NUM_23, GPIO_NUM_22 // SDA, SCL -#define BME_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND +#define HAS_BME 1 // Enable BME sensors in general +#define HAS_BME680 GPIO_NUM_23, GPIO_NUM_22 // SDA, SCL +#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND // user defined sensors //#define HAS_SENSORS 1 // comment out if device has user defined sensors diff --git a/src/hal/ttgobeam.h b/src/hal/ttgobeam.h index d86acd18..dcce95ad 100644 --- a/src/hal/ttgobeam.h +++ b/src/hal/ttgobeam.h @@ -31,8 +31,9 @@ // enable only if device has these sensors, otherwise comment these lines // BME680 sensor on I2C bus -#define HAS_BME SDA, SCL -#define BME_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !! +#define HAS_BME 1 // Enable BME sensors in general +#define HAS_BME680 SDA, SCL +#define BME680_ADDR BME680_I2C_ADDR_PRIMARY // !! connect SDIO of BME680 to GND !! // display (if connected) #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C diff --git a/src/hal/ttgov21new.h b/src/hal/ttgov21new.h index f2cf0571..b327b8d3 100644 --- a/src/hal/ttgov21new.h +++ b/src/hal/ttgov21new.h @@ -13,6 +13,12 @@ #define HAS_LORA 1 // comment out if device shall not send data via LoRa #define CFG_sx1276_radio 1 // HPD13A LoRa SoC +// enable only if device has these sensors, otherwise comment these lines +// BME680 sensor on I2C bus +#define HAS_BME 1 // Enable BME sensors in general +#define HAS_BME280 GPIO_NUM_21, GPIO_NUM_22 // SDA, SCL +#define BME280_ADDR BME680_I2C_ADDR_PRIMARY // connect SDIO of BME680 to GND + #define HAS_DISPLAY U8X8_SSD1306_128X64_NONAME_HW_I2C #define HAS_LED (25) // green on board LED #define HAS_BATTERY_PROBE ADC1_GPIO35_CHANNEL // battery probe GPIO pin -> ADC1_CHANNEL_7 diff --git a/src/main.cpp b/src/main.cpp index 0b44c850..aa56ad64 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -358,11 +358,11 @@ void setup() { &irqHandlerTask, // task handle 1); // CPU core -// initialize bme -#ifdef HAS_BME - strcat_P(features, " BME"); +// initialize bme680 +#ifdef HAS_BME680 + strcat_P(features, " BME280"); if (bme_init()) { - ESP_LOGI(TAG, "Starting BME sensor..."); + ESP_LOGI(TAG, "Starting BME280 sensor..."); xTaskCreatePinnedToCore(bme_loop, // task function "bmeloop", // name of task 2048, // stack size of task @@ -373,6 +373,21 @@ void setup() { } #endif +// initialize BME280 +#ifdef HAS_BME280 + strcat_P(features, " BME280"); + if (bme280_init()) { + ESP_LOGI(TAG, "Starting BME280 sensor..."); + xTaskCreatePinnedToCore(bme280_loop, // task function + "bme280loop", // name of task + 2048, // stack size of task + (void *)1, // parameter of the task + 1, // priority of the task + &Bme280Task, // task handle + 1); // CPU core + } +#endif + // starting timers and interrupts assert(irqHandlerTask != NULL); // has interrupt handler task started? ESP_LOGI(TAG, "Starting Timers..."); diff --git a/src/rcommand.cpp b/src/rcommand.cpp index 34054bc2..dae6332f 100644 --- a/src/rcommand.cpp +++ b/src/rcommand.cpp @@ -262,7 +262,7 @@ void get_gps(uint8_t val[]) { void get_bme(uint8_t val[]) { ESP_LOGI(TAG, "Remote command: get bme680 sensor data"); -#ifdef HAS_BME +#ifdef HAS_BME680 payload.reset(); payload.addBME(bme_status); SendPayload(BMEPORT, prio_high);