When the timer is quickly changed by pressing the “+” or “-” button (or with inactivity for 30 minutes or more), it reboots with an error in Serial.
For more than a week I have been looking for a reason, I failed.
I ask for help to figure it out.
ESP8266 and WiFi.
My ver.: Arduino 1.8.13; Blynk 0.6.1; Ethernet 2.0.0;
A snippet of code for the test
#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp8266.h>
#include <ESP8266WiFi.h>
#include <SoftwareSerial.h>
#include <SimpleTimer.h>
SimpleTimer timer;
char auth[] = "key";
char ssid[] = "ssid";
char pass[] = "pass";
IPAddress device_ip (10, 0, 1, 8);
IPAddress gateway_ip (10, 0, 1, 1);
IPAddress subnet_mask(255, 255, 255, 0);
#define vPIN_TIMER_SET V18
#define vPIN_TIMER_OUT V19
#define vPIN_TIMER_RST_PWR V20
#define PERIOD 1000
bool flag = 0;
uint16_t timeHour, timeMin, timeSec, timeDay, cHour, cMin, cSec;
uint32_t count_time, countSec, count_p = 66;
String hhmmss, ddhhmmss;
void setup() {
Serial.begin(115200); delay(25); Serial.println();
WiFi.config(device_ip, gateway_ip, subnet_mask);
WiFi.begin(ssid, pass);
Blynk.config(auth, "139.59.206.133", 80);
timer.setInterval(1000L, timerRUN);
}
BLYNK_CONNECTED()
{
Blynk.syncAll();
}
BLYNK_WRITE(vPIN_TIMER_SET) {
count_p = param.asInt() * 60;
cHour = count_p / 3600ul;
cMin = (count_p % 3600ul) / 60ul;
cSec = count_p % 60ul;
hhmmss = "";
if (cHour > 0) {
if (cHour > 9) hhmmss = hhmmss + cHour + ':';
else hhmmss = hhmmss + '0' + cHour + ':';
}
if (cMin > 0 || cHour > 0) {
if (cMin > 9) hhmmss = hhmmss + cMin + ':';
else hhmmss = hhmmss + '0' + cMin + ':';
}
if (cSec > 9) hhmmss = hhmmss + cSec; else hhmmss = hhmmss + '0' + cSec;
Blynk.virtualWrite(vPIN_TIMER_OUT, hhmmss);
Serial.print("\n=Timer: "); Serial.println(hhmmss);
}
void timerRUN() {
countSec = count_time / 1000;
timeDay = (countSec / 3600ul) / 24ul;
timeHour = (countSec / 3600ul) % 24;
timeMin = (countSec % 3600ul) / 60ul;
timeSec = countSec % 60ul;
ddhhmmss = "";
if (timeDay > 0) ddhhmmss = ddhhmmss + timeDay + "d ";
if (timeHour > 0 || timeDay > 0) {
if (timeHour > 9) ddhhmmss = ddhhmmss + timeHour + ':'; else ddhhmmss = ddhhmmss + '0' + timeHour + ':';
}
if (timeMin > 0 || timeHour > 0 || timeDay > 0) {
if (timeMin > 9) ddhhmmss = ddhhmmss + timeMin + ':'; else ddhhmmss = ddhhmmss + '0' + timeMin + ':';
}
if (timeSec > 9) ddhhmmss = ddhhmmss + timeSec; else ddhhmmss = ddhhmmss + '0' + timeSec;
Blynk.virtualWrite(vPIN_TIMER_RST_PWR, ddhhmmss);
Serial.print("\nTime: "); Serial.print(ddhhmmss);
// flag = 0; // Removes the error why???
if (flag == 1) { // Conditions are simplified for example, should be triggered under several conditions by &&
cHour = count_p / 3600ul;
cMin = (count_p % 3600ul) / 60ul;
cSec = count_p % 60ul;
hhmmss = "";
if (cHour > 0) {
if (cHour > 9) hhmmss = hhmmss + cHour + ':';
else hhmmss = hhmmss + '0' + cHour + ':';
}
if (cMin > 0 || cHour > 0) {
if (cMin > 9) hhmmss = hhmmss + cMin + ':';
else hhmmss = hhmmss + '0' + cMin + ':';
}
if (cSec > 9) hhmmss = hhmmss + cSec; else hhmmss = hhmmss + '0' + cSec;
Blynk.virtualWrite(vPIN_TIMER_OUT, hhmmss);
Serial.print("\nCountdown: "); Serial.println(hhmmss);
}
if (flag == 1) {
Serial.println("\n Cond.3: Alert");
Blynk.notify("{DEVICE_NAME}: Alarm!");
}
}
void loop() {
timer.run();
Blynk.run();
if (millis() - count_time >= PERIOD) {
count_time += PERIOD;
}
}
Error log
================ Error ==================== =Timer: 10:00 =Timer: 11:00 ets Jan 8 2013,rst cause:4, boot mode:(3,6) wdt reset load 0x4010f000, len 3584, room 16 tail 0 chksum 0xb0 csum 0xb0 v2843a5ac ~ld =============== or ===================== =Timer: 07:00 =Timer: 08:00 =Timer: 09:00 --------------- CUT HERE FOR EXCEPTION DECODER --------------- Exception (9): epc1=0x4020dc11 epc2=0x00000000 epc3=0x00000000 excvaddr=0x3ffe86ca depc=0x00000000 >>>stack>>> ctx: sys sp: 3fffed80 end: 3fffffb0 offset: 0190 3fffef10: 3ffe8304 00000000 0000000a 4023e950 3fffef20: 3fffef93 00000001 00000000 00000000 3fffef30: 3fffdcc0 3ffe92e0 00000002 3ffe86c2 3fffef40: 00000000 3fffeffa 3fffeff0 4020e107 3fffef50: 00000000 ffffffff ffffffff 00000000 3fffef60: 00000002 3fffefa2 00302069 00000000 3fffef70: 00000000 ffffffff ffffffff 40104be9 3fffef80: 40104bef 00047450 00000000 ffffffff 3fffef90: 0039310d ffffffff ffffffff ffffffff 3fffefa0: 4022874c 3fffef3c 40228705 3ffff008 3fffefb0: 3ffff080 3ffff070 00000010 3ffe8304 3fffefc0: 3fffefa0 0000000a 00000000 feefeffe 3fffefd0: feefeffe feefeffe feefeffe 3ffeebd4 3fffefe0: 3ffeeef4 3ffe8304 000003fd 4020a559 3fffeff0: 3ffff0c5 feefeffe 000003fa ffff0208 3ffff000: 00000000 00000000 00000000 3ffeef18 3ffff010: 3ffeeef4 3ffff060 40205b04 3fffefa0 3ffff020: feefeffe feefeffe feefeffe 40206386 3ffff030: feefeffe 3ffeef18 00000000 40202b30 3ffff040: feefeffe feefeffe feefeffe 40201404 3ffff050: 00000005 00000014 00000000 40201e54 3ffff060: 0000000c 0000000b 3ffff0c0 00000000 3ffff070: 3ffff060 3ffff510 3ffff4c0 4020567c 3ffff080: 3ffeeef4 3ffff0c0 3ffff4c0 40205429 3ffff090: 3ffff4c0 3ffff0c0 3ffff4c0 0000040c 3ffff0a0: 3ffeeef4 3ffff4c0 3ffff4c0 402020e0 3ffff0b0: 00000000 feefeffe feefeffe feefeffe 3ffff0c0: 31007776 30310039 0030303a feefeffe 3ffff0d0: feefeffe feefeffe feefeffe feefeffe 3ffff0e0: feefeffe feefeffe feefeffe feefeffe 3ffff0f0: feefeffe feefeffe feefeffe feefeffe 3ffff100: feefeffe feefeffe feefeffe feefeffe 3ffff110: feefeffe feefeffe feefeffe feefeffe 3ffff120: feefeffe feefeffe feefeffe feefeffe 3ffff130: feefeffe feefeffe feefeffe feefeffe 3ffff140: feefeffe feefeffe feefeffe feefeffe 3ffff150: feefeffe feefeffe feefeffe feefeffe 3ffff160: feefeffe feefeffe feefeffe feefeffe 3ffff170: feefeffe feefeffe feefeffe feefeffe 3ffff180: feefeffe feefeffe feefeffe feefeffe 3ffff190: feefeffe feefeffe feefeffe feefeffe 3ffff1a0: feefeffe feefeffe feefeffe feefeffe 3ffff1b0: feefeffe feefeffe feefeffe feefeffe 3ffff1c0: feefeffe feefeffe feefeffe feefeffe 3ffff1d0: feefeffe feefeffe feefeffe feefeffe 3ffff1e0: feefeffe feefeffe feefeffe feefeffe 3ffff1f0: feefeffe feefeffe feefeffe feefeffe 3ffff200: feefeffe feefeffe feefeffe feefeffe 3ffff210: feefeffe feefeffe feefeffe feefeffe 3ffff220: feefeffe feefeffe feefeffe feefeffe 3ffff230: feefeffe feefeffe feefeffe feefeffe 3ffff240: 0000000c 00000000 00000020 40100198 3ffff250: feefeffe feefeffe 0000000c 40101838 3ffff260: 3ffe92ac 40101182 04000000 feefeffe 3ffff270: 00000001 00000004 4021d654 00000000 3ffff280: 00000000 00000000 0000000a 00000000 3ffff290: 00000000 00000000 0000000a 00000000 3ffff2a0: 3ffe92ac 40101182 04000000 feefeffe 3ffff2b0: 00000000 a0000000 00000000 0000001c 3ffff2c0: 00000000 3fffc200 00000000 00000000 3ffff2d0: 3ffff430 00000000 3ffff430 4020dcd6 3ffff2e0: 0000a000 3ffff3d3 fffff0ff 00006f20 3ffff2f0: 3fff0910 3ffed67c 40209e29 00000001 3ffff300: 3ffff430 00000001 3ffff430 4020dcd6 3ffff310: 3ffff390 3ffff3d2 3ffff340 00000000 3ffff320: 7fffffff 3ffe9510 0000007c 4020dc0c 3ffff330: 3ffff430 3ffff3d2 3ffff390 40209f54 3ffff340: 00000001 0000005d 00000045 3ffedec8 3ffff350: 3ffe8304 00000000 0000000a 4023e950 3ffff360: 3ffff3d3 00000000 00000000 feefeffe 3ffff370: feefeffe feefeffe feefeffe 3ffe8eac 3ffff380: 00000000 3ffe8eab 3ffff430 4020e107 3ffff390: 00000000 ffffffff ffffffff 00000000 3ffff3a0: 00000001 00000001 40302064 00000001 3ffff3b0: 00000000 00000000 00000020 40100198 3ffff3c0: 4022aa0a 3ffeca10 00000000 40101838 3ffff3d0: 003031a0 40104acb 3ffecb50 40100198 3ffff3e0: 00000001 40103ca6 00000000 40101838 3ffff3f0: 3ffff4c0 3ffff4b0 0000000c 3ffe8304 3ffff400: 00000001 00000009 00000001 3fff048c 3ffff410: 40103bdf 00000020 00000000 3ffeebd4 3ffff420: 3ffeebd2 3ffeebd0 3ffff510 4020a620 3ffff430: 3ffff4e1 00080000 7ffffffe ffff0208 3ffff440: 3ffff4e0 7fffffff 3ffecd08 00000000 3ffff450: 401023cf 2c9f0300 4000050c 3fffc278 3ffff460: 40102790 3fffc200 00000022 401025ac 3ffff470: 40100280 00000030 00000010 ffffffff 3ffff480: 4010026a 00000000 00000000 4bc6a7f0 3ffff490: 00000005 f5651920 3ffff4c0 3ffff4b0 3ffff4a0: 00000008 00000005 3ffff510 40205740 3ffff4b0: 00000005 3ffff510 00000000 00000083 3ffff4c0: 303a3000 00000030 80fff510 3ffff0c0 3ffff4d0: 0000000c 00000400 3ffff510 4020567c 3ffff4e0: 00000013 3ffff510 3ffff510 402056ac 3ffff4f0: 3ffeebb0 3ffff510 3ffeebb0 3ffeebd4 3ffff500: 3ffeebd2 3ffeebd0 3ffeebb0 40202252 3ffff510: 303a3031 00000030 85000020 40209284 3ffff520: 4bc6a7f0 3ffeeef4 3ffff660 00000002 3ffff530: 3ffeeef4 00000012 3ffff5c8 402017d0 3ffff540: 007a1200 66e15d96 4bc6a700 4021249a 3ffff550: 3ffff5c6 00000002 00000002 3ffff5c0 3ffff560: 00000012 00000000 4bc6a7f0 3ffff5c6 3ffff570: 3ffff5c8 3fff7776 40100286 0e978d4f 3ffff580: 00000008 00000005 00000007 40206386 3ffff590: 00000000 3ffff5c0 3ffeeef4 3ffff5c0 3ffff5a0: 00000000 3ffff5c0 3ffeeef4 40201b8c 3ffff5b0: 3ffeeef4 3ffeef18 3ffeeef4 402018a4 3ffff5c0: 31007776 30310038 00000000 3ffff650 3ffff5d0: 00000000 00000000 00000000 3ffff660 3ffff5e0: 00000000 08229014 00000000 3ffff660 3ffff5f0: 3ffeeef4 3ffeef18 00000000 40205b10 3ffff600: 00000008 3ffeef18 3ffeeef4 40206386 3ffff610: 3ffeeef4 3ffeef18 3ffeeef4 3ffff660 3ffff620: 3ffeeef4 3ffeef18 3ffeeef4 40201e0e 3ffff630: 00000000 3ffeef18 00000000 40202b30 3ffff640: 3ffeeef4 00000014 00000014 3ffff660 3ffff650: 3ffeeef4 00000014 00000014 40201ec7 3ffff660: 000050d8 00000008 3ffff6c0 00000000 3ffff670: 3ffff660 3ffffb20 3ffffac0 4020567c 3ffff680: 3ffeeef4 3ffff6c0 3ffffac0 40205429 3ffff690: 3ffffac0 3ffff6c0 3ffffac0 0000040c 3ffff6a0: 3ffeeef4 3ffffac0 3ffffac0 402020e0 3ffff6b0: 00000000 feefeffe feefeffe feefeffe 3ffff6c0: 32007776 30320030 feefef00 feefeffe 3ffff6d0: feefeffe feefeffe feefeffe feefeffe 3ffff6e0: feefeffe feefeffe 4022a9bb 00000001 3ffff6f0: ffffffff 00000000 3ffe93f1 00000008 3ffff700: 4022aa0a 3ffeca10 3fff048c 00000001 3ffff710: 00000002 00000000 00000020 40100198 3ffff720: 00000005 00000005 00000002 40101838 3ffff730: 3ffe92a2 40229ac7 3ffeca10 00000020 3ffff740: 00000000 4021d07b 3ffedec8 3fff048c 3ffff750: 00000000 00000002 00000000 3ffeca10 3ffff760: 3fff092a 40105133 3fff0400 3ffef294 3ffff770: 3fff0854 40103ca6 00000005 40101838 3ffff780: 3ffe92a5 4020e321 3fff0400 3ffef294 3ffff790: 401023cf 3ffecd08 00000005 40101838 3ffff7a0: 00000000 013a9470 3ffed700 00000000 3ffff7b0: 3ffef6b8 3ffef680 3fff08f4 4020e5ae 3ffff7c0: 00000000 3ffef680 3fff08f4 4020e9cc 3ffff7d0: 3ffef52c 00000000 0000001f 40100198 3ffff7e0: 00000001 00000080 3fffc228 3ffef530 3ffff7f0: 3ffef6b8 00000003 3ffef680 4021645c 3ffff800: 402074c7 00000030 00000010 ffffffff 3ffff810: 00000002 3fff08f4 668bc855 40228705 3ffff820: 00000000 00000000 00000000 3fff08f4 3ffff830: 3fff08f4 3ffef68c 3ffef680 402166b0 3ffff840: 00000000 3ffeeef4 3ffff9a0 00000030 3ffff850: 3fff0938 3fff00f0 3ffef680 40217ea4 3ffff860: 3fff00ec 00000000 00000020 40100a30 3ffff870: 00000014 3fff00ec 000000ff 00000000 3ffff880: 00000002 00000000 0000000a 00000000 3ffff890: 00000002 00000000 0000000a 00000000 3ffff8a0: 3fff02ec 3ffef680 00000000 40217eec 3ffff8b0: 00000000 a0000000 00000000 0000001c 3ffff8c0: 00002000 00001af3 00002000 00000000 3ffff8d0: 3ffffa30 00000000 3ffffa30 4020dcd6 3ffff8e0: 0000a000 3ffff9d3 3fff00ec 40213fa6 3ffff8f0: 00000b38 00000167 40209e29 00000002 3ffff900: 3ffffa30 00000002 3ffffa30 4020dcd6 3ffff910: 3ffff990 3ffff9d1 3ffff940 00000000 3ffff920: 007a1200 66958260 4bc6a700 4020dc0c 3ffff930: 3ffffa30 3ffff9d1 3ffff990 40209f54 3ffff940: 00000002 00000000 4bc6a7f0 00000000 3ffff950: 3ffe8304 00000000 0000000a 4023e950 3ffff960: 3ffff9d3 00000002 00000000 40206386 3ffff970: 3ffeeef4 00000010 00000010 3ffe8eac 3ffff980: 00000000 3ffe8eab 3ffffa30 4020e107 3ffff990: 00000000 ffffffff ffffffff 00000000 3ffff9a0: 00000002 00000002 3f302064 00000000 3ffff9b0: 3ffff9a0 3ffff990 3ffeef18 3ffff990 3ffff9c0: 000003ff 3ffffa00 3ffffe00 40205429 3ffff9d0: 00303200 3ffffa00 3ffffe00 0000040c 3ffff9e0: 3ffeeef4 3ffffe00 00000000 402020e0 3ffff9f0: 3ffffac0 3ffffab0 0000000c 3ffe8304 3ffffa00: 00000002 00000009 00000001 fffffffe 3ffffa10: 00000440 3fffc6fc 00000000 3ffeebda 3ffffa20: 3ffeebe0 3ffeeba4 3ffffb20 4020a620 3ffffa30: 3ffffae2 00000001 7ffffffd ffff0208 3ffffa40: 3ffffae0 7fffffff 00000000 3ffeef7c 3ffffa50: 40204a44 3ffeef7c 3ffffa9f 40204a50 3ffffa60: 40204a44 3ffeef7c 3ffffa9f 40204d81 3ffffa70: 00000031 0000000a 3ffffa9e 40205001 3ffffa80: feefeffe feefeffe feefeffe feefeffe 3ffffa90: 00000002 feefeffe 3ffffac0 3ffffab0 3ffffaa0: 00000008 00000002 3ffffb20 40205740 3ffffab0: 00000002 3ffffb20 00000014 00000000 3ffffac0: 00003000 00000002 80fffb20 3ffff6c0 3ffffad0: 00000009 00000400 3ffffb20 4020567c 3ffffae0: 00000014 3ffffb20 3ffffb20 402056ac 3ffffaf0: 3ffeeba4 3ffffb20 3ffffb20 3ffeebda 3ffffb00: 3ffeebe0 3ffeeba4 3ffffb20 402025d6 3ffffb10: feefeffe feefeffe feefeffe feefeffe 3ffffb20: fe003032 feefeffe 82efeffe feefeffe 3ffffb30: feefeffe feefeffe feefeffe feefeffe 3ffffb40: feefeffe feefeffe feefeffe feefeffe 3ffffb50: feefeffe feefeffe 4022a9bb 00000001 3ffffb60: ffffffff 00000000 3ffe93f1 00000008 3ffffb70: 4022aa0a 3ffeca38 3fff048c 00000001 3ffffb80: 00000002 00000000 00000020 40100198 3ffffb90: 00000005 00000005 00000002 40101838 3ffffba0: 3ffe92a2 40229ac7 3ffeca38 00000020 3ffffbb0: 00000000 4021d07b 3ffedec8 3fff048c 3ffffbc0: 00000000 00000000 0000000a 00000000 3ffffbd0: 00000000 00000000 0000000a 00000000 3ffffbe0: 3fff0854 00000000 00000020 40100198 3ffffbf0: 00000000 a0000000 00000000 0000001c 3ffffc00: 00000000 40104acb 00000000 00000000 3ffffc10: 3ffffd70 00000000 3ffffd70 4020dcd6 3ffffc20: 0000a000 3ffffd13 00000002 40101838 3ffffc30: 3ffe92a2 40104acb 40209e29 00000001 3ffffc40: 3ffffd70 00000001 3ffffd70 4020dcd6 3ffffc50: 3ffffcd0 3ffffd12 3ffffc80 00000000 3ffffc60: 40101c69 40104ae3 4022a9bb 4020dc0c 3ffffc70: 3ffffd70 3ffffd12 3ffffcd0 40209f54 3ffffc80: 00000001 3ffeca10 3fff048c 00000001 3ffffc90: 3ffe8304 00000000 0000000a 4023e950 3ffffca0: 3ffffd13 00000000 00000000 40101838 3ffffcb0: 3ffe92a2 40229ac7 3ffeca10 3ffe8eac 3ffffcc0: 401039db 00040000 00000000 00040000 3ffffcd0: 00002000 401039d8 00040000 00000000 3ffffce0: 3ffed468 4010293f 00302064 3ffef294 3ffffcf0: 3ffed468 4010293f 3ffeca10 00000020 3ffffd00: 00000000 2c9f0300 4000050c 3fffc278 3ffffd10: 40102790 3fffc200 00000022 3fffc278 3ffffd20: 40207e94 00000030 00000010 ffffffff 3ffffd30: 00000002 00000000 00000020 40100198 3ffffd40: 40101c69 00000000 00000002 40101838 3ffffd50: 3ffe92a2 40104acb 3ffeca10 3ffffe50 3ffffd60: 00000001 40103ca6 3ffed468 00000030 3ffffd70: 40104117 40101838 7ffffffe ffff0208 3ffffd80: 3ffffe20 7fffffff 00000020 40100198 3ffffd90: 40103bdf 00000021 00000002 00040000 3ffffda0: 00002200 40104ae3 3ffecd08 401025ac 3ffffdb0: 40102aa8 00080000 00000000 00000021 3ffffdc0: 00007fff 00000000 3ffed700 401025ac 3ffffdd0: 3ffe874f 2c9f0300 4000050c 3fffc278 3ffffde0: 40102790 3fffc200 00000022 40206d39 3ffffdf0: 40201b91 00000030 00000010 ffffffff 3ffffe00: 40201b8c 00000000 6000001c 3ffe874f 3ffffe10: 3ffeebb0 40204a44 00000000 fffffffe 3ffffe20: 00000440 3fffc6fc 00000000 3ffeeef4 3ffffe30: 3fffff00 00000000 3fffff00 00000030 3ffffe40: 3ffeebd2 3ffeef7c 3ffeebb0 4020226a 3ffffe50: 303a3900 00000030 80000020 40209284 3ffffe60: 3ffe9b20 f8475050 00000000 00000001 3ffffe70: 3ffeeef4 00000012 3fffff07 402017d0 3ffffe80: 007a1200 6642cb1d 4bc6a700 4021249a 3ffffe90: 3fffff06 00000001 00000001 3fffff00 3ffffea0: 00000012 00000000 4bc6a7f0 3fffff06 3ffffeb0: 3fffff07 3fff7776 40100286 276c8b43 3ffffec0: 00000007 00000005 00000006 40206386 3ffffed0: 00000000 3fffff00 3ffeeef4 3fffff00 3ffffee0: 00000000 3fffff00 3ffeeef4 40201b8c 3ffffef0: 007a1200 6695df4f 3ffeee00 402018a4 3fffff00: 00000000 4bc6a7f0 00005097 3ffef0a8 3fffff10: 00000000 00000000 4bc6a7f0 00000000 3fffff20: 00005097 3ffeef18 40100286 43d70a3d 3fffff30: 00000000 3ffeef18 40100286 40206386 3fffff40: 3ffeecb0 00000000 3ffef068 00000000 3fffff50: 3ffeecb0 00000000 3ffeecb0 40202d48 3fffff60: 00002954 00002710 00005097 00000000 3fffff70: 00000001 00000002 40100286 39db22d0 3fffff80: 00000000 00000000 00000001 3ffef0a8 3fffff90: 3fffdad0 00000000 3ffef068 402029bd 3fffffa0: 3fffdad0 00000000 3ffef068 40205c28 <<<stack<<< --------------- CUT HERE FOR EXCEPTION DECODER --------------- ets Jan 8 2013,rst cause:2, boot mode:(3,6) load 0x4010f000, len 3584, room 16 tail 0 chksum 0xb0 csum 0xb0 v2843a5ac ~ld [185] ___ __ __ / _ )/ /_ _____ / /__ / _ / / // / _ \/ '_/ /____/_/\_, /_//_/_/\_\ /___/ v0.6.1 on NodeMCU