From 319e910da04bdeea77082dff27b4bcbf3cda8b1c Mon Sep 17 00:00:00 2001 From: t-pi Date: Sun, 6 Feb 2022 22:11:34 +0100 Subject: [PATCH 1/5] BME680 to BSEC lib for indoor air quality. Local logging only --- multigeiger/log_data.cpp | 14 ++-- multigeiger/log_data.h | 2 +- multigeiger/multigeiger.ino | 18 ++--- multigeiger/thp_sensor.cpp | 129 ++++++++++++++++++++++++++++++------ multigeiger/thp_sensor.h | 4 +- platformio-example.ini | 2 +- 6 files changed, 129 insertions(+), 40 deletions(-) diff --git a/multigeiger/log_data.cpp b/multigeiger/log_data.cpp index c7cb19f1..de8831c8 100644 --- a/multigeiger/log_data.cpp +++ b/multigeiger/log_data.cpp @@ -7,10 +7,10 @@ int Serial_Print_Mode; static const char *Serial_Logging_Name = "Simple Multi-Geiger"; -static const char *dashes = "------------------------------------------------------------------------------------------------------------------------"; +static const char *dashes = "-----------------------------------------------------------------------------------------------------------------------------"; -static const char *Serial_Logging_Header = " %10s %15s %10s %9s %9s %8s %9s %9s %9s %5s %5s %6s"; -static const char *Serial_Logging_Body = "DATA %10d %15d %10f %9f %9d %8d %9d %9f %9f %5.1f %5.1f %6.0f"; +static const char *Serial_Logging_Header = " %10s %15s %10s %9s %9s %8s %9s %9s %9s %5s %5s %6s %4s"; +static const char *Serial_Logging_Body = "DATA %10d %15d %10f %9f %9d %8d %9d %9f %9f %5.1f %5.1f %6.0f %4d"; static const char *Serial_One_Minute_Log_Header = " %4s %10s %29s"; static const char *Serial_One_Minute_Log_Body = "DATA %4d %10d %29d"; @@ -28,19 +28,19 @@ void setup_log_data(int mode) { void log_data(int GMC_counts, int time_difference, float Count_Rate, float Dose_Rate, int HV_pulse_count, int accumulated_GMC_counts, int accumulated_time, float accumulated_Count_Rate, float accumulated_Dose_Rate, - float t, float h, float p) { + float t, float h, float p, int iaq) { static int counter = 0; if (counter++ % 20 == 0) { // output the header now and then, so table is better readable log(INFO, Serial_Logging_Header, - "GMC_counts", "Time_difference", "Count_Rate", "Dose_Rate", "HV Pulses", "Accu_GMC", "Accu_Time", "Accu_Rate", "Accu_Dose", "Temp", "Humi", "Press"); + "GMC_counts", "Time_difference", "Count_Rate", "Dose_Rate", "HV Pulses", "Accu_GMC", "Accu_Time", "Accu_Rate", "Accu_Dose", "Temp", "Humi", "Press", "IAQ"); log(INFO, Serial_Logging_Header, - "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[-]", "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[C]", "[%]", "[hPa]"); + "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[-]", "[Counts]", "[ms]", "[cps]", "[uSv/h]", "[C]", "[%]", "[hPa]", "[-]"); log(INFO, dashes); } log(INFO, Serial_Logging_Body, GMC_counts, time_difference, Count_Rate, Dose_Rate, HV_pulse_count, accumulated_GMC_counts, accumulated_time, accumulated_Count_Rate, accumulated_Dose_Rate, - t, h, p); + t, h, p, iaq); } void log_data_one_minute(int time_s, int cpm, int counts) { diff --git a/multigeiger/log_data.h b/multigeiger/log_data.h index 46ad12d8..1579c887 100644 --- a/multigeiger/log_data.h +++ b/multigeiger/log_data.h @@ -15,7 +15,7 @@ extern int Serial_Print_Mode; void setup_log_data(int mode); void log_data(int GMC_counts, int time_difference, float Count_Rate, float Dose_Rate, int HV_pulse_count, int accumulated_GMC_counts, int accumulated_time, float accumulated_Count_Rate, float accumulated_Dose_Rate, - float t, float h, float p); + float t, float h, float p, int iaq); void log_data_one_minute(int time_s, int cpm, int counts); void log_data_statistics(int count_time_between); diff --git a/multigeiger/multigeiger.ino b/multigeiger/multigeiger.ino index 8031f205..5b02a66e 100644 --- a/multigeiger/multigeiger.ino +++ b/multigeiger/multigeiger.ino @@ -107,7 +107,7 @@ int update_ble_status(void) { // currently no error detection } void publish(unsigned long current_ms, unsigned long current_counts, unsigned long gm_count_timestamp, unsigned long current_hv_pulses, - float temperature, float humidity, float pressure) { + float temperature, float humidity, float pressure, int iaq) { static unsigned long last_timestamp = millis(); static unsigned long last_counts = 0; static unsigned long last_hv_pulses = 0; @@ -162,7 +162,7 @@ void publish(unsigned long current_ms, unsigned long current_counts, unsigned lo if (Serial_Print_Mode == Serial_Logging) { log_data(counts, dt, Count_Rate, Dose_Rate, hv_pulses, accumulated_GMC_counts, accumulated_time, accumulated_Count_Rate, accumulated_Dose_Rate, - temperature, humidity, pressure); + temperature, humidity, pressure, iaq); } } else { // If there were no pulses after AFTERSTART msecs after boot, clear display anyway and show 0 counts. @@ -200,14 +200,13 @@ void statistics_log(unsigned long current_counts, unsigned int time_between) { } } -void read_THP(unsigned long current_ms, - bool *have_thp, float *temperature, float *humidity, float *pressure) { +void read_THP(unsigned long current_ms, bool *have_thp, float *temperature, float *humidity, float *pressure, int *iaq) { static unsigned long last_timestamp = 0; // first call: immediately query thp sensor - // subsequent calls: only query every MEASUREMENT_INTERVAL - if (!last_timestamp || (current_ms - last_timestamp) >= (MEASUREMENT_INTERVAL * 1000)) { + // subsequent calls: only query every BME680_BSEC_LP_READOUT_INTERVAL + if (!last_timestamp || (current_ms - last_timestamp) >= BME680_BSEC_LP_READOUT_INTERVAL) { last_timestamp = current_ms; - *have_thp = read_thp_sensor(temperature, humidity, pressure); + *have_thp = read_thp_sensor(temperature, humidity, pressure, iaq); } } @@ -246,6 +245,7 @@ void loop() { static bool have_thp = false; static float temperature = 0.0, humidity = 0.0, pressure = 0.0; + static int iaq = 0; unsigned long current_ms = millis(); // to save multiple calls to millis() @@ -270,7 +270,7 @@ void loop() { read_GMC(&gm_counts, &gm_count_timestamp, &gm_count_time_between); - read_THP(current_ms, &have_thp, &temperature, &humidity, &pressure); + read_THP(current_ms, &have_thp, &temperature, &humidity, &pressure, &iaq); read_hv(&hv_error, &hv_pulses); set_status(STATUS_HV, hv_error ? ST_HV_ERROR : ST_HV_OK); @@ -283,7 +283,7 @@ void loop() { // do any other periodic updates for uplinks poll_transmission(); - publish(current_ms, gm_counts, gm_count_timestamp, hv_pulses, temperature, humidity, pressure); + publish(current_ms, gm_counts, gm_count_timestamp, hv_pulses, temperature, humidity, pressure, iaq); if (Serial_Print_Mode == Serial_One_Minute_Log) one_minute_log(current_ms, gm_counts); diff --git a/multigeiger/thp_sensor.cpp b/multigeiger/thp_sensor.cpp index d4f79f79..2fae5bdd 100644 --- a/multigeiger/thp_sensor.cpp +++ b/multigeiger/thp_sensor.cpp @@ -3,18 +3,47 @@ #include #include -#include -#include - #include "log.h" #include "thp_sensor.h" +#include +/* + Bosch BSEC Lib, https://github.com/BoschSensortec/BSEC-Arduino-library + The BSEC software is only available for download or use after accepting the software license agreement. + By using this library, you have agreed to the terms of the license agreement: + https://ae-bst.resource.bosch.com/media/_tech/media/bsec/2017-07-17_ClickThrough_License_Terms_Environmentalib_SW_CLEAN.pdf */ +#include + +/* Configure the BSEC library with information about the sensor + 18v/33v = Voltage at Vdd. 1.8V or 3.3V + 3s/300s = BSEC operating mode, BSEC_SAMPLE_RATE_LP or BSEC_SAMPLE_RATE_ULP + 4d/28d = Operating age of the sensor in days + generic_18v_3s_4d + generic_18v_3s_28d + generic_18v_300s_4d + generic_18v_300s_28d + generic_33v_3s_4d + generic_33v_3s_28d + generic_33v_300s_4d + generic_33v_300s_28d +*/ +const uint8_t bsec_config_iaq[] = { +#include "config\generic_33v_3s_4d\bsec_iaq.txt" +}; + +// Helper functions declarations +bool checkIaqSensorStatus(void); + +Bsec iaqSensor; // Create an object of the class Bsec +#define BME_TEMP_CORRECTION 1 + static int type_thp = 0; Adafruit_BME280 bme280; -Adafruit_BME680 bme680; bool setup_thp_sensor(void) { + + // BME280 if (bme280.begin(BME280_ADDRESS)) type_thp = 280; @@ -23,22 +52,51 @@ bool setup_thp_sensor(void) { // BME680 if (type_thp == 0) { - if (bme680.begin(BME68X_I2C_ADDR_LOW)) - type_thp = 680; - else if (bme680.begin(BME68X_I2C_ADDR_HIGH)) + iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire); + if (checkIaqSensorStatus()) type_thp = 680; + else { + iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, Wire); + if (checkIaqSensorStatus()) + type_thp = 680; + } } switch (type_thp) { - case 680: - // Set up oversampling and filter initialization - bme680.setTemperatureOversampling(BME680_OS_8X); - bme680.setHumidityOversampling(BME680_OS_2X); - bme680.setPressureOversampling(BME680_OS_4X); - bme680.setIIRFilterSize(BME680_FILTER_SIZE_3); - bme680.setGasHeater(300, 150); // 300*C for 150 ms - log(INFO, "BME_Status: ok, ID: BME680"); + case 680: { + iaqSensor.setConfig(bsec_config_iaq); + if (!checkIaqSensorStatus()) { + type_thp = 0; + log(INFO, "BME_Status: BME680 config error"); + break; + } + 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, + }; + iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP); + if (!checkIaqSensorStatus()) { + type_thp = 0; + log(INFO, "BME_Status: BME680 sensor subscription error"); + break; + } + iaqSensor.setTemperatureOffset(BME_TEMP_CORRECTION); + if (!iaqSensor.run()) { + type_thp = 0; + log(INFO, "BME_Status: BME680 sensor readout error"); + break; + } + log(INFO, "BME_Status: ok, ID: BME680_BSEC"); break; + } case 280: log(INFO, "BME_Status: ok, ID: BME280"); break; @@ -49,24 +107,53 @@ bool setup_thp_sensor(void) { return (type_thp > 0); } -bool read_thp_sensor(float *temperature, float *humidity, float *pressure) { +bool read_thp_sensor(float *temperature, float *humidity, float *pressure, int *iaq) { + static int bsec_failcount = 0; if (type_thp == 280) { *temperature = bme280.readTemperature(); *humidity = bme280.readHumidity(); *pressure = bme280.readPressure(); + *iaq = 0; } else if (type_thp == 680) { - if (!bme680.performReading()) { - log(INFO, "BME680: Failed to perform reading"); + if (!iaqSensor.run()) + bsec_failcount++; + else + bsec_failcount = 0; + if (bsec_failcount > 10) { + log(INFO, "BME680_BSEC: Multiple readout errors"); return false; } - *temperature = bme680.temperature; - *humidity = bme680.humidity; - *pressure = bme680.pressure; + *temperature = iaqSensor.temperature; + *humidity = iaqSensor.humidity; + *pressure = iaqSensor.pressure; + *iaq = iaqSensor.iaq; } else { *temperature = 0.0; *humidity = 0.0; *pressure = 0.0; + *iaq = 0; } return (type_thp > 0); } +bool checkIaqSensorStatus(void) { + if (iaqSensor.status != BSEC_OK) { + if (iaqSensor.status < BSEC_OK) + Serial.print("BSEC error code : "); + else + Serial.print("BSEC warning code : "); + Serial.println(iaqSensor.status); + return false; + } + + if (iaqSensor.bme680Status != BME680_OK) { + if (iaqSensor.bme680Status < BME680_OK) + Serial.print("BME680 error code : "); + else + Serial.print("BME680 warning code : "); + Serial.println(iaqSensor.status); + return false; + } + + return true; +} diff --git a/multigeiger/thp_sensor.h b/multigeiger/thp_sensor.h index f43a9abf..2aa84b34 100644 --- a/multigeiger/thp_sensor.h +++ b/multigeiger/thp_sensor.h @@ -3,7 +3,9 @@ #ifndef _THP_SENSOR_H_ #define _THP_SENSOR_H_ +#define BME680_BSEC_LP_READOUT_INTERVAL 3000 // ms + bool setup_thp_sensor(void); -bool read_thp_sensor(float *temperature, float *humidity, float *pressure); +bool read_thp_sensor(float *temperature, float *humidity, float *pressure, int *iaq); #endif // _THP_SENSOR_H_ diff --git a/platformio-example.ini b/platformio-example.ini index 765db244..63452d1c 100644 --- a/platformio-example.ini +++ b/platformio-example.ini @@ -25,7 +25,7 @@ framework = arduino monitor_speed=115200 lib_deps= U8g2 - Adafruit BME680 Library@^2.0.0 + boschsensortec/BSEC Software Library@^1.6.1480 Adafruit BME280 Library Adafruit Unified Sensor IotWebConf@^3.1.0 From d77dcf35bea01db5f15a7456fe349990ac878148 Mon Sep 17 00:00:00 2001 From: t-pi Date: Sat, 12 Feb 2022 23:18:45 +0100 Subject: [PATCH 2/5] send env data via BLE --- multigeiger/ble.cpp | 68 +++++++++++++++++++++++++++++++++---- multigeiger/ble.h | 2 +- multigeiger/multigeiger.ino | 4 +-- 3 files changed, 64 insertions(+), 10 deletions(-) diff --git a/multigeiger/ble.cpp b/multigeiger/ble.cpp index 4194a774..3e6e39ba 100644 --- a/multigeiger/ble.cpp +++ b/multigeiger/ble.cpp @@ -22,6 +22,14 @@ static NimBLEServer *bleServer; #define BLE_CHAR_HR_MEASUREMENT BLEUUID((uint16_t)0x2A37) // 16 bit UUID of Heart Rate Measurement Characteristic #define BLE_CHAR_HR_POSITION BLEUUID((uint16_t)0x2A38) // 16 bit UUID of Heart Rate Sensor Position Characteristic #define BLE_CHAR_HR_CONTROLPOINT BLEUUID((uint16_t)0x2A39) // 16 bit UUID of Heart Rate Control Point Characteristic + +#define BLE_SERVICE_ENVIRONMENTAL BLEUUID((uint16_t)0x181A) // 16 bit UUID of EnvironmentaL Service +#define BLE_CHAR_ENV_TEMPERATURE BLEUUID((uint16_t)0x2A6E) // 16 bit UUID of EnvironmentaL Temperature Characteristic (yields 16 bit little endian, 0.01 degC) +#define BLE_CHAR_ENV_HUMIDITY BLEUUID((uint16_t)0x2A6F) // 16 bit UUID of EnvironmentaL Humidity Characteristic (yields 16 bit little endian, 0.01 %) +#define BLE_CHAR_ENV_PRESSURE BLEUUID((uint16_t)0x2A6D) // 16 bit UUID of EnvironmentaL Air Pressure Characteristic (yields 32 bit little endian, 0.1 Pa) +#define BLE_CHAR_ENV_IAQ BLEUUID(0x422302f1, 0x2342, 0x2342, 0x2342234223422342) // 128 bit UUID of Environmental Indoor Air Quality (yields 16 bit little endian IAQ) +// Characteristic for IAQ from 2019 Chaos Communication Camp card10 https://firmware.card10.badge.events.ccc.de/bluetooth/ess.html + #define BLE_DESCR_UUID BLEUUID((uint16_t)0x2901) // 16 bit UUID of BLE Descriptor static bool ble_enabled = false; @@ -57,7 +65,7 @@ class MyCharacteristicCallbacks: public NimBLECharacteristicCallbacks { } }; -void update_bledata(unsigned int cpm) { +void update_bledata(unsigned int cpm, float temperature, float humidity, float pressure, int iaq) { if (!ble_enabled) return; cpm_update_counter++; @@ -81,7 +89,34 @@ void update_bledata(unsigned int cpm) { bleChr->notify(); } } + NimBLEService *bleEnvSvc = bleServer->getServiceByUUID(BLE_SERVICE_ENVIRONMENTAL); + if (bleEnvSvc) { + uint8_t txBufferEnv[4]; + NimBLECharacteristic *bleEnvTChr = bleEnvSvc->getCharacteristic(BLE_CHAR_ENV_TEMPERATURE); + if (bleEnvTChr) { + bleEnvTChr->setValue(int(temperature * 100)); + bleEnvTChr->notify(); + } + NimBLECharacteristic *bleEnvHChr = bleEnvSvc->getCharacteristic(BLE_CHAR_ENV_HUMIDITY); + if (bleEnvHChr) { + bleEnvHChr->setValue(int(humidity * 100)); + bleEnvHChr->notify(); + } + NimBLECharacteristic *bleEnvPChr = bleEnvSvc->getCharacteristic(BLE_CHAR_ENV_PRESSURE); + if (bleEnvPChr) { + bleEnvPChr->setValue(int(pressure * 10)); + bleEnvPChr->notify(); + } + NimBLECharacteristic *bleEnvIAQChr = bleEnvSvc->getCharacteristic(BLE_CHAR_ENV_IAQ); + if (bleEnvIAQChr) { + txBufferEnv[0] = iaq & 0xFF; + txBufferEnv[1] = (iaq >> 8) & 0xFF; + bleEnvIAQChr->setValue(txBufferEnv, 2); + bleEnvIAQChr->notify(); + } + } } + } void setup_ble(char *device_name, bool ble_on) { @@ -98,29 +133,48 @@ void setup_ble(char *device_name, bool ble_on) { bleServer = NimBLEDevice::createServer(); bleServer->setCallbacks(new MyServerCallbacks()); - NimBLEService *bleService = bleServer->createService(BLE_SERVICE_HEART_RATE); + // Heart Rate Service for CPM + NimBLEService *bleHRService = bleServer->createService(BLE_SERVICE_HEART_RATE); - NimBLECharacteristic *bleCharHRM = bleService->createCharacteristic(BLE_CHAR_HR_MEASUREMENT, NIMBLE_PROPERTY::NOTIFY); + NimBLECharacteristic *bleCharHRM = bleHRService->createCharacteristic(BLE_CHAR_HR_MEASUREMENT, NIMBLE_PROPERTY::NOTIFY); NimBLEDescriptor *bleDescriptorHRM = bleCharHRM->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 20); bleDescriptorHRM->setValue("Radiation rate CPM"); -// bleCharHRM.addDescriptor(new BLE2902()); // required for notification management of the service; automatically added by NimBLE lib - NimBLECharacteristic *bleCharHRCP = bleService->createCharacteristic(BLE_CHAR_HR_CONTROLPOINT, NIMBLE_PROPERTY::WRITE); + NimBLECharacteristic *bleCharHRCP = bleHRService->createCharacteristic(BLE_CHAR_HR_CONTROLPOINT, NIMBLE_PROPERTY::WRITE); NimBLEDescriptor *bleDescriptorHRCP = bleCharHRCP->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 50); bleDescriptorHRCP->setValue("0x01 for Energy Exp. (packet counter) reset"); - NimBLECharacteristic *bleCharHRPOS = bleService->createCharacteristic(BLE_CHAR_HR_POSITION, NIMBLE_PROPERTY::READ); + NimBLECharacteristic *bleCharHRPOS = bleHRService->createCharacteristic(BLE_CHAR_HR_POSITION, NIMBLE_PROPERTY::READ); NimBLEDescriptor *bleDescriptorHRPOS = bleCharHRPOS->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 30); bleDescriptorHRPOS->setValue("Geiger Mueller Tube Type"); bleCharHRCP->setCallbacks(new MyCharacteristicCallbacks()); bleCharHRPOS->setValue(txBuffer_HRPOS, 1); + // Environmental Service for temperature, humidity, air pressure, IAQ indoor air quality + NimBLEService *bleEnvService = bleServer->createService(BLE_SERVICE_ENVIRONMENTAL); + + NimBLECharacteristic *bleCharEnvT = bleEnvService->createCharacteristic(BLE_CHAR_ENV_TEMPERATURE, NIMBLE_PROPERTY::NOTIFY); + NimBLEDescriptor *bleDescriptorEnvT = bleCharEnvT->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 30); + bleDescriptorEnvT->setValue("Temperature (.01 Celsius)"); + NimBLECharacteristic *bleCharEnvH = bleEnvService->createCharacteristic(BLE_CHAR_ENV_HUMIDITY, NIMBLE_PROPERTY::NOTIFY); + NimBLEDescriptor *bleDescriptorEnvH = bleCharEnvH->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 30); + bleDescriptorEnvH->setValue("Rel. humidity (.01 %)"); + NimBLECharacteristic *bleCharEnvP = bleEnvService->createCharacteristic(BLE_CHAR_ENV_PRESSURE, NIMBLE_PROPERTY::NOTIFY); + NimBLEDescriptor *bleDescriptorEnvP = bleCharEnvP->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 30); + bleDescriptorEnvP->setValue("Air pressure (.1 Pa)"); + NimBLECharacteristic *bleCharEnvIAQ = bleEnvService->createCharacteristic(BLE_CHAR_ENV_IAQ, NIMBLE_PROPERTY::NOTIFY); + NimBLEDescriptor *bleDescriptorEnvIAQ = bleCharEnvIAQ->createDescriptor(BLE_DESCR_UUID, NIMBLE_PROPERTY::READ, 50); + bleDescriptorEnvIAQ->setValue("Indoor air quality (25 good .. 500 bad)"); + + bleServer->getAdvertising()->addServiceUUID(BLE_SERVICE_HEART_RATE); + bleServer->getAdvertising()->addServiceUUID(BLE_SERVICE_ENVIRONMENTAL); bleServer->getAdvertising()->setScanResponse(true); bleServer->getAdvertising()->setMinPreferred(0x06); bleServer->getAdvertising()->setMinPreferred(0x12); - bleService->start(); + bleHRService->start(); + bleEnvService->start(); bleServer->getAdvertising()->start(); set_status(STATUS_BLE, ST_BLE_CONNECTABLE); diff --git a/multigeiger/ble.h b/multigeiger/ble.h index a78aa033..147b011e 100644 --- a/multigeiger/ble.h +++ b/multigeiger/ble.h @@ -5,7 +5,7 @@ #define _BLE_H_ void setup_ble(char *device_name, bool ble_enabled); -void update_bledata(unsigned int cpm); +void update_bledata(unsigned int cpm, float temperature, float humidity, float pressure, int iaq); bool is_ble_connected(void); void disable_ble(void); diff --git a/multigeiger/multigeiger.ino b/multigeiger/multigeiger.ino index 5b02a66e..73a4eb64 100644 --- a/multigeiger/multigeiger.ino +++ b/multigeiger/multigeiger.ino @@ -144,7 +144,7 @@ void publish(unsigned long current_ms, unsigned long current_counts, unsigned lo accumulated_Dose_Rate = accumulated_Count_Rate * GMC_factor_uSvph; // ... and update the data on display, notify via BLE - update_bledata((unsigned int)(Count_Rate * 60)); + update_bledata((unsigned int)(Count_Rate * 60), temperature, humidity, pressure, iaq); display_GMC((unsigned int)(accumulated_time / 1000), (int)(accumulated_Dose_Rate * 1000), (int)(Count_Rate * 60), (showDisplay && switches.display_on)); @@ -170,7 +170,7 @@ void publish(unsigned long current_ms, unsigned long current_counts, unsigned lo static unsigned long afterStartTime = AFTERSTART; if (afterStartTime && ((current_ms - boot_timestamp) >= afterStartTime)) { afterStartTime = 0; - update_bledata(0); + update_bledata(0, 0, 0, 0, 0); display_GMC(0, 0, 0, (showDisplay && switches.display_on)); } } From 5502cc30376c1f114da302f2a750bdea68ea700e Mon Sep 17 00:00:00 2001 From: t-pi Date: Sun, 13 Feb 2022 00:19:55 +0100 Subject: [PATCH 3/5] adjusted platformio.ini file --- platformio-example.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platformio-example.ini b/platformio-example.ini index 63452d1c..608a17e4 100644 --- a/platformio-example.ini +++ b/platformio-example.ini @@ -25,8 +25,8 @@ framework = arduino monitor_speed=115200 lib_deps= U8g2 - boschsensortec/BSEC Software Library@^1.6.1480 Adafruit BME280 Library + boschsensortec/BSEC Software Library@^1.6.1480 Adafruit Unified Sensor IotWebConf@^3.1.0 MCCI LoRaWAN LMIC library From 40cb444e326893152470ee23b4cf28705866a876 Mon Sep 17 00:00:00 2001 From: t-pi Date: Sun, 20 Feb 2022 20:29:39 +0100 Subject: [PATCH 4/5] include bsec_iaq.txt in source, get_thp_name() --- multigeiger/thp_sensor.cpp | 91 ++++++++++++++++++++------------------ multigeiger/thp_sensor.h | 1 + 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/multigeiger/thp_sensor.cpp b/multigeiger/thp_sensor.cpp index 2fae5bdd..d948d6c2 100644 --- a/multigeiger/thp_sensor.cpp +++ b/multigeiger/thp_sensor.cpp @@ -28,21 +28,47 @@ generic_33v_300s_28d */ const uint8_t bsec_config_iaq[] = { -#include "config\generic_33v_3s_4d\bsec_iaq.txt" + // #include "config\generic_33v_3s_4d\bsec_iaq.txt" + 0,8,4,1,61,0,0,0,0,0,0,0,174,1,0,0,48,0,1,0,0,192,168,71,64,49,119,76,0,0,225,68,137,65,0,191,205,204,204,190,0,0,64,191,225,122,148,190,0,0,0,0,216,85,0,100,0,0,0,0,0,0,0,0,28,0,2,0,0,244,1,225,0,25,0,0,128,64,0,0,32,65,144,1,0,0,112,65,0,0,0,63,16,0,3,0,10,215,163,60,10,215,35,59,10,215,35,59,9,0,5,0,0,0,0,0,1,88,0,9,0,229,208,34,62,0,0,0,0,0,0,0,0,218,27,156,62,225,11,67,64,0,0,160,64,0,0,0,0,0,0,0,0,94,75,72,189,93,254,159,64,66,62,160,191,0,0,0,0,0,0,0,0,33,31,180,190,138,176,97,64,65,241,99,190,0,0,0,0,0,0,0,0,167,121,71,61,165,189,41,192,184,30,189,64,12,0,10,0,0,0,0,0,0,0,0,0,229,0,254,0,2,1,5,48,117,100,0,44,1,112,23,151,7,132,3,197,0,92,4,144,1,64,1,64,1,144,1,48,117,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,48,117,48,117,100,0,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,100,0,100,0,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,255,255,255,255,255,255,255,255,220,5,220,5,220,5,255,255,255,255,255,255,220,5,220,5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,44,1,0,0,0,0,237,52,0,0 +}; + +Adafruit_BME280 bme280; +Bsec iaqSensor; // Create an object of the class Bsec, based on BME680 +bsec_virtual_sensor_t sensorList[10] = { // Active virtual sensors for BSEC + 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, }; -// Helper functions declarations -bool checkIaqSensorStatus(void); -Bsec iaqSensor; // Create an object of the class Bsec -#define BME_TEMP_CORRECTION 1 +#define BME_TEMP_CORRECTION 1 // only 1 degree as on separate PCB static int type_thp = 0; -Adafruit_BME280 bme280; +// Helper functions declarations +bool checkIaqSensorStatus(void); -bool setup_thp_sensor(void) { +const char *get_thp_name() { + switch (type_thp) { + case 0: + return "no THP sensor"; + case 280: + return "BME280"; + case 680: + return "BME680_BSEC"; + default: + return "no defined THP sensor"; + } +} +bool setup_thp_sensor(void) { // BME280 if (bme280.begin(BME280_ADDRESS)) @@ -62,48 +88,30 @@ bool setup_thp_sensor(void) { } } - switch (type_thp) { - case 680: { + // BME680 initialization + if (type_thp == 680) { iaqSensor.setConfig(bsec_config_iaq); if (!checkIaqSensorStatus()) { type_thp = 0; - log(INFO, "BME_Status: BME680 config error"); - break; + log(INFO, "THP_Status: BME680 config error"); } - 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, - }; + } + if (type_thp == 680) { iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP); if (!checkIaqSensorStatus()) { type_thp = 0; - log(INFO, "BME_Status: BME680 sensor subscription error"); - break; + log(INFO, "THP_Status: BME680 sensor subscription error"); } + } + if (type_thp == 680) { iaqSensor.setTemperatureOffset(BME_TEMP_CORRECTION); if (!iaqSensor.run()) { type_thp = 0; - log(INFO, "BME_Status: BME680 sensor readout error"); - break; + log(INFO, "THP_Status: BME680 sensor readout error"); } - log(INFO, "BME_Status: ok, ID: BME680_BSEC"); - break; - } - case 280: - log(INFO, "BME_Status: ok, ID: BME280"); - break; - default: - log(INFO, "BME_Status: not found"); - break; } + + log(INFO, "THP_Status: %s initialized", get_thp_name()); return (type_thp > 0); } @@ -120,7 +128,7 @@ bool read_thp_sensor(float *temperature, float *humidity, float *pressure, int * else bsec_failcount = 0; if (bsec_failcount > 10) { - log(INFO, "BME680_BSEC: Multiple readout errors"); + log(INFO, "THP_Status: BME680_BSEC multiple readout errors"); return false; } *temperature = iaqSensor.temperature; @@ -139,18 +147,17 @@ bool read_thp_sensor(float *temperature, float *humidity, float *pressure, int * bool checkIaqSensorStatus(void) { if (iaqSensor.status != BSEC_OK) { if (iaqSensor.status < BSEC_OK) - Serial.print("BSEC error code : "); + log(INFO, "THP_Status: BSEC error - code %d", (int)iaqSensor.status); else - Serial.print("BSEC warning code : "); - Serial.println(iaqSensor.status); + log(INFO, "THP_Status: BSEC warning - code %d", (int)iaqSensor.status); return false; } if (iaqSensor.bme680Status != BME680_OK) { if (iaqSensor.bme680Status < BME680_OK) - Serial.print("BME680 error code : "); + log(INFO, "THP_Status: BME680 error - code %d", (int)iaqSensor.status); else - Serial.print("BME680 warning code : "); + log(INFO, "THP_Status: BME680 warning - code %d", (int)iaqSensor.status); Serial.println(iaqSensor.status); return false; } diff --git a/multigeiger/thp_sensor.h b/multigeiger/thp_sensor.h index 2aa84b34..50a7a915 100644 --- a/multigeiger/thp_sensor.h +++ b/multigeiger/thp_sensor.h @@ -6,6 +6,7 @@ #define BME680_BSEC_LP_READOUT_INTERVAL 3000 // ms bool setup_thp_sensor(void); +const char *get_thp_name(void); bool read_thp_sensor(float *temperature, float *humidity, float *pressure, int *iaq); #endif // _THP_SENSOR_H_ From 4301519c2795b175330308a05c357f8428c5206b Mon Sep 17 00:00:00 2001 From: t-pi Date: Sun, 20 Feb 2022 20:33:05 +0100 Subject: [PATCH 5/5] astyle fix --- multigeiger/thp_sensor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/multigeiger/thp_sensor.cpp b/multigeiger/thp_sensor.cpp index d948d6c2..cc02acc8 100644 --- a/multigeiger/thp_sensor.cpp +++ b/multigeiger/thp_sensor.cpp @@ -29,7 +29,7 @@ */ const uint8_t bsec_config_iaq[] = { // #include "config\generic_33v_3s_4d\bsec_iaq.txt" - 0,8,4,1,61,0,0,0,0,0,0,0,174,1,0,0,48,0,1,0,0,192,168,71,64,49,119,76,0,0,225,68,137,65,0,191,205,204,204,190,0,0,64,191,225,122,148,190,0,0,0,0,216,85,0,100,0,0,0,0,0,0,0,0,28,0,2,0,0,244,1,225,0,25,0,0,128,64,0,0,32,65,144,1,0,0,112,65,0,0,0,63,16,0,3,0,10,215,163,60,10,215,35,59,10,215,35,59,9,0,5,0,0,0,0,0,1,88,0,9,0,229,208,34,62,0,0,0,0,0,0,0,0,218,27,156,62,225,11,67,64,0,0,160,64,0,0,0,0,0,0,0,0,94,75,72,189,93,254,159,64,66,62,160,191,0,0,0,0,0,0,0,0,33,31,180,190,138,176,97,64,65,241,99,190,0,0,0,0,0,0,0,0,167,121,71,61,165,189,41,192,184,30,189,64,12,0,10,0,0,0,0,0,0,0,0,0,229,0,254,0,2,1,5,48,117,100,0,44,1,112,23,151,7,132,3,197,0,92,4,144,1,64,1,64,1,144,1,48,117,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,48,117,48,117,100,0,100,0,100,0,100,0,48,117,48,117,48,117,100,0,100,0,100,0,48,117,48,117,100,0,100,0,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,44,1,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,8,7,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,112,23,255,255,255,255,255,255,255,255,220,5,220,5,220,5,255,255,255,255,255,255,220,5,220,5,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,44,1,0,0,0,0,237,52,0,0 + 0, 8, 4, 1, 61, 0, 0, 0, 0, 0, 0, 0, 174, 1, 0, 0, 48, 0, 1, 0, 0, 192, 168, 71, 64, 49, 119, 76, 0, 0, 225, 68, 137, 65, 0, 191, 205, 204, 204, 190, 0, 0, 64, 191, 225, 122, 148, 190, 0, 0, 0, 0, 216, 85, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 2, 0, 0, 244, 1, 225, 0, 25, 0, 0, 128, 64, 0, 0, 32, 65, 144, 1, 0, 0, 112, 65, 0, 0, 0, 63, 16, 0, 3, 0, 10, 215, 163, 60, 10, 215, 35, 59, 10, 215, 35, 59, 9, 0, 5, 0, 0, 0, 0, 0, 1, 88, 0, 9, 0, 229, 208, 34, 62, 0, 0, 0, 0, 0, 0, 0, 0, 218, 27, 156, 62, 225, 11, 67, 64, 0, 0, 160, 64, 0, 0, 0, 0, 0, 0, 0, 0, 94, 75, 72, 189, 93, 254, 159, 64, 66, 62, 160, 191, 0, 0, 0, 0, 0, 0, 0, 0, 33, 31, 180, 190, 138, 176, 97, 64, 65, 241, 99, 190, 0, 0, 0, 0, 0, 0, 0, 0, 167, 121, 71, 61, 165, 189, 41, 192, 184, 30, 189, 64, 12, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 229, 0, 254, 0, 2, 1, 5, 48, 117, 100, 0, 44, 1, 112, 23, 151, 7, 132, 3, 197, 0, 92, 4, 144, 1, 64, 1, 64, 1, 144, 1, 48, 117, 48, 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 48, 117, 100, 0, 100, 0, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 48, 117, 100, 0, 100, 0, 100, 0, 48, 117, 48, 117, 100, 0, 100, 0, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 8, 7, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 112, 23, 255, 255, 255, 255, 255, 255, 255, 255, 220, 5, 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 220, 5, 220, 5, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 44, 1, 0, 0, 0, 0, 237, 52, 0, 0 }; Adafruit_BME280 bme280;