Merge pull request #3749 from edelstahlratte/development

Utilize SDS0X1 'Working Period' command
This commit is contained in:
Theo Arends 2018-09-10 14:20:29 +02:00 committed by GitHub
commit d967e9f9bf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 58 deletions

View File

@ -335,6 +335,7 @@
#define CO2_HIGH 1200 // Above this CO2 value show red light (needs PWM or WS2812 RG(B) led and enable with SetOption18 1)
#define USE_PMS5003 // Add support for PMS5003 and PMS7003 particle concentration sensor (+1k3 code)
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define WORKING_PERIOD 5 // Working period of the SDS Sensor, Takes a reading every X Minutes
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
//#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud)

View File

@ -27,25 +27,59 @@
#include <TasmotaSerial.h>
#ifndef WORKING_PERIOD
#define WORKING_PERIOD 5
#endif
TasmotaSerial *NovaSdsSerial;
uint8_t novasds_type = 1;
uint8_t novasds_valid = 0;
uint8_t novasds_running = 1;
uint8_t novasds_read_tick = 30;
uint8_t novasds_wakup_tick = 179;
uint8_t novasds_ticker = 0;
uint8_t novasds_workperiod[19] = {0xAA, 0xB4, 0x08, 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x0C, 0xAB}; //5 minutes
uint8_t novasds_setquerymode[19] = {0xAA, 0xB4, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0xAB}; //query mode
uint8_t novasds_querydata[19] = {0xAA, 0xB4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x02, 0xAB}; //query DATA
struct sds011data {
uint16_t pm100;
uint16_t pm25;
} novasds_data;
void NovaSdsSetWorkPeriod()
{
bool NovaSdsReadData(bool publish)
while (NovaSdsSerial->available() > 0) {
NovaSdsSerial->read();
}
novasds_workperiod[4] = WORKING_PERIOD;
novasds_workperiod[17] = ((novasds_workperiod[2] + novasds_workperiod[3] + novasds_workperiod[4] + novasds_workperiod[15] + novasds_workperiod[16]) & 0xFF); //checksum
NovaSdsSerial->write(novasds_workperiod, sizeof(novasds_workperiod));
NovaSdsSerial->flush();
while (NovaSdsSerial->available() > 0) {
NovaSdsSerial->read();
}
NovaSdsSerial->write(novasds_setquerymode, sizeof(novasds_setquerymode));
NovaSdsSerial->flush();
while (NovaSdsSerial->available() > 0) {
NovaSdsSerial->read();
}
}
bool NovaSdsReadData()
{
if (! NovaSdsSerial->available()) return false;
NovaSdsSerial->write(novasds_querydata, sizeof(novasds_querydata));
NovaSdsSerial->flush();
while ((NovaSdsSerial->peek() != 0xAA) && NovaSdsSerial->available()) {
NovaSdsSerial->read();
}
@ -56,9 +90,7 @@ bool NovaSdsReadData(bool publish)
NovaSdsSerial->flush();
AddLogSerial(LOG_LEVEL_DEBUG_MORE, d, 8);
if (!publish){
return false;
}
if (d[7] == ((d[1] + d[2] + d[3] + d[4] + d[5] + d[6]) & 0xFF)) {
novasds_data.pm25 = (d[1] + 256 * d[2]);
novasds_data.pm100 = (d[3] + 256 * d[4]);
@ -66,6 +98,9 @@ bool NovaSdsReadData(bool publish)
AddLog_P(LOG_LEVEL_DEBUG, PSTR("SDS: " D_CHECKSUM_FAILURE));
return false;
}
novasds_valid = 10;
return true;
}
@ -73,35 +108,12 @@ bool NovaSdsReadData(bool publish)
void NovaSdsSecond() // Every second
{
if (novasds_ticker < novasds_read_tick) {
// wake up the sensor and wait read ticks to stabalize the sensor
if (!novasds_running) {
NovaSdsStart();
novasds_running = 1;
}
// drain the serial without publishing data
NovaSdsReadData(false);
novasds_ticker++;
} else if (novasds_ticker == novasds_read_tick) {
// try to take a single stable reading and sleep the sensor
if (NovaSdsReadData(true)) {
novasds_valid = 1;
NovaSdsStop();
novasds_running = 0;
novasds_ticker++;
} else {
novasds_valid = 0;
}
} else if (novasds_ticker >= novasds_wakup_tick) {
// reset the counter
novasds_ticker = 0;
if (NovaSdsReadData()) {
novasds_valid = 10;
} else {
// sensor is sleeping keep waiting
novasds_ticker++;
if (novasds_valid) {
novasds_valid--;
}
}
}
@ -112,34 +124,13 @@ void NovaSdsInit()
novasds_type = 0;
if (pin[GPIO_SDS0X1_RX] < 99 && pin[GPIO_SDS0X1_TX] < 99) {
NovaSdsSerial = new TasmotaSerial(pin[GPIO_SDS0X1_RX], pin[GPIO_SDS0X1_TX], 1);
if (NovaSdsSerial->begin(9600)) {
if (NovaSdsSerial->hardwareSerial()) {
ClaimSerial();
}
novasds_type = 1;
NovaSdsSetWorkPeriod();
}
}
}
void NovaSdsStart()
{
AddLog_P(LOG_LEVEL_DEBUG, "SDS: start");
const uint8_t novasds_start_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0xAB};
NovaSdsSerial->write(novasds_start_cmd, sizeof(novasds_start_cmd));
NovaSdsSerial->flush();
}
void NovaSdsStop()
{
AddLog_P(LOG_LEVEL_DEBUG, "SDS: stop");
const uint8_t novasds_stop_cmd[] = {0xAA, 0xB4, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x05, 0xAB};
NovaSdsSerial->write(novasds_stop_cmd, sizeof(novasds_stop_cmd));
NovaSdsSerial->flush();
// drain any old data
while (NovaSdsSerial->available()) {
NovaSdsSerial->read();
}
}