From 18997e841f62056db8e7e57167e632ce93592cf7 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 18 Nov 2018 15:02:52 +0100 Subject: [PATCH] 6.3.0.9 Add dynamic delay in loop 6.3.0.9 20181118 * Moved command SetSensorXX to debugging driver freeing user code space * Add dynamic delay to main loop providing time for wifi background tasks * Remove delays introduced in 6.3.0.1 (#4233) --- sonoff/_changelog.ino | 7 +- sonoff/i18n.h | 1 - sonoff/sonoff.h | 3 +- sonoff/sonoff.ino | 18 +- sonoff/sonoff_version.h | 2 +- .../{xdrv_95_debug.ino => xdrv_99_debug.ino} | 50 ++- sonoff/xdrv_interface.ino | 2 +- sonoff/xsns_interface.ino | 302 +---------------- sonoff/zzzz_debug.ino | 309 ++++++++++++++++++ 9 files changed, 380 insertions(+), 314 deletions(-) rename sonoff/{xdrv_95_debug.ino => xdrv_99_debug.ino} (91%) create mode 100644 sonoff/zzzz_debug.ino diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 3914c426b..6f1c097f2 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,4 +1,9 @@ -/* 6.3.0.8 20181115 +/* 6.3.0.9 20181118 + * Moved command SetSensorXX to debugging driver freeing user code space + * Add dynamic delay to main loop providing time for wifi background tasks + * Remove delays introduced in 6.3.0.1 (#4233) + * + * 6.3.0.8 20181115 * Stop enforcing flashmode dout but it is still mandatory * Moved bootcount update (being first) flash write to 10 seconds after restart * Add support for Armtronix dimmers. See wiki for info (#4321) diff --git a/sonoff/i18n.h b/sonoff/i18n.h index 36d93ccd7..f53433553 100644 --- a/sonoff/i18n.h +++ b/sonoff/i18n.h @@ -184,7 +184,6 @@ #define D_CMND_DRIVER "Driver" #define D_CMND_SAVEDATA "SaveData" #define D_CMND_SETOPTION "SetOption" -#define D_CMND_SETSENSOR "SetSensor" #define D_CMND_TEMPERATURE_RESOLUTION "TempRes" #define D_CMND_HUMIDITY_RESOLUTION "HumRes" #define D_CMND_PRESSURE_RESOLUTION "PressRes" diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 5a43e147f..3d6acfaab 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -189,7 +189,8 @@ typedef unsigned long power_t; // Power (Relay) type #define KNX_MAX_device_param 30 #define MAX_KNXTX_CMNDS 5 -#define DRIVER_BOOT_DELAY 1 // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting +#define DRIVER_BOOT_DELAY 1 // Number of milliseconds to retard driver cycles during boot-up time to reduce overall CPU load whilst Wifi is connecting +#define LOOP_SLEEP_DELAY 10 // Lowest number of milliseconds to go through the main loop using delay when needed /*********************************************************************************************\ * Enumeration diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index d8d6cba1d..ad50c3573 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -81,7 +81,7 @@ enum TasmotaCommands { CMND_MODULE, CMND_MODULES, CMND_GPIO, CMND_GPIOS, CMND_PWM, CMND_PWMFREQUENCY, CMND_PWMRANGE, CMND_COUNTER, CMND_COUNTERTYPE, CMND_COUNTERDEBOUNCE, CMND_BUTTONDEBOUNCE, CMND_SWITCHDEBOUNCE, CMND_SLEEP, CMND_UPGRADE, CMND_UPLOAD, CMND_OTAURL, CMND_SERIALLOG, CMND_SYSLOG, CMND_LOGHOST, CMND_LOGPORT, CMND_IPADDRESS, CMND_NTPSERVER, CMND_AP, CMND_SSID, CMND_PASSWORD, CMND_HOSTNAME, - CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_SETSENSOR, + CMND_WIFICONFIG, CMND_FRIENDLYNAME, CMND_SWITCHMODE, CMND_TELEPERIOD, CMND_RESTART, CMND_RESET, CMND_TIMEZONE, CMND_TIMESTD, CMND_TIMEDST, CMND_ALTITUDE, CMND_LEDPOWER, CMND_LEDSTATE, CMND_I2CSCAN, CMND_SERIALSEND, CMND_BAUDRATE, CMND_SERIALDELIMITER, CMND_DRIVER }; const char kTasmotaCommands[] PROGMEM = @@ -91,7 +91,7 @@ const char kTasmotaCommands[] PROGMEM = D_CMND_MODULE "|" D_CMND_MODULES "|" D_CMND_GPIO "|" D_CMND_GPIOS "|" D_CMND_PWM "|" D_CMND_PWMFREQUENCY "|" D_CMND_PWMRANGE "|" D_CMND_COUNTER "|" D_CMND_COUNTERTYPE "|" D_CMND_COUNTERDEBOUNCE "|" D_CMND_BUTTONDEBOUNCE "|" D_CMND_SWITCHDEBOUNCE "|" D_CMND_SLEEP "|" D_CMND_UPGRADE "|" D_CMND_UPLOAD "|" D_CMND_OTAURL "|" D_CMND_SERIALLOG "|" D_CMND_SYSLOG "|" D_CMND_LOGHOST "|" D_CMND_LOGPORT "|" D_CMND_IPADDRESS "|" D_CMND_NTPSERVER "|" D_CMND_AP "|" D_CMND_SSID "|" D_CMND_PASSWORD "|" D_CMND_HOSTNAME "|" - D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_SETSENSOR "|" + D_CMND_WIFICONFIG "|" D_CMND_FRIENDLYNAME "|" D_CMND_SWITCHMODE "|" D_CMND_TELEPERIOD "|" D_CMND_RESTART "|" D_CMND_RESET "|" D_CMND_TIMEZONE "|" D_CMND_TIMESTD "|" D_CMND_TIMEDST "|" D_CMND_ALTITUDE "|" D_CMND_LEDPOWER "|" D_CMND_LEDSTATE "|" D_CMND_I2CSCAN "|" D_CMND_SERIALSEND "|" D_CMND_BAUDRATE "|" D_CMND_SERIALDELIMITER "|" D_CMND_DRIVER; @@ -777,13 +777,6 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len) snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_INDEX_SVALUE, command, index, (2 == ptype) ? stemp1 : (1 == ptype) ? GetStateText(bitRead(Settings.flag3.data, pindex)) : GetStateText(bitRead(Settings.flag.data, pindex))); } } - else if ((CMND_SETSENSOR == command_code) && (index < MAX_XSNS_DRIVERS)) { - if ((payload >= 0) && XsnsPresent(index)) { - bitWrite(Settings.sensors[index / 32], index % 32, payload &1); - if (1 == payload) { restart_flag = 2; } // To safely re-enable a sensor currently most sensor need to follow complete restart init cycle - } - snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_XVALUE, command, XsnsGetSensors().c_str()); - } else if (CMND_TEMPERATURE_RESOLUTION == command_code) { if ((payload >= 0) && (payload <= 3)) { Settings.flag2.temperature_resolution = payload; @@ -2753,6 +2746,8 @@ void setup(void) void loop(void) { + uint32_t my_sleep = millis(); + XdrvCall(FUNC_LOOP); OsWatchLoop(); @@ -2791,6 +2786,9 @@ void loop(void) while (arduino_ota_triggered) ArduinoOTA.handle(); #endif // USE_ARDUINO_OTA -// yield(); // yield == delay(0), delay contains yield, auto yield in loop +// yield(); // yield == delay(0), delay contains yield, auto yield in loop delay(sleep); // https://github.com/esp8266/Arduino/issues/2021 + + uint32_t my_activity = millis() - my_sleep; + if (my_activity < LOOP_SLEEP_DELAY) { delay(LOOP_SLEEP_DELAY - my_activity); } // Provide time for background tasks like wifi } diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 9ddcef51c..5ccff62e0 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06030008 +#define VERSION 0x06030009 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xdrv_95_debug.ino b/sonoff/xdrv_99_debug.ino similarity index 91% rename from sonoff/xdrv_95_debug.ino rename to sonoff/xdrv_99_debug.ino index a1c9ac22d..30e51121f 100644 --- a/sonoff/xdrv_95_debug.ino +++ b/sonoff/xdrv_99_debug.ino @@ -1,5 +1,5 @@ /* - xdrv_95_debug.ino - debug support for Sonoff-Tasmota + xdrv_99_debug.ino - debug support for Sonoff-Tasmota Copyright (C) 2018 Theo Arends @@ -27,10 +27,12 @@ #ifdef USE_DEBUG_DRIVER /*********************************************************************************************\ - * Virtual debugging support + * Virtual debugging support - Part1 + * + * Needs file zzzz_debug.ino due to DEFINE processing \*********************************************************************************************/ -#define XDRV_95 95 +#define XDRV_99 99 #ifndef CPU_LOAD_CHECK #define CPU_LOAD_CHECK 1 // Seconds between each CPU_LOAD log @@ -50,9 +52,15 @@ #define D_CMND_FREEMEM "FreeMem" #define D_CMND_RTCDUMP "RtcDump" #define D_CMND_HELP "Help" +#define D_CMND_SETSENSOR "SetSensor" +#define D_CMND_FLASHMODE "FlashMode" -enum DebugCommands { CMND_CFGDUMP, CMND_CFGPEEK, CMND_CFGPOKE, CMND_CFGSHOW, CMND_CFGXOR, CMND_CPUCHECK, CMND_EXCEPTION, CMND_FREEMEM, CMND_RTCDUMP, CMND_HELP }; -const char kDebugCommands[] PROGMEM = D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|" D_CMND_CFGSHOW "|" D_CMND_CFGXOR "|" D_CMND_CPUCHECK "|" D_CMND_EXCEPTION "|" D_CMND_FREEMEM "|" D_CMND_RTCDUMP "|" D_CMND_HELP; +enum DebugCommands { + CMND_CFGDUMP, CMND_CFGPEEK, CMND_CFGPOKE, CMND_CFGSHOW, CMND_CFGXOR, + CMND_CPUCHECK, CMND_EXCEPTION, CMND_FREEMEM, CMND_RTCDUMP, CMND_SETSENSOR, CMND_FLASHMODE, CMND_HELP }; +const char kDebugCommands[] PROGMEM = + D_CMND_CFGDUMP "|" D_CMND_CFGPEEK "|" D_CMND_CFGPOKE "|" D_CMND_CFGSHOW "|" D_CMND_CFGXOR "|" + D_CMND_CPUCHECK "|" D_CMND_EXCEPTION "|" D_CMND_FREEMEM "|" D_CMND_RTCDUMP "|" D_CMND_SETSENSOR "|" D_CMND_FLASHMODE "|" D_CMND_HELP; uint32_t CPU_loops = 0; uint32_t CPU_last_millis = 0; @@ -406,6 +414,23 @@ void DebugCfgShow(uint8_t more) } } +void SetFlashMode(uint8_t mode) +{ + uint8_t *_buffer; + uint32_t address; + + address = 0; + _buffer = new uint8_t[FLASH_SECTOR_SIZE]; + + if (ESP.flashRead(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE)) { + if (_buffer[2] != mode) { // DOUT + _buffer[2] = mode; + if (ESP.flashEraseSector(address / FLASH_SECTOR_SIZE)) ESP.flashWrite(address, (uint32_t*)_buffer, FLASH_SECTOR_SIZE); + } + } + delete[] _buffer; +} + /*******************************************************************************************/ boolean DebugCommand(void) @@ -469,6 +494,19 @@ boolean DebugCommand(void) } snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, CPU_show_freemem); } + else if ((CMND_SETSENSOR == command_code) && (XdrvMailbox.index < MAX_XSNS_DRIVERS)) { + if ((XdrvMailbox.payload >= 0) && XsnsPresent(XdrvMailbox.index)) { + bitWrite(Settings.sensors[XdrvMailbox.index / 32], XdrvMailbox.index % 32, XdrvMailbox.payload &1); + if (1 == XdrvMailbox.payload) { restart_flag = 2; } // To safely re-enable a sensor currently most sensor need to follow complete restart init cycle + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_XVALUE, command, XsnsGetSensors().c_str()); + } + else if (CMND_FLASHMODE == command_code) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + SetFlashMode(XdrvMailbox.payload); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), S_JSON_COMMAND_NVALUE, command, ESP.getFlashChipMode()); + } else serviced = false; // Unknown command return serviced; @@ -478,7 +516,7 @@ boolean DebugCommand(void) * Interface \*********************************************************************************************/ -boolean Xdrv95(byte function) +boolean Xdrv99(byte function) { boolean result = false; diff --git a/sonoff/xdrv_interface.ino b/sonoff/xdrv_interface.ino index c9557ec56..12b9e2711 100644 --- a/sonoff/xdrv_interface.ino +++ b/sonoff/xdrv_interface.ino @@ -238,7 +238,7 @@ boolean XdrvCall(byte Function) boolean result = false; for (byte x = 0; x < xdrv_present; x++) { - AppDelay(); +// AppDelay(); result = xdrv_func_ptr[x](Function); if (result) break; } diff --git a/sonoff/xsns_interface.ino b/sonoff/xsns_interface.ino index 7b5002c88..a7ab6d7a7 100644 --- a/sonoff/xsns_interface.ino +++ b/sonoff/xsns_interface.ino @@ -265,310 +265,22 @@ boolean (* const xsns_func_ptr[])(byte) = { // Sensor Function Pointers for sim const uint8_t xsns_present = sizeof(xsns_func_ptr) / sizeof(xsns_func_ptr[0]); // Number of External Sensors found uint8_t xsns_index = 0; -#ifdef XFUNC_PTR_IN_ROM -const uint8_t kXsnsList[] PROGMEM = { -#else -const uint8_t kXsnsList[] = { -#endif - -#ifdef XSNS_01 - XSNS_01, -#endif - -#ifdef XSNS_02 - XSNS_02, -#endif - -#ifdef XSNS_03 - XSNS_03, -#endif - -#ifdef XSNS_04 - XSNS_04, -#endif - -#ifdef XSNS_05 - XSNS_05, -#endif - -#ifdef XSNS_06 - XSNS_06, -#endif - -#ifdef XSNS_07 - XSNS_07, -#endif - -#ifdef XSNS_08 - XSNS_08, -#endif - -#ifdef XSNS_09 - XSNS_09, -#endif - -#ifdef XSNS_10 - XSNS_10, -#endif - -#ifdef XSNS_11 - XSNS_11, -#endif - -#ifdef XSNS_12 - XSNS_12, -#endif - -#ifdef XSNS_13 - XSNS_13, -#endif - -#ifdef XSNS_14 - XSNS_14, -#endif - -#ifdef XSNS_15 - XSNS_15, -#endif - -#ifdef XSNS_16 - XSNS_16, -#endif - -#ifdef XSNS_17 - XSNS_17, -#endif - -#ifdef XSNS_18 - XSNS_18, -#endif - -#ifdef XSNS_19 - XSNS_19, -#endif - -#ifdef XSNS_20 - XSNS_20, -#endif - -#ifdef XSNS_21 - XSNS_21, -#endif - -#ifdef XSNS_22 - XSNS_22, -#endif - -#ifdef XSNS_23 - XSNS_23, -#endif - -#ifdef XSNS_24 - XSNS_24, -#endif - -#ifdef XSNS_25 - XSNS_25, -#endif - -#ifdef XSNS_26 - XSNS_26, -#endif - -#ifdef XSNS_27 - XSNS_27, -#endif - -#ifdef XSNS_28 - XSNS_28, -#endif - -#ifdef XSNS_29 - XSNS_29, -#endif - -#ifdef XSNS_30 - XSNS_30, -#endif - -#ifdef XSNS_31 - XSNS_31, -#endif - -#ifdef XSNS_32 - XSNS_32, -#endif - -#ifdef XSNS_33 - XSNS_33, -#endif - -#ifdef XSNS_34 - XSNS_34, -#endif - -#ifdef XSNS_35 - XSNS_35, -#endif - -#ifdef XSNS_36 - XSNS_36, -#endif - -#ifdef XSNS_37 - XSNS_37, -#endif - -#ifdef XSNS_38 - XSNS_38, -#endif - -#ifdef XSNS_39 - XSNS_39, -#endif - -#ifdef XSNS_40 - XSNS_40, -#endif - -#ifdef XSNS_41 - XSNS_41, -#endif - -#ifdef XSNS_42 - XSNS_42, -#endif - -#ifdef XSNS_43 - XSNS_43, -#endif - -#ifdef XSNS_44 - XSNS_44, -#endif - -#ifdef XSNS_45 - XSNS_45, -#endif - -#ifdef XSNS_46 - XSNS_46, -#endif - -#ifdef XSNS_47 - XSNS_47, -#endif - -#ifdef XSNS_48 - XSNS_48, -#endif - -#ifdef XSNS_49 - XSNS_49, -#endif - -#ifdef XSNS_50 - XSNS_50, -#endif - -// Optional user defined sensors in range 91 - 99 - -#ifdef XSNS_91 - XSNS_91, -#endif - -#ifdef XSNS_92 - XSNS_92, -#endif - -#ifdef XSNS_93 - XSNS_93, -#endif - -#ifdef XSNS_94 - XSNS_94, -#endif - -#ifdef XSNS_95 - XSNS_95, -#endif - -#ifdef XSNS_96 - XSNS_96, -#endif - -#ifdef XSNS_97 - XSNS_97, -#endif - -#ifdef XSNS_98 - XSNS_98, -#endif - -#ifdef XSNS_99 - XSNS_99 -#endif -}; - - /*********************************************************************************************\ * Function call to all xsns \*********************************************************************************************/ -boolean XsnsEnabled(byte sns_index) -{ - if (sns_index < sizeof(kXsnsList)) { -#ifdef XFUNC_PTR_IN_ROM - uint8_t index = pgm_read_byte(kXsnsList + sns_index); -#else - uint8_t index = kXsnsList[sns_index]; -#endif - return bitRead(Settings.sensors[index / 32], index % 32); - } - return 1; -} - -boolean XsnsPresent(byte sns_index) -{ - uint8_t index = 0; - for (byte i = 0; i < sizeof(kXsnsList); i++) { -#ifdef XFUNC_PTR_IN_ROM - index = pgm_read_byte(kXsnsList + i); -#else - index = kXsnsList[i]; -#endif - if (index == sns_index) { return true; } - } - return false; -} - -String XsnsGetSensors(void) -{ - char state[2] = { 0 }; - - String data = F("["); - for (byte i = 0; i < MAX_XSNS_DRIVERS; i++) { - if (i && (!(i % 16))) { data += F(","); } - if (!(i % 16)) { data += F("\""); } - state[0] = '-'; - if (XsnsPresent(i)) { state[0] = bitRead(Settings.sensors[i / 32], i % 32) ? '1' : '0'; } - data += String(state); - if (i && (!((i +1) % 16))) { data += F("\""); } - } - data += F("]"); - - return data; -} - boolean XsnsNextCall(byte Function) { + xsns_index++; if (xsns_index == xsns_present) { xsns_index = 0; } +#ifdef USE_DEBUG_DRIVER while (!XsnsEnabled(xsns_index) && !xsns_index) { // Perform at least first sensor (counter) xsns_index++; if (xsns_index == xsns_present) { xsns_index = 0; } } - AppDelay(); +#endif +// AppDelay(); return xsns_func_ptr[xsns_index](Function); } @@ -581,12 +293,14 @@ boolean XsnsCall(byte Function) #endif // PROFILE_XSNS_EVERY_SECOND for (byte x = 0; x < xsns_present; x++) { +#ifdef USE_DEBUG_DRIVER if (XsnsEnabled(x)) { +#endif #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND uint32_t profile_start_millis = millis(); #endif // PROFILE_XSNS_SENSOR_EVERY_SECOND - AppDelay(); +// AppDelay(); result = xsns_func_ptr[x](Function); #ifdef PROFILE_XSNS_SENSOR_EVERY_SECOND @@ -600,7 +314,9 @@ boolean XsnsCall(byte Function) #endif // PROFILE_XSNS_SENSOR_EVERY_SECOND if (result) break; +#ifdef USE_DEBUG_DRIVER } +#endif } #ifdef PROFILE_XSNS_EVERY_SECOND diff --git a/sonoff/zzzz_debug.ino b/sonoff/zzzz_debug.ino new file mode 100644 index 000000000..3d159b922 --- /dev/null +++ b/sonoff/zzzz_debug.ino @@ -0,0 +1,309 @@ +/* + zzzz_debug.ino - debug support for Sonoff-Tasmota + + Copyright (C) 2018 Theo Arends + + This program 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 . +*/ + +#ifdef USE_DEBUG_DRIVER +/*********************************************************************************************\ + * Virtual debugging support - Part 2 + * + * Needs to be the last alphabetical file due to DEFINE compile order +\*********************************************************************************************/ + +/*********************************************************************************************\ + * Xsns available list +\*********************************************************************************************/ + +#ifdef XFUNC_PTR_IN_ROM +const uint8_t kXsnsList[] PROGMEM = { +#else +const uint8_t kXsnsList[] = { +#endif + +#ifdef XSNS_01 + XSNS_01, +#endif + +#ifdef XSNS_02 + XSNS_02, +#endif + +#ifdef XSNS_03 + XSNS_03, +#endif + +#ifdef XSNS_04 + XSNS_04, +#endif + +#ifdef XSNS_05 + XSNS_05, +#endif + +#ifdef XSNS_06 + XSNS_06, +#endif + +#ifdef XSNS_07 + XSNS_07, +#endif + +#ifdef XSNS_08 + XSNS_08, +#endif + +#ifdef XSNS_09 + XSNS_09, +#endif + +#ifdef XSNS_10 + XSNS_10, +#endif + +#ifdef XSNS_11 + XSNS_11, +#endif + +#ifdef XSNS_12 + XSNS_12, +#endif + +#ifdef XSNS_13 + XSNS_13, +#endif + +#ifdef XSNS_14 + XSNS_14, +#endif + +#ifdef XSNS_15 + XSNS_15, +#endif + +#ifdef XSNS_16 + XSNS_16, +#endif + +#ifdef XSNS_17 + XSNS_17, +#endif + +#ifdef XSNS_18 + XSNS_18, +#endif + +#ifdef XSNS_19 + XSNS_19, +#endif + +#ifdef XSNS_20 + XSNS_20, +#endif + +#ifdef XSNS_21 + XSNS_21, +#endif + +#ifdef XSNS_22 + XSNS_22, +#endif + +#ifdef XSNS_23 + XSNS_23, +#endif + +#ifdef XSNS_24 + XSNS_24, +#endif + +#ifdef XSNS_25 + XSNS_25, +#endif + +#ifdef XSNS_26 + XSNS_26, +#endif + +#ifdef XSNS_27 + XSNS_27, +#endif + +#ifdef XSNS_28 + XSNS_28, +#endif + +#ifdef XSNS_29 + XSNS_29, +#endif + +#ifdef XSNS_30 + XSNS_30, +#endif + +#ifdef XSNS_31 + XSNS_31, +#endif + +#ifdef XSNS_32 + XSNS_32, +#endif + +#ifdef XSNS_33 + XSNS_33, +#endif + +#ifdef XSNS_34 + XSNS_34, +#endif + +#ifdef XSNS_35 + XSNS_35, +#endif + +#ifdef XSNS_36 + XSNS_36, +#endif + +#ifdef XSNS_37 + XSNS_37, +#endif + +#ifdef XSNS_38 + XSNS_38, +#endif + +#ifdef XSNS_39 + XSNS_39, +#endif + +#ifdef XSNS_40 + XSNS_40, +#endif + +#ifdef XSNS_41 + XSNS_41, +#endif + +#ifdef XSNS_42 + XSNS_42, +#endif + +#ifdef XSNS_43 + XSNS_43, +#endif + +#ifdef XSNS_44 + XSNS_44, +#endif + +#ifdef XSNS_45 + XSNS_45, +#endif + +#ifdef XSNS_46 + XSNS_46, +#endif + +#ifdef XSNS_47 + XSNS_47, +#endif + +#ifdef XSNS_48 + XSNS_48, +#endif + +#ifdef XSNS_49 + XSNS_49, +#endif + +#ifdef XSNS_50 + XSNS_50, +#endif + +// Optional user defined sensors in range 91 - 99 + +#ifdef XSNS_91 + XSNS_91, +#endif + +#ifdef XSNS_92 + XSNS_92, +#endif + +#ifdef XSNS_93 + XSNS_93, +#endif + +#ifdef XSNS_94 + XSNS_94, +#endif + +#ifdef XSNS_95 + XSNS_95 +#endif +}; + +/*********************************************************************************************\ + * Xsns sensor control +\*********************************************************************************************/ + +boolean XsnsEnabled(byte sns_index) +{ + if (sns_index < sizeof(kXsnsList)) { +#ifdef XFUNC_PTR_IN_ROM + uint8_t index = pgm_read_byte(kXsnsList + sns_index); +#else + uint8_t index = kXsnsList[sns_index]; +#endif + return bitRead(Settings.sensors[index / 32], index % 32); + } + return 1; +} + +boolean XsnsPresent(byte sns_index) +{ + uint8_t index = 0; + for (byte i = 0; i < sizeof(kXsnsList); i++) { +#ifdef XFUNC_PTR_IN_ROM + index = pgm_read_byte(kXsnsList + i); +#else + index = kXsnsList[i]; +#endif + if (index == sns_index) { return true; } + } + return false; +} + +String XsnsGetSensors(void) +{ + char state[2] = { 0 }; + + String data = F("["); + for (byte i = 0; i < MAX_XSNS_DRIVERS; i++) { + if (i && (!(i % 16))) { data += F(","); } + if (!(i % 16)) { data += F("\""); } + state[0] = '-'; + if (XsnsPresent(i)) { state[0] = bitRead(Settings.sensors[i / 32], i % 32) ? '1' : '0'; } + data += String(state); + if (i && (!((i +1) % 16))) { data += F("\""); } + } + data += F("]"); + + return data; +} + +#endif // USE_DEBUG_DRIVER \ No newline at end of file