moved to sensor class

This commit is contained in:
2021-07-22 13:54:52 +02:00
parent 4af72b1710
commit 2babfff289
10 changed files with 266 additions and 158 deletions

44
CO2_sensor.cpp Normal file
View File

@@ -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();
}
}

13
CO2_sensor.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include "Arduino.h"
#include "config.h"
#include <Adafruit_SCD30.h>
#include <Adafruit_Sensor.h>
#include "sensor.h"
void initCO2sensor( void );
void handleCO2sensor( void );

View File

@@ -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();
}

View File

@@ -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);
}

53
mqtt.h
View File

@@ -9,55 +9,10 @@
#include <string>
#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);

View File

@@ -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<mqttSensor*> 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();
}

View File

@@ -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 );

View File

@@ -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}

42
sensor.cpp Normal file
View File

@@ -0,0 +1,42 @@
#include "sensor.h"
std::vector<AQSSensor*> 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();
}

70
sensor.h Normal file
View File

@@ -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);