From 0c24651ed0cdee4a1433eddb2c65451312b9de14 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 12 Apr 2020 12:35:58 +0200 Subject: [PATCH] Add interval to PMS5003 sensor Add interval to PMS5003 sensor to extend lifetime (#8128) --- RELEASENOTES.md | 2 + tasmota/CHANGELOG.md | 3 +- tasmota/settings.h | 12 ++-- tasmota/tasmota_template.h | 10 +-- tasmota/xsns_18_pms5003.ino | 120 ++++++++++++++---------------------- 5 files changed, 62 insertions(+), 85 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 053b8bfd4..4686a392d 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -66,6 +66,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add Zigbee command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2`` - Add Zigbee command ``ZbUnbind`` - Add Zigbee command ``ZbBindState`` and ``manuf``attribute +- Add Zigbee command ``ZbConfig`` and configuration in Settings - Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021) - Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075) - Add command ``SetOption41 `` to force sending gratuitous ARP every seconds @@ -86,3 +87,4 @@ The following binary downloads have been compiled with ESP8266/Arduino library c - Add console command history (#7483, #8015) - Add quick wifi reconnect using saved AP parameters when ``SetOption56 0`` (#3189) - Add more accuracy to GPS NTP server (#8088) +- Add interval to PMS5003 sensor to extend lifetime (#8128) diff --git a/tasmota/CHANGELOG.md b/tasmota/CHANGELOG.md index 5f8c6339c..3af55f17e 100644 --- a/tasmota/CHANGELOG.md +++ b/tasmota/CHANGELOG.md @@ -10,6 +10,7 @@ - Fix Zigbee crash with Occupancy sensor (#8089) - Add support for longer template names - Add Zigbee command ``ZbBindState`` and ``manuf``attribute +- Add Zigbee command ``ZbConfig`` and configuration in Settings - Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021) - Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075) - Add command ``SetOption90 1`` to disable non-json MQTT messages (#8044) @@ -25,7 +26,7 @@ - Add support for an iAQ sensor (#8107) - Add support for Seven Segment display using HT16K33 (#8116) - Add support for AS3935 Lightning Sensor by device111 (#8130) -- Add Zigbee command ``ZbConfig`` and configuration in Settings +- Add interval to PMS5003 sensor to extend lifetime (#8128) ### 8.2.0.2 20200328 diff --git a/tasmota/settings.h b/tasmota/settings.h index a9b6d0bc6..0014cac60 100644 --- a/tasmota/settings.h +++ b/tasmota/settings.h @@ -213,9 +213,9 @@ typedef union { typedef union { uint8_t data; - struct { + struct { uint8_t nf_autotune : 1; // Autotune the NF Noise Level - uint8_t dist_autotune : 1; // Autotune Disturber on/off + uint8_t dist_autotune : 1; // Autotune Disturber on/off uint8_t nf_autotune_both : 1; // Autotune over both Areas: INDOORS/OUDOORS uint8_t mqtt_only_Light_Event : 1; // mqtt only if lightning Irq uint8_t spare4 : 1; @@ -227,9 +227,9 @@ typedef union { typedef union { uint16_t data; - struct { + struct { uint16_t nf_autotune_time : 4; // NF Noise Autotune Time - uint16_t dist_autotune_time : 4; // Disturber Autotune Time + uint16_t dist_autotune_time : 4; // Disturber Autotune Time uint16_t nf_autotune_min : 4; // Min Stages uint16_t spare3 : 4; }; @@ -505,9 +505,9 @@ struct PACKED SYSCFG { uint16_t zb_pan_id; // F30 uint8_t zb_channel; // F32 uint8_t zb_free_byte; // F33 - uint16_t pms_wake_interval; + uint16_t pms_wake_interval; // F34 - uint8_t free_f18[130]; // F34 + uint8_t free_f36[130]; // F36 uint16_t pulse_counter_debounce_low; // FB8 uint16_t pulse_counter_debounce_high; // FBA diff --git a/tasmota/tasmota_template.h b/tasmota/tasmota_template.h index ffb520013..6ab153508 100644 --- a/tasmota/tasmota_template.h +++ b/tasmota/tasmota_template.h @@ -93,7 +93,7 @@ enum UserSelectablePins { GPIO_SPI_CS, // SPI Chip Select GPIO_SPI_DC, // SPI Data Direction GPIO_BACKLIGHT, // Display backlight control - GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface + GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface GPIO_SBR_TX, // Serial Bridge Serial interface GPIO_SBR_RX, // Serial Bridge Serial interface @@ -579,12 +579,12 @@ const uint8_t kGpioNiceList[] PROGMEM = { GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface #endif #ifdef USE_HPMA - GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface - GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface + GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface + GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface #endif #ifdef USE_PMS5003 - GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface - GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface + GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface + GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface #endif #if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin diff --git a/tasmota/xsns_18_pms5003.ino b/tasmota/xsns_18_pms5003.ino index 2ad18ba35..022216a4a 100644 --- a/tasmota/xsns_18_pms5003.ino +++ b/tasmota/xsns_18_pms5003.ino @@ -33,7 +33,7 @@ #include #ifndef WARMUP_PERIOD -#define WARMUP_PERIOD 30 // Turn on PMSX003 XX-seconds before read in passive mode +#define WARMUP_PERIOD 30 // Turn on PMSX003 XX-seconds before read in passive mode #endif #ifndef MIN_INTERVAL_PERIOD @@ -42,14 +42,13 @@ TasmotaSerial *PmsSerial; -uint8_t pms_type = 1; -uint8_t pms_valid = 0; -uint16_t pms_time = 0; -uint8_t wake_mode = 1; -uint8_t pms_ready = 1; - -const char ACTIVE_MODE[] = "Active Mode"; -const char PASSIVE_MODE[] = "Passive Mode"; +struct PMS5003 { + uint16_t time = 0; + uint8_t type = 1; + uint8_t valid = 0; + uint8_t wake_mode = 1; + uint8_t ready = 1; +} Pms; enum PmsCommands { @@ -155,7 +154,7 @@ bool PmsReadData(void) #else memcpy((void *)&pms_data, (void *)buffer_u16, 30); #endif // PMS_MODEL_PMS3003 - pms_valid = 10; + Pms.valid = 10; return true; } @@ -164,21 +163,20 @@ bool PmsReadData(void) * Command Sensor18 * * Warmup time for sensor is 30 seconds, therfore setting interval time to less than 60 - * seconds doesn't really make sense. - * + * seconds doesn't really make sense. + * * 0 - 59 - Active Mode (continuous sensor readings) * 60 .. 65535 - Passive Mode (read sensor every x seconds) \*********************************************************************************************/ bool PmsCommandSensor(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 65536)) - { + if ((pin[GPIO_PMS5003_TX] < 99) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 65536)) { if (XdrvMailbox.payload < MIN_INTERVAL_PERIOD) { // Set Active Mode if interval is less than 60 seconds Settings.pms_wake_interval = 0; - wake_mode = 1; - pms_ready = 1; + Pms.wake_mode = 1; + Pms.ready = 1; PmsSendCmd(CMD_MODE_ACTIVE); PmsSendCmd(CMD_WAKEUP); } else { @@ -186,16 +184,10 @@ bool PmsCommandSensor(void) Settings.pms_wake_interval = XdrvMailbox.payload; PmsSendCmd(CMD_MODE_PASSIVE); PmsSendCmd(CMD_SLEEP); - wake_mode = 0; - pms_ready = 0; + Pms.wake_mode = 0; + Pms.ready = 0; } } - - if (pin[GPIO_PMS5003_TX] >= 99) - { - // setting interval not supported if TX pin not connected - Settings.pms_wake_interval = 0; - } Response_P(S_JSON_SENSOR_INDEX_NVALUE, XSNS_18, Settings.pms_wake_interval); @@ -206,46 +198,36 @@ bool PmsCommandSensor(void) void PmsSecond(void) // Every second { - if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) - { + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { // Passive Mode - pms_time++; - if ((Settings.pms_wake_interval - pms_time <= WARMUP_PERIOD) && !wake_mode) - { + Pms.time++; + if ((Settings.pms_wake_interval - Pms.time <= WARMUP_PERIOD) && !Pms.wake_mode) { // wakeup sensor WARMUP_PERIOD before read interval - wake_mode = 1; + Pms.wake_mode = 1; PmsSendCmd(CMD_WAKEUP); } - if (pms_time >= Settings.pms_wake_interval) - { + if (Pms.time >= Settings.pms_wake_interval) { // sensor is awake and warmed up, set up for reading PmsSendCmd(CMD_READ_DATA); - pms_ready = 1; - pms_time = 0; + Pms.ready = 1; + Pms.time = 0; } - } + } - if (pms_ready) - { - if (PmsReadData()) - { - pms_valid = 10; - if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) - { + if (Pms.ready) { + if (PmsReadData()) { + Pms.valid = 10; + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { PmsSendCmd(CMD_SLEEP); - wake_mode = 0; - pms_ready = 0; + Pms.wake_mode = 0; + Pms.ready = 0; } - } - else - { - if (pms_valid) - { - pms_valid--; - if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) - { + } else { + if (Pms.valid) { + Pms.valid--; + if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) { PmsSendCmd(CMD_READ_DATA); - pms_ready = 1; + Pms.ready = 1; } } } @@ -256,25 +238,18 @@ void PmsSecond(void) // Every second void PmsInit(void) { - pms_type = 0; - if ((pin[GPIO_PMS5003_RX] < 99) && (pin[GPIO_PMS5003_TX] < 99)) - { - PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003_RX], pin[GPIO_PMS5003_TX], 1); + Pms.type = 0; + if (pin[GPIO_PMS5003_RX] < 99) { + PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003_RX], (pin[GPIO_PMS5003_TX] < 99) ? pin[GPIO_PMS5003_TX] : -1, 1); if (PmsSerial->begin(9600)) { if (PmsSerial->hardwareSerial()) { ClaimSerial(); } - pms_type = 1; - } - } - else if ((pin[GPIO_PMS5003_RX] < 99)) - { - PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003_RX], -1, 1); - if (PmsSerial->begin(9600)) - { - if (PmsSerial->hardwareSerial()) - { - ClaimSerial(); + + if (99 == pin[GPIO_PMS5003_TX]) { // setting interval not supported if TX pin not connected + Settings.pms_wake_interval = 0; + Pms.ready = 1; } - pms_type = 1; + + Pms.type = 1; } } } @@ -307,7 +282,7 @@ const char HTTP_PMS5003_SNS[] PROGMEM = void PmsShow(bool json) { - if (pms_valid) { + if (Pms.valid) { if (json) { #ifdef PMS_MODEL_PMS3003 ResponseAppend_P(PSTR(",\"PMS3003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"), @@ -352,7 +327,7 @@ bool Xsns18(uint8_t function) { bool result = false; - if (pms_type) { + if (Pms.type) { switch (function) { case FUNC_INIT: PmsInit(); @@ -361,8 +336,7 @@ bool Xsns18(uint8_t function) PmsSecond(); break; case FUNC_COMMAND_SENSOR: - if (XSNS_18 == XdrvMailbox.index) - { + if (XSNS_18 == XdrvMailbox.index) { result = PmsCommandSensor(); } break;