moved to sensor class
This commit is contained in:
44
CO2_sensor.cpp
Normal file
44
CO2_sensor.cpp
Normal 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
13
CO2_sensor.h
Normal 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 );
|
||||
10
main.cpp
10
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();
|
||||
}
|
||||
|
||||
1
mqtt.cpp
1
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);
|
||||
}
|
||||
|
||||
|
||||
53
mqtt.h
53
mqtt.h
@@ -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);
|
||||
157
particles.cpp
157
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<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();
|
||||
}
|
||||
@@ -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 );
|
||||
@@ -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
42
sensor.cpp
Normal 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
70
sensor.h
Normal 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);
|
||||
Reference in New Issue
Block a user