Compare commits

...
Author SHA1 Message Date
ESPEasy release bot b3b68856f0 automatically updated release notes for mega-20181004 2018-10-04 04:00:08 +02:00
Gijs NoorlanderandGitHub bda6011390 Merge pull request #1852 from TD-er/bugfix/wificlient_timeout
[#1830] WiFi client timeout & back to core 2.4.1
2018-10-04 00:56:09 +02:00
Gijs NoorlanderandGitHub f3fdb93a52 Merge pull request #1831 from JojoS62/mega
[P013_HCSR04] added error checking and logging
2018-10-04 00:54:02 +02:00
Gijs NoorlanderandGitHub 200b060b15 Merge pull request #1846 from thomastech/mega
Update _P075_Nextion.ino
2018-10-04 00:51:44 +02:00
Gijs NoorlanderandGitHub ff41cb2f94 Merge pull request #1849 from uzi18/patch9
- partial fix for #1723
2018-10-04 00:51:03 +02:00
TD-er c134eb6d13 [Core 2.4.1] Move back to core 2.4.1 from 2.4.2
PlatformIO `espressif8266@1.7.3` instead of `espressif8266@1.8.0`
2.4.2 has a lot of improvements like 4k of extra free memory.
But also the number of hardware watchdog reboots has increased a lot and the PWM related code no longer seems to work on 2.4.2
So for now, back to 2.4.1 library.
2018-10-04 00:24:28 +02:00
TD-er f9e2a211e1 [WiFiClient] Set timeout and make it configurable for controllers
The default timeout for wificlient is 1000 msec. This may cause all kind of strange effects when the node is being blocked for so long.
2018-10-04 00:21:00 +02:00
Bartlomiej Zimon 3bad683211 - partial fix for #1723 2018-10-03 21:13:56 +00:00
TD-er 68f6e913a2 [sendHttp] #1830 Set timeout and early exit on timeout reached
See #1830
2018-10-03 23:10:47 +02:00
ThomasandGitHub 8eea77e4ed Update _P075_Nextion.ino (#1)
Added DEBUG_LOG define to reduce info log messages and prevent serial log flooding.
Added SendStatus() to post log message on browser to acknowledge HTTP write.
Added reserve() to minimize string memory allocations.
2018-10-03 09:02:02 -07:00
JojoS62 3d1f723787 Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into mega 2018-10-03 15:27:40 +02:00
JojoS62 5d459003e4 fixed 'unused variable' warning 2018-10-03 15:19:19 +02:00
JojoS62 ad208c357c code clean up
added default for filter size = 5.
clode clieanup: using constants, read setting into local vars for better readability,
2018-10-03 14:33:17 +02:00
ESPEasy release bot b1c777e6fd automatically updated release notes for mega-20181003 2018-10-03 04:00:18 +02:00
JojoS62 f5ab15c255 max distance depends on measurement unit
setting is in user units, ping function needs cm. Conversion added.
added unit to log output.
2018-10-02 17:41:23 +02:00
JojoS62 001ec6dcd2 added more settings: unit, filtertype and size
Measuring unit can be changed bewtween metric/imperial
Filtertype can none or median. If median a filtersize can be set.
Meauring value time to distance conversion now as float division, resulting in a higher resolution output.
2018-10-02 17:00:22 +02:00
JojoS62 15e5edccd8 added float calculation for time to distance conversion
returns higher resolution, especially for measuring in inches the integer resolution was low.
2018-10-02 16:57:33 +02:00
Gijs NoorlanderandGitHub 651353cc99 Merge pull request #1842 from crankyoldgit/patch-2
Acknowledge credit & origin of code used in _P016IR.ino
2018-10-02 13:41:35 +02:00
Gijs NoorlanderandGitHub 85f97551c5 Merge pull request #1841 from crankyoldgit/patch-1
Acknowledge credit & origin of code used in IRTX
2018-10-02 13:41:23 +02:00
David ConranandGitHub 6a158f68f5 Acknowledge credit & origin of code used in _P016IR.ino
FYI @TD-er

Ref: https://github.com/letscontrolit/ESPEasy/pull/1645#issuecomment-422253497
2018-10-02 21:36:18 +10:00
David ConranandGitHub 1933714de5 Acknowledge credit & origin of code used in IRTX
FYI @TD-er

Ref: https://github.com/letscontrolit/ESPEasy/pull/1645#issuecomment-422253497
2018-10-02 21:29:57 +10:00
ESPEasy release bot 545117ddf7 automatically updated release notes for mega-20181002 2018-10-02 04:00:29 +02:00
Gijs NoorlanderandGitHub 8eb479c411 Merge pull request #1837 from TD-er/bugfix/schedule_commands_yield
[Stack] Report stack usage on ESP32 and increase stack for ESP8266normal
2018-10-01 23:27:07 +02:00
TD-er b39f51ca3c [Stack] Report stack usage on ESP32 and increase stack for ESP8266normal
Stack usage on ESP32 is querying current stack, not statistics per RTOS task.
2018-10-01 22:15:32 +02:00
Gijs NoorlanderandGitHub 4511e08d3c Merge pull request #1805 from giig1967g/new/parse
split parseTemplate function
2018-10-01 17:12:21 +02:00
Gijs NoorlanderandGitHub 086e836956 Merge pull request #1836 from TD-er/feature/esp32_pio_1_4_0
[ESP32] Update to platform espressif32@1.4.0
2018-10-01 17:10:45 +02:00
Gijs NoorlanderandGitHub 3e20f617ea Merge pull request #1827 from TD-er/bugfix/DTH_Si7021_reading_stability
[#1798] Bugfix Sonoff Si7021 stability
2018-10-01 17:10:23 +02:00
TD-er 8d9aacb6a4 [ESP32] Update to PIO espressif32@1.4.0
[ESP32 IDF 3.1](https://github.com/espressif/esp-idf/releases/tag/v3.1)
[ESP32 PIO 1.4.0](https://github.com/platformio/platform-espressif32/releases/tag/v1.4.0)
2018-10-01 16:34:21 +02:00
TD-er 0670fa98a6 [ESP32] Add default partition table for reference 2018-10-01 16:32:20 +02:00
ESPEasy release bot 2b3d1517c9 automatically updated release notes for mega-20181001 2018-10-01 13:13:13 +02:00
Gijs NoorlanderandGitHub 0be79759d1 Merge pull request #1834 from TD-er/bugfix/detect_large_stack_allocs
[Stack] Move Arduino stack back to top of System stack instead of overlap
2018-10-01 01:25:38 +02:00
TD-er d47bede215 [Stack] Revert move Settings from stack to heap
Apparently the settings are allocated on the system stack and not on the Arduino stack.
This means it takes a lot of ram when allocated on the heap. So move it back to the system stack.
2018-10-01 00:51:04 +02:00
TD-er 2988a244b2 [Stack] Check if a block sent to save on SPIFFS is stack allocated 2018-10-01 00:42:01 +02:00
TD-er 8d87dc0175 [Heap] Use NO_EXTRA_4K_HEAP to get old stack address space
Originally the Arduino stack was placed on top of the system stack.
But since the system stack is mostly empty, it was decided to shift the Arduino stack to overlap the system stack to save an extra 4k of memory.

However, since a lot of Watchdog timer reboots are reported lately, this optimisation will now be reverted to see if it will improve stability.
This will use about 4k more RAM.
2018-10-01 00:40:55 +02:00
Gijs NoorlanderandGitHub 21c86e666a Merge pull request #1829 from TD-er/feature/1824_stack_stats
[#1824] Show stack size on main page
2018-09-30 19:37:16 +02:00
JojoS e6fdd3380a added error checking and logging
there were several errors that all resulted in a distance value reading of 0. Added an errorState that is printed to the log and helps troubleshooting.
Max. Distance checking can be turned off by setting max distance to 0 cm. If max. distance is used, exceeding the range will return a distance of 0 cm and print this to the log.
2018-09-30 15:23:36 +02:00
TD-er e04f71ab47 [#1824] Show stack size on main page
See #1824
2018-09-30 09:32:01 +02:00
ESPEasy release bot 90ae0720cf automatically updated release notes for mega-20180930 2018-09-30 04:00:24 +02:00
TD-er c8ecd8d374 [#1798] Bugfix Sonoff Si7021 stability
See #1798
2018-09-29 22:50:24 +02:00
Gijs NoorlanderandGitHub 7a451dd672 Merge pull request #1825 from TD-er/bugfix/proper_default_settings
Bugfix/proper default settings
2018-09-29 15:39:21 +02:00
Gijs NoorlanderandGitHub b06f6aa360 Merge pull request #1823 from JojoS62/mega
minor change: unit was missing for threshold in 'state' mode
2018-09-29 15:06:36 +02:00
TD-er 6b67415c71 [Defaults] Other default initializations 2018-09-29 15:05:10 +02:00
JojoS b095465d3a minor change: unit was missing for threshold in 'state' mode 2018-09-29 14:09:03 +02:00
Gijs NoorlanderandGitHub 81a5d911ba Merge pull request #1809 from JojoS62/mega
fixed distance reading
2018-09-29 13:38:44 +02:00
TD-er 48060d8d99 [Default Settings] Properly clear settings when reset to default 2018-09-29 12:40:29 +02:00
JojoS d303fa023f changed implementation to use shared_ptr instead of helper structure
this makes it easier to use this as a template for other sensors. No additional helper class/structure is needed.
2018-09-29 11:58:57 +02:00
JojoS 29b0cc1b32 removed sensordefs helper structure
to simplify the code
2018-09-27 22:00:01 +02:00
JojoS 584abd1e75 on INIT, delete sensordef before adding new 2018-09-27 14:19:54 +02:00
JojoS b4d8be0e59 fixed distance reading
the P_013_sensordef object was created on the stack and the destructor was called after leaving the PLUGIN_INIT. That deleted the included NewPingESP8266 object and using this object failed.
2018-09-27 11:56:31 +02:00
Plebs 6e7286c6fb split parseTemplate function
simplifying code
2018-09-26 23:40:01 +02:00
20 changed files with 1074 additions and 504 deletions
+86
View File
@@ -1,3 +1,89 @@
-------------------------------------------------
Changes in release mega-20181004 (since mega-20181003)
-------------------------------------------------
Release date: Thu Oct 4 04:00:08 CEST 2018
Bartlomiej Zimon (1):
- partial fix for #1723
JojoS (1):
added error checking and logging
JojoS62 (5):
added float calculation for time to distance conversion
added more settings: unit, filtertype and size
max distance depends on measurement unit
code clean up
fixed 'unused variable' warning
TD-er (3):
[sendHttp] #1830 Set timeout and early exit on timeout reached
[WiFiClient] Set timeout and make it configurable for controllers
[Core 2.4.1] Move back to core 2.4.1 from 2.4.2
Thomas (1):
Update _P075_Nextion.ino (#1)
-------------------------------------------------
Changes in release mega-20181003 (since mega-20181002)
-------------------------------------------------
Release date: Wed Oct 3 04:00:18 CEST 2018
David Conran (2):
Acknowledge credit & origin of code used in IRTX
Acknowledge credit & origin of code used in _P016IR.ino
-------------------------------------------------
Changes in release mega-20181002 (since mega-20181001)
-------------------------------------------------
Release date: Tue Oct 2 04:00:29 CEST 2018
Plebs (1):
split parseTemplate function
TD-er (4):
[#1798] Bugfix Sonoff Si7021 stability
[ESP32] Add default partition table for reference
[ESP32] Update to PIO espressif32@1.4.0
[Stack] Report stack usage on ESP32 and increase stack for ESP8266normal
-------------------------------------------------
Changes in release mega-20181001 (since mega-20180930)
-------------------------------------------------
Release date: Mon Oct 1 13:13:13 CEST 2018
TD-er (4):
[#1824] Show stack size on main page
[Heap] Use NO_EXTRA_4K_HEAP to get old stack address space
[Stack] Check if a block sent to save on SPIFFS is stack allocated
[Stack] Revert move Settings from stack to heap
-------------------------------------------------
Changes in release mega-20180930 (since mega-20180927)
-------------------------------------------------
Release date: Sun Sep 30 04:00:24 CEST 2018
JojoS (5):
fixed distance reading
on INIT, delete sensordef before adding new
removed sensordefs helper structure
changed implementation to use shared_ptr instead of helper structure
minor change: unit was missing for threshold in 'state' mode
TD-er (2):
[Default Settings] Properly clear settings when reset to default
[Defaults] Other default initializations
-------------------------------------------------
Changes in release mega-20180927 (since mega-20180924)
-------------------------------------------------
+7
View File
@@ -0,0 +1,7 @@
# Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x5000,
otadata, data, ota, 0xe000, 0x2000,
app0, app, ota_0, 0x10000, 0x140000,
app1, app, ota_1, 0x150000,0x140000,
eeprom, data, 0x99, 0x290000,0x1000,
spiffs, data, spiffs, 0x291000,0x16F000,
1 # Name Type SubType Offset Size Flags
2 nvs data nvs 0x9000 0x5000
3 otadata data ota 0xe000 0x2000
4 app0 app ota_0 0x10000 0x140000
5 app1 app ota_1 0x150000 0x140000
6 eeprom data 0x99 0x290000 0x1000
7 spiffs data spiffs 0x291000 0x16F000
+75 -13
View File
@@ -6,12 +6,13 @@
// ---------------------------------------------------------------------------
#include "NewPingESP8266.h"
//#include "ESPEasy-Globals.h"
// ---------------------------------------------------------------------------
// NewPingESP8266 constructor
// ---------------------------------------------------------------------------
NewPingESP8266::NewPingESP8266(uint32_t trigger_pin, uint32_t echo_pin, unsigned int max_cm_distance) {
_errorState = STATUS_SENSOR_READY;
#if DO_BITWISE == true
_triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
_echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin.
@@ -58,7 +59,10 @@ unsigned int NewPingESP8266::ping(unsigned int max_cm_distance) {
while (!digitalRead(_echoPin)) // Wait for the ping echo.
#endif
{
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
if ((_max_cm_distance > 0) && (micros() > _max_time)) {
_errorState = STATUS_MAX_DISTANCE_EXCEEDED;
return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
}
}
#else
#if DO_BITWISE == true
@@ -67,10 +71,14 @@ unsigned int NewPingESP8266::ping(unsigned int max_cm_distance) {
while (digitalRead(_echoPin)) // Wait for the ping echo.
#endif
{
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
if ((_max_cm_distance > 0) && (micros() > _max_time)) {
_errorState = STATUS_MAX_DISTANCE_EXCEEDED;
return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
}
}
#endif
_errorState = STATUS_MEASUREMENT_VALID;
return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead.
}
@@ -144,15 +152,39 @@ boolean NewPingESP8266::ping_trigger() {
#endif
#if URM37_ENABLED == true
if (!(*_echoInput & _echoBit)) return false; // Previous ping hasn't finished, abort.
if (!(*_echoInput & _echoBit)) { // Previous ping hasn't finished, abort.{
_errorState = STATUS_ECHO_STATE_ERROR;
return false;
}
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (*_echoInput & _echoBit) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
{
if (millis() > (start + 50)) {
_errorState = STATUS_ECHO_START_TIMEOUT_50ms;
return false;
}
if ((_max_cm_distance > 0) && (micros() > _max_time)) { // check max. distance if != 0 cm
_errorState = STATUS_ECHO_START_TIMEOUT_DISTANCE;
return false; // echo too late, max distance exceeded
}
}
#else
if (*_echoInput & _echoBit) return false; // Previous ping hasn't finished, abort.
if (*_echoInput & _echoBit) { // Previous ping hasn't finished, abort.
_errorState = STATUS_ECHO_STATE_ERROR;
return false;
}
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (!(*_echoInput & _echoBit)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
{
if (millis() > (start + 50)) {
_errorState = STATUS_ECHO_START_TIMEOUT_50ms;
return false;
}
if ((_max_cm_distance > 0) && (micros() > _max_time)) { // check max. distance if != 0 cm
_errorState = STATUS_ECHO_START_TIMEOUT_DISTANCE;
return false; // echo too late, max distance exceeded
}
}
#endif
#else
#if ONE_PIN_ENABLED == true
@@ -170,30 +202,51 @@ boolean NewPingESP8266::ping_trigger() {
#endif
#if URM37_ENABLED == true
if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
if (!digitalRead(_echoPin)) {
_errorState = STATUS_ECHO_STATE_ERROR;
return false; // Previous ping hasn't finished, abort.
}
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (digitalRead(_echoPin)) // Wait for ping to start.
{
if (millis() > (start + 50)) return false;
if (micros() > _max_time) return false; // Took too long to start, abort.
if (millis() > (start + 50)) {
_errorState = STATUS_ECHO_START_TIMEOUT_50ms;
return false;
}
if ((_max_cm_distance > 0) && (micros() > _max_time)) { // check max. distance if != 0 cm
_errorState = STATUS_ECHO_START_TIMEOUT_DISTANCE;
return false; // echo too late, max distance exceeded
}
}
#else
if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
if (digitalRead(_echoPin)) {
_errorState = STATUS_ECHO_STATE_ERROR;
return false; // Previous ping hasn't finished, abort.
}
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (!digitalRead(_echoPin)) // Wait for ping to start.
{
if (millis() > (start + 50)) return false;
if (micros() > _max_time) return false; // Took too long to start, abort.
if (millis() > (start + 50)) {
_errorState = STATUS_ECHO_START_TIMEOUT_50ms;
return false;
}
if ((_max_cm_distance > 0) && (micros() > _max_time)) { // check max. distance if != 0 cm
_errorState = STATUS_ECHO_START_TIMEOUT_DISTANCE;
return false; // echo too late, max distance exceeded
}
}
#endif
#endif
_max_time = micros() + _maxEchoTime; // Ping started, set the time-out.
_errorState = STATUS_ECHO_TRIGGERED;
return true; // Ping started successfully.
}
void NewPingESP8266::set_max_distance(unsigned int max_cm_distance) {
_max_cm_distance = max_cm_distance;
#if ROUNDING_ENABLED == false
_maxEchoTime = min(max_cm_distance + 1, (unsigned int) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; // Calculate the maximum distance in uS (no rounding).
#else
@@ -222,3 +275,12 @@ unsigned int NewPingESP8266::convert_in(unsigned int echoTime) {
return NewPingESP8266Convert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
#endif
}
float NewPingESP8266::convert_cm_F(unsigned int echoTime) {
return ((float)echoTime / US_ROUNDTRIP_CM); // Convert uS to centimeters (no rounding).
}
float NewPingESP8266::convert_in_F(unsigned int echoTime) {
return ((float)echoTime / US_ROUNDTRIP_IN); // Convert uS to inches (no rounding).
}
+17 -1
View File
@@ -194,15 +194,29 @@
class NewPingESP8266 {
public:
enum errorState {
STATUS_SENSOR_READY, // no error, no measruement started
STATUS_MEASUREMENT_VALID, // no errors
STATUS_ECHO_TRIGGERED, // echo triggered, intermediate state
STATUS_MAX_DISTANCE_EXCEEDED, // echo too late, maximum distance exceeded
STATUS_ECHO_START_TIMEOUT_50ms, // no echo start signal after 50 ms
STATUS_ECHO_START_TIMEOUT_DISTANCE, // no echo start signal after max. distance
STATUS_ECHO_STATE_ERROR // echopin level not low after triggered
};
NewPingESP8266(uint32_t trigger_pin, uint32_t echo_pin, unsigned int max_cm_distance = MAX_SENSOR_DISTANCE);
~NewPingESP8266() { };
unsigned int ping(unsigned int max_cm_distance = 0);
unsigned long ping_cm(unsigned int max_cm_distance = 0);
unsigned long ping_in(unsigned int max_cm_distance = 0);
unsigned long ping_median(uint32_t it = 5, unsigned int max_cm_distance = 0);
static unsigned int convert_cm(unsigned int echoTime);
static unsigned int convert_in(unsigned int echoTime);
static float convert_cm_F(unsigned int echoTime);
static float convert_in_F(unsigned int echoTime);
unsigned int getMaxEchoTime() { return _maxEchoTime; }
unsigned int getMaxEchoTime() { return _maxEchoTime; };
errorState getErrorState() { return _errorState; };
private:
boolean ping_trigger();
void set_max_distance(unsigned int max_cm_distance);
@@ -218,6 +232,8 @@ class NewPingESP8266 {
#endif
unsigned int _maxEchoTime;
unsigned long _max_time;
errorState _errorState;
unsigned int _max_cm_distance;
};
+32 -24
View File
@@ -73,11 +73,14 @@ platform = espressif32@1.2.0
[core_esp32_1_3_0]
platform = espressif32@1.3.0
[core_esp32_1_4_0]
platform = espressif32@1.4.0
[core_esp32_stage]
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
[core_esp32]
platform = ${core_esp32_1_3_0.platform}
platform = ${core_esp32_1_4_0.platform}
build_unflags = -Wall
build_flags = -D BUILD_GIT='"${sysenv.TRAVIS_TAG}"'
lib_ignore = AS_BH1750, ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266HTTPUpdateServer, ESP8266mDNS, IRremoteESP8266, ESPEasy_ESP8266Ping, SerialSensors, SDM
@@ -101,7 +104,10 @@ monitor_speed = 115200
; -DVTABLES_IN_DRAM
; VTABLES in IRAM
; -DVTABLES_IN_IRAM
; NO_EXTRA_4K_HEAP - this forces the default NONOS-SDK user's heap location
; Default currently overlaps cont stack (Arduino) with sys stack (System)
; to save up-to 4 kB of heap. (starting core_2.4.2)
; CONT_STACKSIZE to set the 'cont' (Arduino) stack size. Default = 4096
[common]
board_build.f_cpu = 80000000L
@@ -120,18 +126,20 @@ lib_archive = false
upload_speed = 460800
framework = arduino
board = esp12e
platform = ${core_2_4_2.platform}
platform = ${core_2_4_1.platform}
monitor_speed = 115200
[normal]
platform = ${common.platform}
build_flags = -DNO_EXTRA_4K_HEAP
[testing]
platform = ${core_2_4_2.platform}
platform = ${core_2_4_1.platform}
build_flags = -DNO_EXTRA_4K_HEAP -DPLUGIN_BUILD_TESTING
[dev]
platform = ${core_2_4_2.platform}
platform = ${core_2_4_1.platform}
build_flags = -DNO_EXTRA_4K_HEAP -DPLUGIN_BUILD_DEV
[ir]
lib_ignore = ESP32_ping, ESP32WebServer
@@ -159,7 +167,7 @@ board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
build_unflags = ${common.build_unflags}
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
platform = ${core_2_4_2.platform}
platform = ${core_2_4_1.platform}
[Sonoff_8285]
board_upload.maximum_size = ${esp8285_1M.board_upload.maximum_size}
@@ -168,7 +176,7 @@ board_build.f_cpu = ${esp8285_1M.board_build.f_cpu}
board = ${esp8285_1M.board}
build_unflags = ${esp8285_1M.build_unflags}
build_flags = ${esp8285_1M.build_flags}
platform = ${core_2_4_2.platform}
platform = ${core_2_4_1.platform}
[espWroom2M]
board_build.flash_mode = dout
@@ -242,7 +250,7 @@ board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
build_unflags = ${esp8266_1M.build_unflags}
build_flags = ${esp8266_1M.build_flags}
build_flags = ${esp8266_1M.build_flags} ${normal.build_flags}
; NORMAL: 1024k for esp8285 ----------------------
[env:normal_ESP8285_1024]
@@ -259,7 +267,7 @@ board_upload.maximum_size = ${esp8285_1M.board_upload.maximum_size}
board_build.f_cpu = ${esp8285_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8285_1M.board_build.flash_mode}
build_unflags = ${esp8285_1M.build_unflags}
build_flags = ${esp8285_1M.build_flags}
build_flags = ${esp8285_1M.build_flags} ${normal.build_flags}
; NORMAL: 2048k version --------------------------
[env:normal_WROOM02_2048]
@@ -275,7 +283,7 @@ board = ${espWroom2M.board}
board_build.f_cpu = ${espWroom2M.board_build.f_cpu}
board_build.flash_mode = ${espWroom2M.board_build.flash_mode}
build_unflags = ${espWroom2M.build_unflags}
build_flags = ${espWroom2M.build_flags}
build_flags = ${espWroom2M.build_flags} ${normal.build_flags}
; NORMAL: 4096k version --------------------------
[env:normal_ESP8266_4096]
@@ -291,7 +299,7 @@ board = ${common.board}
board_build.f_cpu = ${esp8266_4M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_4M.board_build.flash_mode}
build_unflags = ${esp8266_4M.build_unflags}
build_flags = ${esp8266_4M.build_flags}
build_flags = ${esp8266_4M.build_flags} ${normal.build_flags}
; NORMAL IR: 4096k version --------------------------
@@ -309,7 +317,7 @@ board = ${common.board}
board_build.f_cpu = ${esp8266_4M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_4M.board_build.flash_mode}
build_unflags = ${esp8266_4M.build_unflags}
build_flags = ${esp8266_4M.build_flags} -DPLUGIN_BUILD_NORMAL_IR
build_flags = ${esp8266_4M.build_flags} ${normal.build_flags} -DPLUGIN_BUILD_NORMAL_IR
;;; TESTING ; ****; ****; ****; ****; ****; ****; ****; ****; ****; ****; ****; ****; ****
@@ -331,7 +339,7 @@ board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
build_unflags = ${esp8266_1M.build_unflags}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_TESTING
build_flags = ${esp8266_1M.build_flags} ${testing.build_flags}
; TEST: 1024k for esp8285 ------------------------
[env:test_ESP8285_1024]
@@ -348,7 +356,7 @@ board_build.f_cpu = ${esp8285_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8285_1M.board_build.flash_mode}
board = ${esp8285_1M.board}
build_unflags = ${esp8285_1M.build_unflags}
build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_TESTING
build_flags = ${esp8285_1M.build_flags} ${testing.build_flags}
; TEST: 2048k version ----------------------------
[env:test_WROOM02_2048]
@@ -364,7 +372,7 @@ board_build.f_cpu = ${espWroom2M.board_build.f_cpu}
board_build.flash_mode = ${espWroom2M.board_build.flash_mode}
board = ${espWroom2M.board}
build_unflags = ${espWroom2M.build_unflags}
build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_TESTING
build_flags = ${espWroom2M.build_flags} ${testing.build_flags}
; TEST: 4096k version ----------------------------
[env:test_ESP8266_4096]
@@ -380,7 +388,7 @@ monitor_speed = ${common.monitor_speed}
board_build.f_cpu = ${esp8266_4M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_4M.board_build.flash_mode}
build_unflags = ${esp8266_4M.build_unflags}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING
build_flags = ${esp8266_4M.build_flags} ${testing.build_flags}
; TEST: 4096k version + FEATURE_ADC_VCC ----------
[env:test_ESP8266_4096_VCC]
@@ -396,7 +404,7 @@ monitor_speed = ${common.monitor_speed}
board_build.f_cpu = ${esp8266_4M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_4M.board_build.flash_mode}
build_unflags = ${esp8266_4M.build_unflags}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING -D FEATURE_ADC_VCC=true
build_flags = ${esp8266_4M.build_flags} ${testing.build_flags} -D FEATURE_ADC_VCC=true
@@ -419,7 +427,7 @@ board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
board = ${common.board}
build_unflags = ${esp8266_1M.build_unflags}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV
build_flags = ${esp8266_1M.build_flags} ${dev.build_flags}
; DEV: 1024k for esp8285 -------------------------
[env:dev_ESP8285_1024]
@@ -436,7 +444,7 @@ board_build.f_cpu = ${esp8285_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8285_1M.board_build.flash_mode}
board = ${esp8285_1M.board}
build_unflags = ${esp8285_1M.build_unflags}
build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_DEV
build_flags = ${esp8285_1M.build_flags} ${dev.build_flags}
; DEV: 2048k version -----------------------------
[env:dev_WROOM02_2048]
@@ -452,7 +460,7 @@ board_build.f_cpu = ${espWroom2M.board_build.f_cpu}
board_build.flash_mode = ${espWroom2M.board_build.flash_mode}
board = ${espWroom2M.board}
build_unflags = ${espWroom2M.build_unflags}
build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_DEV
build_flags = ${espWroom2M.build_flags} ${dev.build_flags}
; DEV : 4096k version ----------------------------
[env:dev_ESP8266_4096]
@@ -468,7 +476,7 @@ monitor_speed = ${common.monitor_speed}
board_build.f_cpu = ${esp8266_4M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_4M.board_build.flash_mode}
build_unflags = ${esp8266_4M.build_unflags}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_DEV
build_flags = ${esp8266_4M.build_flags} ${dev.build_flags}
@@ -491,7 +499,7 @@ board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
build_unflags = ${esp8266_1M.build_unflags}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1
build_flags = ${esp8266_1M.build_flags} ${dev.build_flags} -D FLASH_QUIRK_WRITE_0_TO_1
; DEV+PUYA : 1024k version + FEATURE_ADC_VCC -----
[env:dev_ESP8266PUYA_1024_VCC]
@@ -508,7 +516,7 @@ board_upload.maximum_size = ${esp8266_1M.board_upload.maximum_size}
board_build.f_cpu = ${esp8266_1M.board_build.f_cpu}
board_build.flash_mode = ${esp8266_1M.board_build.flash_mode}
build_unflags = ${esp8266_1M.build_unflags}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1 -D FEATURE_ADC_VCC=true
build_flags = ${esp8266_1M.build_flags} ${dev.build_flags} -D FLASH_QUIRK_WRITE_0_TO_1 -D FEATURE_ADC_VCC=true
+1
View File
@@ -141,6 +141,7 @@ bool MQTTConnect(int controller_idx)
updateMQTTclient_connected();
}
mqtt = WiFiClient(); // workaround see: https://github.com/esp8266/Arduino/issues/4497#issuecomment-373023864
mqtt.setTimeout(ControllerSettings.ClientTimeout);
if (ControllerSettings.UseDNS) {
MQTTclient.setServer(ControllerSettings.getHost().c_str(), ControllerSettings.Port);
} else {
+48 -14
View File
@@ -68,6 +68,9 @@
#if defined(ESP32)
#define USE_RTOS_MULTITASKING
#endif
#ifdef M5STACK_ESP
// #include <M5Stack.h>
#endif
#define DEFAULT_USE_RULES false // (true|false) Enable Rules?
@@ -223,6 +226,9 @@
// N.B. Retries without a connection to wifi do not count as retry.
#define CONTROLLER_DELAY_QUEUE_RETRY_MAX 10
#define CONTROLLER_DELAY_QUEUE_RETRY_DFLT 10
// Timeout of the client in msec.
#define CONTROLLER_CLIENTTIMEOUT_MAX 1000
#define CONTROLLER_CLIENTTIMEOUT_DFLT 100
#define PLUGIN_INIT_ALL 1
@@ -411,6 +417,9 @@ void addToLog(byte loglevel, const String& string);
void addToLog(byte logLevel, const __FlashStringHelper* flashString);
void statusLED(boolean traffic);
void backgroundtasks();
uint32_t getCurrentFreeStack();
uint32_t getFreeStackWatermark();
bool canYield();
bool getBitFromUL(uint32_t number, byte bitnr);
void setBitToUL(uint32_t& number, byte bitnr, bool value);
@@ -684,17 +693,30 @@ struct SettingsStruct
if (VariousBits1 > (1 << 30)) VariousBits1 = 0;
}
void clearNetworkSettings() {
for (byte i = 0; i < 4; ++i) {
IP[i] = 0;
Gateway[i] = 0;
Subnet[i] = 0;
DNS[i] = 0;
}
}
void clearAll() {
PID = 0;
Version = 0;
Build = 0;
IP_Octet = 0;
Unit = 0;
Name[0] = 0;
NTPHost[0] = 0;
Delay = 0;
Pin_i2c_sda = -1;
Pin_i2c_scl = -1;
Pin_status_led = -1;
Pin_sd_cs = -1;
for (byte i = 0; i < 17; ++i) { PinBootStates[i] = 0; }
for (byte i = 0; i < 4; ++i) { Syslog_IP[i] = 0; }
UDPPort = 0;
SyslogLevel = 0;
SerialLogLevel = 0;
@@ -719,12 +741,13 @@ struct SettingsStruct
Pin_status_led_Inversed = false;
deepSleepOnFail = false;
UseValueLogger = false;
ArduinoOTAEnable = false;
DST_Start = 0;
DST_End = 0;
UseRTOSMultitasking = false;
Pin_Reset = -1;
SyslogFacility = DEFAULT_SYSLOG_FACILITY;
StructSize = 0;
StructSize = sizeof(SettingsStruct);
MQTTUseUnitNameAsClientId = 0;
Latitude = 0.0;
Longitude = 0.0;
@@ -741,6 +764,7 @@ struct SettingsStruct
for (byte task = 0; task < TASKS_MAX; ++task) {
clearTask(task);
}
clearNetworkSettings();
}
void clearTask(byte task) {
@@ -862,10 +886,11 @@ struct SettingsStruct
// Try to extend settings to make the checksum 4-byte aligned.
// uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file.
// uint8_t md5[16];
};
} Settings;
/*
SettingsStruct* SettingsStruct_ptr = new SettingsStruct;
SettingsStruct& Settings = *SettingsStruct_ptr;
*/
/*********************************************************************************************\
* ControllerSettingsStruct
@@ -873,7 +898,7 @@ SettingsStruct& Settings = *SettingsStruct_ptr;
struct ControllerSettingsStruct
{
ControllerSettingsStruct() : UseDNS(false), Port(0),
MinimalTimeBetweenMessages(100), MaxQueueDepth(10), MaxRetry(10), DeleteOldest(false) {
MinimalTimeBetweenMessages(100), MaxQueueDepth(10), MaxRetry(10), DeleteOldest(false), ClientTimeout(100) {
for (byte i = 0; i < 4; ++i) {
IP[i] = 0;
}
@@ -897,13 +922,16 @@ struct ControllerSettingsStruct
unsigned int MaxQueueDepth;
unsigned int MaxRetry;
boolean DeleteOldest; // Action to perform when buffer full, delete oldest, or ignore newest.
unsigned int ClientTimeout;
void validate() {
if (Port > 65535) Port = 0;
if (MinimalTimeBetweenMessages < 1) MinimalTimeBetweenMessages = 100;
if (MinimalTimeBetweenMessages > 3600000) MinimalTimeBetweenMessages = 100;
if (MaxQueueDepth > 25) MaxQueueDepth = 10;
if (MaxRetry > 10) MaxRetry = 10;
if (MinimalTimeBetweenMessages < 1 || MinimalTimeBetweenMessages > CONTROLLER_DELAY_QUEUE_DELAY_MAX)
MinimalTimeBetweenMessages = CONTROLLER_DELAY_QUEUE_DELAY_DFLT;
if (MaxQueueDepth > CONTROLLER_DELAY_QUEUE_DEPTH_MAX) MaxQueueDepth = CONTROLLER_DELAY_QUEUE_DEPTH_DFLT;
if (MaxRetry > CONTROLLER_DELAY_QUEUE_RETRY_MAX) MaxRetry = CONTROLLER_DELAY_QUEUE_RETRY_MAX;
if (ClientTimeout < 10 || ClientTimeout > CONTROLLER_CLIENTTIMEOUT_MAX)
ClientTimeout = CONTROLLER_CLIENTTIMEOUT_DFLT;
}
IPAddress getIP() const {
@@ -1401,6 +1429,7 @@ std::map<unsigned long, systemTimerStruct> systemTimers;
\*********************************************************************************************/
struct pinStatesStruct
{
pinStatesStruct() : plugin(0), index(0), mode(0), value(0) {}
byte plugin;
byte index;
byte mode;
@@ -1447,6 +1476,8 @@ float UserVar[VARS_PER_TASK * TASKS_MAX];
\*********************************************************************************************/
struct rulesTimerStatus
{
rulesTimerStatus() : timestamp(0), interval(0), paused(false) {}
unsigned long timestamp;
unsigned int interval; //interval in milliseconds
boolean paused;
@@ -1454,11 +1485,11 @@ struct rulesTimerStatus
msecTimerHandlerStruct msecTimerHandler;
unsigned long timermqtt_interval;
unsigned long lastSend;
unsigned long lastWeb;
unsigned long timermqtt_interval = 250;
unsigned long lastSend = 0;
unsigned long lastWeb = 0;
byte cmd_within_mainloop = 0;
unsigned long connectionFailures;
unsigned long connectionFailures = 0;
unsigned long wdcounter = 0;
unsigned long timerAPoff = 0;
unsigned long timerAwakeFromDeepSleep = 0;
@@ -1608,15 +1639,18 @@ String eventBuffer = "";
uint32_t lowestRAM = 0;
String lowestRAMfunction = "";
uint32_t lowestFreeStack = 0;
String lowestFreeStackfunction = "";
bool shouldReboot=false;
bool firstLoop=true;
boolean activeRuleSets[RULESETS_MAX];
boolean UseRTOSMultitasking;
boolean UseRTOSMultitasking = false;
void (*MainLoopCall_ptr)(void);
// void (*MainLoopCall_ptr)(void); //FIXME TD-er: No idea what this does.
/*********************************************************************************************\
* TimingStats
+5 -2
View File
@@ -109,6 +109,8 @@ void setup()
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
WiFi.setAutoReconnect(false);
setWifiMode(WIFI_OFF);
lowestFreeStack = getFreeStackWatermark();
lowestRAM = FreeMem();
Plugin_id.resize(PLUGIN_MAX);
Task_id_to_Plugin_id.resize(TASKS_MAX);
@@ -119,8 +121,6 @@ void setup()
ledChannelPin[x] = -1;
#endif
lowestRAM = FreeMem();
Serial.begin(115200);
// Serial.print("\n\n\nBOOOTTT\n\n\n");
@@ -462,8 +462,11 @@ int getLoopCountPerSec() {
\*********************************************************************************************/
void loop()
{
/*
//FIXME TD-er: No idea what this does.
if(MainLoopCall_ptr)
MainLoopCall_ptr();
*/
updateLoopStats();
+9
View File
@@ -535,6 +535,15 @@ String InitFile(const char* fname, int datasize)
\*********************************************************************************************/
String SaveToFile(char* fname, int index, byte* memAddress, int datasize)
{
#ifndef ESP32
if (allocatedOnStack(memAddress)) {
String log = F("SaveToFile: ");
log += fname;
log += F(" ERROR, Data allocated on stack");
addLog(LOG_LEVEL_ERROR, log);
// return log; // FIXME TD-er: Should this be considered a breaking error?
}
#endif
if (index < 0) {
String log = F("SaveToFile: ");
log += fname;
+329 -225
View File
@@ -23,6 +23,85 @@ void tcpCleanup()
}
#endif
// For keeping track of 'cont' stack
// See: https://github.com/esp8266/Arduino/issues/2557
// https://github.com/esp8266/Arduino/issues/5148#issuecomment-424329183
// https://github.com/letscontrolit/ESPEasy/issues/1824
#ifdef ESP32
// FIXME TD-er: For ESP32 you need to provide the task number, or NULL to get from the calling task.
uint32_t getCurrentFreeStack() {
register uint8_t *sp asm("a1");
return (sp - pxTaskGetStackStart(NULL));
}
uint32_t getFreeStackWatermark() {
return uxTaskGetStackHighWaterMark(NULL);
}
// FIXME TD-er: Must check if these functions are also needed for ESP32.
bool canYield() { return true; }
#else
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1)
// All version before core 2.4.2
extern "C" {
#include <cont.h>
extern cont_t g_cont;
}
uint32_t getCurrentFreeStack() {
register uint32_t *sp asm("a1");
return 4 * (sp - g_cont.stack);
}
uint32_t getFreeStackWatermark() {
return cont_get_free_stack(&g_cont);
}
bool canYield() {
return cont_can_yield(&g_cont);
}
bool allocatedOnStack(const void* address) {
register uint32_t *sp asm("a1");
if (sp < address) return false;
return g_cont.stack < address;
}
#else
// All version from core 2.4.2
// See: https://github.com/esp8266/Arduino/pull/5018
// https://github.com/esp8266/Arduino/pull/4553
extern "C" {
#include <cont.h>
extern cont_t* g_pcont;
}
uint32_t getCurrentFreeStack() {
// https://github.com/esp8266/Arduino/issues/2557
register uint32_t *sp asm("a1");
return 4 * (sp - g_pcont->stack);
}
uint32_t getFreeStackWatermark() {
return cont_get_free_stack(g_pcont);
}
bool canYield() {
return cont_can_yield(g_pcont);
}
bool allocatedOnStack(const void* address) {
register uint32_t *sp asm("a1");
if (sp < address) return false;
return g_pcont->stack < address;
}
#endif // ARDUINO_ESP8266_RELEASE_2_x_x
#endif // ESP32
bool isDeepSleepEnabled()
{
if (!Settings.deepSleep)
@@ -1365,7 +1444,7 @@ String parseTemplate(String &tmpString, byte lineSize)
{
checkRAM(F("parseTemplate"));
String newString = "";
String tmpStringMid = "";
//String tmpStringMid = "";
newString.reserve(lineSize);
// replace task template variables
@@ -1384,7 +1463,7 @@ String parseTemplate(String &tmpString, byte lineSize)
int rightBracketIndex = tmpString.indexOf(']');
if (rightBracketIndex >= 0)
{
tmpStringMid = tmpString.substring(0, rightBracketIndex);
String tmpStringMid = tmpString.substring(0, rightBracketIndex);
tmpString = tmpString.substring(rightBracketIndex + 1);
int hashtagIndex = tmpStringMid.indexOf('#');
if (hashtagIndex >= 0) {
@@ -1421,232 +1500,14 @@ String parseTemplate(String &tmpString, byte lineSize)
if (valueName.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceValueNames[z]))
{
// here we know the task and value, so find the uservar
// Try to format and transform the values
// y = taskNr
// z = var_of_task
match = true;
bool isvalid;
String value = formatUserVar(y, z, isvalid);
if (isvalid) {
// start changes by giig1967g - 2018-04-20
// Syntax: [task#value#transformation#justification]
// valueFormat="transformation#justification"
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
{
String valueJust = "";
hashtagIndex = valueFormat.indexOf('#');
if (hashtagIndex >= 0)
{
valueJust = valueFormat.substring(hashtagIndex + 1); //Justification part
valueFormat = valueFormat.substring(0, hashtagIndex); //Transformation part
}
// valueFormat="transformation"
// valueJust="justification"
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
{
const int val = value == "0" ? 0 : 1; //to be used for GPIO status (0 or 1)
const float valFloat = value.toFloat();
String tempValueFormat = valueFormat;
int tempValueFormatLength = tempValueFormat.length();
const int invertedIndex = tempValueFormat.indexOf('!');
const bool inverted = invertedIndex >= 0 ? 1 : 0;
if (inverted)
tempValueFormat.remove(invertedIndex,1);
const int rightJustifyIndex = tempValueFormat.indexOf('R');
const bool rightJustify = rightJustifyIndex >= 0 ? 1 : 0;
if (rightJustify)
tempValueFormat.remove(rightJustifyIndex,1);
tempValueFormatLength = tempValueFormat.length(); //needed because could have been changed after '!' and 'R' removal
//Check Transformation syntax
if (tempValueFormatLength > 0)
{
switch (tempValueFormat[0])
{
case 'V': //value = value without transformations
break;
case 'O':
value = val == inverted ? F("OFF") : F(" ON"); //(equivalent to XOR operator)
break;
case 'C':
value = val == inverted ? F("CLOSE") : F(" OPEN");
break;
case 'M':
value = val == inverted ? F("AUTO") : F(" MAN");
break;
case 'm':
value = val == inverted ? F("A") : F("M");
break;
case 'H':
value = val == inverted ? F("COLD") : F(" HOT");
break;
case 'U':
value = val == inverted ? F("DOWN") : F(" UP");
break;
case 'u':
value = val == inverted ? F("D") : F("U");
break;
case 'Y':
value = val == inverted ? F(" NO") : F("YES");
break;
case 'y':
value = val == inverted ? F("N") : F("Y");
break;
case 'X':
value = val == inverted ? F("O") : F("X");
break;
case 'I':
value = val == inverted ? F("OUT") : F(" IN");
break;
case 'Z' :// return "0" or "1"
value = val == inverted ? F("0") : F("1");
break;
case 'D' ://Dx.y min 'x' digits zero filled & 'y' decimal fixed digits
{
int x;
int y;
x = 0;
y = 0;
switch (tempValueFormatLength)
{
case 2: //Dx
if (isDigit(tempValueFormat[1]))
{
x = (int)tempValueFormat[1]-'0';
}
break;
case 3: //D.y
if (tempValueFormat[1]=='.' && isDigit(tempValueFormat[2]))
{
y = (int)tempValueFormat[2]-'0';
}
break;
case 4: //Dx.y
if (isDigit(tempValueFormat[1]) && tempValueFormat[2]=='.' && isDigit(tempValueFormat[3]))
{
x = (int)tempValueFormat[1]-'0';
y = (int)tempValueFormat[3]-'0';
}
break;
case 1: //D
default: //any other combination x=0; y=0;
break;
}
value = toString(valFloat,y);
int indexDot;
indexDot = value.indexOf('.') > 0 ? value.indexOf('.') : value.length();
for (byte f = 0; f < (x - indexDot); f++)
value = "0" + value;
break;
}
case 'F' :// FLOOR (round down)
value = (int)floorf(valFloat);
break;
case 'E' :// CEILING (round up)
value = (int)ceilf(valFloat);
break;
default:
value = F("ERR");
break;
}
// Check Justification syntax
const int valueJustLength = valueJust.length();
if (valueJustLength > 0) //do the checks only if a Justification is defined to optimize loop
{
value.trim(); //remove right justification spaces for backward compatibility
switch (valueJust[0])
{
case 'P' :// Prefix Fill with n spaces: Pn
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check Pn where n is between 0 and 9
{
int filler = valueJust[1] - value.length() - '0' ; //char '0' = 48; char '9' = 58
for (byte f = 0; f < filler; f++)
newString += " ";
}
}
break;
case 'S' :// Suffix Fill with n spaces: Sn
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check Sn where n is between 0 and 9
{
int filler = valueJust[1] - value.length() - '0' ; //48
for (byte f = 0; f < filler; f++)
value += " ";
}
}
break;
case 'L': //left part of the string
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check n where n is between 0 and 9
{
value = value.substring(0,(int)valueJust[1]-'0');
}
}
break;
case 'R': //Right part of the string
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check n where n is between 0 and 9
{
value = value.substring(std::max(0,(int)value.length()-((int)valueJust[1]-'0')));
}
}
break;
case 'U': //Substring Ux.y where x=firstChar and y=number of characters
if (valueJustLength > 1)
{
if (isDigit(valueJust[1]) && valueJust[2]=='.' && isDigit(valueJust[3]) && valueJust[1] > '0' && valueJust[3] > '0')
{
value = value.substring(std::min((int)value.length(),(int)valueJust[1]-'0'-1),(int)valueJust[1]-'0'-1+(int)valueJust[3]-'0');
}
else
{
newString += F("ERR");
}
}
break;
default:
newString += F("ERR");
break;
}
}
}
if (rightJustify)
{
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
for (byte f = 0; f < filler; f++)
newString += " ";
}
{
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String logFormatted = F("DEBUG: Formatted String='");
logFormatted += newString;
logFormatted += value;
logFormatted += "'";
addLog(LOG_LEVEL_DEBUG, logFormatted);
}
}
}
}
//end of changes by giig1967g - 2018-04-18
newString += String(value);
{
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
String logParsed = F("DEBUG DEV: Parsed String='");
logParsed += newString;
logParsed += "'";
addLog(LOG_LEVEL_DEBUG_DEV, logParsed);
}
}
transformValue(newString, lineSize, value, valueFormat, tmpString);
break;
}
}
@@ -1685,6 +1546,245 @@ String parseTemplate(String &tmpString, byte lineSize)
return newString;
}
/********************************************************************************************\
Transform values
\*********************************************************************************************/
// Syntax: [task#value#transformation#justification]
// valueFormat="transformation#justification"
void transformValue(
String& newString,
byte lineSize,
String value,
String& valueFormat,
const String &tmpString)
{
checkRAM(F("transformValue"));
// start changes by giig1967g - 2018-04-20
// Syntax: [task#value#transformation#justification]
// valueFormat="transformation#justification"
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
{
String valueJust = "";
int hashtagIndex = valueFormat.indexOf('#');
if (hashtagIndex >= 0)
{
valueJust = valueFormat.substring(hashtagIndex + 1); //Justification part
valueFormat = valueFormat.substring(0, hashtagIndex); //Transformation part
}
// valueFormat="transformation"
// valueJust="justification"
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
{
const int val = value == "0" ? 0 : 1; //to be used for GPIO status (0 or 1)
const float valFloat = value.toFloat();
String tempValueFormat = valueFormat;
int tempValueFormatLength = tempValueFormat.length();
const int invertedIndex = tempValueFormat.indexOf('!');
const bool inverted = invertedIndex >= 0 ? 1 : 0;
if (inverted)
tempValueFormat.remove(invertedIndex,1);
const int rightJustifyIndex = tempValueFormat.indexOf('R');
const bool rightJustify = rightJustifyIndex >= 0 ? 1 : 0;
if (rightJustify)
tempValueFormat.remove(rightJustifyIndex,1);
tempValueFormatLength = tempValueFormat.length(); //needed because could have been changed after '!' and 'R' removal
//Check Transformation syntax
if (tempValueFormatLength > 0)
{
switch (tempValueFormat[0])
{
case 'V': //value = value without transformations
break;
case 'O':
value = val == inverted ? F("OFF") : F(" ON"); //(equivalent to XOR operator)
break;
case 'C':
value = val == inverted ? F("CLOSE") : F(" OPEN");
break;
case 'M':
value = val == inverted ? F("AUTO") : F(" MAN");
break;
case 'm':
value = val == inverted ? F("A") : F("M");
break;
case 'H':
value = val == inverted ? F("COLD") : F(" HOT");
break;
case 'U':
value = val == inverted ? F("DOWN") : F(" UP");
break;
case 'u':
value = val == inverted ? F("D") : F("U");
break;
case 'Y':
value = val == inverted ? F(" NO") : F("YES");
break;
case 'y':
value = val == inverted ? F("N") : F("Y");
break;
case 'X':
value = val == inverted ? F("O") : F("X");
break;
case 'I':
value = val == inverted ? F("OUT") : F(" IN");
break;
case 'Z' :// return "0" or "1"
value = val == inverted ? F("0") : F("1");
break;
case 'D' ://Dx.y min 'x' digits zero filled & 'y' decimal fixed digits
{
int x;
int y;
x = 0;
y = 0;
switch (tempValueFormatLength)
{
case 2: //Dx
if (isDigit(tempValueFormat[1]))
{
x = (int)tempValueFormat[1]-'0';
}
break;
case 3: //D.y
if (tempValueFormat[1]=='.' && isDigit(tempValueFormat[2]))
{
y = (int)tempValueFormat[2]-'0';
}
break;
case 4: //Dx.y
if (isDigit(tempValueFormat[1]) && tempValueFormat[2]=='.' && isDigit(tempValueFormat[3]))
{
x = (int)tempValueFormat[1]-'0';
y = (int)tempValueFormat[3]-'0';
}
break;
case 1: //D
default: //any other combination x=0; y=0;
break;
}
value = toString(valFloat,y);
int indexDot;
indexDot = value.indexOf('.') > 0 ? value.indexOf('.') : value.length();
for (byte f = 0; f < (x - indexDot); f++)
value = "0" + value;
break;
}
case 'F' :// FLOOR (round down)
value = (int)floorf(valFloat);
break;
case 'E' :// CEILING (round up)
value = (int)ceilf(valFloat);
break;
default:
value = F("ERR");
break;
}
// Check Justification syntax
const int valueJustLength = valueJust.length();
if (valueJustLength > 0) //do the checks only if a Justification is defined to optimize loop
{
value.trim(); //remove right justification spaces for backward compatibility
switch (valueJust[0])
{
case 'P' :// Prefix Fill with n spaces: Pn
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check Pn where n is between 0 and 9
{
int filler = valueJust[1] - value.length() - '0' ; //char '0' = 48; char '9' = 58
for (byte f = 0; f < filler; f++)
newString += " ";
}
}
break;
case 'S' :// Suffix Fill with n spaces: Sn
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check Sn where n is between 0 and 9
{
int filler = valueJust[1] - value.length() - '0' ; //48
for (byte f = 0; f < filler; f++)
value += " ";
}
}
break;
case 'L': //left part of the string
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check n where n is between 0 and 9
{
value = value.substring(0,(int)valueJust[1]-'0');
}
}
break;
case 'R': //Right part of the string
if (valueJustLength > 1)
{
if (isDigit(valueJust[1])) //Check n where n is between 0 and 9
{
value = value.substring(std::max(0,(int)value.length()-((int)valueJust[1]-'0')));
}
}
break;
case 'U': //Substring Ux.y where x=firstChar and y=number of characters
if (valueJustLength > 1)
{
if (isDigit(valueJust[1]) && valueJust[2]=='.' && isDigit(valueJust[3]) && valueJust[1] > '0' && valueJust[3] > '0')
{
value = value.substring(std::min((int)value.length(),(int)valueJust[1]-'0'-1),(int)valueJust[1]-'0'-1+(int)valueJust[3]-'0');
}
else
{
newString += F("ERR");
}
}
break;
default:
newString += F("ERR");
break;
}
}
}
if (rightJustify)
{
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
for (byte f = 0; f < filler; f++)
newString += " ";
}
{
if (loglevelActiveFor(LOG_LEVEL_DEBUG)) {
String logFormatted = F("DEBUG: Formatted String='");
logFormatted += newString;
logFormatted += value;
logFormatted += "'";
addLog(LOG_LEVEL_DEBUG, logFormatted);
}
}
}
}
//end of changes by giig1967g - 2018-04-18
newString += String(value);
{
if (loglevelActiveFor(LOG_LEVEL_DEBUG_DEV)) {
String logParsed = F("DEBUG DEV: Parsed String='");
logParsed += newString;
logParsed += "'";
addLog(LOG_LEVEL_DEBUG_DEV, logParsed);
}
}
checkRAM(F("transformValue2"));
}
/********************************************************************************************\
Calculate function for simple expressions
\*********************************************************************************************/
@@ -2905,12 +3005,16 @@ void checkRAM( const __FlashStringHelper* flashString)
myRamTracker.registerRamState(s);
uint32_t freeRAM = FreeMem();
if (freeRAM < lowestRAM)
{
lowestRAM = freeRAM;
lowestRAMfunction = flashString;
}
uint32_t freeStack = getFreeStackWatermark();
if (freeStack < lowestFreeStack) {
lowestFreeStack = freeStack;
lowestFreeStackfunction = flashString;
}
}
void checkRAM( String &a ) {
+20 -1
View File
@@ -875,6 +875,13 @@ void handle_root() {
TXBuffer += F(" - ");
TXBuffer += String(lowestRAMfunction);
TXBuffer += F(")");
html_TR_TD(); TXBuffer += F("Free Stack:<TD>");
TXBuffer += String(getCurrentFreeStack());
TXBuffer += F(" (");
TXBuffer += String(lowestFreeStack);
TXBuffer += F(" - ");
TXBuffer += String(lowestFreeStackfunction);
TXBuffer += F(")");
html_TR_TD(); TXBuffer += F("IP:<TD>");
TXBuffer += formatIP(ip);
@@ -1176,6 +1183,7 @@ void handle_controllers() {
const int maxqueuedepth = getFormItemInt(F("maxqueuedepth"), 10);
const int maxretry = getFormItemInt(F("maxretry"), 10);
String deleteoldest = WebServer.arg(F("deleteoldest"));
const int clienttimeout = getFormItemInt(F("clienttimeout"), CONTROLLER_CLIENTTIMEOUT_DFLT);
//submitted data
@@ -1194,7 +1202,8 @@ void handle_controllers() {
//reset (some) default-settings
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[controllerindex]);
ControllerSettings.Port = Protocol[ProtocolIndex].defaultPort;
ControllerSettings.MinimalTimeBetweenMessages = 100;
ControllerSettings.MinimalTimeBetweenMessages = CONTROLLER_DELAY_QUEUE_DELAY_DFLT;
ControllerSettings.ClientTimeout = CONTROLLER_CLIENTTIMEOUT_DFLT;
// ControllerSettings.MaxQueueDepth = 0;
if (Protocol[ProtocolIndex].usesTemplate)
CPlugin_ptr[ProtocolIndex](CPLUGIN_PROTOCOL_TEMPLATE, &TempEvent, dummyString);
@@ -1259,6 +1268,7 @@ void handle_controllers() {
ControllerSettings.MaxQueueDepth = maxqueuedepth;
ControllerSettings.MaxRetry = maxretry;
ControllerSettings.DeleteOldest = deleteoldest.toInt();
ControllerSettings.ClientTimeout = clienttimeout;
CPlugin_ptr[ProtocolIndex](CPLUGIN_INIT, &TempEvent, dummyString);
@@ -1366,6 +1376,8 @@ void handle_controllers() {
addFormNumericBox( F("Max Queue Depth"), F("maxqueuedepth"), ControllerSettings.MaxQueueDepth, 1, CONTROLLER_DELAY_QUEUE_DEPTH_MAX);
addFormNumericBox( F("Max Retries"), F("maxretry"), ControllerSettings.MaxRetry, 1, CONTROLLER_DELAY_QUEUE_RETRY_MAX);
addFormSelector(F("Full Queue Action"), F("deleteoldest"), 2, options_delete_oldest, NULL, NULL, choice_delete_oldest, true);
addFormNumericBox( F("Client Timeout"), F("clienttimeout"), ControllerSettings.ClientTimeout, 10, CONTROLLER_CLIENTTIMEOUT_MAX);
addUnit(F("ms"));
if (Protocol[ProtocolIndex].usesAccount)
@@ -5250,6 +5262,13 @@ void handle_sysinfo() {
TXBuffer += F(" - ");
TXBuffer += lowestRAMfunction;
TXBuffer += F(")");
html_TR_TD(); TXBuffer += F("Free Stack<TD>");
TXBuffer += getCurrentFreeStack();
TXBuffer += F(" (");
TXBuffer += lowestFreeStack;
TXBuffer += F(" - ");
TXBuffer += lowestFreeStackfunction;
TXBuffer += F(")");
html_TR_TD(); TXBuffer += F("Boot<TD>");
TXBuffer += getLastBootCauseString();
+7 -3
View File
@@ -382,7 +382,7 @@ bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned i
int c;
const unsigned long start = millis();
const unsigned long timer = start + timeout;
unsigned long backgroundtasks_timer = start + 100;
unsigned long backgroundtasks_timer = start + 10;
str = "";
do {
@@ -405,7 +405,7 @@ bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned i
}
// We must run the backgroundtasks every now and then.
if (timeOutReached(backgroundtasks_timer)) {
backgroundtasks_timer += 100;
backgroundtasks_timer += 10;
backgroundtasks();
} else {
yield();
@@ -584,6 +584,7 @@ bool count_connection_results(bool success, const String& prefix, int controller
}
bool try_connect_host(int controller_number, WiFiUDP& client, ControllerSettingsStruct& ControllerSettings) {
client.setTimeout(ControllerSettings.ClientTimeout);
log_connecting_to(F("UDP : "), controller_number, ControllerSettings);
bool success = ControllerSettings.beginPacket(client) != 0;
return count_connection_results(
@@ -593,6 +594,7 @@ bool try_connect_host(int controller_number, WiFiUDP& client, ControllerSettings
bool try_connect_host(int controller_number, WiFiClient& client, ControllerSettingsStruct& ControllerSettings) {
// Use WiFiClient class to create TCP connections
client.setTimeout(ControllerSettings.ClientTimeout);
log_connecting_to(F("HTTP : "), controller_number, ControllerSettings);
bool success = ControllerSettings.connectToHost(client);
return count_connection_results(
@@ -613,8 +615,10 @@ bool send_via_http(const String& logIdentifier, WiFiClient& client, const String
client.print(postStr);
unsigned long timer = millis() + 200;
while (!client.available() && !timeOutReached(timer))
while (!client.available()) {
if (timeOutReached(timer)) return false;
delay(1);
}
// Read all the lines of the reply from server and print them to Serial
while (client_available(client) && !success) {
+1
View File
@@ -73,6 +73,7 @@ boolean NPlugin_001_send(const NotificationSettingsStruct& notificationsettings,
// Use WiFiClient class to create TCP connections
WiFiClient client;
client.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT);
String aHost = notificationsettings.Server;
addLog(LOG_LEVEL_DEBUG, String(F("EMAIL: Connecting to ")) + aHost + notificationsettings.Port);
if (client.connect(aHost.c_str(), notificationsettings.Port) != 1) {
+4 -4
View File
@@ -90,7 +90,7 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
resolutionChoice = Plugin_004_DS_getResolution(savedAddress);
else
resolutionChoice = 9;
String resultsOptions[4] = { "9", "10", "11", "12" };
String resultsOptions[4] = { F("9"), F("10"), F("11"), F("12") };
int resultsOptionValues[4] = { 9, 10, 11, 12 };
addFormSelector(F("Device Resolution"), F("plugin_004_res"), 4, resultsOptions, resultsOptionValues, resolutionChoice);
addHtml(F(" Bit"));
@@ -105,7 +105,6 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
// save the address for selected device and store into extra tasksettings
Plugin_004_DallasPin = Settings.TaskDevicePin1[event->TaskIndex];
// byte devCount =
if (Plugin_004_DallasPin != -1){
Plugin_004_DS_scan(getFormItemInt(F("plugin_004_dev")), addr);
for (byte x = 0; x < 8; x++)
@@ -124,11 +123,12 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
{
if (x != 0)
string += "-";
// string += String(ExtraTaskSettings.TaskDevicePluginConfigLong[x], HEX);
string += String(ExtraTaskSettings.TaskDevicePluginConfigLong[x], HEX);
}
success = true;
break;
}
case PLUGIN_INIT:
{
Plugin_004_DallasPin = Settings.TaskDevicePin1[event->TaskIndex];
@@ -169,7 +169,7 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
for (byte x = 0; x < 8; x++)
{
if (x != 0)
log += "-";
log += '-';
log += String(ExtraTaskSettings.TaskDevicePluginConfigLong[x], HEX);
}
+142 -116
View File
@@ -9,6 +9,19 @@
#define PLUGIN_VALUENAME1_005 "Temperature"
#define PLUGIN_VALUENAME2_005 "Humidity"
#define P005_DHT11 11
#define P005_DHT12 12
#define P005_DHT22 22
#define P005_AM2301 23
#define P005_SI7021 70
#define P005_error_no_reading 1
#define P005_error_protocol_timeout 2
#define P005_error_checksum_error 3
#define P005_error_invalid_NAN_reading 4
#define P005_info_temperature 5
#define P005_info_humidity 6
uint8_t Plugin_005_DHT_Pin;
boolean Plugin_005(byte function, struct EventStruct *event, String& string)
@@ -49,7 +62,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
const String options[] = { F("DHT 11"), F("DHT 22"), F("DHT 12"), F("Sonoff am2301"), F("Sonoff si7021") };
int indices[] = { 11, 22, 12, 23, 70 };
int indices[] = { P005_DHT11, P005_DHT22, P005_DHT12, P005_AM2301, P005_SI7021 };
addFormSelector(F("DHT Type"), F("plugin_005_dhttype"), 5, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
@@ -67,92 +80,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
case PLUGIN_READ:
{
byte dht_dat[5];
byte i;
boolean error = false;
byte Par3 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
Plugin_005_DHT_Pin = Settings.TaskDevicePin1[event->TaskIndex];
pinMode(Plugin_005_DHT_Pin, OUTPUT);
digitalWrite(Plugin_005_DHT_Pin, LOW); // Pull low
if(Par3 == 11 || Par3 == 22 || Par3 == 12) delay(18);
else if (Par3 == 23 ) delayMicroseconds(900);
else if (Par3 == 70 ) delayMicroseconds(500);
pinMode(Plugin_005_DHT_Pin, INPUT); // change pin to input
delayMicroseconds(50);
error = waitState(0);
if(error)
{ logError(event, F("DHT : no Reading !"));
break;
}
error = waitState(1);
if(error)
{ logError(event, F("DHT : no Reading !"));
break;
}
noInterrupts();
error = waitState(0);
if(error)
{ logError(event, F("DHT : no Reading !"));
break;
}
for (i = 0; i < 5; i++)
{
byte data = Plugin_005_read_dht_dat();
if(data == -1)
{ logError(event, F("DHT : protocol timeout!"));
break;
}
dht_dat[i] = data;
}
interrupts();
// Checksum calculation is a Rollover Checksum by design!
byte dht_check_sum = (dht_dat[0] + dht_dat[1] + dht_dat[2] + dht_dat[3]) & 0xFF; // check check_sum
if (dht_dat[4] != dht_check_sum)
{
logError(event, F("DHT : checksum error!"));
break;
}
float temperature = NAN;
float humidity = NAN;
if (Par3 == 11)
{
temperature = float(dht_dat[2]); // Temperature
humidity = float(dht_dat[0]); // Humidity
}
else if (Par3 == 12)
{
temperature = float(dht_dat[2]*10 + (dht_dat[3] & 0x7f)) / 10.0; // Temperature
if (dht_dat[3] & 0x80) { temperature = -temperature; } // Negative temperature
humidity = float(dht_dat[0]*10+dht_dat[1]) / 10.0; // Humidity
}
else if (Par3 == 22 || Par3 == 23 || Par3 == 70)
{
if (dht_dat[2] & 0x80) // negative temperature
temperature = -0.1 * word(dht_dat[2] & 0x7F, dht_dat[3]);
else
temperature = 0.1 * word(dht_dat[2], dht_dat[3]);
humidity = 0.1 * word(dht_dat[0], dht_dat[1]); // Humidity
}
if (temperature == NAN || humidity == NAN)
{ logError(event, F("DHT : invalid NAN reading !"));
break;
}
UserVar[event->BaseVarIndex] = temperature;
UserVar[event->BaseVarIndex + 1] = humidity;
String log = F("DHT : Temperature: ");
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO, log);
log = F("DHT : Humidity: ");
log += UserVar[event->BaseVarIndex + 1];
addLog(LOG_LEVEL_INFO, log);
success = true;
success = P005_do_plugin_read(event);
break;
}
}
@@ -163,28 +91,144 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
/*********************************************************************************************\
* DHT sub to log an error
\*********************************************************************************************/
void logError(struct EventStruct *event, String text)
void P005_log(struct EventStruct *event, int logNr)
{
bool isError = true;
String text = F("DHT : ");
switch (logNr) {
case P005_error_no_reading: text += F("No Reading"); break;
case P005_error_protocol_timeout: text += F("Protocol Timeout"); break;
case P005_error_checksum_error: text += F("Checksum Error"); break;
case P005_error_invalid_NAN_reading: text += F("Invalid NAN reading"); break;
case P005_info_temperature:
text += F("Temperature: ");
text += UserVar[event->BaseVarIndex];
isError = false;
break;
case P005_info_humidity:
text += F("Humidity: ");
text += UserVar[event->BaseVarIndex + 1];
isError = false;
break;
}
addLog(LOG_LEVEL_INFO, text);
UserVar[event->BaseVarIndex] = NAN;
UserVar[event->BaseVarIndex + 1] = NAN;
if (isError) {
UserVar[event->BaseVarIndex] = NAN;
UserVar[event->BaseVarIndex + 1] = NAN;
}
}
/*********************************************************************************************\
* DHT sub to wait until a pin is in a certiin state
* DHT sub to wait until a pin is in a certain state
\*********************************************************************************************/
boolean waitState(int state)
boolean P005_waitState(int state)
{
byte counter = 0;
while (( digitalRead(Plugin_005_DHT_Pin) != state) && (counter < 100))
unsigned long timeout = micros() + 100;
while (digitalRead(Plugin_005_DHT_Pin) != state)
{
if (usecTimeOutReached(timeout)) return false;
delayMicroseconds(1);
counter++;
}
if( counter < 100) return false;
return true;
}
/*********************************************************************************************\
* Perform the actual reading + interpreting of data.
\*********************************************************************************************/
bool P005_do_plugin_read(struct EventStruct *event) {
byte i;
byte Par3 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
Plugin_005_DHT_Pin = Settings.TaskDevicePin1[event->TaskIndex];
pinMode(Plugin_005_DHT_Pin, OUTPUT);
digitalWrite(Plugin_005_DHT_Pin, LOW); // Pull low
switch (Par3) {
case P005_DHT11:
case P005_DHT22:
case P005_DHT12: delay(18); break; // FIXME TD-er: Must this be so long?
case P005_AM2301: delayMicroseconds(900); break;
case P005_SI7021: delayMicroseconds(500); break;
}
switch (Par3) {
case P005_DHT11:
case P005_DHT22:
case P005_DHT12:
case P005_AM2301:
pinMode(Plugin_005_DHT_Pin, INPUT);
delayMicroseconds(50);
break;
case P005_SI7021:
// See: https://github.com/letscontrolit/ESPEasy/issues/1798
digitalWrite(Plugin_005_DHT_Pin, HIGH);
delayMicroseconds(20);
pinMode(Plugin_005_DHT_Pin, INPUT);
break;
}
if(!P005_waitState(0)) {P005_log(event, P005_error_no_reading); return false; }
if(!P005_waitState(1)) {P005_log(event, P005_error_no_reading); return false; }
noInterrupts();
if(!P005_waitState(0)) {P005_log(event, P005_error_no_reading); return false; }
bool readingAborted = false;
byte dht_dat[5];
for (i = 0; i < 5 && !readingAborted; i++)
{
byte data = Plugin_005_read_dht_dat();
if(data == -1)
{ P005_log(event, P005_error_protocol_timeout);
readingAborted = true;
}
dht_dat[i] = data;
}
interrupts();
if (readingAborted)
return false;
// Checksum calculation is a Rollover Checksum by design!
byte dht_check_sum = (dht_dat[0] + dht_dat[1] + dht_dat[2] + dht_dat[3]) & 0xFF; // check check_sum
if (dht_dat[4] != dht_check_sum)
{
P005_log(event, P005_error_checksum_error);
return false;
}
float temperature = NAN;
float humidity = NAN;
switch (Par3) {
case P005_DHT11:
temperature = float(dht_dat[2]); // Temperature
humidity = float(dht_dat[0]); // Humidity
break;
case P005_DHT12:
temperature = float(dht_dat[2]*10 + (dht_dat[3] & 0x7f)) / 10.0; // Temperature
if (dht_dat[3] & 0x80) { temperature = -temperature; } // Negative temperature
humidity = float(dht_dat[0]*10+dht_dat[1]) / 10.0; // Humidity
break;
case P005_DHT22:
case P005_AM2301:
case P005_SI7021:
if (dht_dat[2] & 0x80) // negative temperature
temperature = -0.1 * word(dht_dat[2] & 0x7F, dht_dat[3]);
else
temperature = 0.1 * word(dht_dat[2], dht_dat[3]);
humidity = 0.1 * word(dht_dat[0], dht_dat[1]); // Humidity
break;
}
if (temperature == NAN || humidity == NAN)
{ P005_log(event, P005_error_invalid_NAN_reading);
return false;
}
UserVar[event->BaseVarIndex] = temperature;
UserVar[event->BaseVarIndex + 1] = humidity;
P005_log(event, P005_info_temperature);
P005_log(event, P005_info_humidity);
return true;
}
/*********************************************************************************************\
* DHT sub to get an 8 bit value from the receiving bitstream
\*********************************************************************************************/
@@ -192,31 +236,13 @@ int Plugin_005_read_dht_dat(void)
{
byte i = 0;
byte result = 0;
byte counter = 0;
for (i = 0; i < 8; i++)
{
while ((!digitalRead(Plugin_005_DHT_Pin)) && (counter < 100))
{
delayMicroseconds(1);
counter++;
}
if (counter >= 100)
{
return -1;
}
if (!P005_waitState(1)) return -1;
delayMicroseconds(35); // was 30
if (digitalRead(Plugin_005_DHT_Pin))
result |= (1 << (7 - i));
counter = 0;
while ((digitalRead(Plugin_005_DHT_Pin)) && (counter < 100))
{
delayMicroseconds(1);
counter++;
}
if (counter >= 100)
{
return -1;
}
if (!P005_waitState(0)) return -1;
}
return result;
}
+199 -58
View File
@@ -12,27 +12,21 @@
#include <map>
#include <NewPingESP8266.h>
struct P_013_sensordef {
P_013_sensordef() : sonar(NULL) {}
P_013_sensordef(byte TRIG_Pin, byte IRQ_Pin, int16_t max_cm_distance) : sonar(NULL) {
sonar = new NewPingESP8266(TRIG_Pin, IRQ_Pin, max_cm_distance);
}
~P_013_sensordef() {
if (sonar != NULL) {
delete sonar;
sonar = NULL;
}
}
NewPingESP8266 *sonar;
};
std::map<unsigned int, P_013_sensordef> P_013_sensordefs;
// PlugIn specific defines
// operatingMode
#define OPMODE_VALUE (0)
#define OPMODE_STATE (1)
// measuringUnit
#define UNIT_CM (0)
#define UNIT_INCH (1)
// filterType
#define FILTER_NONE (0)
#define FILTER_MEDIAN (1)
// map of sensors
std::map<unsigned int, std::shared_ptr<NewPingESP8266> > P_013_sensordefs;
boolean Plugin_013(byte function, struct EventStruct *event, String& string)
{
@@ -54,6 +48,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
break;
}
@@ -72,19 +67,51 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
options[0] = F("Value");
options[1] = F("State");
int optionValues[2] = { 1, 2 };
addFormSelector(F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
int16_t operatingMode = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int16_t threshold = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
int16_t max_distance = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
int16_t measuringUnit = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
int16_t filterType = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
int16_t filterSize = Settings.TaskDevicePluginConfig[event->TaskIndex][5];
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
addFormNumericBox(F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
// default filtersize = 5
if (filterSize == 0) {
filterSize = 5;
Settings.TaskDevicePluginConfig[event->TaskIndex][5] = filterSize;
}
addFormNumericBox(F("Max Distance"), F("plugin_013_max_distance"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 500);
addUnit(F("cm"));
String strUnit = (measuringUnit == UNIT_CM) ? F("cm") : F("inch");
String optionsOpMode[2];
int optionValuesOpMode[2] = { 0, 1 };
optionsOpMode[0] = F("Value");
optionsOpMode[1] = F("State");
addFormSelector(F("Mode"), F("plugin_013_mode"), 2, optionsOpMode, optionValuesOpMode, operatingMode);
if (operatingMode == OPMODE_STATE)
{
addFormNumericBox(F("Threshold"), F("plugin_013_threshold"), threshold);
addUnit(strUnit);
}
addFormNumericBox(F("Max Distance"), F("plugin_013_max_distance"), max_distance, 0, 500);
addUnit(strUnit);
String optionsUnit[2];
int optionValuesUnit[2] = { 0, 1 };
optionsUnit[0] = F("Metric");
optionsUnit[1] = F("Imperial");
addFormSelector(F("Unit"), F("plugin_013_Unit"), 2, optionsUnit, optionValuesUnit, measuringUnit);
String optionsFilter[2];
int optionValuesFilter[2] = { 0, 1 };
optionsFilter[0] = F("None");
optionsFilter[1] = F("Median");
addFormSelector(F("Filter"), F("plugin_013_FilterType"), 2, optionsFilter, optionValuesFilter, filterType);
// enable filtersize option if filter is used,
if (filterType != FILTER_NONE)
addFormNumericBox(F("Filter size"), F("plugin_013_FilterSize"), filterSize, 2, 20);
success = true;
break;
@@ -92,33 +119,60 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_SAVE:
{
int16_t operatingMode = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int16_t filterType = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_013_mode"));
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
if (operatingMode == OPMODE_STATE)
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_013_threshold"));
}
Settings.TaskDevicePluginConfig[event->TaskIndex][2] = getFormItemInt(F("plugin_013_max_distance"));
Settings.TaskDevicePluginConfig[event->TaskIndex][3] = getFormItemInt(F("plugin_013_Unit"));
Settings.TaskDevicePluginConfig[event->TaskIndex][4] = getFormItemInt(F("plugin_013_FilterType"));
if (filterType != FILTER_NONE)
Settings.TaskDevicePluginConfig[event->TaskIndex][5] = getFormItemInt(F("plugin_013_FilterSize"));
success = true;
break;
}
case PLUGIN_INIT:
{
byte Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
byte Plugin_013_IRQ_Pin = Settings.TaskDevicePin2[event->TaskIndex];
int16_t max_cm_distance = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
int16_t max_distance = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
int16_t measuringUnit = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
int16_t filterType = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
int16_t filterSize = Settings.TaskDevicePluginConfig[event->TaskIndex][5];
int8_t Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
int8_t Plugin_013_IRQ_Pin = Settings.TaskDevicePin2[event->TaskIndex];
int16_t max_distance_cm = (measuringUnit == UNIT_CM) ? max_distance : (float)max_distance * 2.54f;
// create sensor instance and add to std::map
P_013_sensordefs.erase(event->TaskIndex);
P_013_sensordefs[event->TaskIndex] =
P_013_sensordef(Plugin_013_TRIG_Pin, Plugin_013_IRQ_Pin, max_cm_distance);
std::shared_ptr<NewPingESP8266> (new NewPingESP8266(Plugin_013_TRIG_Pin, Plugin_013_IRQ_Pin, max_distance_cm));
String log = F("ULTRASONIC : TaskNr: ");
log += event->TaskIndex +1;
log += F(" TrigPin: ");
log += Plugin_013_TRIG_Pin;
log += F(" IRQ_Pin: ");
log += Plugin_013_IRQ_Pin;
log += F(" max dist cm: ");
log += max_cm_distance;
log += F(" max dist ");
log += (measuringUnit == UNIT_CM) ? F("[cm]: ") : F("[inch]: ");
log += max_distance;
log += F(" max echo: ");
log += P_013_sensordefs[event->TaskIndex].sonar->getMaxEchoTime();
log += P_013_sensordefs[event->TaskIndex]->getMaxEchoTime();
log += F(" Filter: ");
if (filterType == FILTER_NONE)
log += F("none");
else
if (filterType == FILTER_MEDIAN) {
log += F("Median size: ");
log += filterSize;
}
else
log += F("invalid!");
log += F(" nr_tasks: ");
log += P_013_sensordefs.size();
addLog(LOG_LEVEL_INFO, log);
@@ -136,7 +190,6 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
log += F(" usec, ");
addLog(LOG_LEVEL_INFO, log);
success = true;
break;
}
@@ -149,39 +202,48 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
case PLUGIN_READ: // If we select value mode, read and send the value based on global timer
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 1)
int16_t operatingMode = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int16_t measuringUnit = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
if (operatingMode == OPMODE_VALUE)
{
float value = Plugin_013_read(event->TaskIndex);
String log = F("ULTRASONIC : TaskNr: ");
log += event->TaskIndex +1;
log += F(" Distance: ");
if (value > 0)
UserVar[event->BaseVarIndex] = value;
log += UserVar[event->BaseVarIndex];
log += (measuringUnit == UNIT_CM) ? F(" cm ") : F(" inch ");
if (value == NO_ECHO)
{
UserVar[event->BaseVarIndex] = value;
log += UserVar[event->BaseVarIndex];
success = true;
log += F(" Error: ");
log += Plugin_013_getErrorStatusString(event->TaskIndex);
}
else
log += F("No reading!");
addLog(LOG_LEVEL_INFO,log);
addLog(LOG_LEVEL_INFO,log);
}
success = true;
break;
}
case PLUGIN_TEN_PER_SECOND: // If we select state mode, do more frequent checks and send only state changes
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
int16_t operatingMode = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int16_t threshold = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
if (operatingMode == OPMODE_STATE)
{
byte state = 0;
float value = Plugin_013_read(event->TaskIndex);
if (value > 0)
if (value != NO_ECHO)
{
if (value < Settings.TaskDevicePluginConfig[event->TaskIndex][1])
if (value < threshold)
state = 1;
if (state != switchstate[event->TaskIndex])
{
String log = F("ULTRASONIC : State ");
String log = F("ULTRASONIC : TaskNr: ");
log += event->TaskIndex +1;
log += F(" state: ");
log += state;
addLog(LOG_LEVEL_INFO,log);
switchstate[event->TaskIndex] = state;
@@ -190,6 +252,14 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
sendData(event);
}
}
else {
String log = F("ULTRASONIC : TaskNr: ");
log += event->TaskIndex +1;
log += F(" Error: ");
log += Plugin_013_getErrorStatusString(event->TaskIndex);
addLog(LOG_LEVEL_INFO,log);
}
}
success = true;
break;
@@ -202,11 +272,82 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
float Plugin_013_read(unsigned int taskIndex)
/*********************************************************************/
{
if (P_013_sensordefs.count(taskIndex) == 0) return 0;
if (P_013_sensordefs[taskIndex].sonar == NULL) return 0;
delay(1);
float distance = P_013_sensordefs[taskIndex].sonar->ping_cm();
delay(1);
return distance;
if (P_013_sensordefs.count(taskIndex) == 0)
return 0;
int16_t max_distance = Settings.TaskDevicePluginConfig[taskIndex][2];
int16_t measuringUnit = Settings.TaskDevicePluginConfig[taskIndex][3];
int16_t filterType = Settings.TaskDevicePluginConfig[taskIndex][4];
int16_t filterSize = Settings.TaskDevicePluginConfig[taskIndex][5];
int16_t max_distance_cm = (measuringUnit == UNIT_CM) ? max_distance : (float)max_distance * 2.54f;
unsigned int echoTime = 0;
switch (filterType) {
case FILTER_NONE:
echoTime = (P_013_sensordefs[taskIndex])->ping();
break;
case FILTER_MEDIAN:
echoTime = (P_013_sensordefs[taskIndex])->ping_median(filterSize, max_distance_cm);
break;
default:
addLog(LOG_LEVEL_INFO, F("invalid Filter Type setting!"));
}
if (measuringUnit == UNIT_CM)
return NewPingESP8266::convert_cm_F(echoTime);
else
return NewPingESP8266::convert_in_F(echoTime);
}
/*********************************************************************/
String Plugin_013_getErrorStatusString(unsigned int taskIndex)
/*********************************************************************/
{
if (P_013_sensordefs.count(taskIndex) == 0)
return String(F("invalid taskindex"));
switch ((P_013_sensordefs[taskIndex])->getErrorState()) {
case NewPingESP8266::STATUS_SENSOR_READY: {
return String(F("Sensor ready"));
break;
}
case NewPingESP8266::STATUS_MEASUREMENT_VALID: {
return String(F("no error, measurement valid"));
break;
}
case NewPingESP8266::STATUS_ECHO_TRIGGERED: {
return String(F("Echo triggered, waiting for Echo end"));
break;
}
case NewPingESP8266::STATUS_ECHO_STATE_ERROR: {
return String(F("Echo pulse error, Echopin not low on trigger"));
break;
}
case NewPingESP8266::STATUS_ECHO_START_TIMEOUT_50ms: {
return String(F("Echo timeout error, no echo start whithin 50 ms"));
break;
}
case NewPingESP8266::STATUS_ECHO_START_TIMEOUT_DISTANCE: {
return String(F("Echo timeout error, no echo start whithin time for max. distance"));
break;
}
case NewPingESP8266::STATUS_MAX_DISTANCE_EXCEEDED: {
return String(F("Echo too late, maximum distance exceeded"));
break;
}
default: {
return String(F("unknown error"));
break;
}
}
}
#endif // USES_P013
+3
View File
@@ -41,6 +41,9 @@ decode_results results;
#define PLUGIN_NAME_016 "Communication - TSOP4838"
#define PLUGIN_VALUENAME1_016 "IR"
// A lot of the following code has been taken directly (with permission) from the IRrecvDumpV2.ino example code
// of the IRremoteESP8266 library. (https://github.com/markszabo/IRremoteESP8266)
// ==================== start of TUNEABLE PARAMETERS ====================
// As this program is a special purpose capture/decoder, let us use a larger
// than normal buffer so we can handle Air Conditioner remote codes.
+3 -1
View File
@@ -274,6 +274,8 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
return success;
}
// A lot of the following code has been taken directly (with permission) from the IRMQTTServer.ino example code
// of the IRremoteESP8266 library. (https://github.com/markszabo/IRremoteESP8266)
// Parse an Air Conditioner A/C Hex String/code and send it.
// Args:
@@ -615,4 +617,4 @@ uint16_t countValuesInStr(const String str, char sep) {
// }
// return result;
//}
#endif // USES_P035
#endif // USES_P035
+2
View File
@@ -41,6 +41,7 @@ void Plugin_037_try_connect() {
if (MQTTclient_037_connected) return;
// workaround see: https://github.com/esp8266/Arduino/issues/4497#issuecomment-373023864
espclient_037 = WiFiClient();
espclient_037.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT);
if (MQTTclient_037 == NULL) {
MQTTclient_037 = new PubSubClient(espclient_037);
@@ -69,6 +70,7 @@ void Plugin_037_update_connect_status() {
if (!connected) {
// workaround see: https://github.com/esp8266/Arduino/issues/4497#issuecomment-373023864
espclient_037 = WiFiClient();
espclient_037.setTimeout(CONTROLLER_CLIENTTIMEOUT_DFLT);
++reconnectCount;
addLog(LOG_LEVEL_ERROR, F("IMPT : MQTT 037 Connection lost"));
}
+84 -42
View File
@@ -3,10 +3,15 @@
//################################### Plugin 075: Nextion <info@sensorio.cz> ###########################
//################################### Created on the work of majklovec ###########################
//################################### Revisions by BertB and ThomasB ###########################
//################################### Last Revision: Aug-03-2018 (TB) ###########################
//################################### Last Revision: Oct-03-2018 (TB) ###########################
//#######################################################################################################
//
// Updated: Aug-03-2018, ThomasB.
// Updated: Oct-03-2018, ThomasB.
// Added DEBUG_LOG define to reduce info log messages and prevent serial log flooding.
// Added SendStatus() to post log message on browser to acknowledge HTTP write.
// Added reserve() to minimize string memory allocations.
//
// Aug-03-2018 change log summary:
// This updated Nextion Plugin introduces hardware (UART) serial as an alternative to SoftSerial.
// Hardware serial offers more reliable communication with the Nextion display.
// Created on the experimental Serial.swap() work of BertB.
@@ -19,6 +24,9 @@
// Defines start here
// *****************************************************************************************************
//#define DEBUG_LOG // Enable this to include additional info messages in log output.
// Plug-In defines
#define PLUGIN_075
#define PLUGIN_ID_075 75
@@ -241,7 +249,9 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
SoftSerial = NULL;
}
String log = F("NEXTION075 : serial pin config RX:");
String log;
log.reserve(80); // Prevent re-allocation
log = F("NEXTION075 : serial pin config RX:");
log += rxPin;
log += F(", TX:");
log += txPin;
@@ -313,6 +323,7 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
RssiIndex = UcTmpString.indexOf(F("RSSIBAR")); // RSSI bargraph Keyword found, wifi value in dBm.
if(RssiIndex >= 0) {
int barVal;
newString.reserve(Lenlines+10); // Prevent re-allocation
newString = tmpString.substring(0, RssiIndex);
int nbars = WiFi.RSSI();
if (nbars < -100 || nbars >= 0)
@@ -345,31 +356,38 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
}
sendCommand(newString.c_str(), HwSerial);
String log = F("NEXTION075 : Cmd Statement Line-");
log += String(x+1);
log += F(" Sent: ");
log += newString;
addLog(LOG_LEVEL_INFO, log);
#ifdef DEBUG_LOG
String log;
log.reserve(Lenlines+50); // Prevent re-allocation
log = F("NEXTION075 : Cmd Statement Line-");
log += String(x+1);
log += F(" Sent: ");
log += newString;
addLog(LOG_LEVEL_INFO, log);
#endif
}
}
// At Interval timer, send idx & value data only if user enabled "values" interval mode.
if(IncludeValues) {
/*
String log = F("NEXTION075: Interval values data enabled, resending idx=");
log += String(UserVar[event->BaseVarIndex]);
log += F(", value=");
log += String(UserVar[event->BaseVarIndex+1]);
addLog(LOG_LEVEL_INFO, log);
*/
#ifdef DEBUG_LOG
String log;
log.reserve(120); // Prevent re-allocation
log = F("NEXTION075: Interval values data enabled, resending idx=");
log += String(UserVar[event->BaseVarIndex]);
log += F(", value=");
log += String(UserVar[event->BaseVarIndex+1]);
addLog(LOG_LEVEL_INFO, log);
#endif
success = true;
}
else {
/*
String log = F("NEXTION075: Interval values data disabled, idx & value not resent");
addLog(LOG_LEVEL_INFO, log);
*/
#ifdef DEBUG_LOG
String log = F("NEXTION075: Interval values data disabled, idx & value not resent");
addLog(LOG_LEVEL_INFO, log);
#endif
success = false;
}
@@ -386,6 +404,8 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
// Enable addLog() code below to help debug plugin write problems.
/*
String log;
log.reserve(140); // Prevent re-allocation
String log = F("Nextion arg0: ");
log += tmpString;
log += F(", TaskDeviceName: ");
@@ -401,11 +421,14 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
tmpString = string.substring(argIndex + 1);
sendCommand(tmpString.c_str(), HwSerial);
String log = F("NEXTION075 : WRITE, ");
log += F("Command is ");
log += (tmpString.c_str());
addLog(LOG_LEVEL_INFO, log);
String log;
log.reserve(110); // Prevent re-allocation
log = F("NEXTION075 : WRITE = ");
log += tmpString;
#ifdef DEBUG_LOG
addLog(LOG_LEVEL_INFO, log);
#endif
SendStatus(event->Source, log); // Reply (echo) to sender. This will print message on browser.
success = true; // Set true only if plugin found a command to execute.
}
break;
@@ -439,7 +462,6 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
uint16_t i;
uint8_t c;
uint8_t charCount;
String log;
String Vidx;
String Nvalue;
String Svalue;
@@ -447,7 +469,7 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
char __buffer[RXBUFFSZ+1]; // Staging buffer.
if(rxPin < 0) {
String log = F("NEXTION075 : Missing RxD Pin Number, aborted serial receive");
String log = F("NEXTION075 : Missing RxD Pin, aborted serial receive");
addLog(LOG_LEVEL_INFO, log);
break;
}
@@ -455,6 +477,8 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
if(HwSerial == UARTSERIAL) {
charCount = Serial.available(); // Prime the Hardware Serial engine.
if(charCount >= RXBUFFWARN) { // ESP8266 has 128 byte circular Rx buffer.
String log;
log.reserve(70); // Prevent re-allocation
log = F("NEXTION075 : RxD UART Buffer capacity warning,");
log += String(charCount);
log += F(" bytes");
@@ -465,6 +489,8 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
if(SoftSerial == NULL) break; // SoftSerial missing, exit.
charCount = SoftSerial->available(); // Prime the Soft Serial engine.
if(charCount >= RXBUFFWARN) {
String log;
log.reserve(70); // Prevent re-allocation
log = F("NEXTION075 : RxD SoftSerial Buffer capacity warning, ");
log += String(charCount);
log += F(" bytes");
@@ -495,13 +521,17 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
UserVar[event->BaseVarIndex + 1] = __buffer[3];
sendData(event);
log = F("NEXTION075 : code: ");
log += __buffer[1];
log += ",";
log += __buffer[2];
log += ",";
log += __buffer[3];
addLog(LOG_LEVEL_INFO, log);
#ifdef DEBUG_LOG
String log;
log.reserve(70); // Prevent re-allocation
log = F("NEXTION075 : code: ");
log += __buffer[1];
log += ",";
log += __buffer[2];
log += ",";
log += __buffer[3];
addLog(LOG_LEVEL_INFO, log);
#endif
}
}
}
@@ -534,9 +564,14 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
__buffer[i] = 0x00;
String tmpString = __buffer;
log = F("NEXTION075 : code: ");
log += tmpString;
addLog(LOG_LEVEL_INFO, log);
#ifdef DEBUG_LOG
String log;
log.reserve(50); // Prevent re-allocation
log = F("NEXTION075 : Code = ");
log += tmpString;
addLog(LOG_LEVEL_INFO, log);
#endif
int argIndex = tmpString.indexOf(F(",i"));
int argEnd = tmpString.indexOf(',', argIndex + 1);
@@ -568,14 +603,21 @@ boolean Plugin_075(byte function, struct EventStruct *event, String& string)
UserVar[event->BaseVarIndex+1] = Svalue.toFloat();
sendData(event);
log = F("NEXTION075 : Pipe Command Sent: ");
log += __buffer;
log += UserVar[event->BaseVarIndex];
#ifdef DEBUG_LOG
String log;
log.reserve(80); // Prevent re-allocation
log = F("NEXTION075 : Pipe Command Sent: ");
log += __buffer;
log += UserVar[event->BaseVarIndex];
addLog(LOG_LEVEL_INFO, log);
#endif
}
else {
log = F("NEXTION075 : Unknown Pipe Command, skipped");
#ifdef DEBUG_LOG
String log = F("NEXTION075 : Unknown Pipe Command, skipped");
addLog(LOG_LEVEL_INFO, log);
#endif
}
addLog(LOG_LEVEL_INFO, log);
}
}
if(HwSerial == UARTSERIAL) charCount = Serial.available();