From 2babfff289b4fcd2df5f9bb16a3a2958d9926763 Mon Sep 17 00:00:00 2001 From: Willem Date: Thu, 22 Jul 2021 13:54:52 +0200 Subject: [PATCH] moved to sensor class --- CO2_sensor.cpp | 44 ++++++++++++++ CO2_sensor.h | 13 ++++ main.cpp | 10 +++- mqtt.cpp | 1 + mqtt.h | 53 ++--------------- particles.cpp | 157 +++++++++++++++++++++---------------------------- particles.h | 3 +- platformio.ini | 31 +++++----- sensor.cpp | 42 +++++++++++++ sensor.h | 70 ++++++++++++++++++++++ 10 files changed, 266 insertions(+), 158 deletions(-) create mode 100644 CO2_sensor.cpp create mode 100644 CO2_sensor.h create mode 100644 sensor.cpp create mode 100644 sensor.h diff --git a/CO2_sensor.cpp b/CO2_sensor.cpp new file mode 100644 index 0000000..8c4f4e1 --- /dev/null +++ b/CO2_sensor.cpp @@ -0,0 +1,44 @@ +#include "CO2_sensor.h" + +Adafruit_SCD30 scd30; + +#define CO2_INTERVAL 120000 //ms + +uint8_t CO2_samples = 3600 / g_pms_report_period; + +AQSSensor SCD30_temperature("Temperature", device_name, CO2_samples); +AQSSensor SCD30_Humidity("Humidity", device_name, CO2_samples); +AQSSensor SCD30_CO2("CO2", device_name, CO2_samples); + +uint32_t CO2_lastUpdate = 0; + +void initCO2sensor(void) +{ + Serial.print("Init SCD30:"); + if (!scd30.begin(true)) + { + Serial.println("Failed to find SCD30 device"); + } + + addSensorToList(&SCD30_temperature); + addSensorToList(&SCD30_Humidity); + addSensorToList(&SCD30_CO2); + + Serial.println(" OK"); +} + +void handleCO2sensor(void) +{ + uint32_t currentmillis = millis(); + + if (currentmillis - CO2_lastUpdate > CO2_INTERVAL) + { + SCD30_temperature.set(uint32_t(scd30.temperature)); + SCD30_Humidity.set(uint32_t(scd30.relative_humidity)); + SCD30_CO2.set(uint32_t(scd30.CO2)); + + SCD30_temperature.publish(); + SCD30_Humidity.publish(); + SCD30_CO2.publish(); + } +} \ No newline at end of file diff --git a/CO2_sensor.h b/CO2_sensor.h new file mode 100644 index 0000000..86bddf0 --- /dev/null +++ b/CO2_sensor.h @@ -0,0 +1,13 @@ +#pragma once + +#include "Arduino.h" +#include "config.h" + +#include +#include + +#include "sensor.h" + + +void initCO2sensor( void ); +void handleCO2sensor( void ); \ No newline at end of file diff --git a/main.cpp b/main.cpp index 03c2afe..630d7d6 100644 --- a/main.cpp +++ b/main.cpp @@ -17,6 +17,7 @@ Adafruit_NeoPixel.h Adafruit_Sensor.h Adafruit_BME680.h + AdaFruit_SCD30.h "PubSubClient" by Nick O'Leary RunningMedian @@ -36,6 +37,7 @@ #include "lcd.h" #include "mqtt.h" #include "particles.h" +#include "CO2_sensor.h" #include "button.h" /*--------------------------- Program ---------------------------------------*/ @@ -48,10 +50,12 @@ void setup() Serial.println(); Serial.print("Air Quality Sensor starting up, v"); Serial.println(VERSION); - + initWifi(); initMQTT(); + initSensor(); initParticles(); + initCO2sensor(); initLCD(); initButtons(); } @@ -62,7 +66,9 @@ void setup() void loop() { handleParticles(); - handleMQTT(); + handleCO2sensor(); handleButtons(); + handleSensor(); handleLCD(); + handleMQTT(); } diff --git a/mqtt.cpp b/mqtt.cpp index a3d0e79..c918cb8 100644 --- a/mqtt.cpp +++ b/mqtt.cpp @@ -154,3 +154,4 @@ void publishSingle(uint32_t value, char *topic) message_string.toCharArray(g_mqtt_message_buffer, message_string.length() + 1); client.publish(topic, g_mqtt_message_buffer); } + diff --git a/mqtt.h b/mqtt.h index a82179a..ff5e7c1 100644 --- a/mqtt.h +++ b/mqtt.h @@ -9,55 +9,10 @@ #include #include "RunningMedian.h" - -void initMQTT( void ); -void handleMQTT( void ); +void initMQTT(void); +void handleMQTT(void); bool initWifi(); -uint32_t getDeviceID( void ); +uint32_t getDeviceID(void); -void publishSingle(uint32_t value, char *topic); - -class mqttSensor -{ - char _topic[50]; - char _topic_1h[50]; - char _topic_24h[50]; - const String _name; - uint32_t _value; - RunningMedian _average1h; - RunningMedian _average24h; - public: - - mqttSensor(String name, String deviceID, uint8_t avgSamples): _name(name), - _average1h(avgSamples), - _average24h(avgSamples*24) - { - sprintf(_topic, "Sensors/%s/%s", deviceID.c_str(),name.c_str() ); - sprintf(_topic_1h, "Sensors/%s/%s/1h/", deviceID.c_str(),name.c_str() ); - sprintf(_topic_24h, "Sensors/%s/%s/24h/", deviceID.c_str(),name.c_str() ); - } - - - void publish(void) - { - publishSingle(_value, _topic); - publishSingle(_average1h.getMedian(),_topic_1h); - publishSingle(_average24h.getMedian(),_topic_24h); - } - - virtual void set(uint32_t value) - { - _value = value; - _average1h.add(_value); - _average24h.add(_value); - } - - uint32_t value() {return _value;} - - void print( void ) - { - Serial.printf("sensor:%s = %d\n",_name.c_str(), _value); - } - -}; +void publishSingle(uint32_t value, char *topic); \ No newline at end of file diff --git a/particles.cpp b/particles.cpp index 3bb28c7..a0ee574 100644 --- a/particles.cpp +++ b/particles.cpp @@ -12,71 +12,99 @@ char g_command_topic[50]; // MQTT topic for receiving commands #define PMS_STATE_READY 2 // Warmed up, ready to give data uint8_t g_pms_state = PMS_STATE_WAKING_UP; - - uint32_t g_pms_state_start = 0; // Timestamp when PMS state last changed uint8_t g_pms_readings_taken = 0; // 0/1: whether any readings have been taken uint8_t g_pms_ppd_readings_taken = 0; // 0/1: whether PPD readings have been taken uint8_t samples = 3600 / g_pms_report_period; -mqttSensor g_pm1p0_sp("SP_1P0", device_name, samples); -mqttSensor g_pm2p5_sp("SP_2P5", device_name, samples); -mqttSensor g_pm10p0_sp("SP_10P0", device_name, samples); +AQSSensor g_pm1p0_sp("SP_1P0", device_name, samples); +AQSSensor g_pm2p5_sp("SP_2P5", device_name, samples); +AQSSensor g_pm10p0_sp("SP_10P0", device_name, samples); -mqttSensor g_pm1p0_ae("AE_1P0", device_name, samples); -mqttSensor g_pm2p5_ae("AE_2P5", device_name, samples); -mqttSensor g_pm10p0_ae("AE_10P0", device_name, samples); +AQSSensor g_pm1p0_ae("AE_1P0", device_name, samples); +AQSSensor g_pm2p5_ae("AE_2P5", device_name, samples); +AQSSensor g_pm10p0_ae("AE_10P0", device_name, samples); -mqttSensor g_pm0p3_ppd("PPD_0P3", device_name, samples); -mqttSensor g_pm0p5_ppd("PPD_0P5", device_name, samples); -mqttSensor g_pm1p0_ppd("PPD_1P0", device_name, samples); -mqttSensor g_pm2p5_ppd("PPD_2P5", device_name, samples); -mqttSensor g_pm5p0_ppd("PPD_5P0", device_name, samples); -mqttSensor g_pm10p0_ppd("PPD_10P0", device_name, samples); +AQSSensor g_pm0p3_ppd("PPD_0P3", device_name, samples); +AQSSensor g_pm0p5_ppd("PPD_0P5", device_name, samples); +AQSSensor g_pm1p0_ppd("PPD_1P0", device_name, samples); +AQSSensor g_pm2p5_ppd("PPD_2P5", device_name, samples); +AQSSensor g_pm5p0_ppd("PPD_5P0", device_name, samples); +AQSSensor g_pm10p0_ppd("PPD_10P0", device_name, samples); -std::vector sensorList; +void PMS_publishSensors(void ); -void prepareTopics( void ) + +void PMS_AddSensors( void ) { - sensorList.push_back(&g_pm1p0_sp); - sensorList.push_back(&g_pm2p5_sp); - sensorList.push_back(&g_pm10p0_sp); + addSensorToList(&g_pm1p0_sp); + addSensorToList(&g_pm2p5_sp); + addSensorToList(&g_pm10p0_sp); - sensorList.push_back(&g_pm1p0_ae); - sensorList.push_back(&g_pm2p5_ae); - sensorList.push_back(&g_pm10p0_ae); + addSensorToList(&g_pm1p0_ae); + addSensorToList(&g_pm2p5_ae); + addSensorToList(&g_pm10p0_ae); - sensorList.push_back(&g_pm0p3_ppd); - sensorList.push_back(&g_pm0p5_ppd); - sensorList.push_back(&g_pm1p0_ppd); - sensorList.push_back(&g_pm2p5_ppd); - sensorList.push_back(&g_pm5p0_ppd); - sensorList.push_back(&g_pm10p0_ppd); + addSensorToList(&g_pm0p3_ppd); + addSensorToList(&g_pm0p5_ppd); + addSensorToList(&g_pm1p0_ppd); + addSensorToList(&g_pm2p5_ppd); + addSensorToList(&g_pm5p0_ppd); + addSensorToList(&g_pm10p0_ppd); } uint32_t getLCDvalue(void) { return g_pm2p5_ae.value(); } -/** - Report the latest values to the serial console -*/ -void reportToSerial() + + +void PMS_publishSensors(void ) { + String message_string; + /* Report PM1.0 AE value */ - for( auto && sensor : sensorList) + g_pm1p0_ae.publish(); + g_pm2p5_ae.publish(); + g_pm10p0_ae.publish(); + + g_pm1p0_sp.publish(); + g_pm2p5_sp.publish(); + g_pm10p0_sp.publish(); + + if (1 == g_pms_ppd_readings_taken) { - sensor->print(); + /* Report PM0.3 PPD value */ + g_pm0p3_ppd.publish(); + g_pm0p5_ppd.publish(); + g_pm1p0_ppd.publish(); + g_pm2p5_ppd.publish(); + g_pm5p0_ppd.publish(); + g_pm10p0_ppd.publish(); } } -/** - Update particulate matter sensor values -*/ -void updatePmsReadings() +void initParticles( void ) { - uint32_t time_now = millis(); + Serial.print("initPMS:"); + // Open a connection to the PMS and put it into passive mode + Serial2.begin(PMS_BAUD_RATE, SERIAL_8N1, PMS_RX_PIN, PMS_TX_PIN); // Connection for PMS5003 + pms.activeMode(); // Tell PMS to stop sending data automatically + delay(100); + pms.wakeUp(); // Tell PMS to wake up (turn on fan and laser) + + //Serial2.begin(PMS_BAUD_RATE, SERIAL_8N1, PMS_RX_PIN, PMS_TX_PIN); + + PMS_AddSensors(); + + Serial.println(" OK"); + +} + +void handleParticles( void ) +{ + uint32_t time_now = millis(); // Check if we've been in the sleep state for long enough if (PMS_STATE_ASLEEP == g_pms_state) @@ -135,60 +163,11 @@ void updatePmsReadings() pms.sleep(); // Report the new values - reportToMqtt(); - reportToSerial(); + PMS_publishSensors(); g_pms_readings_taken = 1; g_pms_state_start = time_now; g_pms_state = PMS_STATE_ASLEEP; } } -} - - -void reportToMqtt(void ) -{ - String message_string; - - /* Report PM1.0 AE value */ - g_pm1p0_ae.publish(); - g_pm2p5_ae.publish(); - g_pm10p0_ae.publish(); - - g_pm1p0_sp.publish(); - g_pm2p5_sp.publish(); - g_pm10p0_sp.publish(); - - if (1 == g_pms_ppd_readings_taken) - { - /* Report PM0.3 PPD value */ - g_pm0p3_ppd.publish(); - g_pm0p5_ppd.publish(); - g_pm1p0_ppd.publish(); - g_pm2p5_ppd.publish(); - g_pm5p0_ppd.publish(); - g_pm10p0_ppd.publish(); - } -} - -void initParticles( void ) -{ - Serial.print("initPMS:"); - // Open a connection to the PMS and put it into passive mode - Serial2.begin(PMS_BAUD_RATE, SERIAL_8N1, PMS_RX_PIN, PMS_TX_PIN); // Connection for PMS5003 - pms.activeMode(); // Tell PMS to stop sending data automatically - delay(100); - pms.wakeUp(); // Tell PMS to wake up (turn on fan and laser) - - //Serial2.begin(PMS_BAUD_RATE, SERIAL_8N1, PMS_RX_PIN, PMS_TX_PIN); - - prepareTopics(); - - Serial.println(" OK"); - -} - -void handleParticles( void ) -{ - updatePmsReadings(); } \ No newline at end of file diff --git a/particles.h b/particles.h index be49709..881c961 100644 --- a/particles.h +++ b/particles.h @@ -6,10 +6,9 @@ #include "PMS.h" // Particulate Matter Sensor driver (embedded) #include "RunningMedian.h" -#include "mqtt.h" +#include "sensor.h" uint32_t getLCDvalue(void); -void reportToMqtt(void ); void initParticles( void ); void handleParticles( void ); \ No newline at end of file diff --git a/platformio.ini b/platformio.ini index 418e5ac..02450c5 100644 --- a/platformio.ini +++ b/platformio.ini @@ -6,31 +6,30 @@ ; Advanced options: extra scripting ; ; Please visit documentation for the other options and examples -; http://docs.platformio.org/page/projectconf.html +; https://docs.platformio.org/page/projectconf.html [platformio] default_envs = esp32 src_dir = . [common] -lib_deps_builtin = - WiFi - TFT_eSPI - -lib_deps = - #adafruit/Adafruit BME680 Library - #adafruit/Adafruit GFX Library - #adafruit/Adafruit Neopixel - #adafruit/Adafruit Unified Sensor - knolleary/PubSubClient - robtillaart/RunningMedian - bodmer/Tjpg_decoder +lib_deps_builtin = + WiFi + TFT_eSPI +lib_deps = + adafruit/Adafruit Unified Sensor + knolleary/PubSubClient + robtillaart/RunningMedian + bodmer/Tjpg_decoder + adafruit/Adafruit SCD30 + adafruit/Adafruit BusIO [env:esp32] platform = espressif32 board = esp-wrover-kit framework = arduino monitor_speed = 115200 -lib_deps = - ${common.lib_deps_builtin} - ${common.lib_deps} +lib_deps = + ${common.lib_deps_builtin} + ${common.lib_deps} + diff --git a/sensor.cpp b/sensor.cpp new file mode 100644 index 0000000..76f4f32 --- /dev/null +++ b/sensor.cpp @@ -0,0 +1,42 @@ +#include "sensor.h" + + +std::vector sensorList; + +void publishAll(void); + +void reportToSerial(void) +{ + /* Report PM1.0 AE value */ + for( auto && sensor : sensorList) + { + sensor->print(); + } +} + +void addSensorToList(AQSSensor* sensor) +{ + sensorList.push_back(sensor); + Serial.printf("AQSSensor: added %s", sensor->getName().c_str()); +} + + +void publishAll(void) +{ + for(auto && sensor : sensorList) + { + sensor->print(); + sensor->publishMQTT(); + } +} + +void initSensor(void) +{ + Serial.print("InitSensor:"); + Serial.println(" OK"); +} + +void handleSensor(void) +{ + publishAll(); +} \ No newline at end of file diff --git a/sensor.h b/sensor.h new file mode 100644 index 0000000..f42f07d --- /dev/null +++ b/sensor.h @@ -0,0 +1,70 @@ +#pragma once + +#include "Arduino.h" +#include "mqtt.h" + +class AQSSensor +{ + char _topic[50]; + char _topic_1h[50]; + char _topic_24h[255]; + const String _name; + uint32_t _value; + RunningMedian _average1h; + RunningMedian _average24h; + bool _publish = false; + +public: + AQSSensor(String name, String deviceID, uint8_t avgSamples) : _name(name), + _average1h(avgSamples), + _average24h(avgSamples * 24) + { + sprintf(_topic, "Sensors/%s/%s", deviceID.c_str(), name.c_str()); + sprintf(_topic_1h, "Sensors/%s/%s/1h/", deviceID.c_str(), name.c_str()); + sprintf(_topic_24h, "Sensors/%s/%s/24h/", deviceID.c_str(), name.c_str()); + } + + void publish(void) + { + _publish = true; + } + + String getName(void) + { + return _name; + } + + void publishMQTT(void) + { + if (_publish == true) + { + publishSingle(_value, _topic); + publishSingle(_average1h.getMedian(), _topic_1h); + publishSingle(_average24h.getMedian(), _topic_24h); + _publish = false; + } + } + + virtual void set(uint32_t value) + { + _value = value; + _average1h.add(_value); + _average24h.add(_value); + } + + uint32_t value() { return _value; } + + void print(void) + { + if (_publish) + { + Serial.printf("sensor:%s = %d\n", _name.c_str(), _value); + } + } +}; + +void addSensorToList(AQSSensor *sensor); +void reportToSerial(void); + +void initSensor(void); +void handleSensor(void); \ No newline at end of file