Skip to content

Commit

Permalink
Merged in OscarRoviraLopez/espurna/sensors (pull request #41)
Browse files Browse the repository at this point in the history
Add PMSX003 air quality sensors

Approved-by: Xose Pérez <[email protected]>
  • Loading branch information
Oscar Rovira authored and xoseperez committed Dec 17, 2017
2 parents f95e46c + 5b0411b commit 9d63e56
Show file tree
Hide file tree
Showing 11 changed files with 695 additions and 545 deletions.
2 changes: 2 additions & 0 deletions code/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
.piolibdeps
.vscode/c_cpp_properties.json
core_version.h
.pioenvs
.piolibdeps
6 changes: 6 additions & 0 deletions code/espurna/config/general.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,9 @@ PROGMEM const char* const custom_reset_string[] = {
#define SENSOR_POWER_DECIMALS 0
#define SENSOR_POWER_FACTOR_DECIMALS 0
#define SENSOR_ENERGY_DECIMALS 0
#define SENSOR_PM1dot0_DECIMALS 0
#define SENSOR_PM2dot5_DECIMALS 0
#define SENSOR_PM10_DECIMALS 0

#define SENSOR_UNKNOWN_TOPIC "unknown"
#define SENSOR_TEMPERATURE_TOPIC "temperature"
Expand All @@ -787,6 +790,9 @@ PROGMEM const char* const custom_reset_string[] = {
#define SENSOR_POWER_FACTOR_TOPIC "factor"
#define SENSOR_ENERGY_TOPIC "energy"
#define SENSOR_ENERGY_DELTA_TOPIC "energy_delta"
#define SENSOR_PM1dot0_TOPIC "pm1dot0"
#define SENSOR_PM2dot5_TOPIC "pm2dot5"
#define SENSOR_PM10_TOPIC "pm10"
#define SENSOR_ANALOG_TOPIC "analog"
#define SENSOR_EVENTS_TOPIC "events"

Expand Down
5 changes: 5 additions & 0 deletions code/espurna/config/prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ template<typename T> bool idbSend(const char * topic, unsigned char id, T payloa
#include <OneWire.h>
#endif

#if PMSX003_SUPPORT
#include <SoftwareSerial.h>
#include <PMS.h>
#endif

// -----------------------------------------------------------------------------
// Utils
// -----------------------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions code/espurna/config/sensors.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,18 @@
#define EMON_ADS1X15_ADC_BITS 16 // ADC depth
#define EMON_ADS1X15_REFERENCE_VOLTAGE 8.192 // Double the gain for peak-to-peak

//--------------------------------------------------------------------------------
// Particle Monitor based on Plantower PMSX003
// Enable support by passing PMSX003_SUPPORT=1 build flag
//--------------------------------------------------------------------------------

#ifndef PMSX003_SUPPORT
#define PMSX003_SUPPORT 1
#endif

#define PMS_RX_PIN 13
#define PMS_TX_PIN 15

//--------------------------------------------------------------------------------
// Internal power montior
// Enable support by passing ADC_VCC_ENABLED=1 build flag
Expand Down
Binary file modified code/espurna/data/index.html.gz
Binary file not shown.
14 changes: 14 additions & 0 deletions code/espurna/sensor.ino
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ String _sensorTopic(magnitude_t type) {
if (type == MAGNITUDE_ENERGY_DELTA) return String(SENSOR_ENERGY_DELTA_TOPIC);
if (type == MAGNITUDE_ANALOG) return String(SENSOR_ANALOG_TOPIC);
if (type == MAGNITUDE_EVENTS) return String(SENSOR_EVENTS_TOPIC);
if (type == MAGNITUDE_PM1dot0) return String(SENSOR_PM1dot0_TOPIC);
if (type == MAGNITUDE_PM2dot5) return String(SENSOR_PM2dot5_TOPIC);
if (type == MAGNITUDE_PM10) return String(SENSOR_PM10_TOPIC);
return String(SENSOR_UNKNOWN_TOPIC);
}

Expand All @@ -67,6 +70,9 @@ unsigned char _sensorDecimals(magnitude_t type) {
if (type == MAGNITUDE_ENERGY_DELTA) return SENSOR_ENERGY_DECIMALS;
if (type == MAGNITUDE_ANALOG) return SENSOR_ANALOG_DECIMALS;
if (type == MAGNITUDE_EVENTS) return SENSOR_EVENTS_DECIMALS;
if (type == MAGNITUDE_PM1dot0) return SENSOR_PM1dot0_DECIMALS;
if (type == MAGNITUDE_PM2dot5) return SENSOR_PM2dot5_DECIMALS;
if (type == MAGNITUDE_PM10) return SENSOR_PM10_DECIMALS;
return 0;
}

Expand All @@ -83,6 +89,9 @@ String _sensorUnits(magnitude_t type) {
if (type == MAGNITUDE_ENERGY) return String("J");
if (type == MAGNITUDE_ENERGY_DELTA) return String("J");
if (type == MAGNITUDE_EVENTS) return String("/m");
if (type == MAGNITUDE_PM1dot0) return String("µg/m3");
if (type == MAGNITUDE_PM2dot5) return String("µg/m3");
if (type == MAGNITUDE_PM10) return String("µg/m3");
return String();
}

Expand Down Expand Up @@ -252,6 +261,11 @@ void sensorInit() {
#include "sensors/EmonADS1X15Sensor.h"
sensorRegister(new EmonADS1X15Sensor(EMON_ADS1X15_I2C_ADDRESS, EMON_ADS1X15_ADS1115, EMON_ADS1X15_PORT_MASK, EMON_MAINS_VOLTAGE, EMON_ADS1X15_ADC_BITS, EMON_ADS1X15_REFERENCE_VOLTAGE, EMON_ADS1X15_CURRENT_RATIO));
#endif

#if PMSX003_SUPPORT
#include "sensors/PMSX003Sensor.h"
sensorRegister(new PMSX003Sensor(PMS_RX_PIN, PMS_TX_PIN));
#endif

#if COUNTER_SUPPORT
if (_sensor_isr == 0xFF) {
Expand Down
5 changes: 5 additions & 0 deletions code/espurna/sensors/BaseSensor.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,17 @@ typedef enum magnitude_t {
MAGNITUDE_ANALOG,
MAGNITUDE_EVENTS,

MAGNITUDE_PM1dot0,
MAGNITUDE_PM2dot5,
MAGNITUDE_PM10,

MAGNITUDE_MAX,

} magnitude_t;

#define SENSOR_ERROR_OK 0
#define SENSOR_ERROR_OUT_OF_RANGE 1
#define SENSOR_ERROR_WARM_UP 2

class BaseSensor {

Expand Down
101 changes: 101 additions & 0 deletions code/espurna/sensors/PMSX003Sensor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// -----------------------------------------------------------------------------
// PMSX003 Dust sensor
// -----------------------------------------------------------------------------

#pragma once

#include "Arduino.h"
#include "BaseSensor.h"

#include <PMS.h>
#include <SoftwareSerial.h>

class PMSX003Sensor : public BaseSensor {

public:

PMSX003Sensor(int pin_rx = PMS_RX_PIN, int pin_tx = PMS_TX_PIN): BaseSensor() {
_pmsSerial = new SoftwareSerial(pin_rx, pin_tx, false, 256);
_pmsSerial->begin(9600);
_pms = new PMS(* _pmsSerial);
_pms->passiveMode();
_pin_rx = pin_rx;
_pin_tx = pin_tx;
_count = 3;
_startTime = millis();
}

// Descriptive name of the sensor
String name() {
char buffer[28];
snprintf(buffer, sizeof(buffer), "PMSX003 @ SwSerial(%i,%i)", _pin_rx, _pin_tx);
return String(buffer);
}

// Descriptive name of the slot # index
String slot(unsigned char index) {
if (index < _count) {
_error = SENSOR_ERROR_OK;
char buffer[36];
if (index == 0) snprintf(buffer, sizeof(buffer), "PM1.0 @ PMSX003 @ SwSerial(%i,%i)", _pin_rx, _pin_tx);
if (index == 1) snprintf(buffer, sizeof(buffer), "PM2.5 @ PMSX003 @ SwSerial(%i,%i)", _pin_rx, _pin_tx);
if (index == 2) snprintf(buffer, sizeof(buffer), "PM10 @ PMSX003 @ SwSerial(%i,%i)", _pin_rx, _pin_tx);
return String(buffer);
}
_error = SENSOR_ERROR_OUT_OF_RANGE;
return String();
}

// Type for slot # index
magnitude_t type(unsigned char index) {
if (index < _count) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_PM1dot0;
if (index == 1) return MAGNITUDE_PM2dot5;
if (index == 2) return MAGNITUDE_PM10;
}
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}

void pre() {
if(millis() - _startTime > 30000) {
_error = SENSOR_ERROR_OK;
} else {
_error = SENSOR_ERROR_WARM_UP;
}
_pms->requestRead();
}

void tick() {
if(_pms->read(_data)) {
_pm1dot0 = _data.PM_AE_UG_1_0;
_pm2dot5 = _data.PM_AE_UG_2_5;
_pm10 = _data.PM_AE_UG_10_0;
}
}

// Current value for slot # index
double value(unsigned char index) {
if (index < _count) {
_error = SENSOR_ERROR_OK;
if(index == 0) return _pm1dot0;
if(index == 1) return _pm2dot5;
if(index == 2) return _pm10;
}
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}

protected:
unsigned int _pm1dot0;
unsigned int _pm2dot5;
unsigned int _pm10;
unsigned int _pin_rx;
unsigned int _pin_tx;
unsigned long _startTime;
SoftwareSerial * _pmsSerial;
PMS * _pms;
PMS::DATA _data;

};
Loading

0 comments on commit 9d63e56

Please sign in to comment.