Compare commits

...
Author SHA1 Message Date
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
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
10 changed files with 625 additions and 396 deletions
+47
View File
@@ -1,3 +1,50 @@
-------------------------------------------------
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
+27 -19
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.
; CONT_STACKSIZE to set the 'cont' (Arduino) stack size. Default = 4096
[common]
board_build.f_cpu = 80000000L
@@ -123,15 +129,17 @@ board = esp12e
platform = ${core_2_4_2.platform}
monitor_speed = 115200
[normal]
platform = ${common.platform}
build_flags = -DNO_EXTRA_4K_HEAP -DCONT_STACKSIZE=5120
[testing]
platform = ${core_2_4_2.platform}
build_flags = -DNO_EXTRA_4K_HEAP -DPLUGIN_BUILD_TESTING
[dev]
platform = ${core_2_4_2.platform}
build_flags = -DNO_EXTRA_4K_HEAP -DPLUGIN_BUILD_DEV
[ir]
lib_ignore = ESP32_ping, ESP32WebServer
@@ -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
+37 -9
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?
@@ -411,6 +414,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 +690,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 +738,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 +761,7 @@ struct SettingsStruct
for (byte task = 0; task < TASKS_MAX; ++task) {
clearTask(task);
}
clearNetworkSettings();
}
void clearTask(byte task) {
@@ -862,10 +883,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
@@ -1401,6 +1423,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 +1470,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 +1479,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 +1633,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 ) {
+14
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);
@@ -5250,6 +5257,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();
+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;
}
+8 -25
View File
@@ -10,29 +10,11 @@
#include <Arduino.h>
#include <map>
//#include <shared_ptr>
#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;
// map of sensors
std::map<unsigned int, std::shared_ptr<NewPingESP8266> > P_013_sensordefs;
boolean Plugin_013(byte function, struct EventStruct *event, String& string)
{
@@ -82,6 +64,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
addFormNumericBox(F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(F("cm"));
}
addFormNumericBox(F("Max Distance"), F("plugin_013_max_distance"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 500);
addUnit(F("cm"));
@@ -107,8 +90,9 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
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];
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_cm_distance));
String log = F("ULTRASONIC : TaskNr: ");
log += event->TaskIndex +1;
log += F(" TrigPin: ");
@@ -118,7 +102,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
log += F(" max dist cm: ");
log += max_cm_distance;
log += F(" max echo: ");
log += P_013_sensordefs[event->TaskIndex].sonar->getMaxEchoTime();
log += P_013_sensordefs[event->TaskIndex]->getMaxEchoTime();
log += F(" nr_tasks: ");
log += P_013_sensordefs.size();
addLog(LOG_LEVEL_INFO, log);
@@ -203,9 +187,8 @@ 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();
float distance = (P_013_sensordefs[taskIndex])->ping_cm();
delay(1);
return distance;
}