Browse Source

Adding HCHO magnitude

rfm69
Xose Pérez 6 years ago
parent
commit
7ca3ae5f7d
7 changed files with 854 additions and 843 deletions
  1. +3
    -2
      code/espurna/config/progmem.h
  2. +13
    -3
      code/espurna/config/sensors.h
  3. +2
    -1
      code/espurna/config/types.h
  4. BIN
      code/espurna/data/index.html.gz
  5. +107
    -109
      code/espurna/sensors/PMSX003Sensor.h
  6. +727
    -726
      code/espurna/static/index.html.gz.h
  7. +2
    -2
      code/html/custom.js

+ 3
- 2
code/espurna/config/progmem.h View File

@ -60,6 +60,7 @@ PROGMEM const char magnitude_co2_topic[] = "co2";
PROGMEM const char magnitude_lux_topic[] = "lux"; PROGMEM const char magnitude_lux_topic[] = "lux";
PROGMEM const char magnitude_uv_topic[] = "uv"; PROGMEM const char magnitude_uv_topic[] = "uv";
PROGMEM const char magnitude_distance_topic[] = "distance"; PROGMEM const char magnitude_distance_topic[] = "distance";
PROGMEM const char magnitude_hcho_topic[] = "hcho";
PROGMEM const char* const magnitude_topics[] = { PROGMEM const char* const magnitude_topics[] = {
magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic, magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic,
@ -69,7 +70,7 @@ PROGMEM const char* const magnitude_topics[] = {
magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic, magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic, magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic, magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic,
magnitude_distance_topic
magnitude_distance_topic, magnitude_hcho_topic
}; };
PROGMEM const char magnitude_empty[] = ""; PROGMEM const char magnitude_empty[] = "";
@ -97,7 +98,7 @@ PROGMEM const char* const magnitude_units[] = {
magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_ppm, magnitude_lux, magnitude_uv, magnitude_ppm, magnitude_lux, magnitude_uv,
magnitude_distance
magnitude_distance, magnitude_empty
}; };


+ 13
- 3
code/espurna/config/sensors.h View File

@ -391,14 +391,25 @@
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Particle Monitor based on Plantower PMSX003
// Enable support by passing PMSX003_SUPPORT=1 build flag
// Particle Monitor based on Plantower PMS
// Enable support by passing PMS_SUPPORT=1 build flag
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifndef PMSX003_SUPPORT #ifndef PMSX003_SUPPORT
#define PMSX003_SUPPORT 0 #define PMSX003_SUPPORT 0
#endif #endif
#ifndef PMS_TYPE
#define PMS_TYPE PMS_TYPE_X003
#endif
// You can enable smart sleep (read 6-times then sleep on 24-reading-cycles) to extend PMS sensor's life.
// Otherwise the default lifetime of PMS sensor is about 8000-hours/1-years.
// The PMS's fan will stop working on sleeping cycle, and will wake up on reading cycle.
#ifndef PMS_SMART_SLEEP
#define PMS_SMART_SLEEP 0
#endif
#ifndef PMS_RX_PIN #ifndef PMS_RX_PIN
#define PMS_RX_PIN 13 #define PMS_RX_PIN 13
#endif #endif
@ -649,7 +660,6 @@
#if PMSX003_SUPPORT #if PMSX003_SUPPORT
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
#include <PMS.h>
#include "../sensors/PMSX003Sensor.h" #include "../sensors/PMSX003Sensor.h"
#endif #endif


+ 2
- 1
code/espurna/config/types.h View File

@ -278,5 +278,6 @@
#define MAGNITUDE_LUX 19 #define MAGNITUDE_LUX 19
#define MAGNITUDE_UV 20 #define MAGNITUDE_UV 20
#define MAGNITUDE_DISTANCE 21 #define MAGNITUDE_DISTANCE 21
#define MAGNITUDE_HCHO 22
#define MAGNITUDE_MAX 22
#define MAGNITUDE_MAX 23

BIN
code/espurna/data/index.html.gz View File


+ 107
- 109
code/espurna/sensors/PMSX003Sensor.h View File

@ -1,5 +1,5 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PMSX003 Dust Sensor
// PMS Dust Sensor
// Uses SoftwareSerial library // Uses SoftwareSerial library
// Contribution by Òscar Rovira López // Contribution by Òscar Rovira López
// Refine to support PMS5003T/PMS5003ST by Yonsm Guo // Refine to support PMS5003T/PMS5003ST by Yonsm Guo
@ -12,25 +12,16 @@
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"
#include <PMS.h>
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
//
#define PMS_TYPE_X003 0
#define PMS_TYPE_X003_9 1
#define PMS_TYPE_5003T 2
#define PMS_TYPE_5003ST 3
// Type of sensor
#define PMS_TYPE_X003 0
#define PMS_TYPE_X003_9 1
#define PMS_TYPE_5003T 2
#define PMS_TYPE_5003ST 3
#ifndef PMS_TYPE
#define PMS_TYPE PMS_TYPE_X003
#endif
// You can enable smart sleep (read 6-times then sleep on 24-reading-cycles) to extend PMS sensor's life.
// Otherwise the default lifetime of PMS sensor is about 8000-hours/1-years.
// The PMS's fan will stop working on sleeping cycle, and will wake up on reading cycle.
#ifndef PMS_SMART_SLEEP
#define PMS_SMART_SLEEP 0
#endif
// These should not be static, instead a setType method should be used to
// dinamically choose the type of sensor...
// [MAGIC][LEN][DATA9|13|17][SUM] // [MAGIC][LEN][DATA9|13|17][SUM]
#if PMS_TYPE == PMS_TYPE_5003ST #if PMS_TYPE == PMS_TYPE_5003ST
@ -38,7 +29,7 @@
#define PMS_DATA_COUNT 17 #define PMS_DATA_COUNT 17
#define PMS_SLOT_COUNT 4 #define PMS_SLOT_COUNT 4
#define PMS_SLOT_NAMES {"PM2.5", "TEMP", "HUMI", "HCHO"} #define PMS_SLOT_NAMES {"PM2.5", "TEMP", "HUMI", "HCHO"}
#define PMS_SLOT_TYPES {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY, MAGNITUDE_ANALOG}
#define PMS_SLOT_TYPES {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY, MAGNITUDE_HCHO}
#elif PMS_TYPE == PMS_TYPE_5003T #elif PMS_TYPE == PMS_TYPE_5003T
#define PMS_TYPE_NAME "PMS5003T" #define PMS_TYPE_NAME "PMS5003T"
#define PMS_DATA_COUNT 13 #define PMS_DATA_COUNT 13
@ -63,107 +54,112 @@
#define PMS_PAYLOAD_SIZE (PMS_DATA_COUNT * 2 + 2) #define PMS_PAYLOAD_SIZE (PMS_DATA_COUNT * 2 + 2)
// PMSX003 sensor utils
// PMS sensor utils
// Command functions copied from: https://github.com/fu-hsi/PMS/blob/master/src/PMS.cpp // Command functions copied from: https://github.com/fu-hsi/PMS/blob/master/src/PMS.cpp
// Reading function is rewrited to support flexible reading for PMS5003T/PMS5003ST // Reading function is rewrited to support flexible reading for PMS5003T/PMS5003ST
class PMSX003 { class PMSX003 {
protected:
SoftwareSerial *_serial = NULL; // Should initialized by child class
public:
// Standby mode. For low power consumption and prolong the life of the sensor.
inline void sleep() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73 };
_serial->write(command, sizeof(command));
}
// Operating mode. Stable data should be got at least 30 seconds after the sensor wakeup from the sleep mode because of the fan's performance.
inline void wakeUp() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74 };
_serial->write(command, sizeof(command));
}
// Active mode. Default mode after power up. In this mode sensor would send serial data to the host automatically.
inline void activeMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Passive mode. In this mode, sensor would send serial data to the host only for request.
inline void passiveMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70 };
_serial->write(command, sizeof(command));
}
// Request read, ONLY needed in Passive Mode!!
inline void requestRead() {
uint8_t command[] = { 0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Read sensor's data
bool readData(uint16_t data[PMS_DATA_COUNT]) {
do
{
int avail = _serial->available();
#if SENSOR_DEBUG
//debugSend("[SENSOR] %s: Packet available = %d\n", PMS_TYPE_NAME, avail);
#endif
if (avail < PMS_PACKET_SIZE)
break;
if (_serial->read() == 0x42 && _serial->read() == 0x4D)
{
uint16_t sum = 0x42 + 0x4D;
uint16_t size = read16(sum);
protected:
SoftwareSerial *_serial = NULL; // Should initialized by child class
public:
// Standby mode. For low power consumption and prolong the life of the sensor.
inline void sleep() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73 };
_serial->write(command, sizeof(command));
}
// Operating mode. Stable data should be got at least 30 seconds after the sensor wakeup from the sleep mode because of the fan's performance.
inline void wakeUp() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74 };
_serial->write(command, sizeof(command));
}
// Active mode. Default mode after power up. In this mode sensor would send serial data to the host automatically.
inline void activeMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Passive mode. In this mode, sensor would send serial data to the host only for request.
inline void passiveMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70 };
_serial->write(command, sizeof(command));
}
// Request read, ONLY needed in Passive Mode!!
inline void requestRead() {
uint8_t command[] = { 0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Read sensor's data
bool readData(uint16_t data[PMS_DATA_COUNT]) {
do {
int avail = _serial->available();
#if SENSOR_DEBUG #if SENSOR_DEBUG
debugSend("[SENSOR] %s: Payload size = %d\n", PMS_TYPE_NAME, size);
//debugSend("[SENSOR] %s: Packet available = %d\n", PMS_TYPE_NAME, avail);
#endif #endif
if (size != PMS_PAYLOAD_SIZE)
{
#if SENSOR_DEBUG
debugSend(("[SENSOR] %s: Payload size != %d \n"), PMS_TYPE_NAME, PMS_PAYLOAD_SIZE);
#endif
if (avail < PMS_PACKET_SIZE) {
break; break;
} }
for (int i = 0; i < PMS_DATA_COUNT; i++)
{
data[i] = read16(sum);
if (_serial->read() == 0x42 && _serial->read() == 0x4D) {
uint16_t sum = 0x42 + 0x4D;
uint16_t size = read16(sum);
#if SENSOR_DEBUG #if SENSOR_DEBUG
//debugSend(("[SENSOR] %s: data[%d] = %d\n"), PMS_TYPE_NAME, i, data[i]);
debugSend("[SENSOR] %s: Payload size = %d\n", PMS_TYPE_NAME, size);
#endif #endif
}
if (size != PMS_PAYLOAD_SIZE) {
#if SENSOR_DEBUG
debugSend(("[SENSOR] %s: Payload size != %d \n"), PMS_TYPE_NAME, PMS_PAYLOAD_SIZE);
#endif
break;
}
uint16_t checksum = read16();
#if SENSOR_DEBUG
debugSend(("[SENSOR] %s: Sum=%04X, Checksum=%04X\n"), PMS_TYPE_NAME, sum, checksum);
#endif
if (sum == checksum)
{
return true;
for (int i = 0; i < PMS_DATA_COUNT; i++) {
data[i] = read16(sum);
#if SENSOR_DEBUG
//debugSend(("[SENSOR] %s: data[%d] = %d\n"), PMS_TYPE_NAME, i, data[i]);
#endif
}
uint16_t checksum = read16();
#if SENSOR_DEBUG
debugSend(("[SENSOR] %s: Sum=%04X, Checksum=%04X\n"), PMS_TYPE_NAME, sum, checksum);
#endif
if (sum == checksum) {
return true;
}
break;
} }
break;
}
} while (true);
return false;
}
private:
// Read 16-bit
inline uint16_t read16() {
return ((uint16_t) _serial->read()) << 8 | _serial->read();
}
// Read 16-bit and calculate checksum
uint16_t read16(uint16_t &checksum) {
uint8_t high = _serial->read();
uint8_t low = _serial->read();
checksum += high;
checksum += low;
return ((uint16_t) high) << 8 | low;
} }
while (true);
return false;
}
private:
// Read 16-bit
inline uint16_t read16() {
return ((uint16_t) _serial->read()) << 8 | _serial->read();
}
// Read 16-bit and calculate checksum
uint16_t read16(uint16_t &checksum) {
uint8_t high = _serial->read();
uint8_t low = _serial->read();
checksum += high;
checksum += low;
return ((uint16_t) high) << 8 | low;
}
}; };
class PMSX003Sensor : public BaseSensor, PMSX003 { class PMSX003Sensor : public BaseSensor, PMSX003 {
@ -313,6 +309,7 @@ class PMSX003Sensor : public BaseSensor, PMSX003 {
#endif #endif
requestRead(); requestRead();
} }
// Current value for slot # index // Current value for slot # index
@ -326,9 +323,10 @@ class PMSX003Sensor : public BaseSensor, PMSX003 {
unsigned long _startTime; unsigned long _startTime;
double _slot_values[PMS_SLOT_COUNT] = {0}; double _slot_values[PMS_SLOT_COUNT] = {0};
#if PMS_SMART_SLEEP
unsigned int _readCount = 0;
#endif
#if PMS_SMART_SLEEP
unsigned int _readCount = 0;
#endif
}; };
#endif // SENSOR_SUPPORT && PMSX003_SUPPORT
#endif // SENSOR_SUPPORT && PMS_SUPPORT

+ 727
- 726
code/espurna/static/index.html.gz.h
File diff suppressed because it is too large
View File


+ 2
- 2
code/html/custom.js View File

@ -39,7 +39,7 @@ function sensorName(id) {
"HLW8012", "V9261F", "ECH1560", "Analog", "Digital", "HLW8012", "V9261F", "ECH1560", "Analog", "Digital",
"Events", "PMSX003", "BMX280", "MHZ19", "SI7021", "Events", "PMSX003", "BMX280", "MHZ19", "SI7021",
"SHT3X I2C", "BH1750", "PZEM004T", "AM2320 I2C", "GUVAS12SD", "SHT3X I2C", "BH1750", "PZEM004T", "AM2320 I2C", "GUVAS12SD",
"TMP3X", "HC-SR04"
"TMP3X", "HC-SR04", "SenseAir"
]; ];
if (1 <= id && id <= names.length) { if (1 <= id && id <= names.length) {
return names[id - 1]; return names[id - 1];
@ -53,7 +53,7 @@ function magnitudeType(type) {
"Current", "Voltage", "Active Power", "Apparent Power", "Current", "Voltage", "Active Power", "Apparent Power",
"Reactive Power", "Power Factor", "Energy", "Energy (delta)", "Reactive Power", "Power Factor", "Energy", "Energy (delta)",
"Analog", "Digital", "Events", "Analog", "Digital", "Events",
"PM1.0", "PM2.5", "PM10", "CO2", "Lux", "UV", "Distance"
"PM1.0", "PM2.5", "PM10", "CO2", "Lux", "UV", "Distance" , "HCHO"
]; ];
if (1 <= type && type <= types.length) { if (1 <= type && type <= types.length) {
return types[type - 1]; return types[type - 1];


Loading…
Cancel
Save