From 361b092d4e63cdcf7480e243e5e4d77b92fdf4ef Mon Sep 17 00:00:00 2001 From: Clemens-Dautermann Date: Wed, 9 Feb 2022 20:22:55 +0100 Subject: [PATCH 1/5] implemented make discoverable button --- firmware/src/ble/BluetoothServer.cpp | 23 +++++++++++++++++++++++ firmware/src/ble/BluetoothServer.h | 2 ++ firmware/src/main.cpp | 20 +++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/firmware/src/ble/BluetoothServer.cpp b/firmware/src/ble/BluetoothServer.cpp index 4586e42..5c67cae 100644 --- a/firmware/src/ble/BluetoothServer.cpp +++ b/firmware/src/ble/BluetoothServer.cpp @@ -8,6 +8,8 @@ #define SERVICE_UUID "2150123c-af53-4038-bc92-ba3d0870a9e4" #define TEMPERATURE_CHARACTERISTIC_UUID "cba1d466-344c-4be3-ab3f-189f80dd7518" #define PRESSURE_CHARACTERISTIC_UUID "ca73b3ba-39f6-4ab3-91ae-186dc9577d99" +#define BLINK_TIME_DELAY_MS 500 +#define BLINK_TIMES 5 //Setup callbacks onConnect and onDisconnect class ServerCallbacks : public BLEServerCallbacks { @@ -51,6 +53,9 @@ BluetoothServer::BluetoothServer() { //set initial values temperatureCharacteristic->setValue("NA"); pressureCharacteristic->setValue("NA"); + + //allow advertiser function to be called + this->advertiserLock = false; } /** @@ -89,4 +94,22 @@ void BluetoothServer::setPressure(float pressure) { ->setValue(pressure); } +/** + * This method will start advertising via Bluetooth and blink the LED + */ +void BluetoothServer::startAdvertising() { + if (!this->advertiserLock) { + this->advertiserLock = true; + this->bleServer->getAdvertising()->start(); + Serial.println("Starting Bluetooth advertising..."); + for (int i = 0; i < BLINK_TIMES; ++i) { + digitalWrite(INTERNAL_LED_PIN, HIGH); + delay(BLINK_TIME_DELAY_MS); + digitalWrite(INTERNAL_LED_PIN, LOW); + delay(BLINK_TIME_DELAY_MS); + } + this->advertiserLock = false; + } +} + diff --git a/firmware/src/ble/BluetoothServer.h b/firmware/src/ble/BluetoothServer.h index 4afd1ec..ecbe38f 100644 --- a/firmware/src/ble/BluetoothServer.h +++ b/firmware/src/ble/BluetoothServer.h @@ -13,9 +13,11 @@ class BluetoothServer { private: BLEService *sensorService; BLEServer *bleServer; + bool advertiserLock; public: BluetoothServer(); + void startAdvertising(); void startServer(); void setTemperature(float temperature); void setPressure(float pressure); diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index 38b5852..fe9f32d 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -2,13 +2,20 @@ #include #include -#define SLEEP_TIME 2 +#define SLEEP_TIME 1 #define BAUD_RATE 112500 #define INTERNAL_LED_PIN 2 +#define INTERRUPT_MAKE_DISCOVERABLE_PIN 15 Sensor *bmpSensor; BluetoothServer *server; +bool makeDiscoverable = false; + + +void IRAM_ATTR startBleServerAdvertising() { + makeDiscoverable = true; +} void setup() { Serial.begin(BAUD_RATE); @@ -18,9 +25,20 @@ void setup() { server = new BluetoothServer(); server->startServer(); + + //set up Interrupt to enable make discoverable button + pinMode(INTERRUPT_MAKE_DISCOVERABLE_PIN, INPUT_PULLDOWN); + attachInterrupt(digitalPinToInterrupt(INTERRUPT_MAKE_DISCOVERABLE_PIN), + startBleServerAdvertising, + RISING); } void loop() { + if (makeDiscoverable) { + server->startAdvertising(); + makeDiscoverable = false; + } + sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy(); server->setPressure(sample.pressure); server->setTemperature(sample.temperature); From 9225cb3d51e74c8ef31976389e3abf6d83cfc99b Mon Sep 17 00:00:00 2001 From: Clemens-Dautermann Date: Wed, 9 Feb 2022 21:38:43 +0100 Subject: [PATCH 2/5] excluded app dev directory --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 5dcc104..50b7945 100644 --- a/.gitignore +++ b/.gitignore @@ -444,3 +444,6 @@ obj/ # End of https://www.toptal.com/developers/gitignore/api/platformio,c,cmake,c++,intellij,android,androidstudio,clion+all,java + +###only in firmware_dev +ClimateGoApp/ From 8097446a16dc2ca472416d6e91b870953c4db5e3 Mon Sep 17 00:00:00 2001 From: Clemens-Dautermann Date: Wed, 9 Feb 2022 21:40:09 +0100 Subject: [PATCH 3/5] some weird line ending change... --- firmware/CMakeListsPrivate.txt | 150 +++++++++++++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 firmware/CMakeListsPrivate.txt diff --git a/firmware/CMakeListsPrivate.txt b/firmware/CMakeListsPrivate.txt new file mode 100644 index 0000000..3de7299 --- /dev/null +++ b/firmware/CMakeListsPrivate.txt @@ -0,0 +1,150 @@ +# !!! WARNING !!! AUTO-GENERATED FILE, PLEASE DO NOT MODIFY IT AND USE +# https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags +# +# If you need to override existing CMake configuration or add extra, +# please create `CMakeListsUser.txt` in the root of project. +# The `CMakeListsUser.txt` will not be overwritten by PlatformIO. + + + +set(CMAKE_CONFIGURATION_TYPES "esp32dev" CACHE STRING "Build Types reflect PlatformIO Environments" FORCE) + +# Convert "Home Directory" that may contain unescaped backslashes on Windows + + +SET(CMAKE_C_COMPILER "$ENV{HOME}/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-gcc") +SET(CMAKE_CXX_COMPILER "$ENV{HOME}/.platformio/packages/toolchain-xtensa32/bin/xtensa-esp32-elf-g++") +SET(CMAKE_CXX_FLAGS "-fno-rtti -fno-exceptions -std=gnu++11 -Os -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder") +SET(CMAKE_C_FLAGS "-std=gnu99 -Wno-old-style-declaration -Os -g3 -Wall -nostdlib -Wpointer-arith -Wno-error=unused-but-set-variable -Wno-error=unused-variable -mlongcalls -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -Wno-error=deprecated-declarations -Wno-error=unused-function -Wno-unused-parameter -Wno-sign-compare -fstack-protector -fexceptions -Werror=reorder") + +SET(CMAKE_C_STANDARD 99) +set(CMAKE_CXX_STANDARD 11) + +if (CMAKE_BUILD_TYPE MATCHES "esp32dev") + add_definitions(-DPLATFORMIO=50204) + add_definitions(-DARDUINO_ESP32_DEV) + add_definitions(-DESP32) + add_definitions(-DESP_PLATFORM) + add_definitions(-DF_CPU=240000000L) + add_definitions(-DHAVE_CONFIG_H) + add_definitions(-DMBEDTLS_CONFIG_FILE=\"mbedtls/esp_config.h\") + add_definitions(-DARDUINO=10805) + add_definitions(-DARDUINO_ARCH_ESP32) + add_definitions(-DARDUINO_VARIANT=\"esp32\") + add_definitions(-DARDUINO_BOARD=\"Espressif\ ESP32\ Dev\ Module\") + + include_directories("${CMAKE_CURRENT_LIST_DIR}/include") + include_directories("${CMAKE_CURRENT_LIST_DIR}/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src") + include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/Adafruit BMP280 Library") + include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/Adafruit BusIO") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Wire/src") + include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/Adafruit Unified Sensor") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/config") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_trace") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/app_update") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/asio") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bootloader_support") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/bt") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/coap") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/console") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/driver") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/efuse") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-tls") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_adc_cal") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_event") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_client") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_http_server") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_ota") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_https_server") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_ringbuf") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp_websocket_client") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/espcoredump") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ethernet") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/expat") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fatfs") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freemodbus") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/freertos") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/heap") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/idf_test") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/jsmn") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/json") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/libsodium") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/log") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/lwip") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mbedtls") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mdns") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/micro-ecc") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/mqtt") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/newlib") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nghttp") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/nvs_flash") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/openssl") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protobuf-c") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/protocomm") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/pthread") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/sdmmc") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/smartconfig_ack") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/soc") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spi_flash") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/spiffs") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcp_transport") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/tcpip_adapter") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/ulp") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/unity") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/vfs") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wear_levelling") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wifi_provisioning") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/wpa_supplicant") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/xtensa-debug-module") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp-face") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/esp32-camera") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/tools/sdk/include/fb_gfx") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/cores/esp32") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/variants/esp32") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ArduinoOTA/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/AsyncUDP/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/AzureIoT/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/BluetoothSerial/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/DNSServer/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/EEPROM/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ESP32/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/ESPmDNS/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/FFat/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/FS/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPClient/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdate/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/HTTPUpdateServer/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/NetBIOS/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Preferences/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SD/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SD_MMC/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SPIFFS/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SimpleBLE/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Ticker/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/Update/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WebServer/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFi/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiClientSecure/src") + include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/WiFiProv/src") + include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0") + include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include/c++/5.2.0/xtensa-esp32-elf") + include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include-fixed") + include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa32/lib/gcc/xtensa-esp32-elf/5.2.0/include") + include_directories("$ENV{HOME}/.platformio/packages/toolchain-xtensa32/xtensa-esp32-elf/include") + + FILE(GLOB_RECURSE EXTRA_LIB_SOURCES + ${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/*.* + ) +endif() + + +FILE(GLOB_RECURSE SRC_LIST + ${CMAKE_CURRENT_LIST_DIR}/src/*.* + ${CMAKE_CURRENT_LIST_DIR}/lib/*.* + ${CMAKE_CURRENT_LIST_DIR}/test/*.* +) + +list(APPEND SRC_LIST ${EXTRA_LIB_SOURCES}) From 89d6acf1812036a9c0900bc39530023c191f27f2 Mon Sep 17 00:00:00 2001 From: Clemens-Dautermann Date: Mon, 14 Feb 2022 18:39:31 +0100 Subject: [PATCH 4/5] started implementing PM sensor --- firmware/CMakeListsPrivate.txt | 4 +- firmware/platformio.ini | 1 + firmware/src/main.cpp | 21 ++++++ firmware/src/sensors/BmpSensor.cpp | 4 +- firmware/src/sensors/BmpSensor.h | 1 + firmware/src/sensors/PmSensor.cpp | 95 ++++++++++++++++++++++++++++ firmware/src/sensors/PmSensor.h | 35 ++++++++++ firmware/src/sensors/Sensor.h | 4 +- firmware/src/sensors/sensor_data_t.h | 8 +-- 9 files changed, 165 insertions(+), 8 deletions(-) create mode 100644 firmware/src/sensors/PmSensor.cpp create mode 100644 firmware/src/sensors/PmSensor.h diff --git a/firmware/CMakeListsPrivate.txt b/firmware/CMakeListsPrivate.txt index 3de7299..e39b280 100644 --- a/firmware/CMakeListsPrivate.txt +++ b/firmware/CMakeListsPrivate.txt @@ -21,7 +21,7 @@ SET(CMAKE_C_STANDARD 99) set(CMAKE_CXX_STANDARD 11) if (CMAKE_BUILD_TYPE MATCHES "esp32dev") - add_definitions(-DPLATFORMIO=50204) + add_definitions(-DPLATFORMIO=50205) add_definitions(-DARDUINO_ESP32_DEV) add_definitions(-DESP32) add_definitions(-DESP_PLATFORM) @@ -36,6 +36,8 @@ if (CMAKE_BUILD_TYPE MATCHES "esp32dev") include_directories("${CMAKE_CURRENT_LIST_DIR}/include") include_directories("${CMAKE_CURRENT_LIST_DIR}/src") include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/BLE/src") + include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/esp_sds011/src") + include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/EspSoftwareSerial/src") include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/Adafruit BMP280 Library") include_directories("${CMAKE_CURRENT_LIST_DIR}/.pio/libdeps/esp32dev/Adafruit BusIO") include_directories("$ENV{HOME}/.platformio/packages/framework-arduinoespressif32/libraries/SPI/src") diff --git a/firmware/platformio.ini b/firmware/platformio.ini index 1a0090b..6db8dfe 100644 --- a/firmware/platformio.ini +++ b/firmware/platformio.ini @@ -13,3 +13,4 @@ platform = espressif32 board = esp32dev framework = arduino lib_deps = adafruit/Adafruit BMP280 Library@^2.6.1 + dok-net/esp_sds011@^1.0.0 diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index fe9f32d..f9fc036 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #define SLEEP_TIME 1 #define BAUD_RATE 112500 @@ -9,6 +10,7 @@ Sensor *bmpSensor; +Sensor *pmSensor; BluetoothServer *server; bool makeDiscoverable = false; @@ -18,11 +20,16 @@ void IRAM_ATTR startBleServerAdvertising() { } void setup() { + //initialize a Serial Connection Serial.begin(BAUD_RATE); + //setup the internal LED pinMode(INTERNAL_LED_PIN, OUTPUT); + //create sensor objects bmpSensor = new BmpSensor(); + pmSensor = new PmSensor(); + //setup & start Bluetooth server server = new BluetoothServer(); server->startServer(); @@ -39,8 +46,22 @@ void loop() { makeDiscoverable = false; } + //setup PM sensor measurement TODO: This blocks for 120 seconds and needs to be executed asynchronously + //((PmSensor *) pmSensor)->startAsyncSampling(); + + //obtain measurement from BMP280 Sensor sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy(); server->setPressure(sample.pressure); server->setTemperature(sample.temperature); + //Obtain measurement from PM Sensor + sensor_data_t pmSample = pmSensor->sample(); + + //Print measured data + Serial.printf("Pressure: %f hPa | Temperature: %f °C | PM10: %f ppm| PM2.5: %f ppm\n", + sample.pressure, + sample.temperature, + pmSample.pm10, + pmSample.pm25); + //wait for one measurement cycle delay(SLEEP_TIME * 1000); } \ No newline at end of file diff --git a/firmware/src/sensors/BmpSensor.cpp b/firmware/src/sensors/BmpSensor.cpp index 7f68a25..b4a5724 100644 --- a/firmware/src/sensors/BmpSensor.cpp +++ b/firmware/src/sensors/BmpSensor.cpp @@ -69,7 +69,9 @@ sensor_data_t BmpSensor::sample() { return sensor_data_t { temp_event.temperature, - pressure_event.pressure + pressure_event.pressure, + 0.0, + 0.0 }; } diff --git a/firmware/src/sensors/BmpSensor.h b/firmware/src/sensors/BmpSensor.h index f5949fc..a7d9ffa 100644 --- a/firmware/src/sensors/BmpSensor.h +++ b/firmware/src/sensors/BmpSensor.h @@ -14,6 +14,7 @@ public: BmpSensor(); sensor_data_t sample() override; + sensor_data_t sampleLowEnergy(); void enableStandbyMode() override; diff --git a/firmware/src/sensors/PmSensor.cpp b/firmware/src/sensors/PmSensor.cpp new file mode 100644 index 0000000..7e0fc03 --- /dev/null +++ b/firmware/src/sensors/PmSensor.cpp @@ -0,0 +1,95 @@ +#include "PmSensor.h" +#include +#include + +#define SDS_PIN_RX 18 +#define SDS_PIN_TX 19 +#define SENSOR_BAUD_RATE 9600 +#define SLEEP_TIME 90 +#define MEASURE_TIME 30 + +#ifdef ESP32 +HardwareSerial &serialSDS(Serial2); +Sds011Async sds011(serialSDS); +#else +SoftwareSerial serialSDS; +Sds011Async< SoftwareSerial > sds011(serialSDS); +#endif + + +PmSensor::PmSensor() { + this->PmSensor::sensor_setup(); +} + +void PmSensor::startAsyncSampling() { + + this->enableStandbyMode(); + PmSensor::sensorWait(SLEEP_TIME); + + this->wakeUp(); + sds011.perform_work(); + + if (!sds011.query_data_auto_async(pm_tablesize, pm25_table, pm10_table)) { + Serial.println("measurement capture start failed"); + } + + PmSensor::sensorWait(MEASURE_TIME); +} + +/** + * Put the sensor to standby mode + */ +void PmSensor::enableStandbyMode() { + if (sds011.set_sleep(true)) { this->state = SensorState::ASLEEP; } +} + +/** + * Activate the sensor + */ +void PmSensor::wakeUp() { + if (sds011.set_sleep(false)) { this->state = SensorState::AWAKE; } +} + +/** + * Method to set up and initialize the sensor + */ +void PmSensor::sensor_setup() { +#ifdef ESP32 + serialSDS.begin(SENSOR_BAUD_RATE, SERIAL_8N1, SDS_PIN_RX, SDS_PIN_TX); + delay(100); +#else + serialSDS.begin(SENSOR_BAUD_RATE, SWSERIAL_8N1, SDS_PIN_RX, SDS_PIN_TX, false, 192); +#endif + + //put the sensor into standby mode initially + this->PmSensor::enableStandbyMode(); + Serial.println("SDS011 sensor initialized to standby mode."); + + //attach a callback on what to do when data sampling is complete + sds011.on_query_data_auto_completed([this](int n) { + int pm25; + int pm10; + if (sds011.filter_data(n, pm25_table, pm10_table, pm25, pm10) && + !isnan(pm10) && !isnan(pm25)) { + //set the right values + this->latestPM10 = float(pm10) / 10; + this->latestPM25 = float(pm25) / 10; + } + }); +} + +/** + * Method to wait for some time and perform the appropriate task + * @param time the time to wait for in seconds + */ +void PmSensor::sensorWait(int time) { + uint32_t deadline = millis() + time * 1000; + while (static_cast(deadline - millis()) > 0) { + delay(1000); + sds011.perform_work(); + } +} + +sensor_data_t PmSensor::sample() { + return {0.0, 0.0, this->latestPM10, this->latestPM25}; +} diff --git a/firmware/src/sensors/PmSensor.h b/firmware/src/sensors/PmSensor.h new file mode 100644 index 0000000..3a3bd84 --- /dev/null +++ b/firmware/src/sensors/PmSensor.h @@ -0,0 +1,35 @@ +#ifndef FIRMWARE_PMSENSOR_H +#define FIRMWARE_PMSENSOR_H + +#include "Sensor.h" +#include "sensor_data_t.h" + +class PmSensor : public Sensor { +public: + static const int pm_tablesize = 20; + int pm25_table[pm_tablesize]; + int pm10_table[pm_tablesize]; + + float latestPM10; + float latestPM25; + + PmSensor(); + + sensor_data_t sample() override; + + void startAsyncSampling(); + + + void enableStandbyMode() override; + + void wakeUp() override; + +protected: + void sensor_setup() override; + +private: + static void sensorWait(int time); +}; + + +#endif //FIRMWARE_PMSENSOR_H diff --git a/firmware/src/sensors/Sensor.h b/firmware/src/sensors/Sensor.h index 7f3a1f8..bba9e33 100644 --- a/firmware/src/sensors/Sensor.h +++ b/firmware/src/sensors/Sensor.h @@ -1,5 +1,5 @@ -#ifndef NEW_CLIMTE_GO_SENSOR_H -#define NEW_CLIMTE_GO_SENSOR_H +#ifndef FIRMWARE_SENSOR_H +#define FIRMWARE_SENSOR_H #include diff --git a/firmware/src/sensors/sensor_data_t.h b/firmware/src/sensors/sensor_data_t.h index 0d96e8d..cc76161 100644 --- a/firmware/src/sensors/sensor_data_t.h +++ b/firmware/src/sensors/sensor_data_t.h @@ -1,7 +1,5 @@ -#ifndef NEW_CLIMTE_GO_SENSOR_DATA_T_H -#define NEW_CLIMTE_GO_SENSOR_DATA_T_H - -#include +#ifndef FIRMWARE_SENSOR_DATA_T_H +#define FIRMWARE_SENSOR_DATA_T_H /** * This struct represents data read from any sensor. @@ -11,6 +9,8 @@ struct sensor_data_t { float temperature; float pressure; + float pm10; + float pm25; }; #endif From fe18044edd176c45a78a79311eb2c3bf89e24740 Mon Sep 17 00:00:00 2001 From: CDaut Date: Mon, 14 Feb 2022 20:09:10 +0100 Subject: [PATCH 5/5] implemented async PM sensor sampling --- firmware/src/main.cpp | 24 +++++++++++---- firmware/src/sensors/PmSensor.cpp | 50 +++++++++++++++++-------------- firmware/src/sensors/PmSensor.h | 2 +- 3 files changed, 48 insertions(+), 28 deletions(-) diff --git a/firmware/src/main.cpp b/firmware/src/main.cpp index f9fc036..51b119b 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -14,11 +14,16 @@ Sensor *pmSensor; BluetoothServer *server; bool makeDiscoverable = false; - +//interrupt handler for sensor being pressed void IRAM_ATTR startBleServerAdvertising() { makeDiscoverable = true; } +//helper function to create task for PM measurement +void startPmAsyncSampling(void * param){ + ((PmSensor *) pmSensor)->startAsyncSampling(); +} + void setup() { //initialize a Serial Connection Serial.begin(BAUD_RATE); @@ -38,17 +43,25 @@ void setup() { attachInterrupt(digitalPinToInterrupt(INTERRUPT_MAKE_DISCOVERABLE_PIN), startBleServerAdvertising, RISING); + + //start an async task for measuring PM so the sensor won't block the whole system + xTaskCreate( + startPmAsyncSampling, + "Async PM sampling", + 1024, + nullptr, + 1, + nullptr + ); } void loop() { + //check if the button has been pressed and handle appropriately if (makeDiscoverable) { server->startAdvertising(); makeDiscoverable = false; } - //setup PM sensor measurement TODO: This blocks for 120 seconds and needs to be executed asynchronously - //((PmSensor *) pmSensor)->startAsyncSampling(); - //obtain measurement from BMP280 Sensor sensor_data_t sample = ((BmpSensor *) bmpSensor)->sampleLowEnergy(); server->setPressure(sample.pressure); @@ -57,11 +70,12 @@ void loop() { sensor_data_t pmSample = pmSensor->sample(); //Print measured data - Serial.printf("Pressure: %f hPa | Temperature: %f °C | PM10: %f ppm| PM2.5: %f ppm\n", + Serial.printf("Pressure: %f hPa | Temperature: %f °C | PM10: %f ppm | PM2.5: %f ppm\n", sample.pressure, sample.temperature, pmSample.pm10, pmSample.pm25); + //wait for one measurement cycle delay(SLEEP_TIME * 1000); } \ No newline at end of file diff --git a/firmware/src/sensors/PmSensor.cpp b/firmware/src/sensors/PmSensor.cpp index 7e0fc03..b43a7bd 100644 --- a/firmware/src/sensors/PmSensor.cpp +++ b/firmware/src/sensors/PmSensor.cpp @@ -21,19 +21,35 @@ PmSensor::PmSensor() { this->PmSensor::sensor_setup(); } -void PmSensor::startAsyncSampling() { +[[noreturn]] void PmSensor::startAsyncSampling() { - this->enableStandbyMode(); - PmSensor::sensorWait(SLEEP_TIME); + Serial.println("Started async task for PM sensor sampling."); - this->wakeUp(); - sds011.perform_work(); + while (true) { + this->wakeUp(); - if (!sds011.query_data_auto_async(pm_tablesize, pm25_table, pm10_table)) { - Serial.println("measurement capture start failed"); + //attach a callback on what to do when data sampling is complete + sds011.on_query_data_auto_completed([this](int n) { + Serial.println("Sampled new PM data."); + int pm25; + int pm10; + if (sds011.filter_data(n, pm25_table, pm10_table, pm25, pm10) && + !isnan(pm10) && !isnan(pm25)) { + //set the right values + this->latestPM10 = float(pm10) / 10; + this->latestPM25 = float(pm25) / 10; + } + }); + + if (!sds011.query_data_auto_async(pm_tablesize, pm25_table, pm10_table)) { + Serial.println("measurement capture start failed"); + } + + PmSensor::sensorWait(MEASURE_TIME); + + this->enableStandbyMode(); + PmSensor::sensorWait(SLEEP_TIME); } - - PmSensor::sensorWait(MEASURE_TIME); } /** @@ -41,6 +57,7 @@ void PmSensor::startAsyncSampling() { */ void PmSensor::enableStandbyMode() { if (sds011.set_sleep(true)) { this->state = SensorState::ASLEEP; } + Serial.println("PM sensor went to sleep mode."); } /** @@ -48,6 +65,7 @@ void PmSensor::enableStandbyMode() { */ void PmSensor::wakeUp() { if (sds011.set_sleep(false)) { this->state = SensorState::AWAKE; } + Serial.println("PM sensor woke up."); } /** @@ -64,18 +82,6 @@ void PmSensor::sensor_setup() { //put the sensor into standby mode initially this->PmSensor::enableStandbyMode(); Serial.println("SDS011 sensor initialized to standby mode."); - - //attach a callback on what to do when data sampling is complete - sds011.on_query_data_auto_completed([this](int n) { - int pm25; - int pm10; - if (sds011.filter_data(n, pm25_table, pm10_table, pm25, pm10) && - !isnan(pm10) && !isnan(pm25)) { - //set the right values - this->latestPM10 = float(pm10) / 10; - this->latestPM25 = float(pm25) / 10; - } - }); } /** @@ -85,7 +91,7 @@ void PmSensor::sensor_setup() { void PmSensor::sensorWait(int time) { uint32_t deadline = millis() + time * 1000; while (static_cast(deadline - millis()) > 0) { - delay(1000); + vTaskDelay(1000 / portTICK_PERIOD_MS); sds011.perform_work(); } } diff --git a/firmware/src/sensors/PmSensor.h b/firmware/src/sensors/PmSensor.h index 3a3bd84..626b586 100644 --- a/firmware/src/sensors/PmSensor.h +++ b/firmware/src/sensors/PmSensor.h @@ -17,7 +17,7 @@ public: sensor_data_t sample() override; - void startAsyncSampling(); + [[noreturn]] void startAsyncSampling(); void enableStandbyMode() override;