diff --git a/README.md b/README.md index 3feb7fc5b..c2f88067f 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ## Sonoff-Tasmota Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE. -Current version is **5.10.0b** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. +Current version is **5.10.0c** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information. ### ATTENTION All versions diff --git a/lib/TasmotaSerial-1.0.0/README.md b/lib/TasmotaSerial-1.0.0/README.md new file mode 100644 index 000000000..5c7a24721 --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/README.md @@ -0,0 +1,8 @@ +# TasmotaSerial + +Implementation of software serial library for the ESP8266 at 9600 baud + +Allows for several instances to be active at the same time. + +Please note that due to the fact that the ESP always have other activities ongoing, there will be some inexactness in interrupt +timings. This may lead to bit errors when having heavy data traffic. diff --git a/lib/TasmotaSerial-1.0.0/examples/swsertest/swsertest.ino b/lib/TasmotaSerial-1.0.0/examples/swsertest/swsertest.ino new file mode 100644 index 000000000..9e9e30179 --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/examples/swsertest/swsertest.ino @@ -0,0 +1,27 @@ + +#include + +TasmotaSerial swSer(14, 12); + +void setup() { + Serial.begin(115200); + swSer.begin(); + + Serial.println("\nTasmota serial test started"); + + for (char ch = ' '; ch <= 'z'; ch++) { + swSer.write(ch); + } + swSer.println(""); + +} + +void loop() { + while (swSer.available() > 0) { + Serial.write(swSer.read()); + } + while (Serial.available() > 0) { + swSer.write(Serial.read()); + } + +} diff --git a/lib/TasmotaSerial-1.0.0/keywords.txt b/lib/TasmotaSerial-1.0.0/keywords.txt new file mode 100644 index 000000000..87974971e --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/keywords.txt @@ -0,0 +1,26 @@ +####################################### +# Syntax Coloring Map for TasmotaSerial +# (esp8266) +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +TasmotaSerial KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +read KEYWORD2 +write KEYWORD2 +available KEYWORD2 +flush KEYWORD2 +peek KEYWORD2 + +####################################### +# Constants (LITERAL1) +####################################### + diff --git a/lib/TasmotaSerial-1.0.0/library.json b/lib/TasmotaSerial-1.0.0/library.json new file mode 100644 index 000000000..986c6d7ac --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/library.json @@ -0,0 +1,15 @@ +{ + "name": "TasmotaSerial", + "version": "1.0.0", + "keywords": [ + "serial", "io", "TasmotaSerial" + ], + "description": "Implementation of software serial for ESP8266 at 9600 baud.", + "repository": + { + "type": "git", + "url": "https://github.com/arendst/Sonoff-Tasmota/lib/TasmotaSerial" + }, + "frameworks": "arduino", + "platforms": "espressif8266" +} diff --git a/lib/TasmotaSerial-1.0.0/library.properties b/lib/TasmotaSerial-1.0.0/library.properties new file mode 100644 index 000000000..703b613ee --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/library.properties @@ -0,0 +1,9 @@ +name=TasmotaSerial +version=1.0 +author=Theo Arends +maintainer=Theo Arends +sentence=Implementation of software serial for ESP8266 at 9600 baud. +paragraph= +category=Signal Input/Output +url= +architectures=esp8266 diff --git a/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.cpp b/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.cpp new file mode 100644 index 000000000..1b55818e0 --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.cpp @@ -0,0 +1,193 @@ +/* + TasmotaSerial.cpp - Minimal implementation of software serial for Tasmota + + Copyright (C) 2018 Theo Arends + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include + +// The Arduino standard GPIO routines are not enough, +// must use some from the Espressif SDK as well +extern "C" { +#include "gpio.h" +} + +#include + +// As the Arduino attachInterrupt has no parameter, lists of objects +// and callbacks corresponding to each possible GPIO pins have to be defined +TasmotaSerial *ObjList[16]; + +#ifdef TM_SERIAL_USE_IRAM +void ICACHE_RAM_ATTR sws_isr_0() { ObjList[0]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_1() { ObjList[1]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_2() { ObjList[2]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_3() { ObjList[3]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_4() { ObjList[4]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_5() { ObjList[5]->rxRead(); }; +// Pin 6 to 11 can not be used +void ICACHE_RAM_ATTR sws_isr_12() { ObjList[12]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_13() { ObjList[13]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_14() { ObjList[14]->rxRead(); }; +void ICACHE_RAM_ATTR sws_isr_15() { ObjList[15]->rxRead(); }; +#else +void sws_isr_0() { ObjList[0]->rxRead(); }; +void sws_isr_1() { ObjList[1]->rxRead(); }; +void sws_isr_2() { ObjList[2]->rxRead(); }; +void sws_isr_3() { ObjList[3]->rxRead(); }; +void sws_isr_4() { ObjList[4]->rxRead(); }; +void sws_isr_5() { ObjList[5]->rxRead(); }; +// Pin 6 to 11 can not be used +void sws_isr_12() { ObjList[12]->rxRead(); }; +void sws_isr_13() { ObjList[13]->rxRead(); }; +void sws_isr_14() { ObjList[14]->rxRead(); }; +void sws_isr_15() { ObjList[15]->rxRead(); }; +#endif // TM_SERIAL_USE_IRAM + +static void (*ISRList[16])() = { + sws_isr_0, + sws_isr_1, + sws_isr_2, + sws_isr_3, + sws_isr_4, + sws_isr_5, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + sws_isr_12, + sws_isr_13, + sws_isr_14, + sws_isr_15 +}; + +TasmotaSerial::TasmotaSerial(int receive_pin, int transmit_pin) +{ + m_valid = false; + if (!((isValidGPIOpin(receive_pin)) && (isValidGPIOpin(transmit_pin) || transmit_pin == 16))) { + return; + } + m_buffer = (uint8_t*)malloc(TM_SERIAL_BUFFER_SIZE); + if (m_buffer == NULL) { + return; + } + m_valid = true; + m_rx_pin = receive_pin; + m_tx_pin = transmit_pin; + m_in_pos = m_out_pos = 0; + // Use getCycleCount() loop to get as exact timing as possible + m_bit_time = ESP.getCpuFreqMHz() *1000000 /TM_SERIAL_BAUDRATE; + pinMode(m_rx_pin, INPUT); + ObjList[m_rx_pin] = this; + attachInterrupt(m_rx_pin, ISRList[m_rx_pin], FALLING); + pinMode(m_tx_pin, OUTPUT); + digitalWrite(m_tx_pin, HIGH); +} + +bool TasmotaSerial::isValidGPIOpin(int pin) +{ + return (pin >= 0 && pin <= 5) || (pin >= 12 && pin <= 15); +} + +bool TasmotaSerial::begin() { + return m_valid; +} + +int TasmotaSerial::read() +{ + if (m_in_pos == m_out_pos) { + return -1; + } + uint8_t ch = m_buffer[m_out_pos]; + m_out_pos = (m_out_pos +1) % TM_SERIAL_BUFFER_SIZE; + return ch; +} + +int TasmotaSerial::available() +{ + int avail = m_in_pos - m_out_pos; + if (avail < 0) { + avail += TM_SERIAL_BUFFER_SIZE; + } + return avail; +} + +//#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait) optimistic_yield(1); wait += m_bit_time; } // Watchdog timeouts +#define TM_SERIAL_WAIT { while (ESP.getCycleCount()-start < wait); wait += m_bit_time; } + +size_t TasmotaSerial::txWrite(uint8_t b) +{ + unsigned long wait = m_bit_time; + digitalWrite(m_tx_pin, HIGH); + unsigned long start = ESP.getCycleCount(); + // Start bit; + digitalWrite(m_tx_pin, LOW); + TM_SERIAL_WAIT; + for (int i = 0; i < 8; i++) { + digitalWrite(m_tx_pin, (b & 1) ? HIGH : LOW); + TM_SERIAL_WAIT; + b >>= 1; + } + // Stop bit + digitalWrite(m_tx_pin, HIGH); + TM_SERIAL_WAIT; + return 1; +} + +size_t TasmotaSerial::write(const uint8_t *buffer, size_t size) +{ + size_t n = 0; + // Flush input buffer on every write + m_in_pos = m_out_pos = 0; + while(size--) { + n += txWrite(*buffer++); + } + return n; +} + +#ifdef TM_SERIAL_USE_IRAM +void ICACHE_RAM_ATTR TasmotaSerial::rxRead() +{ +#else +void TasmotaSerial::rxRead() +{ +#endif + // Advance the starting point for the samples but compensate for the + // initial delay which occurs before the interrupt is delivered + unsigned long wait = m_bit_time + m_bit_time/3 - 500; + unsigned long start = ESP.getCycleCount(); + uint8_t rec = 0; + for (int i = 0; i < 8; i++) { + TM_SERIAL_WAIT; + rec >>= 1; + if (digitalRead(m_rx_pin)) { + rec |= 0x80; + } + } + // Stop bit + TM_SERIAL_WAIT; + // Store the received value in the buffer unless we have an overflow + int next = (m_in_pos+1) % TM_SERIAL_BUFFER_SIZE; + if (next != m_out_pos) { + m_buffer[m_in_pos] = rec; + m_in_pos = next; + } + // Must clear this bit in the interrupt register, + // it gets set even when interrupts are disabled + GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << m_rx_pin); +} diff --git a/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.h b/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.h new file mode 100644 index 000000000..beada7792 --- /dev/null +++ b/lib/TasmotaSerial-1.0.0/src/TasmotaSerial.h @@ -0,0 +1,56 @@ +/* + TasmotaSerial.h - Minimal implementation of software serial for Tasmota + + Copyright (C) 2018 Theo Arends + + This library is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef TasmotaSerial_h +#define TasmotaSerial_h +/*********************************************************************************************\ + * TasmotaSerial supports 9600 baud with fixed buffer size of 20 bytes using optional no iram + * + * Based on EspSoftwareSerial v3.3.1 by Peter Lerup (https://github.com/plerup/espsoftwareserial) +\*********************************************************************************************/ + +#define TM_SERIAL_BAUDRATE 9600 +#define TM_SERIAL_BUFFER_SIZE 20 +//#define TM_SERIAL_USE_IRAM // Enable to use iram (+368 bytes) + +class TasmotaSerial { + public: + TasmotaSerial(int receive_pin, int transmit_pin); + bool begin(); + size_t write(const uint8_t *buffer, size_t size = 1); + int read(); + int available(); + + void rxRead(); + + private: + bool isValidGPIOpin(int pin); + size_t txWrite(uint8_t byte); + + // Member variables + bool m_valid; + int m_rx_pin; + int m_tx_pin; + unsigned long m_bit_time; + unsigned int m_in_pos; + unsigned int m_out_pos; + uint8_t *m_buffer; +}; + +#endif // TasmotaSerial_h diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino index bfabfeed0..bab94bd58 100644 --- a/sonoff/_releasenotes.ino +++ b/sonoff/_releasenotes.ino @@ -1,10 +1,16 @@ -/* 5.10.0b +/* 5.10.0c + * Consolidate device serial (MH-Z19, SenseAir and Pzem004T) into TasmotaSerial library + * Consolidate PWM device recognition + * Fix Wemo Emulation (#1357) + * Add support for Arilux LC06 (#1414) + * + * 5.10.0b * Add support for PZEM004T energy sensor to be enabled with define USE_PZEM004T in user_config.h * Change Sonoff Pow Energy MQTT data message and consolidate Status 8 into Status 10 * Change Wemo SetBinaryState to distinguish from GetBinaryState (#1357) * Change output of HTTP command to valid JSON and Array only (#1363) * Add support for MH-Z19(B) CO2 sensor to be enabled with define USE_MHZ19 in user_config.h (#561, #1248) - * Add support for senseair S8 CO2 sensor to be enabled with define USE_SENSEAIR in user_config.h + * Add support for SenseAir S8 CO2 sensor to be enabled with define USE_SENSEAIR in user_config.h * Add support for Domoticz Air Quality sensor to be used by MH-Z19(B) and SenseAir sensors * * 5.10.0a diff --git a/sonoff/settings.ino b/sonoff/settings.ino index 53eb67eff..c6ed275db 100644 --- a/sonoff/settings.ino +++ b/sonoff/settings.ino @@ -182,7 +182,7 @@ void SettingsSaveAll() } else { Settings.power = 0; } - XsnsCall(FUNC_XSNS_SAVE_BEFORE_RESTART); + XsnsCall(FUNC_SAVE_BEFORE_RESTART); SettingsSave(0); } diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index f18c5820c..558e4d6ab 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -133,7 +133,7 @@ enum LightTypes {LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT_PWM5, LT_PWM6, enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC}; enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX}; -enum XsnsFunctions {FUNC_XSNS_INIT, FUNC_XSNS_EVERY_SECOND, FUNC_XSNS_PREP_BEFORE_TELEPERIOD, FUNC_XSNS_JSON_APPEND, FUNC_XSNS_WEB_APPEND, FUNC_XSNS_SAVE_BEFORE_RESTART}; +enum XsnsFunctions {FUNC_INIT, FUNC_EVERY_50_MSECOND, FUNC_EVERY_SECOND, FUNC_PREP_BEFORE_TELEPERIOD, FUNC_JSON_APPEND, FUNC_WEB_APPEND, FUNC_SAVE_BEFORE_RESTART}; const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 }; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 005dff5fa..a08318e2a 100644 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -25,8 +25,8 @@ - Select IDE Tools - Flash Size: "1M (no SPIFFS)" ====================================================*/ -#define VERSION 0x050A0002 -#define VERSION_STRING "5.10.0b" // Would be great to have a macro that fills this from VERSION ... +#define VERSION 0x050A0003 +#define VERSION_STRING "5.10.0c" // Would be great to have a macro that fills this from VERSION ... // Location specific includes #include "sonoff.h" // Enumaration used in user_config.h @@ -1812,7 +1812,7 @@ boolean MqttShowSensor() snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, GetStateText(swm ^ lastwallswitch[i])); } } - XsnsCall(FUNC_XSNS_JSON_APPEND); + XsnsCall(FUNC_JSON_APPEND); boolean json_data_available = (strlen(mqtt_data) - json_data_start); if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit()); @@ -1871,7 +1871,7 @@ void PerformEverySecond() if (Settings.tele_period) { tele_period++; if (tele_period == Settings.tele_period -1) { - XsnsCall(FUNC_XSNS_PREP_BEFORE_TELEPERIOD); + XsnsCall(FUNC_PREP_BEFORE_TELEPERIOD); } if (tele_period >= Settings.tele_period) { tele_period = 0; @@ -1887,7 +1887,7 @@ void PerformEverySecond() } } - XsnsCall(FUNC_XSNS_EVERY_SECOND); + XsnsCall(FUNC_EVERY_SECOND); if ((2 == RtcTime.minute) && latest_uptime_flag) { latest_uptime_flag = false; @@ -2220,6 +2220,8 @@ void StateLoop() LightAnimate(); } + XsnsCall(FUNC_EVERY_50_MSECOND); + /*-------------------------------------------------------------------------------------------*\ * Every 0.2 second \*-------------------------------------------------------------------------------------------*/ @@ -2521,17 +2523,20 @@ void GpioInit() #endif // USE_I2C devices_present = 1; + + light_type = LT_BASIC; // Use basic PWM control if SetOption15 = 0 if (Settings.flag.pwm_control) { - light_type = LT_BASIC; for (byte i = 0; i < MAX_PWMS; i++) { if (pin[GPIO_PWM1 +i] < 99) { light_type++; // Use Dimmer/Color control for all PWM as SetOption15 = 1 } } } + if (SONOFF_BRIDGE == Settings.module) { baudrate = 19200; } + if (SONOFF_DUAL == Settings.module) { devices_present = 2; baudrate = 19200; @@ -2544,11 +2549,6 @@ void GpioInit() devices_present = 0; baudrate = 19200; } - else if ((H801 == Settings.module) || (MAGICHOME == Settings.module) || (ARILUX_LC01 == Settings.module) || (ARILUX_LC11 == Settings.module)) { // PWM RGBCW led - if (!Settings.flag.pwm_control) { - light_type = LT_BASIC; // Use basic PWM control if SetOption15 = 0 - } - } else if (SONOFF_BN == Settings.module) { // PWM Single color led (White) light_type = LT_PWM1; } @@ -2572,6 +2572,7 @@ void GpioInit() } } } + for (byte i = 0; i < MAX_KEYS; i++) { if (pin[GPIO_KEY1 +i] < 99) { pinMode(pin[GPIO_KEY1 +i], (16 == pin[GPIO_KEY1 +i]) ? INPUT_PULLDOWN_16 : INPUT_PULLUP); @@ -2599,7 +2600,7 @@ void GpioInit() if (light_type) { // Any Led light under Dimmer/Color control LightInit(); } else { - for (byte i = 0; i < MAX_PWMS; i++) { + for (byte i = 0; i < MAX_PWMS; i++) { // Basic PWM control only if (pin[GPIO_PWM1 +i] < 99) { pinMode(pin[GPIO_PWM1 +i], OUTPUT); analogWrite(pin[GPIO_PWM1 +i], bitRead(pwm_inverted, i) ? Settings.pwm_range - Settings.pwm_value[i] : Settings.pwm_value[i]); @@ -2623,8 +2624,6 @@ void GpioInit() } #endif // USE_IR_RECEIVE #endif // USE_IR_REMOTE - -// energy_flg = (((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99)) || ((pin[GPIO_PZEM_RX] < 99) && (pin[GPIO_PZEM_TX]))); } extern "C" { diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h index 14893593e..268288d88 100644 --- a/sonoff/sonoff_template.h +++ b/sonoff/sonoff_template.h @@ -209,6 +209,7 @@ enum SupportedModules { ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, + ARILUX_LC06, MAXMODULE }; /********************************************************************************************/ @@ -260,6 +261,7 @@ const uint8_t kNiceList[MAXMODULE] PROGMEM = { H801, MAGICHOME, ARILUX_LC01, + ARILUX_LC06, ARILUX_LC11, HUAFAN_SS, KMC_70011, @@ -747,7 +749,7 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_REL1, // GPIO14 Relay 0, 0, 0 }, - { "Arilux", // Arilux AL-LC01 (ESP8285) - https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html + { "Arilux LC01", // Arilux AL-LC01 (ESP8285) - https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html // (PwmFrequency 1111Hz) GPIO_KEY1, // GPIO00 Optional Button 0, @@ -790,7 +792,38 @@ const mytmplt kModules[MAXMODULE] PROGMEM = { GPIO_REL1, // GPIO12 Relay 1 (0 = Off, 1 = On) GPIO_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) 0, 0, 0, 0 + }, + { "Arilux LC06", // Arilux AL-LC06 (ESP8285) - https://www.banggood.com/ARILUX-AL-LC06-LED-WIFI-Smartphone-Controller-Romote-5-Channels-DC12-24V-For-RGBWW-Strip-light-p-1061476.html + GPIO_KEY1, // GPIO00 Optional Button + 0, + GPIO_USER, // GPIO02 Empty pad + 0, + GPIO_USER, // GPIO04 W2 - PWM5 + 0, + 0, 0, 0, 0, 0, 0, // Flash connection + GPIO_PWM2, // GPIO12 RGB LED Green + GPIO_PWM3, // GPIO13 RGB LED Blue + GPIO_PWM1, // GPIO14 RGB LED Red + GPIO_USER, // GPIO15 RGBW LED White + 0, 0 } }; +/* + Optionals + + { "Xenon 3CH", // Xenon 3CH (ESP8266) - (#1128) + 0, 0, 0, + GPIO_KEY2, // GPIO03 Serial TXD and Optional sensor + GPIO_REL2, // GPIO04 Relay 2 + GPIO_KEY3, // GPIO05 Input 2 + 0, 0, 0, 0, 0, 0, // Flash connection + GPIO_KEY1, // GPIO12 Key input + GPIO_REL1, // GPIO13 Relay 1 + 0, + GPIO_REL3, // GPIO15 Relay 3 + 0, 0 + } +*/ + #endif // _SONOFF_TEMPLATE_H_ \ No newline at end of file diff --git a/sonoff/support.ino b/sonoff/support.ino index 35ff9966b..bee00b2ca 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -1337,15 +1337,15 @@ boolean Xsns02(byte function) if (pin[GPIO_ADC0] < 99) { switch (function) { -// case FUNC_XSNS_INIT: +// case FUNC_INIT: // break; -// case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: +// case FUNC_PREP_BEFORE_TELEPERIOD: // break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: AdcShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: AdcShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/user_config.h b/sonoff/user_config.h index 6bd035ec3..dbeb0cca9 100644 --- a/sonoff/user_config.h +++ b/sonoff/user_config.h @@ -163,7 +163,7 @@ // -- Sensor code selection ----------------------- #define USE_ADC_VCC // Display Vcc in Power status. Disable for use as Analog input on selected devices -//#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k3 code) +//#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) // WARNING: Select none for default one DS18B20 sensor or enable one of the following two options for multiple sensors //#define USE_DS18x20 // Optional for more than one DS18x20 sensors with id sort, single scan and read retry (+1k3 code) @@ -192,8 +192,8 @@ #define USE_WS2812_CTYPE 1 // WS2812 Color type (0 - RGB, 1 - GRB, 2 - RGBW, 3 - GRBW) // #define USE_WS2812_DMA // DMA supports only GPIO03 (= Serial RXD) (+1k mem). When USE_WS2812_DMA is enabled expect Exceptions on Pow -//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+1k8 code) -//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+1k8 code) +//#define USE_MHZ19 // Add support for MH-Z19 CO2 sensor (+2k code) +//#define USE_SENSEAIR // Add support for SenseAir K30, K70 and S8 CO2 sensor (+2k3 code) #define USE_ARILUX_RF // Add support for Arilux RF remote controller (+0k8 code) diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino index a71d332f6..21242702f 100644 --- a/sonoff/webserver.ino +++ b/sonoff/webserver.ino @@ -511,7 +511,7 @@ void HandleAjaxStatusRefresh() String page = ""; mqtt_data[0] = '\0'; - XsnsCall(FUNC_XSNS_WEB_APPEND); + XsnsCall(FUNC_WEB_APPEND); if (strlen(mqtt_data)) { page += FPSTR(HTTP_TABLE100); page += mqtt_data; diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index 14d86b05a..082360235 100755 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -268,6 +268,17 @@ const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" "\r\n" "\r\n"; + +const char WEMO_RESPONSE_STATE_SOAP[] PROGMEM = + "" + "" + "" + "{x1" + "" + "" + "\r\n" + "\r\n"; + const char WEMO_SETUP_XML[] PROGMEM = "" "" @@ -299,17 +310,21 @@ void HandleUpnpEvent() { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); String request = WebServer->arg(0); + String state_xml = FPSTR(WEMO_RESPONSE_STATE_SOAP); + //differentiate get and set state if (request.indexOf(F("SetBinaryState")) > 0) { if (request.indexOf(F("State>1 0) { - // ExecuteCommandPower(1, 1); ExecuteCommandPower(devices_present, 1); } - if (request.indexOf(F("State>0 0) { - // ExecuteCommandPower(1, 0); + else if (request.indexOf(F("State>0 0) { ExecuteCommandPower(devices_present, 0); } } - WebServer->send(200, FPSTR(HDR_CTYPE_PLAIN), ""); + else if(request.indexOf(F("GetBinaryState")) > 0){ + state_xml.replace("Set", "Get"); + } + state_xml.replace("{x1", String(bitRead(power, devices_present -1))); + WebServer->send(200, FPSTR(HDR_CTYPE_XML), state_xml); } void HandleUpnpService() diff --git a/sonoff/xsns_01_counter.ino b/sonoff/xsns_01_counter.ino index 743822af6..316445dfb 100644 --- a/sonoff/xsns_01_counter.ino +++ b/sonoff/xsns_01_counter.ino @@ -130,20 +130,18 @@ boolean Xsns01(byte function) boolean result = false; switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: CounterInit(); break; -// case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: -// break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: CounterShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: CounterShow(0); break; #endif // USE_WEBSERVER - case FUNC_XSNS_SAVE_BEFORE_RESTART: + case FUNC_SAVE_BEFORE_RESTART: CounterSaveState(); break; } diff --git a/sonoff/xsns_03_energy.ino b/sonoff/xsns_03_energy.ino index cc02fef11..4d67fb2c4 100644 --- a/sonoff/xsns_03_energy.ino +++ b/sonoff/xsns_03_energy.ino @@ -41,7 +41,6 @@ const char kEnergyCommands[] PROGMEM = D_CMND_MAXPOWER "|" D_CMND_MAXPOWERHOLD "|" D_CMND_MAXPOWERWINDOW "|" D_CMND_SAFEPOWER "|" D_CMND_SAFEPOWERHOLD "|" D_CMND_SAFEPOWERWINDOW ; -bool energy_power_factor_ready = false; float energy_voltage = 0; // 123.1 V float energy_current = 0; // 123.123 A float energy_power = 0; // 123.1 W @@ -208,25 +207,6 @@ void HlwEvery200ms() hlw_cf1_summed_pulse_length = 0; hlw_cf1_pulse_counter = 0; } - -/* - energy_power = 0; - if (hlw_cf_pulse_length && (power &1) && !hlw_load_off) { - hlw_w = (HLW_PREF * Settings.hlw_power_calibration) / hlw_cf_pulse_length; - energy_power = (float)hlw_w / 10; - } - energy_voltage = 0; - if (hlw_cf1_voltage_pulse_length && (power &1)) { // If powered on always provide voltage - hlw_u = (HLW_UREF * Settings.hlw_voltage_calibration) / hlw_cf1_voltage_pulse_length; - energy_voltage = (float)hlw_u / 10; - } - energy_current = 0; - if (hlw_cf1_current_pulse_length && energy_power) { // No current if no power being consumed - hlw_i = (HLW_IREF * Settings.hlw_current_calibration) / hlw_cf1_current_pulse_length; - energy_current = (float)hlw_i / 1000; - } -*/ - energy_power_factor_ready = true; } void HlwInit() @@ -269,119 +249,9 @@ void HlwInit() * Based on: PZEM004T library https://github.com/olehs/PZEM004T \*********************************************************************************************/ -#define PZEM_BAUD_RATE 9600 +#include -/*********************************************************************************************\ - * Subset SoftwareSerial -\*********************************************************************************************/ - -#define PZEM_SERIAL_BUFFER_SIZE 20 -#define PZEM_SERIAL_WAIT { while (ESP.getCycleCount() -start < wait) optimistic_yield(1); wait += pzem_serial_bit_time; } - -uint8_t pzem_serial_rx_pin; -uint8_t pzem_serial_tx_pin; -uint8_t pzem_serial_in_pos = 0; -uint8_t pzem_serial_out_pos = 0; -uint8_t pzem_serial_buffer[PZEM_SERIAL_BUFFER_SIZE]; -unsigned long pzem_serial_bit_time; -unsigned long pzem_serial_bit_time_start; - -bool PzemSerialValidGpioPin(uint8_t pin) { - return (pin >= 0 && pin <= 5) || (pin >= 9 && pin <= 10) || (pin >= 12 && pin <= 15); -} - -bool PzemSerial(uint8_t receive_pin, uint8_t transmit_pin) -{ - if (!((PzemSerialValidGpioPin(receive_pin)) && (PzemSerialValidGpioPin(transmit_pin) || transmit_pin == 16))) { - return false; - } - pzem_serial_rx_pin = receive_pin; - pinMode(pzem_serial_rx_pin, INPUT); - attachInterrupt(pzem_serial_rx_pin, PzemSerialRxRead, FALLING); - - pzem_serial_tx_pin = transmit_pin; - pinMode(pzem_serial_tx_pin, OUTPUT); - digitalWrite(pzem_serial_tx_pin, 1); - - pzem_serial_bit_time = ESP.getCpuFreqMHz() *1000000 /PZEM_BAUD_RATE; // 8333 - pzem_serial_bit_time_start = pzem_serial_bit_time + pzem_serial_bit_time /3 -500; // 10610 ICACHE_RAM_ATTR start delay -// pzem_serial_bit_time_start = pzem_serial_bit_time; // Non ICACHE_RAM_ATTR start delay (experimental) - - return true; -} - -int PzemSerialRead() { - if (pzem_serial_in_pos == pzem_serial_out_pos) { - return -1; - } - int ch = pzem_serial_buffer[pzem_serial_out_pos]; - pzem_serial_out_pos = (pzem_serial_out_pos +1) % PZEM_SERIAL_BUFFER_SIZE; - return ch; -} - -int PzemSerialAvailable() { - int avail = pzem_serial_in_pos - pzem_serial_out_pos; - if (avail < 0) { - avail += PZEM_SERIAL_BUFFER_SIZE; - } - return avail; -} - -size_t PzemSerialTxWrite(uint8_t b) -{ - unsigned long wait = pzem_serial_bit_time; - digitalWrite(pzem_serial_tx_pin, HIGH); - unsigned long start = ESP.getCycleCount(); - // Start bit; - digitalWrite(pzem_serial_tx_pin, LOW); - PZEM_SERIAL_WAIT; - for (int i = 0; i < 8; i++) { - digitalWrite(pzem_serial_tx_pin, (b & 1) ? HIGH : LOW); - PZEM_SERIAL_WAIT; - b >>= 1; - } - // Stop bit - digitalWrite(pzem_serial_tx_pin, HIGH); - PZEM_SERIAL_WAIT; - return 1; -} - -size_t PzemSerialWrite(const uint8_t *buffer, size_t size = 1) { - size_t n = 0; - while(size--) { - n += PzemSerialTxWrite(*buffer++); - } - return n; -} - -//void PzemSerialRxRead() ICACHE_RAM_ATTR; // Add 215 bytes to iram usage -void PzemSerialRxRead() { - // Advance the starting point for the samples but compensate for the - // initial delay which occurs before the interrupt is delivered - unsigned long wait = pzem_serial_bit_time_start; - unsigned long start = ESP.getCycleCount(); - uint8_t rec = 0; - for (int i = 0; i < 8; i++) { - PZEM_SERIAL_WAIT; - rec >>= 1; - if (digitalRead(pzem_serial_rx_pin)) { - rec |= 0x80; - } - } - // Stop bit - PZEM_SERIAL_WAIT; - // Store the received value in the buffer unless we have an overflow - int next = (pzem_serial_in_pos +1) % PZEM_SERIAL_BUFFER_SIZE; - if (next != pzem_serial_out_pos) { - pzem_serial_buffer[pzem_serial_in_pos] = rec; - pzem_serial_in_pos = next; - } - // Must clear this bit in the interrupt register, - // it gets set even when interrupts are disabled - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << pzem_serial_rx_pin); -} - -/*********************************************************************************************/ +TasmotaSerial *PzemSerial; #define PZEM_VOLTAGE (uint8_t)0xB0 #define RESP_VOLTAGE (uint8_t)0xA0 @@ -402,7 +272,6 @@ void PzemSerialRxRead() { #define RESP_POWER_ALARM (uint8_t)0xA5 #define PZEM_DEFAULT_READ_TIMEOUT 500 -#define PZEM_ERROR_VALUE -1.0 struct PZEMCommand { uint8_t command; @@ -413,52 +282,16 @@ struct PZEMCommand { IPAddress pzem_ip(192, 168, 1, 1); -float PZEM004T_voltage_rcv() +uint8_t PzemCrc(uint8_t *data) { - uint8_t data[sizeof(PZEMCommand) -2]; - - if (!PZEM004T_recieve(RESP_VOLTAGE, data)) { - return PZEM_ERROR_VALUE; + uint16_t crc = 0; + for (uint8_t i = 0; i < sizeof(PZEMCommand) -1; i++) { + crc += *data++; } - return (data[0] << 8) + data[1] + (data[2] / 10.0); // 65535.x V + return (uint8_t)(crc & 0xFF); } -float PZEM004T_current_rcv() -{ - uint8_t data[sizeof(PZEMCommand) -2]; - - if (!PZEM004T_recieve(RESP_CURRENT, data)) { - return PZEM_ERROR_VALUE; - } - return (data[0] << 8) + data[1] + (data[2] / 100.0); // 65535.xx A -} - -float PZEM004T_power_rcv() -{ - uint8_t data[sizeof(PZEMCommand) -2]; - - if (!PZEM004T_recieve(RESP_POWER, data)) { - return PZEM_ERROR_VALUE; - } - return (data[0] << 8) + data[1]; // 65535 W -} - -float PZEM004T_energy_rcv() -{ - uint8_t data[sizeof(PZEMCommand) -2]; - - if (!PZEM004T_recieve(RESP_ENERGY, data)) { - return PZEM_ERROR_VALUE; - } - return ((uint32_t)data[0] << 16) + ((uint16_t)data[1] << 8) + data[2]; // 16777215 Wh -} - -bool PZEM004T_setAddress_rcv() -{ - return PZEM004T_recieve(RESP_SET_ADDRESS, 0); -} - -void PZEM004T_send(uint8_t cmd) +void PzemSend(uint8_t cmd) { PZEMCommand pzem; @@ -469,41 +302,37 @@ void PZEM004T_send(uint8_t cmd) pzem.data = 0; uint8_t *bytes = (uint8_t*)&pzem; - pzem.crc = PZEM004T_crc(bytes, sizeof(pzem) - 1); + pzem.crc = PzemCrc(bytes); - while (PzemSerialAvailable()) { - PzemSerialRead(); - } - PzemSerialWrite(bytes, sizeof(pzem)); + PzemSerial->write(bytes, sizeof(pzem)); } -bool PZEM004T_isReady() +bool PzemReceiveReady() { - return PzemSerialAvailable() >= sizeof(PZEMCommand); + return PzemSerial->available() >= sizeof(PZEMCommand); } -bool PZEM004T_recieve(uint8_t resp, uint8_t *data) +bool PzemRecieve(uint8_t resp, float *data) { uint8_t buffer[sizeof(PZEMCommand)]; - unsigned long startTime = millis(); + unsigned long start = millis(); uint8_t len = 0; - while ((len < sizeof(PZEMCommand)) && (millis() - startTime < PZEM_DEFAULT_READ_TIMEOUT)) { - if (PzemSerialAvailable() > 0) { - uint8_t c = (uint8_t)PzemSerialRead(); + while ((len < sizeof(PZEMCommand)) && (millis() - start < PZEM_DEFAULT_READ_TIMEOUT)) { + if (PzemSerial->available() > 0) { + uint8_t c = (uint8_t)PzemSerial->read(); if (!c && !len) { continue; // skip 0 at startup } buffer[len++] = c; } -// yield(); // do background netw tasks while blocked for IO (prevents ESP watchdog trigger) - This triggers Watchdog!!! } if (len != sizeof(PZEMCommand)) { // AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Pzem comms timeout")); return false; } - if (buffer[6] != PZEM004T_crc(buffer, len - 1)) { + if (buffer[6] != PzemCrc(buffer)) { // AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Pzem crc error")); return false; } @@ -511,77 +340,51 @@ bool PZEM004T_recieve(uint8_t resp, uint8_t *data) // AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "Pzem bad response")); return false; } - if (data) { - for (int i = 0; i < sizeof(PZEMCommand) -2; i++) { - data[i] = buffer[1 + i]; - } - } + switch (resp) { + case RESP_VOLTAGE: + *data = (float)(buffer[1] << 8) + buffer[2] + (buffer[3] / 10.0); // 65535.x V + break; + case RESP_CURRENT: + *data = (float)(buffer[1] << 8) + buffer[2] + (buffer[3] / 100.0); // 65535.xx A + break; + case RESP_POWER: + *data = (float)(buffer[1] << 8) + buffer[2]; // 65535 W + break; + case RESP_ENERGY: + *data = (float)((uint32_t)buffer[1] << 16) + ((uint16_t)buffer[2] << 8) + buffer[3]; // 16777215 Wh + break; + } return true; } -uint8_t PZEM004T_crc(uint8_t *data, uint8_t sz) -{ - uint16_t crc = 0; - for (uint8_t i = 0; i < sz; i++) { - crc += *data++; - } - return (uint8_t)(crc & 0xFF); -} - /*********************************************************************************************/ -typedef enum -{ - SET_ADDRESS, - READ_VOLTAGE, - READ_CURRENT, - READ_POWER, - READ_ENERGY, -} PZEMReadStates; +const uint8_t pzem_commands[] { PZEM_SET_ADDRESS, PZEM_VOLTAGE, PZEM_CURRENT, PZEM_POWER, PZEM_ENERGY }; +const uint8_t pzem_responses[] { RESP_SET_ADDRESS, RESP_VOLTAGE, RESP_CURRENT, RESP_POWER, RESP_ENERGY }; -PZEMReadStates pzem_read_state = SET_ADDRESS; - -byte pzem_sendRetry = 0; +uint8_t pzem_read_state = 0; +uint8_t pzem_sendRetry = 0; void PzemEvery200ms() { - bool dataReady = PZEM004T_isReady(); + bool data_ready = PzemReceiveReady(); - if (dataReady) { - float pzem_value; - switch (pzem_read_state) { - case SET_ADDRESS: - if (PZEM004T_setAddress_rcv()) { - pzem_read_state = READ_VOLTAGE; - } - break; - case READ_VOLTAGE: - pzem_value = PZEM004T_voltage_rcv(); - if (pzem_value != PZEM_ERROR_VALUE) { - energy_voltage = pzem_value; // 230.2V - pzem_read_state = READ_CURRENT; - } - break; - case READ_CURRENT: - pzem_value = PZEM004T_current_rcv(); - if (pzem_value != PZEM_ERROR_VALUE) { - energy_current = pzem_value; // 17.32A - pzem_read_state = READ_POWER; - } - break; - case READ_POWER: - pzem_value = PZEM004T_power_rcv(); - if (pzem_value != PZEM_ERROR_VALUE) { - energy_power = pzem_value; // 20W - energy_power_factor_ready = true; - pzem_read_state = READ_ENERGY; - } - break; - case READ_ENERGY: - pzem_value = PZEM004T_energy_rcv(); - if (pzem_value != PZEM_ERROR_VALUE) { - energy_total = pzem_value / 1000; // 99999Wh + if (data_ready) { + float value = 0; + if (PzemRecieve(pzem_responses[pzem_read_state], &value)) { + switch (pzem_read_state) { + case 1: + energy_voltage = value; // 230.2V + break; + case 2: + energy_current = value; // 17.32A + break; + case 3: + energy_power = value; // 20W + break; + case 4: + energy_total = value / 1000; // 99999Wh if (!energy_startup) { if (energy_total < energy_start) { energy_start = energy_total; @@ -590,32 +393,18 @@ void PzemEvery200ms() energy_kWhtoday = (energy_total - energy_start) * 100000000; energy_daily = (float)energy_kWhtoday / 100000000; } - pzem_read_state = READ_VOLTAGE; - } - break; + break; + } + pzem_read_state++; + if (5 == pzem_read_state) { + pzem_read_state = 1; + } } } - if (0 == pzem_sendRetry || dataReady) { + if (0 == pzem_sendRetry || data_ready) { pzem_sendRetry = 5; - - switch (pzem_read_state) { - case SET_ADDRESS: - PZEM004T_send(PZEM_SET_ADDRESS); - break; - case READ_VOLTAGE: - PZEM004T_send(PZEM_VOLTAGE); - break; - case READ_CURRENT: - PZEM004T_send(PZEM_CURRENT); - break; - case READ_POWER: - PZEM004T_send(PZEM_POWER); - break; - case READ_ENERGY: - PZEM004T_send(PZEM_ENERGY); - break; - } + PzemSend(pzem_commands[pzem_read_state]); } else { pzem_sendRetry--; @@ -624,7 +413,8 @@ void PzemEvery200ms() bool PzemInit() { - return PzemSerial(pin[GPIO_PZEM_RX], pin[GPIO_PZEM_TX]); + PzemSerial = new TasmotaSerial(pin[GPIO_PZEM_RX], pin[GPIO_PZEM_TX]); + return PzemSerial->begin(); } /********************************************************************************************/ @@ -676,14 +466,14 @@ void Energy200ms() #endif // USE_PZEM004T } - if (energy_power_factor_ready && energy_voltage && energy_current && energy_power) { - energy_power_factor_ready = false; - float power_factor = energy_power / (energy_voltage * energy_current); + float power_factor = 0; + if (energy_voltage && energy_current && energy_power) { + power_factor = energy_power / (energy_voltage * energy_current); if (power_factor > 1) { power_factor = 1; } - energy_power_factor = power_factor; } + energy_power_factor = power_factor; } void EnergySaveState() @@ -1143,23 +933,21 @@ boolean Xsns03(byte function) if (energy_flg) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: EnergyInit(); break; - case FUNC_XSNS_EVERY_SECOND: + case FUNC_EVERY_SECOND: EnergyMarginCheck(); break; -// case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: -// break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: EnergyShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: EnergyShow(0); break; #endif // USE_WEBSERVER - case FUNC_XSNS_SAVE_BEFORE_RESTART: + case FUNC_SAVE_BEFORE_RESTART: EnergySaveState(); break; } diff --git a/sonoff/xsns_04_snfsc.ino b/sonoff/xsns_04_snfsc.ino index 04a552ac5..f6e44eae5 100644 --- a/sonoff/xsns_04_snfsc.ino +++ b/sonoff/xsns_04_snfsc.ino @@ -148,16 +148,14 @@ boolean Xsns04(byte function) if (SONOFF_SC == Settings.module) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: SonoffScInit(); break; -// case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: -// break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: SonoffScShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: SonoffScShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_05_ds18b20.ino b/sonoff/xsns_05_ds18b20.ino index 19281349e..4a4220831 100644 --- a/sonoff/xsns_05_ds18b20.ino +++ b/sonoff/xsns_05_ds18b20.ino @@ -219,17 +219,17 @@ boolean Xsns05(byte function) if (pin[GPIO_DSB] < 99) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Ds18x20Init(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ds18x20Convert(); // Start conversion, takes up to one second break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ds18b20Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ds18b20Show(0); Ds18x20Convert(); // Start conversion, takes up to one second break; diff --git a/sonoff/xsns_05_ds18x20.ino b/sonoff/xsns_05_ds18x20.ino index c0bd66673..c8ed8be59 100644 --- a/sonoff/xsns_05_ds18x20.ino +++ b/sonoff/xsns_05_ds18x20.ino @@ -401,17 +401,17 @@ boolean Xsns05(byte function) if (pin[GPIO_DSB] < 99) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Ds18x20Init(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ds18x20Convert(); // Start conversion, takes up to one second break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ds18x20Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ds18x20Show(0); Ds18x20Convert(); // Start conversion, takes up to one second break; diff --git a/sonoff/xsns_05_ds18x20_legacy.ino b/sonoff/xsns_05_ds18x20_legacy.ino index 0a389300c..881337656 100644 --- a/sonoff/xsns_05_ds18x20_legacy.ino +++ b/sonoff/xsns_05_ds18x20_legacy.ino @@ -219,18 +219,18 @@ boolean Xsns05(byte function) if (pin[GPIO_DSB] < 99) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Ds18x20Init(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ds18x20Search(); // Check for changes in sensors number Ds18x20Convert(); // Start Conversion, takes up to one second break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ds18x20Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ds18x20Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_06_dht.ino b/sonoff/xsns_06_dht.ino index 3598c40f2..620b57cd5 100644 --- a/sonoff/xsns_06_dht.ino +++ b/sonoff/xsns_06_dht.ino @@ -253,17 +253,17 @@ boolean Xsns06(byte function) if (dht_flg) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: DhtInit(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: DhtReadPrep(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: DhtShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: DhtShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_07_sht1x.ino b/sonoff/xsns_07_sht1x.ino index dad419f5e..6ff557aff 100644 --- a/sonoff/xsns_07_sht1x.ino +++ b/sonoff/xsns_07_sht1x.ino @@ -223,16 +223,14 @@ boolean Xsns07(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: ShtDetect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: ShtShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: ShtShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_08_htu21.ino b/sonoff/xsns_08_htu21.ino index 4950be405..d19453e4d 100644 --- a/sonoff/xsns_08_htu21.ino +++ b/sonoff/xsns_08_htu21.ino @@ -284,16 +284,14 @@ boolean Xsns08(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: HtuDetect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: HtuShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: HtuShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_09_bmp.ino b/sonoff/xsns_09_bmp.ino index f3130abde..0653d0c0d 100644 --- a/sonoff/xsns_09_bmp.ino +++ b/sonoff/xsns_09_bmp.ino @@ -502,19 +502,17 @@ boolean Xsns09(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: BmpDetect(); #ifdef USE_BME680 Bme680PerformReading(); #endif // USE_BME680 break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: BmpShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: BmpShow(0); #ifdef USE_BME680 Bme680PerformReading(); diff --git a/sonoff/xsns_10_bh1750.ino b/sonoff/xsns_10_bh1750.ino index 1a8873647..fc05673d0 100644 --- a/sonoff/xsns_10_bh1750.ino +++ b/sonoff/xsns_10_bh1750.ino @@ -99,16 +99,14 @@ boolean Xsns10(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Bh1750Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Bh1750Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Bh1750Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_11_veml6070.ino b/sonoff/xsns_11_veml6070.ino index aafd0da74..6b27de71e 100644 --- a/sonoff/xsns_11_veml6070.ino +++ b/sonoff/xsns_11_veml6070.ino @@ -104,16 +104,14 @@ boolean Xsns11(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Veml6070Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Veml6070Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Veml6070Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_12_ads1115.ino b/sonoff/xsns_12_ads1115.ino index 447ad98c9..4c2e7f976 100644 --- a/sonoff/xsns_12_ads1115.ino +++ b/sonoff/xsns_12_ads1115.ino @@ -218,16 +218,14 @@ boolean Xsns12(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ads1115Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ads1115Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ads1115Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_12_ads1115_i2cdev.ino b/sonoff/xsns_12_ads1115_i2cdev.ino index 0d599f0a5..d9735327a 100644 --- a/sonoff/xsns_12_ads1115_i2cdev.ino +++ b/sonoff/xsns_12_ads1115_i2cdev.ino @@ -138,16 +138,14 @@ boolean Xsns12(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ads1115Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ads1115Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ads1115Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_13_ina219.ino b/sonoff/xsns_13_ina219.ino index 4848b383b..211021d9e 100644 --- a/sonoff/xsns_13_ina219.ino +++ b/sonoff/xsns_13_ina219.ino @@ -219,16 +219,14 @@ boolean Xsns13(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Ina219Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Ina219Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Ina219Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_14_sht3x.ino b/sonoff/xsns_14_sht3x.ino index 35800adf2..39b24d8b4 100644 --- a/sonoff/xsns_14_sht3x.ino +++ b/sonoff/xsns_14_sht3x.ino @@ -125,17 +125,17 @@ boolean Xsns14(byte function) if (i2c_flg) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Sht3xDetect(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Sht3xConvert(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Sht3xShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Sht3xShow(0); Sht3xConvert(); break; diff --git a/sonoff/xsns_14_sht3x_v2.ino b/sonoff/xsns_14_sht3x_v2.ino index f794d971b..85de8512a 100644 --- a/sonoff/xsns_14_sht3x_v2.ino +++ b/sonoff/xsns_14_sht3x_v2.ino @@ -122,16 +122,14 @@ boolean Xsns14(byte function) if (i2c_flg) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Sht3xDetect(); break; -// case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: -// break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Sht3xShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Sht3xShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_14_sht3x_v3.ino b/sonoff/xsns_14_sht3x_v3.ino index e165fbf01..aff368c1a 100644 --- a/sonoff/xsns_14_sht3x_v3.ino +++ b/sonoff/xsns_14_sht3x_v3.ino @@ -132,17 +132,17 @@ boolean Xsns14(byte function) if (i2c_flg) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: Sht3xDetect(); break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Sht3xConvert(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Sht3xShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Sht3xShow(0); Sht3xConvert(); break; diff --git a/sonoff/xsns_15_mhz19.ino b/sonoff/xsns_15_mhz19.ino index 4b5b24ec3..7f5e56aa8 100644 --- a/sonoff/xsns_15_mhz19.ino +++ b/sonoff/xsns_15_mhz19.ino @@ -28,7 +28,7 @@ * Select filter usage on low stability readings \*********************************************************************************************/ -enum Mhz19FilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILTER_FAST, MHZ19_FILTER_MEDIUM, MHZ19_FILTER_SLOW}; +enum MhzFilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FILTER_FAST, MHZ19_FILTER_MEDIUM, MHZ19_FILTER_SLOW}; #define MHZ19_FILTER_OPTION MHZ19_FILTER_FAST @@ -52,159 +52,47 @@ enum Mhz19FilterOptions {MHZ19_FILTER_OFF, MHZ19_FILTER_OFF_ALLSAMPLES, MHZ19_FI /*********************************************************************************************/ -#define MHZ19_BAUDRATE 9600 +#include + +TasmotaSerial *MhzSerial; + #define MHZ19_READ_TIMEOUT 500 // Must be way less than 1000 #define MHZ19_RETRY_COUNT 8 -const char kMhz19Types[] PROGMEM = "MHZ19|MHZ19B"; +const char kMhzTypes[] PROGMEM = "MHZ19|MHZ19B"; -const uint8_t mhz19_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; -const uint8_t mhz19_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; -const uint8_t mhz19_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; +const uint8_t mhz_cmnd_read_ppm[9] = {0xFF, 0x01, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79}; +const uint8_t mhz_cmnd_abc_enable[9] = {0xFF, 0x01, 0x79, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xE6}; +const uint8_t mhz_cmnd_abc_disable[9] = {0xFF, 0x01, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86}; -uint8_t mhz19_type = 1; -uint16_t mhz19_last_ppm = 0; -uint8_t mhz19_filter = MHZ19_FILTER_OPTION; -bool mhz19_abc_enable = MHZ19_ABC_ENABLE; -bool mhz19_abc_must_apply = false; -char mhz19_types[7]; +uint8_t mhz_type = 1; +uint16_t mhz_last_ppm = 0; +uint8_t mhz_filter = MHZ19_FILTER_OPTION; +bool mhz_abc_enable = MHZ19_ABC_ENABLE; +bool mhz_abc_must_apply = false; +char mhz_types[7]; -float mhz19_temperature = 0; -uint8_t mhz19_timer = 0; -uint8_t mhz19_retry = MHZ19_RETRY_COUNT; -Ticker mhz19_ticker; +float mhz_temperature = 0; +uint8_t mhz_timer = 0; +uint8_t mhz_retry = MHZ19_RETRY_COUNT; -/*********************************************************************************************\ - * Subset SoftwareSerial -\*********************************************************************************************/ - -#define MHZ19_SERIAL_BUFFER_SIZE 20 -#define MHZ19_SERIAL_WAIT { while (ESP.getCycleCount() -start < wait) optimistic_yield(1); wait += mhz19_serial_bit_time; } - -uint8_t mhz19_serial_rx_pin; -uint8_t mhz19_serial_tx_pin; -uint8_t mhz19_serial_in_pos = 0; -uint8_t mhz19_serial_out_pos = 0; -uint8_t mhz19_serial_buffer[MHZ19_SERIAL_BUFFER_SIZE]; -unsigned long mhz19_serial_bit_time; -unsigned long mhz19_serial_bit_time_start; - -bool Mhz19SerialValidGpioPin(uint8_t pin) { - return (pin >= 0 && pin <= 5) || (pin >= 9 && pin <= 10) || (pin >= 12 && pin <= 15); -} - -bool Mhz19Serial(uint8_t receive_pin, uint8_t transmit_pin) -{ - if (!((Mhz19SerialValidGpioPin(receive_pin)) && (Mhz19SerialValidGpioPin(transmit_pin) || transmit_pin == 16))) { - return false; - } - mhz19_serial_rx_pin = receive_pin; - pinMode(mhz19_serial_rx_pin, INPUT); - attachInterrupt(mhz19_serial_rx_pin, Mhz19SerialRxRead, FALLING); - - mhz19_serial_tx_pin = transmit_pin; - pinMode(mhz19_serial_tx_pin, OUTPUT); - digitalWrite(mhz19_serial_tx_pin, 1); - - mhz19_serial_bit_time = ESP.getCpuFreqMHz() *1000000 /MHZ19_BAUDRATE; // 8333 - mhz19_serial_bit_time_start = mhz19_serial_bit_time + mhz19_serial_bit_time /3 -500; // 10610 ICACHE_RAM_ATTR start delay -// mhz19_serial_bit_time_start = mhz19_serial_bit_time; // Non ICACHE_RAM_ATTR start delay (experimental) - - return true; -} - -int Mhz19SerialRead() { - if (mhz19_serial_in_pos == mhz19_serial_out_pos) { - return -1; - } - int ch = mhz19_serial_buffer[mhz19_serial_out_pos]; - mhz19_serial_out_pos = (mhz19_serial_out_pos +1) % MHZ19_SERIAL_BUFFER_SIZE; - return ch; -} - -int Mhz19SerialAvailable() { - int avail = mhz19_serial_in_pos - mhz19_serial_out_pos; - if (avail < 0) { - avail += MHZ19_SERIAL_BUFFER_SIZE; - } - return avail; -} - -void Mhz19SerialFlush() -{ - mhz19_serial_in_pos = 0; - mhz19_serial_out_pos = 0; -} - -size_t Mhz19SerialTxWrite(uint8_t b) -{ - unsigned long wait = mhz19_serial_bit_time; - digitalWrite(mhz19_serial_tx_pin, HIGH); - unsigned long start = ESP.getCycleCount(); - // Start bit; - digitalWrite(mhz19_serial_tx_pin, LOW); - MHZ19_SERIAL_WAIT; - for (int i = 0; i < 8; i++) { - digitalWrite(mhz19_serial_tx_pin, (b & 1) ? HIGH : LOW); - MHZ19_SERIAL_WAIT; - b >>= 1; - } - // Stop bit - digitalWrite(mhz19_serial_tx_pin, HIGH); - MHZ19_SERIAL_WAIT; - return 1; -} - -size_t Mhz19SerialWrite(const uint8_t *buffer, size_t size = 1) { - size_t n = 0; - while(size--) { - n += Mhz19SerialTxWrite(*buffer++); - } - return n; -} - -//void Mhz19SerialRxRead() ICACHE_RAM_ATTR; // Add 215 bytes to iram usage -void Mhz19SerialRxRead() { - // Advance the starting point for the samples but compensate for the - // initial delay which occurs before the interrupt is delivered - unsigned long wait = mhz19_serial_bit_time_start; - unsigned long start = ESP.getCycleCount(); - uint8_t rec = 0; - for (int i = 0; i < 8; i++) { - MHZ19_SERIAL_WAIT; - rec >>= 1; - if (digitalRead(mhz19_serial_rx_pin)) { - rec |= 0x80; - } - } - // Stop bit - MHZ19_SERIAL_WAIT; - // Store the received value in the buffer unless we have an overflow - int next = (mhz19_serial_in_pos +1) % MHZ19_SERIAL_BUFFER_SIZE; - if (next != mhz19_serial_out_pos) { - mhz19_serial_buffer[mhz19_serial_in_pos] = rec; - mhz19_serial_in_pos = next; - } - // Must clear this bit in the interrupt register, - // it gets set even when interrupts are disabled - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << mhz19_serial_rx_pin); -} +uint8_t mhz_state = 0; /*********************************************************************************************/ -bool Mhz19CheckAndApplyFilter(uint16_t ppm, uint8_t s) +bool MhzCheckAndApplyFilter(uint16_t ppm, uint8_t s) { if (1 == s) { return false; // S==1 => "A" version sensor bootup, do not use values. } - if (mhz19_last_ppm < 400 || mhz19_last_ppm > 5000) { + if (mhz_last_ppm < 400 || mhz_last_ppm > 5000) { // Prevent unrealistic values during start-up with filtering enabled. // Just assume the entered value is correct. - mhz19_last_ppm = ppm; + mhz_last_ppm = ppm; return true; } - int32_t difference = ppm - mhz19_last_ppm; - if (s > 0 && s < 64 && mhz19_filter != MHZ19_FILTER_OFF) { + int32_t difference = ppm - mhz_last_ppm; + if (s > 0 && s < 64 && mhz_filter != MHZ19_FILTER_OFF) { // Not the "B" version of the sensor, S value is used. // S==0 => "B" version, else "A" version // The S value is an indication of the stability of the reading. @@ -216,127 +104,129 @@ bool Mhz19CheckAndApplyFilter(uint16_t ppm, uint8_t s) difference *= s; difference /= 64; } - if (MHZ19_FILTER_OFF == mhz19_filter) { + if (MHZ19_FILTER_OFF == mhz_filter) { if (s != 0 && s != 64) { return false; } } else { - difference >>= (mhz19_filter -1); + difference >>= (mhz_filter -1); } - mhz19_last_ppm = static_cast(mhz19_last_ppm + difference); + mhz_last_ppm = static_cast(mhz_last_ppm + difference); return true; } -void Mhz19Ticker() +void Mhz50ms() { - uint8_t mhz19_response[9]; + mhz_state++; + if (4 == mhz_state) { // Every 200 mSec + mhz_state = 0; - mhz19_timer++; - if (6 == mhz19_timer) { // MH-Z19 measuring cycle takes 1005 +5% ms - mhz19_timer = 0; + uint8_t mhz_response[9]; - Mhz19SerialFlush(); - Mhz19SerialWrite(mhz19_cmnd_read_ppm, 9); - } + mhz_timer++; + if (6 == mhz_timer) { // MH-Z19 measuring cycle takes 1005 +5% ms + mhz_timer = 0; - if (1 == mhz19_timer) { - if (mhz19_retry) { - mhz19_retry--; - if (!mhz19_retry) { - mhz19_last_ppm = 0; - mhz19_temperature = 0; + MhzSerial->write(mhz_cmnd_read_ppm, 9); + } + + if (1 == mhz_timer) { + if (mhz_retry) { + mhz_retry--; + if (!mhz_retry) { + mhz_last_ppm = 0; + mhz_temperature = 0; + } } - } - unsigned long start = millis(); - uint8_t counter = 0; - while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) { - if (Mhz19SerialAvailable() > 0) { - mhz19_response[counter++] = Mhz19SerialRead(); + unsigned long start = millis(); + uint8_t counter = 0; + while (((millis() - start) < MHZ19_READ_TIMEOUT) && (counter < 9)) { + if (MhzSerial->available() > 0) { + mhz_response[counter++] = MhzSerial->read(); + } } - } - if (counter < 9) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout")); - return; - } - - byte crc = 0; - for (uint8_t i = 1; i < 8; i++) { - crc += mhz19_response[i]; - } - crc = 255 - crc; - crc++; - if (mhz19_response[8] != crc) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error")); - return; - } - if (0xFF != mhz19_response[0] || 0x86 != mhz19_response[1]) { -// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response")); - return; - } - - uint16_t u = (mhz19_response[6] << 8) | mhz19_response[7]; - if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000 - if (!mhz19_abc_enable) { - // After bootup of the sensor the ABC will be enabled. - // Thus only actively disable after bootup. - mhz19_abc_must_apply = true; + if (counter < 9) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 comms timeout")); + return; } - } else { - uint16_t ppm = (mhz19_response[2] << 8) | mhz19_response[3]; - mhz19_temperature = ConvertTemp((float)mhz19_response[4] - 40); - uint8_t s = mhz19_response[5]; - mhz19_type = (s) ? 1 : 2; - if (Mhz19CheckAndApplyFilter(ppm, s)) { - mhz19_retry = MHZ19_RETRY_COUNT; - if (0 == s || 64 == s) { // Reading is stable. - if (mhz19_abc_must_apply) { - mhz19_abc_must_apply = false; - if (mhz19_abc_enable) { - Mhz19SerialWrite(mhz19_cmnd_abc_enable, 9); // Sent sensor ABC Enable - } else { - Mhz19SerialWrite(mhz19_cmnd_abc_disable, 9); // Sent sensor ABC Disable + byte crc = 0; + for (uint8_t i = 1; i < 8; i++) { + crc += mhz_response[i]; + } + crc = 255 - crc; + crc++; + if (mhz_response[8] != crc) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 crc error")); + return; + } + if (0xFF != mhz_response[0] || 0x86 != mhz_response[1]) { +// AddLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DEBUG "MH-Z19 bad response")); + return; + } + + uint16_t u = (mhz_response[6] << 8) | mhz_response[7]; + if (15000 == u) { // During (and only ever at) sensor boot, 'u' is reported as 15000 + if (!mhz_abc_enable) { + // After bootup of the sensor the ABC will be enabled. + // Thus only actively disable after bootup. + mhz_abc_must_apply = true; + } + } else { + uint16_t ppm = (mhz_response[2] << 8) | mhz_response[3]; + mhz_temperature = ConvertTemp((float)mhz_response[4] - 40); + uint8_t s = mhz_response[5]; + mhz_type = (s) ? 1 : 2; + if (MhzCheckAndApplyFilter(ppm, s)) { + mhz_retry = MHZ19_RETRY_COUNT; + + if (0 == s || 64 == s) { // Reading is stable. + if (mhz_abc_must_apply) { + mhz_abc_must_apply = false; + if (mhz_abc_enable) { + MhzSerial->write(mhz_cmnd_abc_enable, 9); // Sent sensor ABC Enable + } else { + MhzSerial->write(mhz_cmnd_abc_disable, 9); // Sent sensor ABC Disable + } } } - } + } } } + } } /*********************************************************************************************/ -void Mhz19Init() +void MhzInit() { - mhz19_type = 0; + mhz_type = 0; if ((pin[GPIO_MHZ_RXD] < 99) && (pin[GPIO_MHZ_TXD] < 99)) { - if (Mhz19Serial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD])) { - mhz19_type = 1; - mhz19_ticker.attach_ms(222, Mhz19Ticker); + MhzSerial = new TasmotaSerial(pin[GPIO_MHZ_RXD], pin[GPIO_MHZ_TXD]); + if (MhzSerial->begin()) { + mhz_type = 1; } } } -void Mhz19Show(boolean json) +void MhzShow(boolean json) { char temperature[10]; - dtostrfd(mhz19_temperature, Settings.flag2.temperature_resolution, temperature); - GetTextIndexed(mhz19_types, sizeof(mhz19_types), mhz19_type -1, kMhz19Types); -// uint8_t co2_limit = (mhz19_last_ppm > 1200) ? 3 : (mhz19_last_ppm > 800) ? 2 : 1; -// uint16_t co2_limit = mhz19_last_ppm / 400; // <800 = 1(Green), <1200 = 2(Orange), >1200 = 3(Red) + dtostrfd(mhz_temperature, Settings.flag2.temperature_resolution, temperature); + GetTextIndexed(mhz_types, sizeof(mhz_types), mhz_type -1, kMhzTypes); if (json) { -// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_CO2 "\":%d,\"" D_LIMIT "\":%d,\"" D_TEMPERATURE "\":%s}"), mqtt_data, mhz19_types, mhz19_last_ppm, co2_limit, temperature); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_CO2 "\":%d,\"" D_TEMPERATURE "\":%s}"), mqtt_data, mhz19_types, mhz19_last_ppm, temperature); + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_CO2 "\":%d,\"" D_TEMPERATURE "\":%s}"), mqtt_data, mhz_types, mhz_last_ppm, temperature); #ifdef USE_DOMOTICZ - DomoticzSensor(DZ_AIRQUALITY, mhz19_last_ppm); + DomoticzSensor(DZ_AIRQUALITY, mhz_last_ppm); #endif // USE_DOMOTICZ #ifdef USE_WEBSERVER } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_CO2, mqtt_data, mhz19_types, mhz19_last_ppm); - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, mhz19_types, temperature, TempUnit()); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_CO2, mqtt_data, mhz_types, mhz_last_ppm); + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, mhz_types, temperature, TempUnit()); #endif // USE_WEBSERVER } } @@ -351,17 +241,20 @@ boolean Xsns15(byte function) { boolean result = false; - if (mhz19_type) { + if (mhz_type) { switch (function) { - case FUNC_XSNS_INIT: - Mhz19Init(); + case FUNC_INIT: + MhzInit(); break; - case FUNC_XSNS_JSON_APPEND: - Mhz19Show(1); + case FUNC_EVERY_50_MSECOND: + Mhz50ms(); + break; + case FUNC_JSON_APPEND: + MhzShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: - Mhz19Show(0); + case FUNC_WEB_APPEND: + MhzShow(0); break; #endif // USE_WEBSERVER } diff --git a/sonoff/xsns_16_tsl2561.ino b/sonoff/xsns_16_tsl2561.ino index 12c0b15c2..cbddb7e8e 100644 --- a/sonoff/xsns_16_tsl2561.ino +++ b/sonoff/xsns_16_tsl2561.ino @@ -91,16 +91,14 @@ boolean Xsns16(byte function) if (i2c_flg) { switch (function) { -// case FUNC_XSNS_INIT: -// break; - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: + case FUNC_PREP_BEFORE_TELEPERIOD: Tsl2561Detect(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_JSON_APPEND: Tsl2561Show(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: Tsl2561Show(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_17_senseair.ino b/sonoff/xsns_17_senseair.ino index 56ab7595f..c3457af18 100644 --- a/sonoff/xsns_17_senseair.ino +++ b/sonoff/xsns_17_senseair.ino @@ -1,5 +1,5 @@ /* - xsns_17_senseair_s8.ino - SenseAir S8 CO2 sensor support for Sonoff-Tasmota + xsns_17_senseair.ino - SenseAir CO2 sensor support for Sonoff-Tasmota Copyright (C) 2018 Theo Arends @@ -19,16 +19,14 @@ #ifdef USE_SENSEAIR /*********************************************************************************************\ - * SenseAir S8 - CO2 sensor + * SenseAir K30, K70 and S8 - CO2 sensor * * Adapted from EspEasy plugin P052 by Mikael Trieb (mikael__AT__triebconsulting.se) - ********************************************************************************************** - * Filter usage - * - * Select filter usage on low stability readings \*********************************************************************************************/ -#define SENSEAIR_BAUDRATE 9600 +#include + +TasmotaSerial *SensairSerial; const char kSenseairTypes[] PROGMEM = "Kx0|S8"; @@ -39,123 +37,7 @@ uint16_t senseair_co2 = 0; float senseair_temperature = 0; float senseair_humidity = 0; -Ticker senseair_ticker; - -/*********************************************************************************************\ - * Subset SoftwareSerial -\*********************************************************************************************/ - -#define SENSEAIR_SERIAL_BUFFER_SIZE 20 -#define SENSEAIR_SERIAL_WAIT { while (ESP.getCycleCount() -start < wait) optimistic_yield(1); wait += senseair_serial_bit_time; } - -uint8_t senseair_serial_rx_pin; -uint8_t senseair_serial_tx_pin; -uint8_t senseair_serial_in_pos = 0; -uint8_t senseair_serial_out_pos = 0; -uint8_t senseair_serial_buffer[SENSEAIR_SERIAL_BUFFER_SIZE]; -unsigned long senseair_serial_bit_time; -unsigned long senseair_serial_bit_time_start; - -bool SenseairSerialValidGpioPin(uint8_t pin) { - return (pin >= 0 && pin <= 5) || (pin >= 9 && pin <= 10) || (pin >= 12 && pin <= 15); -} - -bool SenseairSerial(uint8_t receive_pin, uint8_t transmit_pin) -{ - if (!((SenseairSerialValidGpioPin(receive_pin)) && (SenseairSerialValidGpioPin(transmit_pin) || transmit_pin == 16))) { - return false; - } - senseair_serial_rx_pin = receive_pin; - pinMode(senseair_serial_rx_pin, INPUT); - attachInterrupt(senseair_serial_rx_pin, SenseairSerialRxRead, FALLING); - - senseair_serial_tx_pin = transmit_pin; - pinMode(senseair_serial_tx_pin, OUTPUT); - digitalWrite(senseair_serial_tx_pin, 1); - - senseair_serial_bit_time = ESP.getCpuFreqMHz() *1000000 /SENSEAIR_BAUDRATE; // 8333 - senseair_serial_bit_time_start = senseair_serial_bit_time + senseair_serial_bit_time /3 -500; // 10610 ICACHE_RAM_ATTR start delay -// senseair_serial_bit_time_start = senseair_serial_bit_time; // Non ICACHE_RAM_ATTR start delay (experimental) - - return true; -} - -int SenseairSerialRead() { - if (senseair_serial_in_pos == senseair_serial_out_pos) { - return -1; - } - int ch = senseair_serial_buffer[senseair_serial_out_pos]; - senseair_serial_out_pos = (senseair_serial_out_pos +1) % SENSEAIR_SERIAL_BUFFER_SIZE; - return ch; -} - -int SenseairSerialAvailable() { - int avail = senseair_serial_in_pos - senseair_serial_out_pos; - if (avail < 0) { - avail += SENSEAIR_SERIAL_BUFFER_SIZE; - } - return avail; -} - -void SenseairSerialFlush() -{ - senseair_serial_in_pos = 0; - senseair_serial_out_pos = 0; -} - -size_t SenseairSerialTxWrite(uint8_t b) -{ - unsigned long wait = senseair_serial_bit_time; - digitalWrite(senseair_serial_tx_pin, HIGH); - unsigned long start = ESP.getCycleCount(); - // Start bit; - digitalWrite(senseair_serial_tx_pin, LOW); - SENSEAIR_SERIAL_WAIT; - for (int i = 0; i < 8; i++) { - digitalWrite(senseair_serial_tx_pin, (b & 1) ? HIGH : LOW); - SENSEAIR_SERIAL_WAIT; - b >>= 1; - } - // Stop bit - digitalWrite(senseair_serial_tx_pin, HIGH); - SENSEAIR_SERIAL_WAIT; - return 1; -} - -size_t SenseairSerialWrite(const uint8_t *buffer, size_t size = 1) { - size_t n = 0; - while(size--) { - n += SenseairSerialTxWrite(*buffer++); - } - return n; -} - -//void SenseairSerialRxRead() ICACHE_RAM_ATTR; // Add 215 bytes to iram usage -void SenseairSerialRxRead() { - // Advance the starting point for the samples but compensate for the - // initial delay which occurs before the interrupt is delivered - unsigned long wait = senseair_serial_bit_time_start; - unsigned long start = ESP.getCycleCount(); - uint8_t rec = 0; - for (int i = 0; i < 8; i++) { - SENSEAIR_SERIAL_WAIT; - rec >>= 1; - if (digitalRead(senseair_serial_rx_pin)) { - rec |= 0x80; - } - } - // Stop bit - SENSEAIR_SERIAL_WAIT; - // Store the received value in the buffer unless we have an overflow - int next = (senseair_serial_in_pos +1) % SENSEAIR_SERIAL_BUFFER_SIZE; - if (next != senseair_serial_out_pos) { - senseair_serial_buffer[senseair_serial_in_pos] = rec; - senseair_serial_in_pos = next; - } - // Must clear this bit in the interrupt register, - // it gets set even when interrupts are disabled - GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << senseair_serial_rx_pin); -} +uint8_t senseair_state = 0; /*********************************************************************************************/ @@ -185,13 +67,12 @@ void ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register frame[7] = (uint8_t)((crc >> 8) & 0xFF); frame[6] = (uint8_t)(crc & 0xFF); - SenseairSerialFlush(); - SenseairSerialWrite(frame, sizeof(frame)); + SensairSerial->write(frame, sizeof(frame)); } bool ModbusReceiveReady() { - return (SenseairSerialAvailable() >= 5); // 5 - Error frame, 7 - Ok frame + return (SensairSerial->available() >= 5); // 5 - Error frame, 7 - Ok frame } uint8_t ModbusReceive(uint16_t *value) @@ -199,8 +80,8 @@ uint8_t ModbusReceive(uint16_t *value) uint8_t buffer[7]; uint8_t len = 0; - while (SenseairSerialAvailable() > 0) { - buffer[len++] = (uint8_t)SenseairSerialRead(); + while (SensairSerial->available() > 0) { + buffer[len++] = (uint8_t)SensairSerial->read(); if (3 == len) { if (buffer[1] & 0x80) { // fe 84 02 f2 f1 return buffer[2]; // 1 = Illegal Function, 2 = Illegal Data Address, 3 = Illegal Data Value @@ -221,68 +102,74 @@ const uint8_t start_addresses[] { 0x1A, 0x00, 0x03, 0x04, 0x05, 0x1C, 0x0A }; uint8_t senseair_read_state = 0; uint8_t senseair_send_retry = 0; -void SenseairTicker() +void Senseair50ms() // Every 50 mSec { - uint16_t value = 0; - bool data_ready = ModbusReceiveReady(); + senseair_state++; + if (6 == senseair_state) { // Every 300 mSec + senseair_state = 0; - if (data_ready) { - uint8_t error = ModbusReceive(&value); - if (error) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir response error %d"), error); - AddLog(LOG_LEVEL_DEBUG); - } else { - switch(senseair_read_state) { - case 0: // 0x1A (26) READ_TYPE_LOW - S8: fe 04 02 01 77 ec 92 - senseair_type = 2; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir type id low %04X"), value); - AddLog(LOG_LEVEL_DEBUG); - break; - case 1: // 0x00 (0) READ_ERRORLOG - fe 04 02 00 00 ad 24 - if (value) { - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir error %04X"), value); + uint16_t value = 0; + bool data_ready = ModbusReceiveReady(); + + if (data_ready) { + uint8_t error = ModbusReceive(&value); + if (error) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir response error %d"), error); + AddLog(LOG_LEVEL_DEBUG); + } else { + switch(senseair_read_state) { + case 0: // 0x1A (26) READ_TYPE_LOW - S8: fe 04 02 01 77 ec 92 + senseair_type = 2; + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir type id low %04X"), value); AddLog(LOG_LEVEL_DEBUG); + break; + case 1: // 0x00 (0) READ_ERRORLOG - fe 04 02 00 00 ad 24 + if (value) { + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir error %04X"), value); + AddLog(LOG_LEVEL_DEBUG); + } + break; + case 2: // 0x03 (3) READ_CO2 - fe 04 02 06 2c af 59 + senseair_co2 = value; + break; + case 3: // 0x04 (4) READ_TEMPERATURE - S8: fe 84 02 f2 f1 - Illegal Data Address + senseair_temperature = ConvertTemp((float)value / 100); + break; + case 4: // 0x05 (5) READ_HUMIDITY - S8: fe 84 02 f2 f1 - Illegal Data Address + senseair_humidity = (float)value / 100; + break; + case 5: // 0x1C (28) READ_RELAY_STATE - S8: fe 04 02 01 54 ad 4b - firmware version + { + bool relay_state = value >> 8 & 1; + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir relay state %d"), relay_state); + AddLog(LOG_LEVEL_DEBUG); + break; } - break; - case 2: // 0x03 (3) READ_CO2 - fe 04 02 06 2c af 59 - senseair_co2 = value; - break; - case 3: // 0x04 (4) READ_TEMPERATURE - S8: fe 84 02 f2 f1 - Illegal Data Address - senseair_temperature = ConvertTemp((float)value / 100); - break; - case 4: // 0x05 (5) READ_HUMIDITY - S8: fe 84 02 f2 f1 - Illegal Data Address - senseair_humidity = (float)value / 100; - break; - case 5: // 0x1C (28) READ_RELAY_STATE - S8: fe 04 02 01 54 ad 4b - firmware version - { - bool relay_state = value >> 8 & 1; - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir relay state %d"), relay_state); - AddLog(LOG_LEVEL_DEBUG); - break; + case 6: // 0x0A (10) READ_TEMP_ADJUSTMENT - S8: fe 84 02 f2 f1 - Illegal Data Address + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir temp adjustment %d"), value); + AddLog(LOG_LEVEL_DEBUG); + break; + } + } + senseair_read_state++; + if (2 == senseair_type) { // S8 + if (3 == senseair_read_state) { + senseair_read_state = 1; + } + } else { // K30, K70 + if (sizeof(start_addresses) == senseair_read_state) { + senseair_read_state = 1; } - case 6: // 0x0A (10) READ_TEMP_ADJUSTMENT - S8: fe 84 02 f2 f1 - Illegal Data Address - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SenseAir temp adjustment %d"), value); - AddLog(LOG_LEVEL_DEBUG); - break; } } - senseair_read_state++; - if (2 == senseair_type) { // S8 - if (3 == senseair_read_state) { - senseair_read_state = 1; - } - } else { // K30, K70 - if (sizeof(start_addresses) == senseair_read_state) { - senseair_read_state = 1; - } - } - } - if (0 == senseair_send_retry || data_ready) { - senseair_send_retry = 5; - ModbusSend(0x04, (uint16_t)start_addresses[senseair_read_state], 1); - } else { - senseair_send_retry--; + if (0 == senseair_send_retry || data_ready) { + senseair_send_retry = 5; + ModbusSend(0x04, (uint16_t)start_addresses[senseair_read_state], 1); + } else { + senseair_send_retry--; + } + } } @@ -292,9 +179,9 @@ void SenseairInit() { senseair_type = 0; if ((pin[GPIO_SAIR_RX] < 99) && (pin[GPIO_SAIR_TX] < 99)) { - if (SenseairSerial(pin[GPIO_SAIR_RX], pin[GPIO_SAIR_TX])) { + SensairSerial = new TasmotaSerial(pin[GPIO_SAIR_RX], pin[GPIO_SAIR_TX]); + if (SensairSerial->begin()) { senseair_type = 1; - senseair_ticker.attach_ms(510, SenseairTicker); } } } @@ -306,11 +193,8 @@ void SenseairShow(boolean json) dtostrfd(senseair_temperature, Settings.flag2.temperature_resolution, temperature); dtostrfd(senseair_humidity, Settings.flag2.temperature_resolution, humidity); GetTextIndexed(senseair_types, sizeof(senseair_types), senseair_type -1, kSenseairTypes); -// uint8_t co2_limit = (senseair_co2 > 1200) ? 3 : (senseair_co2 > 800) ? 2 : 1; -// uint16_t co2_limit = senseair_co2 / 400; // <800 = 1(Green), <1200 = 2(Orange), >1200 = 3(Red) if (json) { -// snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_CO2 "\":%d,\"" D_LIMIT "\":%d"), mqtt_data, senseair_types, senseair_co2, co2_limit); snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_CO2 "\":%d"), mqtt_data, senseair_types, senseair_co2); if (senseair_type != 2) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"" D_TEMPERATURE "\":%s,\"" D_HUMIDITY "\":%s"), mqtt_data, temperature, humidity); @@ -342,14 +226,17 @@ boolean Xsns17(byte function) if (senseair_type) { switch (function) { - case FUNC_XSNS_INIT: + case FUNC_INIT: SenseairInit(); break; - case FUNC_XSNS_JSON_APPEND: + case FUNC_EVERY_50_MSECOND: + Senseair50ms(); + break; + case FUNC_JSON_APPEND: SenseairShow(1); break; #ifdef USE_WEBSERVER - case FUNC_XSNS_WEB_APPEND: + case FUNC_WEB_APPEND: SenseairShow(0); break; #endif // USE_WEBSERVER diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index d07982037..2893e3f51 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -104,7 +104,10 @@ void XSnsInit() xsns_func_ptr[xsns_present++] = &Xsns20; #endif - XsnsCall(FUNC_XSNS_INIT); +// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "Sensors found %d"), xsns_present); +// AddLog(LOG_LEVEL_DEBUG); + + XsnsCall(FUNC_INIT); } /*********************************************************************************************\ @@ -115,18 +118,23 @@ boolean XsnsCall(byte Function) { boolean result = false; +/* switch (Function) { - case FUNC_XSNS_INIT: - case FUNC_XSNS_EVERY_SECOND: - case FUNC_XSNS_PREP_BEFORE_TELEPERIOD: - case FUNC_XSNS_JSON_APPEND: - case FUNC_XSNS_WEB_APPEND: - case FUNC_XSNS_SAVE_BEFORE_RESTART: + case FUNC_INIT: + case FUNC_EVERY_50_MSECOND: + case FUNC_EVERY_SECOND: + case FUNC_PREP_BEFORE_TELEPERIOD: + case FUNC_JSON_APPEND: + case FUNC_WEB_APPEND: + case FUNC_SAVE_BEFORE_RESTART: +*/ for (byte x = 0; x < xsns_present; x++) { xsns_func_ptr[x](Function); } +/* break; } +*/ return result; }