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/ diff --git a/firmware/CMakeListsPrivate.txt b/firmware/CMakeListsPrivate.txt new file mode 100644 index 0000000..e39b280 --- /dev/null +++ b/firmware/CMakeListsPrivate.txt @@ -0,0 +1,152 @@ +# !!! 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=50205) + 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/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") + 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}) 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/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..51b119b 100644 --- a/firmware/src/main.cpp +++ b/firmware/src/main.cpp @@ -1,28 +1,81 @@ #include #include #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; +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); + //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(); + + //set up Interrupt to enable make discoverable button + pinMode(INTERRUPT_MAKE_DISCOVERABLE_PIN, INPUT_PULLDOWN); + 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; + } + + //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..b43a7bd --- /dev/null +++ b/firmware/src/sensors/PmSensor.cpp @@ -0,0 +1,101 @@ +#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(); +} + +[[noreturn]] void PmSensor::startAsyncSampling() { + + Serial.println("Started async task for PM sensor sampling."); + + while (true) { + this->wakeUp(); + + //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); + } +} + +/** + * Put the sensor to standby mode + */ +void PmSensor::enableStandbyMode() { + if (sds011.set_sleep(true)) { this->state = SensorState::ASLEEP; } + Serial.println("PM sensor went to sleep mode."); +} + +/** + * Activate the sensor + */ +void PmSensor::wakeUp() { + if (sds011.set_sleep(false)) { this->state = SensorState::AWAKE; } + Serial.println("PM sensor woke up."); +} + +/** + * 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."); +} + +/** + * 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) { + vTaskDelay(1000 / portTICK_PERIOD_MS); + 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..626b586 --- /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; + + [[noreturn]] 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