tzapu / WiFiManager

ESP8266 WiFi Connection manager with web captive portal
http://tzapu.com/esp8266-wifi-connection-manager-library-arduino-ide/
MIT License
6.63k stars 1.98k forks source link

crash when trying to connect to MQTT server #880

Open TinajaLabs opened 5 years ago

TinajaLabs commented 5 years ago

Getting a crash on a wemos d1 mini (and also on the Feather Huzzah ESP8266 ) after a few minutes of the device trying to reconnect to the wifi router. The router's running openwrt and is about 8 feet away, so I doubt it's a problem with OTA connectivity.

I'm trying to make a room sensor with a collection of sensors (temp, humidity, pir, light level) and associated libraries - WifiManager ("version": "1.0.0" - from library.json), MQTT (pupsub), DHT22 (temp/humidity), TSL2561 (lux), and a PIR sensor.

Below is the list of libraries I use to accomplish this. I'm trying to understand any interaction between these libs. I've read that the FS library needs to always be first one defined. Are there any others that need to be sequenced in the order?

The code compiles fine and doesn't seem to be related to a memory problem:

Sketch uses 383968 bytes (36%) of program storage space. Maximum is 1044464 bytes.
Global variables use 33948 bytes (41%) of dynamic memory, leaving 47972 bytes for local variables. Maximum is 81920 bytes.

Thanks for any tips,

Chris.

#include <FS.h> //this needs to be first, or it all crashes and burns...

#include <Wire.h>
#include <Adafruit_Sensor.h>  // Adafruit Unified Sensor Driver - https://github.com/adafruit/Adafruit_Sensor

#include <DNSServer.h>  
#include <ESP8266WiFi.h>      // https://github.com/esp8266/Arduino
#include <WiFiManager.h>      // https://github.com/tzapu/WiFiManager
#include <ESP8266WebServer.h> //Local WebServer used to serve the configuration portal
#include <ArduinoJson.h>      //https://github.com/bblanchon/ArduinoJson

#include <PubSubClient.h>
#ifdef ESP32
#include <SPIFFS.h>
#endif

#include <Adafruit_TSL2561_U.h>
#include <DHT.h>

The error stack... in case it's meaningful to anyone. First some normal output, then a few dozen attempts to reconnect then - boom.

Attempting connection to MQTT server: 192.168.1.138...  Not connected.

=========================================================

mqtt pub - PIR state:   0
mqtt pub - RSSI level: -50
mqtt pub - temperature: 73.94 *F
mqtt pub - rel humidity:    60.20 %
mqtt pub - lux value:       0
mqtt pub - lux broaband:    24
mqtt pub - lux infrared:    5
mqttClient not connected...

Soft WDT reset

>>>stack>>>

ctx: sys
sp: 3fffed40 end: 3fffffb0 offset: 01b0
3fffeef0:  00000000 127f2f22 3ffed770 40222016  
3fffef00:  00000000 3ffee088 00000000 00000000  
3fffef10:  40240ac4 3ffee088 3ffef040 40201ce8  
3fffef20:  4024353d 3ffee088 3ffef040 3b3138ed  
3fffef30:  40243582 3fffdab0 00000000 3fffdcb0  
3fffef40:  3ffef050 3fffdad0 3ffefd84 40216ec7  
3fffef50:  40000f49 40000f49 3fffdab0 40000f49  
3fffef60:  40000e19 40001878 00000002 00000000  
3fffef70:  3fffff10 aa55aa55 000000f2 4010542c  
3fffef80:  40105432 00000002 00000000 e82bcda6  
3fffef90:  4010000d a3ca2c98 dda558a1 83153daf  
3fffefa0:  401015fc 3fffef3c 401015a9 3fffff58  
3fffefb0:  3fffffc0 00000000 00000000 feefeffe  
3fffefc0:  feefeffe feefeffe feefeffe feefeffe  
3fffefd0:  feefeffe feefeffe feefeffe feefeffe  
3fffefe0:  feefeffe feefeffe feefeffe feefeffe  
3fffeff0:  feefeffe feefeffe feefeffe feefeffe  
3ffff000:  feefeffe feefeffe feefeffe feefeffe  
3ffff010:  feefeffe feefeffe feefeffe feefeffe  
3ffff020:  feefeffe feefeffe feefeffe feefeffe  
3ffff030:  feefeffe feefeffe feefeffe feefeffe  
3ffff040:  feefeffe feefeffe feefeffe feefeffe  
3ffff050:  feefeffe feefeffe feefeffe feefeffe  
3ffff060:  feefeffe feefeffe feefeffe feefeffe  
3ffff070:  feefeffe feefeffe feefeffe feefeffe  
3ffff080:  feefeffe feefeffe feefeffe feefeffe  
3ffff090:  feefeffe feefeffe feefeffe feefeffe  
3ffff0a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff0c0:  feefeffe feefeffe feefeffe 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:  feefeffe feefeffe feefeffe feefeffe  
3ffff250:  feefeffe feefeffe feefeffe feefeffe  
3ffff260:  feefeffe feefeffe feefeffe feefeffe  
3ffff270:  feefeffe feefeffe feefeffe feefeffe  
3ffff280:  feefeffe feefeffe feefeffe feefeffe  
3ffff290:  feefeffe feefeffe feefeffe feefeffe  
3ffff2a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff2f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff300:  feefeffe feefeffe feefeffe feefeffe  
3ffff310:  feefeffe feefeffe feefeffe feefeffe  
3ffff320:  feefeffe feefeffe feefeffe feefeffe  
3ffff330:  feefeffe feefeffe feefeffe feefeffe  
3ffff340:  feefeffe feefeffe feefeffe feefeffe  
3ffff350:  feefeffe feefeffe feefeffe feefeffe  
3ffff360:  feefeffe feefeffe feefeffe feefeffe  
3ffff370:  feefeffe feefeffe feefeffe feefeffe  
3ffff380:  feefeffe feefeffe feefeffe feefeffe  
3ffff390:  feefeffe feefeffe feefeffe feefeffe  
3ffff3a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff3f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff400:  feefeffe feefeffe feefeffe feefeffe  
3ffff410:  feefeffe feefeffe feefeffe feefeffe  
3ffff420:  feefeffe feefeffe feefeffe feefeffe  
3ffff430:  feefeffe feefeffe feefeffe feefeffe  
3ffff440:  feefeffe feefeffe feefeffe feefeffe  
3ffff450:  feefeffe feefeffe feefeffe feefeffe  
3ffff460:  feefeffe feefeffe feefeffe feefeffe  
3ffff470:  feefeffe feefeffe feefeffe feefeffe  
3ffff480:  feefeffe feefeffe feefeffe feefeffe  
3ffff490:  feefeffe feefeffe feefeffe feefeffe  
3ffff4a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff4f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff500:  feefeffe feefeffe feefeffe feefeffe  
3ffff510:  feefeffe feefeffe feefeffe feefeffe  
3ffff520:  feefeffe feefeffe feefeffe feefeffe  
3ffff530:  feefeffe feefeffe feefeffe feefeffe  
3ffff540:  feefeffe feefeffe feefeffe feefeffe  
3ffff550:  feefeffe feefeffe feefeffe feefeffe  
3ffff560:  feefeffe feefeffe feefeffe feefeffe  
3ffff570:  feefeffe feefeffe feefeffe feefeffe  
3ffff580:  feefeffe feefeffe feefeffe feefeffe  
3ffff590:  feefeffe feefeffe feefeffe feefeffe  
3ffff5a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff5f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff600:  feefeffe feefeffe feefeffe feefeffe  
3ffff610:  feefeffe feefeffe feefeffe feefeffe  
3ffff620:  feefeffe feefeffe feefeffe feefeffe  
3ffff630:  feefeffe feefeffe feefeffe feefeffe  
3ffff640:  feefeffe feefeffe feefeffe feefeffe  
3ffff650:  feefeffe feefeffe feefeffe feefeffe  
3ffff660:  feefeffe feefeffe feefeffe feefeffe  
3ffff670:  feefeffe feefeffe feefeffe feefeffe  
3ffff680:  feefeffe feefeffe feefeffe feefeffe  
3ffff690:  feefeffe feefeffe feefeffe feefeffe  
3ffff6a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff6f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff700:  feefeffe feefeffe feefeffe feefeffe  
3ffff710:  feefeffe feefeffe feefeffe feefeffe  
3ffff720:  feefeffe feefeffe feefeffe feefeffe  
3ffff730:  feefeffe feefeffe feefeffe feefeffe  
3ffff740:  feefeffe feefeffe feefeffe feefeffe  
3ffff750:  feefeffe feefeffe feefeffe feefeffe  
3ffff760:  feefeffe feefeffe feefeffe feefeffe  
3ffff770:  feefeffe feefeffe feefeffe feefeffe  
3ffff780:  feefeffe feefeffe feefeffe feefeffe  
3ffff790:  feefeffe feefeffe feefeffe feefeffe  
3ffff7a0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7b0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7c0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7d0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7e0:  feefeffe feefeffe feefeffe feefeffe  
3ffff7f0:  feefeffe feefeffe feefeffe feefeffe  
3ffff800:  feefeffe feefeffe feefeffe feefeffe  
3ffff810:  feefeffe feefeffe feefeffe feefeffe  
3ffff820:  feefeffe feefeffe feefeffe feefeffe  
3ffff830:  feefeffe feefeffe feefeffe feefeffe  
3ffff840:  feefeffe feefeffe feefeffe feefeffe  
3ffff850:  feefeffe feefeffe feefeffe feefeffe  
3ffff860:  00000002 4000444e feefeffe feefeffe  
3ffff870:  00000000 4000422e 60000200 3ffff8f4  
3ffff880:  00000100 40004aa0 000000fc 00101b04  
3ffff890:  00000100 3ffff8f0 3fffc718 00101b04  
3ffff8a0:  00000004 0168a101 40106888 00000004  
3ffff8b0:  3ffff8f0 00101b05 00000000 00101b05  
3ffff8c0:  3fffc718 3ffff8f0 000000fc 00101d04  
3ffff8d0:  00101b04 4021565d 00000001 00101b04  
3ffff8e0:  00000004 0168a101 00000001 40217dc4  
3ffff8f0:  ffffff7e 00101d05 00000000 00101d05  
3ffff900:  3fffc718 3ffff930 feefeffe feefeffe  
3ffff910:  00101d04 4021565d 00000001 00101d04  
3ffff920:  00000002 4000444e 00000001 40217dc4  
3ffff930:  00000000 4000422e 60000200 3ffff9b4  
3ffff940:  00000100 40004aa0 000000b8 00101e48  
3ffff950:  00000100 3ffff9b0 3fffc718 00101e48  
3ffff960:  00000004 0168a101 40106888 00000004  
3ffff970:  00000000 4000444e 00000000 00101e4a  
3ffff980:  00000000 400041bc 60000200 3fff14d4  
3ffff990:  00000100 40004b14 00000100 00101d00  
3ffff9a0:  00000100 3fff13d4 3fffc718 00101e00  
3ffff9b0:  00000100 00000000 40106888 00000100  
3ffff9c0:  3fff13d4 00101e00 00101d00 00101e00  
3ffff9d0:  3fffc718 3fff13d4 6b616d22 682f7265  
3ffff9e0:  00101d00 4021565d 00000100 00101e00  
3ffff9f0:  00000006 00000000 00000100 40217d49  
3ffffa00:  0000000a 40255410 00000001 3ffffb20  
3ffffa10:  00000002 00000000 0000000a 00000000  
3ffffa20:  00000002 00000000 0000000a 00000000  
3ffffa30:  00000002 00000000 0000000a 00000000  
3ffffa40:  00000000 a0000000 00000000 0000001c  
3ffffa50:  00002000 a0000000 00002000 00000000  
3ffffa60:  00000003 00000000 0000000a 00000000  
3ffffa70:  00000003 00000000 0000000a 00000000  
3ffffa80:  00000002 00000000 0000000a 00000000  
3ffffa90:  00000001 00000000 0000000a 00000000  
3ffffaa0:  00000000 00000000 0000001f 40105c05  
3ffffab0:  4000050c 40105308 3fff0edc 00000000  
3ffffac0:  00000000 00000000 00000020 40101f22  
3ffffad0:  00000000 00000000 00000020 40101f22  
3ffffae0:  00000000 00000000 00000020 40101f22  
3ffffaf0:  3ffe9d30 40105308 3fff0edc 40105c05  
3ffffb00:  00000001 4010452b 3ffedeb0 00000030  
3ffffb10:  4010498e 00000030 00000000 ffffffff  
3ffffb20:  40104472 0000007f 7fffffff 00000000  
3ffffb30:  40104472 0000007f 7fffffff 00000000  
3ffffb40:  0000007f 00080000 ff000fff 3ffee958  
3ffffb50:  401032e7 00080000 00000000 4000050c  
3ffffb60:  00000000 40102fe4 00000000 4000050c  
3ffffb70:  3fffc278 40102fe4 3fffc200 00000022  
3ffffb80:  00000000 00000000 0000001f 40105c05  
3ffffb90:  4000050c 00000030 00000000 ffffffff  
3ffffba0:  4022f515 00000030 4023d20b 00000001  
3ffffbb0:  ffffffff 00000000 3ffe9e81 00000008  
3ffffbc0:  00000000 00000000 0000001f 40105c05  
3ffffbd0:  4000050c 3ffed4c8 3fff05dc 3ffed4c8  
3ffffbe0:  4021b3fc 4022f403 3ffee958 3fff05dc  
3ffffbf0:  3fff2ce8 3fff2ce8 4023d20b 00000001  
3ffffc00:  00000000 00000002 00000000 00000008  
3ffffc10:  3fff3362 401059ab 3fff2ce8 3fff0d6c  
3ffffc20:  3fff332c 3ffed428 3fff05dc 3ffed428  
3ffffc30:  00000002 402218e9 3ffeff88 3fff0d6c  
3ffffc40:  3fff3362 00000036 3ffee958 3fff05dc  
3ffffc50:  00000005 00000000 0000000a 00000000  
3ffffc60:  00000005 00000000 0000000a 00000000  
3ffffc70:  3fff3362 3fff0394 3fff332c 40221f5c  
3ffffc80:  00000000 a0000000 00000000 0000001c  
3ffffc90:  00005000 402218e9 00005000 00000000  
3ffffca0:  3ffffe00 00000000 3ffffe00 4021fcc6  
3ffffcb0:  0000a000 3ffffda3 3fff21b0 00000000  
3ffffcc0:  00000002 3fff332c 4021b7c0 00000001  
3ffffcd0:  3ffffe00 00000001 3ffffe00 4021fcc6  
3ffffce0:  3ffffd60 3ffffda2 3ffffd10 00000000  
3ffffcf0:  00000005 00000000 0000000a 4021fc00  
3ffffd00:  3ffffe00 3ffffda2 3ffffd60 4021b8c0  
3ffffd10:  00000001 a0000000 00000000 0000001c  
3ffffd20:  3ffe8300 00000000 0000000a 40255410  
3ffffd30:  3ffffda3 00000005 00000000 4021fcc6  
3ffffd40:  0000a000 3ffffe33 0000006c 3ffe9a97  
3ffffd50:  00000000 3ffe9a96 3ffffe00 402200d7  
3ffffd60:  00000080 ffffffff ffffffff 00000000  
3ffffd70:  00000001 00000001 3f302064 00000000  
3ffffd80:  3fff0394 00000000 00000000 4021fc00  
3ffffd90:  00000000 4bc6a7f0 000f25db 3ffef938  
3ffffda0:  00353200 00000000 4bc6a7f0 3ffefb33  
3ffffdb0:  3ffefb35 00000000 00000000 40201871  
3ffffdc0:  3ffffe90 3ffffe80 00000010 3ffe8300  
3ffffdd0:  00000001 00000009 00000001 40201871  
3ffffde0:  3ffefb35 00000001 3ffefb35 3ffefa98  
3ffffdf0:  42100000 3ffe8300 0000004b 4021c045  
3ffffe00:  3ffffeb1 00000001 00000049 ffff0208  
3ffffe10:  3ffffeb0 0000004a 3ffefb31 4020a4b8  
3ffffe20:  3ffef900 000000ae 3ffef94c 4020a4e0  
3ffffe30:  3ffef9ae 00000000 3ffef94c 4020a6ec  
3ffffe40:  3ffef96a 3ffef968 3ffef724 4021920c  
3ffffe50:  42100000 00000001 3ffef724 4021500c  
3ffffe60:  00000000 4bc6a7f0 000f2739 3ffefd84  
3ffffe70:  00000000 00000000 4bc6a7f0 00000000  
3ffffe80:  42100000 3ffef724 40100a9e ba1cac08  
3ffffe90:  00000000 3ffffeb0 3ffefc74 40215bfc  
3ffffea0:  3fffdad0 3ffef720 00000001 40208213  
3ffffeb0:  00000035 00000028 3ffffedd 3ffef724  
3ffffec0:  00000010 3fffff60 3fffff60 402162cf  
3ffffed0:  3fffff20 00000005 3fffff60 4021631b  
3ffffee0:  34320002 00000000 3fffff60 40216364  
3ffffef0:  00000000 4bc6a7f0 000f2739 3ffefd84  
3fffff00:  00000000 00000000 4bc6a7f0 00000000  
3fffff10:  00000000 4bc6a7f0 000f2739 3ffefd84  
3fffff20:  00000000 00000000 4bc6a7f0 00000000  
3fffff30:  3fffdad0 3ffef720 40100a9e b8d4fdf3  
3fffff40:  40105d48 127fbd7f 3ffefe5c 00000000  
3fffff50:  3ffef040 3ffefe5c 3ffe87fc 3ffefe5c  
3fffff60:  3fffdad0 3ffefd84 40216f0c 3fffefa0  
3fffff70:  3ffefe5c 3fffdad0 00000064 40201d6f  
3fffff80:  3fffdad0 3ffef720 00000001 4020a1b6  
3fffff90:  00000000 00000000 00000001 40216f2d  
3fffffa0:  3fffdad0 00000000 3ffefd54 40216fb8  
<<<stack<<<
TinajaLabs commented 5 years ago

Just happened again, and this is the lead up to the crash:

mqtt pub - PIR state:   1
mqtt pub - RSSI level: -56
mqtt pub - temperature:     71.96 *F
mqtt pub - rel humidity:    59.40 %
mqtt pub - lux value:       0
mqtt pub - lux broaband:    17
mqtt pub - lux infrared:    3
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqtt pub - PIR state:   1
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqtt pub - PIR state:   1
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...
mqttClient not connected...

Soft WDT reset

>>>stack>>>

ctx: sys
sp: 3fffed40 end: 3fffffb0 offset: 01b0
.
.
.
tablatronix commented 5 years ago

see if you have time to decode the stack trace, it will tell you exactly where its crashing

TinajaLabs commented 5 years ago

Just learned how to decode the stack trace. Please see below. This is a more recent crash, not from the prior post.

It is revealing. I added a check with Serial.println(ESP.getFreeHeap()); and it shows a slow reduction in free memory.

Is there a trick to tell where the memory leak is happening?

Thank you, Chris.

Memory allocation of 116 bytes failed at 0x4022ad8c: mem_malloc at core/mem.c line 210

Decoding stack results
0x40222086: memp_free at core/memp.c line 447
0x402149ef: loop_task(ETSEvent*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 133
0x40213159: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x402158ec: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x40213159: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x402158ec: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x40213159: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x40215871: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 127
0x40214a34: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40100119: __wrap_spi_flash_read at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_phy.c line 267
0x40215788: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 67
0x4021fd36: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021fc70: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x4021b830: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 194
0x4021fd36: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021fc70: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x4021b930: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 244
0x4021fd36: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x40220147: _svfprintf_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 660
0x4021fc70: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x40101564: free at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/umm_malloc/umm_malloc.c line 1760
0x40202291: uart_do_write_char at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/uart.c line 450
0x40202652: uart_write at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/uart.c line 496
0x40101564: free at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/umm_malloc/umm_malloc.c line 1760
0x4020b2a4: ClientContext::_s_connected(void*, tcp_pcb*, long) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/include/ClientContext.h line 635
0x402217ad: operator delete(void*) at ../../../../../dl/gcc-xtensa/libstdc++-v3/libsupc++/del_op.cc line 48
0x4020b4ab: ClientContext::unref() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/include/ClientContext.h line 123
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x4020b004: WiFiClient::connect(char const*, unsigned short) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/WiFiClient.cpp line 133
0x402081e3: publishLuxValues() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 844
0x40219150: PubSubClient::connected() at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 606
0x4021337c: HardwareSerial::write(unsigned char const*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/HardwareSerial.h line 174
0x40213681: Print::write(char const*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Print.h line 60
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40214a34: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40201d6f: delay at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 51
0x4020a1e2: loop() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 289
0x40214ae0: loop_wrapper() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 125
TinajaLabs commented 5 years ago

Happened again when It was Attempting connection to MQTT server: 192.168.1.138...

Heapfree starts at 39344 and is 33344 just before the crash. It took less than 5 minutes to happen and

Decoding stack results
0x40214a7f: loop_task(ETSEvent*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 133
0x40213211: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x4021597c: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x40213211: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x4021597c: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x40213211: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x40215901: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 127
0x40214ac4: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40100119: __wrap_spi_flash_read at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_phy.c line 267
0x40213235: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 639
0x40215818: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 67
0x4020699d: spiffs_phys_rd at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs/spiffs_cache.c line 153
0x402219e9: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x402219e9: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x4021fdc6: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x40221c7a: new_linkoutput at glue-lwip/lwip-git.c line 238
0x4022205c: ethernet_output at netif/ethernet.c line 312
0x40229734: etharp_output_to_arp_index at core/ipv4/etharp.c line 770
0x40229938: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x402201d7: _svfprintf_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 660
0x4022a350: ip4_output_if_opt_src at core/ipv4/ip4.c line 1007
0x4021fdc6: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021fd00: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x4022a398: ip4_output_if_opt at core/ipv4/ip4.c line 820
0x4022ae1c: mem_malloc at core/mem.c line 210
0x4022ae1c: mem_malloc at core/mem.c line 210
0x4022a3be: ip4_output_if at core/ipv4/ip4.c line 793
0x4022af2f: ip_chksum_pseudo at core/inet_chksum.c line 395
0x4022731e: tcp_output at core/tcp_out.c line 1361
0x40226609: tcp_create_segment at core/tcp_out.c line 190
0x40214ac4: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40201d6f: delay at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 51
0x4020bb6d: WiFiClient::connect(IPAddress const&, unsigned short) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/include/ClientContext.h line 136
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x4020b0bc: WiFiClient::connect(char const*, unsigned short) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/WiFiClient.cpp line 133
0x402191e0: PubSubClient::connected() at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 606
0x4020c02b: PubSubClient::connect(char const*, char const*, char const*, char const*, unsigned char, unsigned char, char const*, unsigned char) at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 129
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40213434: HardwareSerial::write(unsigned char const*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/HardwareSerial.h line 174
0x4020c214: PubSubClient::connect(char const*) at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 106
0x4021374c: Print::print(char const*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Print.cpp line 122
0x40207d6f: mqttReconnected() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 447
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40100b31: __digitalWrite at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring_digital.c line 82
0x4020a262: loop() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 263
0x40214b70: loop_wrapper() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 125
TinajaLabs commented 5 years ago

And another after about an hour and 10 minutes of running OK:

Memory went from 40668 to 35408. It happened right after it's attempt to connect: TL: Attempting connection to MQTT server: 192.168.1.138... Not connected, error code: -2 ... then

TL: Attempting connection to MQTT server: 192.168.1.138...
Soft WDT reset

>>>stack>>>

ctx: sys
sp: 3fffed40 end: 3fffffb0 offset: 01b0
3fffeef0:  3ffe9be8 35e33b83 60000600 40222106  
etc.
Decoding stack results
0x40222106: memp_free at core/memp.c line 447
0x402131fd: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x40215968: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x402131fd: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x40215968: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x402131fd: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x402158ed: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 127
0x40213221: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 639
0x402219d9: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x402219d9: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x40221c6a: new_linkoutput at glue-lwip/lwip-git.c line 238
0x4022204c: ethernet_output at netif/ethernet.c line 312
0x4021fdb6: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x40229724: etharp_output_to_arp_index at core/ipv4/etharp.c line 770
0x4021b9b0: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 244
0x40229928: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x4022a340: ip4_output_if_opt_src at core/ipv4/ip4.c line 1007
0x4021fdb6: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021fcf0: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x4022a388: ip4_output_if_opt at core/ipv4/ip4.c line 820
0x4022ae0c: mem_malloc at core/mem.c line 210
0x4022a3ae: ip4_output_if at core/ipv4/ip4.c line 793
0x4022af1f: ip_chksum_pseudo at core/inet_chksum.c line 395
0x4022730e: tcp_output at core/tcp_out.c line 1361
0x402238d9: sys_timeout_abs at core/timeouts.c line 189
0x40214ab0: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40201d6f: delay at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 51
0x4020bb59: WiFiClient::connect(IPAddress const&, unsigned short) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/include/ClientContext.h line 136
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x4020b0a8: WiFiClient::connect(char const*, unsigned short) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/libraries/ESP8266WiFi/src/WiFiClient.cpp line 133
0x40208237: publishLuxValues() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 855
0x402191cc: PubSubClient::connected() at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 606
0x4020c017: PubSubClient::connect(char const*, char const*, char const*, char const*, unsigned char, unsigned char, char const*, unsigned char) at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 129
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40213420: HardwareSerial::write(unsigned char const*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/HardwareSerial.h line 174
0x4020c200: PubSubClient::connect(char const*) at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 106
0x40213738: Print::print(char const*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Print.cpp line 122
0x40207d6f: mqttReconnected() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 447
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40100b31: __digitalWrite at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring_digital.c line 82
0x4020a24e: loop() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 263
0x40214b5c: loop_wrapper() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 125
tablatronix commented 5 years ago

are you writing to spiffs over and over ? What are you using spiffs for?

is there a loop that updates some variables than then get saved ?

TinajaLabs commented 5 years ago

I do write to the file system with spiffs library to save 2 parameters (as json), the MQTT server, and the location part of the topic string (e.g., ) for the calls being made when published. These are accessed in setup and during a reset when running wifimanager.

My code for my room sensor - PIR, TSL2561 (lux/light), DHT22 (temp, humidity), RSSI + MQTT and wifimanager.

It's a tedious bit of code, but I've broken out much of the bits into separate methods.

The key parts:

Variables:

I don't expect anyone to go through this code in any detail, but I appreciate any insights into where I'm going wrong here.

BTW, I'm hoping to show how this can work at Maker Faire next week.

Thank you, Chris.

/*
   TinajaLabs.com, Chris Jefferies, May 2019
  ---------------------------------------------------------------
   roomSensor-wfm-lux-temp-hum-01

   Attributes:
   - WifiManager
   - FS
   - MQTT

   - RSSI: dbm, wifi signal strength
   - TSL2561: light level in lux
   - DHT22: temperature & humidity
   - pir: motion sensor
   - // bme280: temperature, humidity, barometric pressure
   - // tmp36: temperature

   Arduino IDE settings:
    Board: Feather HUZZAH ESP8266
    Flash Size: 1M (64k SPIFFS)
    lwIPVariant: v2 Lower Memory
    VTables: Flash
    CPU Frequency: 80MHz
    Upload Speed: 230400
    Port: dev/ttyUSB0, dev/ttyUSB1

    Board: LOLIN (WEMOS) D1, R2 & Mini
    Flash Size: 4M (64k SPIFFS)
    lwIPVariant: v2 Lower Memory
    VTables: Flash
    CPU Frequency: 80MHz
    Upload Speed: 921600
    Port: dev/ttyUSB0, dev/ttyUSB1

  ---------------------------------------------------------------
*/

#include <FS.h> // this needs to be first, or it all crashes and burns...
#include <Wire.h>
#include <ESP8266WiFi.h> // https://github.com/esp8266/Arduino
#include <ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson
#include <PubSubClient.h>
// #include <DNSServer.h>        // this conflicts with other libraries
#include <ESP8266WebServer.h>   // Local WebServer used to serve the configuration portal
#include <WiFiManager.h>        // https://github.com/tzapu/WiFiManager
#include <Adafruit_Sensor.h>    // Adafruit Unified Sensor Driver - https://github.com/adafruit/Adafruit_Sensor
#include <Adafruit_TSL2561_U.h> // https://adafruit.github.io/Adafruit_TSL2561/html/index.html
#include <DHT.h>
// #include <SPI.h>  // for BME280, Serial Peripheral Interface (SPI)
// #include <Adafruit_BME280.h>
#ifdef ESP32
#include <SPIFFS.h>
#endif

// ========================== for this system device

// -------------------------- pin definitions
#define DHT_PIN 2       // D4, GPIO2 on wemos d1 mini
#define PIR_PIN 12      // D6, GPIO12, on wemos d1 mini, motion detection
#define WIFI_MNGR_PIN 0 // D3, GPIO0, on wemos d1 mini, reset button for wifiManager
#define MQTT_LED 16     // D0, GPIO16, on wemos d1 mini, mqtt functions
#define PIR_LED 14      // D5, GPIO14, on wemos d1 mini, pir led
// define SCL 5         // D1, GPIO5, on wemos d1 mini
// define SDA 4         // D2, GPIO4, on wemos d1 mini

// defines specific microcontroller device
// char topic_device[20] = "WemosD1Mini/";
char topic_device[20] = "feather-esp/";

// ========================== specific sensor configs

// -------------------------- RSSI sensor value
long pubLastRssi = 0;
long pubIntervalRssi = 5000; // every 5 seconds
char chipID[10];
char rssi_base[60] = "rssi/state/room";
char rssi_topic[100];

char heap_base[60] = "heap/state/room";
char heap_topic[100];

// -------------------------- for TSL2561 light sensor
long pubLastLux = 0;
long pubIntervalLux = 5000;
char lux[20];
char lux_base[60] = "lux/state/room";
char lux_bb_base[60] = "lux_bb/state/room";
char lux_ir_base[60] = "lux_ir/state/room";

char lux_topic[100];
char lux_bb_topic[100];
char lux_ir_topic[100];
uint16_t broadband = 0;
uint16_t infrared = 0;
Adafruit_TSL2561_Unified tsl = Adafruit_TSL2561_Unified(TSL2561_ADDR_FLOAT, 72921);

// -------------------------- DHT22 sensor values
#define DHTTYPE DHT22 // DHT 22  (AM2302)
DHT dht(DHT_PIN, DHTTYPE);
long pubLastDHT22 = 0;
long pubIntervalDHT22 = 5000;
char temperature[20];
char temp_base[60] = "temperature/state/room";
char humi_base[60] = "humidity/state/room";
char temp_topic[100];
char humi_topic[100];

// -------------------------- for PIR sensor
// hook up to +5V, Gnd, output = 0V - 3.3V
int pirState = 0;
long pubLastPir = 0;
long pubIntervalPir = 1000;
char pir[20];
char pir_base[60] = "pir/state/room";
char pir_topic[100];

// -------------------------- for mqtt
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient);
String mqttClientId = "";
long lastMqttReconnectAttempt = 0;
char mqtt_server[40] = "192.168.0.254"; // configurable in wifiManager

// -------------------------- for wifiManager
// to save settings, SPIFFS
// for SPIFFS, keep to less than 31 characters
bool shouldSaveConfig = true;
const char *CONFIG_FILE = "/config.json";

// -------------------------- generic topic strings

// topic_loc is for the location prefix for all of the topics - it is configurable
// the middle is injected with the chipid
// the rest are suffixes for the various pub/sub entities

char topic_loc[30] = "maker/house/livingroom/"; // configurable in wifiManager

char publ_base[60] = "publish/state/room";
char subs_base[60] = "subscribe/state/room";
char publ_topic[100];
char subs_topic[100];

// Function Prototypes
bool loadConfigFile();
bool saveConfigFile();

// ###############################################################################
// SETUP & LOOP: #################################################################

// ==========================================================
// SETUP ====================================================
void setup()
{

  Serial.begin(57600);
  while (!Serial)
    ; // wait for serial monitor to open

  Serial.println("\n\nTL: === Starting Tinaja Device ===");
  Serial.print("TL: === ");
  Serial.println(topic_loc);
  Serial.print("TL: === ");
  Serial.println(topic_device);

  // set the pins to be used for buttons, LEDs, etc.
  pinMode(PIR_PIN, INPUT);              // set the pin to trigger pir detection
  pinMode(PIR_LED, OUTPUT);             // set the pin to trigger pir detection
  pinMode(WIFI_MNGR_PIN, INPUT_PULLUP); // set the pin to trigger wifiManager
  pinMode(MQTT_LED, OUTPUT);            // Initialize the MQTT_LED pin as an output

  digitalWrite(MQTT_LED, LOW); // turn on LED during setup
  digitalWrite(PIR_LED, LOW);  // turn on LED during setup

  // Create a random client ID
  mqttClientId = "tinajaMQTTClient-";
  mqttClientId += String(random(0xffff), HEX);

  setChipId();
  runWifiManager("auto");

  // setupBme280();
  dht.begin();

  if (!tsl.begin())
  {
    /* There was a problem detecting the TSL2561 ... check your connections */
    Serial.print("TL: Ooops, no TSL2561 detected... Check your wiring or I2C ADDR!");
    while (1)
      ;
  }
  /* Setup the sensor gain and integration time */
  printLuxSensorDetails();
  configureLuxSensor();

  // ----------------------------- set mqtt topics
  Serial.println("TL: final mqtt topics list: ");
  setTopicsDevices();
  setTopicsDht22();
  setTopicsLux();
  setTopicsPir();
  // setBme280Topics();
  // setTmp36Topics();

  // ----------------------------- for mqtt client
  mqttClient.setServer(mqtt_server, 1883);
  mqttClient.setCallback(mqttCallback); // listening for subscriptions

  Serial.println("TL: === Finished setup ===");
  Serial.println("");
  digitalWrite(MQTT_LED, HIGH); // turn off LED after setup
  digitalWrite(PIR_LED, HIGH);  // turn off LED after setup
}

// ==========================================================
// LOOP =====================================================
void loop()
{

  checkWifiManagerButton();

  if (!mqttClient.connected())
  {
    Serial.println("TL: mqttClient not connected...");
    digitalWrite(MQTT_LED, LOW); // turn on LED to indicate disconnected
    long now = millis();
    if (now - lastMqttReconnectAttempt > 10000)
    {
      lastMqttReconnectAttempt = now;
      // Attempt to reconnect
      if (mqttReconnected())
      {
        digitalWrite(MQTT_LED, HIGH);
        lastMqttReconnectAttempt = 0;
      }
    }
    mqttClient.loop();
  }
  else
  {
    // Client connected
    mqttClient.loop();
    digitalWrite(MQTT_LED, HIGH); // turn off LED
  }

  // ----------------------------------------------------------
  // put the main code below, to run repeatedly:

  // publish msgs about the sensor stats
  publishPirValues();
  publishRssiValues();
  publishDHT22Values();
  publishLuxValues();

  delay(250); // longer than 50 if mqttClient is often not connected...
}

// ###############################################################################
// Special Methods: ##############################################################

// ========================== wifi manager methods

// ----------------------------------------------------------
void checkWifiManagerButton()
{
  // if config reset pin has been pushed down
  if (digitalRead(WIFI_MNGR_PIN) == LOW)
  {
    Serial.println("TL:     ========>    Wifi Manager trigger pin detected...");

    delay(50); // poor mans debounce, not recommended for production code
    if (digitalRead(WIFI_MNGR_PIN) == LOW)
    {
      delay(3000);
      // if config reset pin has been pushed down for more than 3 seconds, reset/restart
      if (digitalRead(WIFI_MNGR_PIN) == LOW)
      {
        Serial.println("TL: Trigger pin low for 3+ seconds. Resetting device...");
        runWifiManager("reset"); // < <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< RESET CAN HAPPEN
      }
      else
      {
        Serial.println("TL: Starting config portal, auto ...");
        runWifiManager("auto");
      }
    }
  }
}

// ----------------------------------------------------------
void saveConfigCallback()
{
  //callback notifying us of the need to save config
  Serial.println("TL:  --- Should save config");
  shouldSaveConfig = true;
}

// ----------------------------------------------------------
void runWifiManager(String mode)
{

  //Local intialization. Once its business is done, there is no need to keep it around
  WiFiManager wifiManager;

  wifiManager.setSaveConfigCallback(saveConfigCallback);

  if (mode == "reset")
  {
    Serial.println("TL: Resetting/restarting the current configuration...");
    wifiManager.resetSettings(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< RESET CAN HAPPEN
    ESP.restart();
  }

  // load the settings from the file system (FS), from setupSpiffs
  loadConfigFile();

  Serial.println("TL: starting wifiManager");

  // set up some additional parameters
  WiFiManagerParameter custom_mqtt_server("mqtt_server", "MQTT server addr", mqtt_server, 40);
  WiFiManagerParameter custom_topic_loc("topic_loc", "Topic Location", topic_loc, 30);
  wifiManager.addParameter(&custom_mqtt_server);
  wifiManager.addParameter(&custom_topic_loc);

  wifiManager.setConfigPortalTimeout(60); // sets timeout until configuration portal gets turned off
  wifiManager.setConnectTimeout(5);       // how long to try to connect for before continuing

  // TODO: add password to wifimanager login
  if (mode == "auto")
  {
    Serial.println("TL: Attempting automatic connection");
    if (!wifiManager.autoConnect("TinajaAutoAP"))
    {
      Serial.println("TL: failed to connect and hit timeout");
      delay(3000);
      //reset and try again, or maybe put it to deep sleep
      ESP.reset();
      delay(5000);
    }
  }
  else
  {
    Serial.println("TL: Attempting on demand connection");
    if (!wifiManager.startConfigPortal("TinajaOnDemandAP"))
    {
      Serial.println("TL: Failed to connect and hit timeout");
      delay(3000);
      //reset and try again, or maybe put it to deep sleep
      ESP.reset();
      delay(5000);
    }
  }

  strcpy(mqtt_server, custom_mqtt_server.getValue());
  strcpy(topic_loc, custom_topic_loc.getValue());

  // ----------------------------- save the custom parameters to FS
  if (shouldSaveConfig)
  {
    saveConfigFile();
    shouldSaveConfig = false;
  }

  //if you get here you have connected to the WiFi
  Serial.print("TL: == OK ==  Device is running with IP address: ");
  Serial.println(WiFi.localIP());
  // Serial.println(WiFi.SSID());
  // Serial.println(WiFi.psk());
}

// ----------------------------------------------------------
// mqtt subscription callback listener
void mqttCallback(char *topic, byte *payload, unsigned int length)
{
  Serial.print("TL: Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++)
  {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1')
  {
    digitalWrite(MQTT_LED, LOW); // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  }
  else
  {
    digitalWrite(MQTT_LED, HIGH); // Turn the LED off by making the voltage HIGH
  }
}

// ----------------------------------------------------------
bool mqttReconnected()
{

  // Loop until we're reconnected
  Serial.print("TL: Attempting connection to MQTT server: ");
  Serial.print(mqtt_server);
  Serial.print("...");

  // // Create a random client ID
  // String clientId = "tinajaMQTTClient-";
  // clientId += String(random(0xffff), HEX);

  // Attempt to connect
  if (mqttClient.connect(mqttClientId.c_str()))
  {
    Serial.println("  Connected.");

    // Once connected, publish an announcement...
    char publVal[50];
    snprintf(publVal, 75, "%ld", 0);

    mqttClient.publish(publ_topic, publVal);
    Serial.print("TL:   published to topic: ");
    Serial.println(publ_topic);

    // ... and resubscribe
    mqttClient.subscribe(subs_topic);
    Serial.print("TL:  subscribed to topic: ");
    Serial.println(subs_topic);
  }
  else
  {
    Serial.print("  Not connected, error code: ");
    Serial.println(mqttClient.state());
  }

  Serial.println();
  Serial.println("=========================================================");
  Serial.println();

  return mqttClient.connected();
}

// ----------------------------------------------------------
bool loadConfigFile()
{

  // clean FS, for testing
  // SPIFFS.format(); // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

  //read configuration from FS json
  Serial.println("");
  Serial.print("TL: mounting FS...");

  if (SPIFFS.begin())
  {
    Serial.println("  mounted.");
    if (SPIFFS.exists(CONFIG_FILE))
    {
      //file exists, reading and loading
      Serial.print("TL: reading config file, ");
      Serial.println(CONFIG_FILE);
      File cfgFile = SPIFFS.open(CONFIG_FILE, "r");

      if (cfgFile)
      {
        Serial.println("TL: opened and retrieved data:");
        size_t size = cfgFile.size();

        // Allocate a buffer to store contents of the file.
        std::unique_ptr<char[]> buf(new char[size]);

        cfgFile.readBytes(buf.get(), size);

        DynamicJsonBuffer jsonBuffer;
        JsonObject &json = jsonBuffer.parseObject(buf.get());

        // this prints the json that was loaded
        json.printTo(Serial);

        if (json.success())
        {

          // set up the extra parameters
          if (json.containsKey("mqtt_server"))
          {
            strcpy(mqtt_server, json["mqtt_server"]);
          }
          if (json.containsKey("topic_loc"))
          {
            strcpy(topic_loc, json["topic_loc"]);
          }

          Serial.println("\nTL: successfully loaded json config");
        }
        else
        {
          Serial.println("\n\nTL:  >>> failed to load json config <<<");
        }
      }
    }
  }
  else
  {
    Serial.println("\n\nTL:  >>> failed to mount FS <<<\n\n");
  }
  //end read
}

// ----------------------------------------------------------
bool saveConfigFile()
{

  // write configs to local file store

  Serial.println("TL: Saving config...");
  DynamicJsonBuffer jsonBuffer;
  JsonObject &json = jsonBuffer.createObject();

  // JSONify local configuration parameters

  //  json["ssid"] = ssid;
  //  json["password"] = password;
  json["mqtt_server"] = mqtt_server;
  json["topic_loc"] = topic_loc;

  // Open file for writing
  File cfgFile = SPIFFS.open(CONFIG_FILE, "w");
  if (!cfgFile)
  {
    Serial.println("TL: Failed to open config file for saving");
    return false;
  }

  json.prettyPrintTo(Serial);
  // Write data to file and close it
  json.printTo(cfgFile);
  cfgFile.close();

  Serial.println("\nTL: Config file was successfully saved");
  return true;
}

// ----------------------------------------------------------
void configureLuxSensor(void)
{
  // Configures the gain and integration time for the TSL2561

  /* You can also manually set the gain or enable auto-gain support */
  // tsl.setGain(TSL2561_GAIN_1X); /* No gain ... use in bright light to avoid sensor saturation */
  // tsl.setGain(TSL2561_GAIN_16X);     /* 16x gain ... use in low light to boost sensitivity */
  tsl.enableAutoRange(true); /* Auto-gain ... switches automatically between 1x and 16x */

  /* Changing the integration time gives you better sensor resolution (402ms = 16-bit data) */
  tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_13MS); /* fast but low resolution */
  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_101MS); /* medium resolution and speed   */
  // tsl.setIntegrationTime(TSL2561_INTEGRATIONTIME_402MS);  /* 16-bit data but slowest conversions */

  /* Update these values depending on what you've set above! */
  Serial.println("TL: ------------------------------------");
  Serial.print("TL: Gain:\t");
  Serial.println("1x");
  Serial.print("TL: Timing:\t");
  Serial.println("101 ms");
  Serial.println("TL: ------------------------------------");
}

void printLuxSensorDetails(void)
{
  /* Populate broadband and infrared with the latest values */
  tsl.getLuminosity(&broadband, &infrared);

  sensor_t sensor;
  tsl.getSensor(&sensor);
  Serial.println("\nTL: Lux Sensor Details ------------------------");
  Serial.print("TL: Sensor:\t");
  Serial.println(sensor.name);
  Serial.print("TL: Driver Ver:\t");
  Serial.println(sensor.version);
  Serial.print("TL: Unique ID:\t");
  Serial.println(sensor.sensor_id);
  Serial.print("TL: Max Value:\t");
  Serial.print(sensor.max_value);
  Serial.println(" lux");
  Serial.print("TL: Min Value:\t");
  Serial.print(sensor.min_value);
  Serial.println(" lux");
  Serial.print("TL: Resolution:\t");
  Serial.print(sensor.resolution);
  Serial.println(" lux");
  Serial.print("TL: Broadband:\t");
  Serial.println(broadband);
  Serial.print("TL: Infrared:\t");
  Serial.println(infrared);
}

// ========================== sensor checks ==

// ----------------------------------------------------------
void publishRssiValues()
{
  if (millis() - pubLastRssi <= pubIntervalRssi)
  {
    return;
  }

  int32_t heapValue = ESP.getFreeHeap();
  char heapMsg[50];
  snprintf(heapMsg, 75, "%ld", heapValue);

  Serial.print("TL: mqtt pub - FreeHeap: \t");
  Serial.println(heapMsg);
  mqttClient.publish(heap_topic, heapMsg);

  int32_t rssiValue = WiFi.RSSI();
  char rssiMsg[50];
  // snprintf(rssiMsg, 75, "%ld", WiFi.RSSI());
  snprintf(rssiMsg, 75, "%ld", rssiValue);

  Serial.print("TL: mqtt pub - RSSI level: \t");
  Serial.println(rssiValue);
  mqttClient.publish(rssi_topic, rssiMsg);

  pubLastRssi = millis();
}

// ----------------------------------------------------------
void publishDHT22Values()
{

  if (millis() - pubLastDHT22 <= pubIntervalDHT22)
  {
    return;
  }

  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)

  // delay(2000);
  float h = dht.readHumidity();

  //  // Read temperature as Celsius (the default)
  //  delay(1000);
  //  float t = dht.readTemperature();

  // Read temperature as Fahrenheit (isFahrenheit = true)
  // delay(2000);
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  // if (isnan(h) || isnan(t) || isnan(f)) {
  if (isnan(h))
  {
    Serial.println("TL: Failed to read from DHT humidity sensor!");
    Serial.println(h);
    Serial.println(f);
    return;
  }
  if (isnan(f))
  {
    Serial.println("TL: Failed to read from DHT temperature sensor!");
    // Serial.println(h);
    // Serial.println(f);
    return;
  }

  Serial.print("TL: mqtt pub - temperature:\t");
  Serial.print(f);
  Serial.println(" *F");
  mqttClient.publish(temp_topic, String(f).c_str());

  Serial.print("TL: mqtt pub - rel humidity:\t");
  Serial.print(h);
  Serial.println(" %");
  mqttClient.publish(humi_topic, String(h).c_str());

  pubLastDHT22 = millis();
}

// ----------------------------------------------------------
void publishLuxValues()
{

  if (millis() - pubLastLux <= pubIntervalLux)
  {
    return;
  }

  /* Get a new sensor event */
  sensors_event_t event;
  tsl.getEvent(&event);

  tsl.getLuminosity(&broadband, &infrared);

  /* Display the results (light is measured in lux) */
  uint16_t lux = event.light;
  if (lux)
  {
    char luxMsg[50];
    snprintf(luxMsg, 75, "%ld", lux);
    char luxbbMsg[50];
    snprintf(luxbbMsg, 75, "%ld", broadband);
    char luxirMsg[50];
    snprintf(luxirMsg, 75, "%ld", infrared);

    // these are the raw values
    Serial.print("\tlux level:\t");
    Serial.println(event.light);
    Serial.print("\tbroadband:\t");
    Serial.println(broadband);
    Serial.print("\tinfrared:\t");
    Serial.println(infrared);

    // these are for publishing to mqtt
    Serial.print("TL: mqtt pub - lux:\t\t");
    Serial.println(luxMsg);
    mqttClient.publish(lux_topic, luxMsg);

    Serial.print("TL: mqtt pub - lux broaband:\t");
    Serial.println(luxbbMsg);
    mqttClient.publish(lux_bb_topic, luxbbMsg);

    Serial.print("TL: mqtt pub - lux infrared:\t");
    Serial.println(luxirMsg);
    mqttClient.publish(lux_ir_topic, luxirMsg);
  }
  else
  {
    /* If event.light = 0 lux the sensor is probably saturated
       and no reliable data could be generated! */
    Serial.println("TL: Sensor overload");
  }
  // delay(250);

  pubLastLux = millis();
}

// ----------------------------------------------------------
void publishPirValues()
{

  if (millis() - pubLastPir <= pubIntervalPir)
  {
    return;
  }

  pirState = digitalRead(PIR_PIN);

  if (pirState == LOW) // low means no action
  {
    // pirState = 0;
    digitalWrite(PIR_LED, LOW); // turns ON the LED
  }
  else
  {
    // pirState = 1;
    digitalWrite(PIR_LED, HIGH); // turns OFF the LED
  }

  char pirMsg[50];
  snprintf(pirMsg, 75, "%ld", pirState);

  Serial.print("TL: mqtt pub - PIR state:\t");
  Serial.println(pirMsg);
  mqttClient.publish(pir_topic, pirMsg);

  pubLastPir = millis();
}

void setTopicsDevices()
{
  strcat(rssi_topic, topic_loc);
  strcat(rssi_topic, topic_device);
  strcat(rssi_topic, chipID);
  strcat(rssi_topic, "/");
  strcat(rssi_topic, "device/");
  strcat(rssi_topic, rssi_base);

  strcat(heap_topic, topic_loc);
  strcat(heap_topic, topic_device);
  strcat(heap_topic, chipID);
  strcat(heap_topic, "/");
  strcat(heap_topic, "device/");
  strcat(heap_topic, heap_base);

  strcat(publ_topic, topic_loc);
  strcat(publ_topic, topic_device);
  strcat(publ_topic, chipID);
  strcat(publ_topic, "/");
  strcat(publ_topic, "device/");
  strcat(publ_topic, publ_base);

  strcat(subs_topic, topic_loc);
  strcat(subs_topic, topic_device);
  strcat(subs_topic, chipID);
  strcat(subs_topic, "/");
  strcat(subs_topic, "device/");
  strcat(subs_topic, subs_base);

  Serial.println(rssi_topic);
  Serial.println(publ_topic);
  Serial.println(subs_topic);
}

// ----------------------------------------------------------
void setTopicsDht22()
{
  strcat(temp_topic, topic_loc);
  strcat(temp_topic, topic_device);
  strcat(temp_topic, chipID);
  strcat(temp_topic, "/");
  strcat(temp_topic, "dht22/");
  strcat(temp_topic, temp_base);

  strcat(humi_topic, topic_loc);
  strcat(humi_topic, topic_device);
  strcat(humi_topic, chipID);
  strcat(humi_topic, "/");
  strcat(humi_topic, "dht22/");
  strcat(humi_topic, humi_base);

  Serial.println(temp_topic);
  Serial.println(humi_topic);
}

// ----------------------------------------------------------
void setTopicsLux()
{
  strcat(lux_topic, topic_loc);
  strcat(lux_topic, topic_device);
  strcat(lux_topic, chipID);
  strcat(lux_topic, "/");
  strcat(lux_topic, "tsl2561/");
  strcat(lux_topic, lux_base);

  strcat(lux_bb_topic, topic_loc);
  strcat(lux_bb_topic, topic_device);
  strcat(lux_bb_topic, chipID);
  strcat(lux_bb_topic, "/");
  strcat(lux_bb_topic, "tsl2561/");
  strcat(lux_bb_topic, lux_bb_base);

  strcat(lux_ir_topic, topic_loc);
  strcat(lux_ir_topic, topic_device);
  strcat(lux_ir_topic, chipID);
  strcat(lux_ir_topic, "/");
  strcat(lux_ir_topic, "tsl2561/");
  strcat(lux_ir_topic, lux_ir_base);

  Serial.println(lux_topic);
  Serial.println(lux_bb_topic);
  Serial.println(lux_ir_topic);
}

// ----------------------------------------------------------
void setTopicsPir()
{
  strcat(pir_topic, topic_loc);
  strcat(pir_topic, topic_device);
  strcat(pir_topic, chipID);
  strcat(pir_topic, "/");
  strcat(pir_topic, "pir/");
  strcat(pir_topic, pir_base);

  Serial.println(pir_topic);
}

// ========================== specilized methods

// ----------------------------------------------------------
void setChipId()
{
  snprintf(chipID, 10, "%ld", ESP.getChipId());
  Serial.print("TL: === Device id: ");
  Serial.println(chipID);
  // return chipID;
}
TinajaLabs commented 5 years ago

Things I've done to try and fix the problem...

Aligned the variables associated with the payload value when publishing to MQTT. Changed code like this:

char luxMsg[50];
    snprintf(luxMsg, 75, "%ld", lux);

to this:

char luxMsg[50];
    snprintf(luxMsg, 50, "%ld", lux);

Changed timer variables that change within the loop from long to unsigned long.

unsigned long now = millis();
unsigned long pubLastPir = 0;
tablatronix commented 5 years ago

Lots of code lol

Are you closing spiffs when done with it? Are you passing any of those large char to a async pub func as refs

Are you creating any objects on loops say wifimanager?

I would reduce the complexity, bug could be any one of those sensor libraries, make your code so you can disable large pieces maybe use includes or defines also add a debugging wrapper.

Put a debug log call at every benchmark function say debug func name then in debuglog you can output memory logging and try to narrow it down.

TinajaLabs commented 5 years ago

Screenshot from 2019-05-08 19-46-13

TinajaLabs commented 5 years ago

The above is an image of the free heap over the afternoon. The code reboots after the crash. Once the leak starts it cascades out over about 15 minutes and eventually chokes.

The room sensor sends mqtt data (the publish routines) to node-red and node-red forwards to grafana.

Obviously I don't know where the leak is happening, but I'll look at your advice and see where I can inject a peek at the memory status. The tedious part is that, as you can see in the chart, it takes about an hour to an hour and a half to start the memory leak cascade... ugh.

Thank you.

tablatronix commented 5 years ago

Yeah that is hard to debug, at least its not 24 hours.. maybe you can log what it was doing when the memory starts to change beyond a nominal value, and catch it that way, maybe you get a different response from something, maybe you hit a rate limit threshold

tablatronix commented 5 years ago

I would also remove all string operations for testing, those strcat for example, and use dummy messages

tablatronix commented 5 years ago

I would also suspect anything that you are doing repeatedly like getting something from a class or library, in case the leak in inside one of those, could even be in side esp lib.

ALSO never use loops in esp while (!Serial) ; // wait for serial monitor to open

these are all bad for the watch dog, make sure there is a yield in every loop

dontsovcmc commented 5 years ago

@TinajaLabs a use MQTT with WiFiManager without problems. It can be a bug in char arrays operations... This is a code in my project: https://github.com/dontsovcmc/waterius/blob/master/ESP8266/src/sender_mqtt.h

I don't use SPIFFS, maybe some heap problems...
I also had a bugs with arrays and dangerous functions that don't check null terminators. And my favourite bug is unsigned/signed arithmetic... Every operations with millis() should be unsigned..

Refactor idea: You needn't call setTopicsDevices You can build topic realtime.

int32_t rssiValue = WiFi.RSSI();
  char rssiMsg[50];
  // snprintf(rssiMsg, 75, "%ld", WiFi.RSSI());
  snprintf(rssiMsg, 75, "%ld", rssiValue);

  Serial.print("TL: mqtt pub - RSSI level: \t");
  Serial.println(rssiValue);
  mqttClient.publish(rssi_topic, rssiMsg);

Example:
String topic = topic_loc + topic_device + chipID + "/device/" + rssi_base;
String msg = String((uint16_t)WiFi.RSSI());
mqttClient.publish(topic, msg);

Example 2:
String root = topic_loc + topic_device + chipID;

bool mqtt_publish(const String &section, const String &title, const String &msg)  {
   LOG_DEBUG() << section << title << ": " << msg;
   mqttClient.publish(root + section + title, msg);
}

mqtt_publish("/device", "/rssi/state/room", String((uint16_t)WiFi.RSSI());
TinajaLabs commented 5 years ago

Evgeny,

You have advised a refactoring similar to what I have just done. I refactored all the parts where I used snprintf and it has been running for a few hours now without any change to the HeapFree value. We'll see if it holds.

Instead of using the approach where I use something like this:

int16_t rssiValue = WiFi.RSSI();
char rssiMsg[50];
snprintf(rssiMsg, 50, "%ld", rssiValue);

Serial.print("TL: mqtt pub - RSSI level: \t");
Serial.println(rssiMsg);
mqttPublish(rssi_topic, rssiMsg, false);

I am using this:

int16_t rssiValue = WiFi.RSSI();
mqttPublish(rssi_topic, String(rssiValue).c_str(), true);

Also, your approach to create the concatenated topic string, real-time, with String(type) cast looks very efficient. My thought was to create all the topic strings within the setup and thereafter when I need them, they already exist.

As you can probably see all of the topic string manipulation is so I can use wifimanager to update the location part in the field. The rest of the topic is embedded and is associated with the set of sensors and values built into the device.

Thank you for your help, Chris.

TinajaLabs commented 5 years ago

Ach...

How does one read the stack? Top to bottom, bottom to top? Is this an exact trace through to the actual lines where the error occurred?

I see references to spiffs which I executed early on when launching the application. Perhaps that should be removed per Evgeny's suggestion. What is the alternative to persisting data on esp8266?

Thanks.

0x40214adb: loop_task(ETSEvent*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 133
0x4021326d: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x402159d8: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x4021326d: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x402159d8: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 161
0x4021326d: EspClass::flashWrite(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 634
0x4021595d: spiffs_hal_write(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 127
0x40214b20: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40100119: __wrap_spi_flash_read at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_phy.c line 267
0x40213291: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Esp.cpp line 639
0x40215874: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/spiffs_hal.cpp line 67
0x40221a41: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x40221cd2: new_linkoutput at glue-lwip/lwip-git.c line 238
0x402220b4: ethernet_output at netif/ethernet.c line 312
0x4021b581: _printf_common at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 94
0x40221a41: glue2esp_linkoutput at glue-esp/lwip-esp.c line 299
0x4022978c: etharp_output_to_arp_index at core/ipv4/etharp.c line 770
0x40229990: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x4021fe1e: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021b918: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 194
0x4021fe1e: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 233
0x4021b918: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 194
0x4021fd58: __ssputs_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 180
0x4021ba18: _printf_i at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf_i.c line 244
0x4022022f: _svfprintf_r at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/nano-vfprintf.c line 660
0x40212c9a: DHT::read(bool) at /home/chrisj/Documents/code/arduino/libraries/DHT_sensor_library/DHT.cpp line 221
0x40202291: uart_do_write_char at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/uart.c line 450
0x4021c264: sprintf at ../../../../../../dl/newlib-xtensa/newlib/libc/stdio/sprintf.c line 646
0x40101401: realloc at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/umm_malloc/umm_malloc.c line 1504
0x40213edf: String::changeBuffer(unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/WString.cpp line 156
0x40213490: HardwareSerial::write(unsigned char const*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/HardwareSerial.h line 174
0x40213795: Print::write(char const*) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/Print.h line 60
0x40213edf: String::changeBuffer(unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/WString.cpp line 156
0x40213f2b: String::reserve(unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/WString.cpp line 146
0x40219238: PubSubClient::connected() at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 606
0x4020c294: PubSubClient::publish(char const*, unsigned char const*, unsigned int, unsigned char) at /home/chrisj/Documents/code/arduino/libraries/PubSubClient/src/PubSubClient.cpp line 399
0x40213490: HardwareSerial::write(unsigned char const*, unsigned int) at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/HardwareSerial.h line 174
0x40100a9e: millis at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 183
0x40208277: publishLuxValues() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 869
0x40214b20: esp_yield() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 91
0x40201d6f: delay at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_wiring.c line 51
0x4020a2f9: loop() at /home/chrisj/Documents/code/arduino/tinaja/roomSensor-wfm-lux-temp-hum-01/roomSensor-wfm-lux-temp-hum-01.ino line 295
0x40214bcc: loop_wrapper() at /home/chrisj/.arduino15/packages/esp8266/hardware/esp8266/2.5.0/cores/esp8266/core_esp8266_main.cpp line 125
bkrajendra commented 5 years ago

Hi @TinajaLabs , The best MQTT client i used till date is https://github.com/256dpi/arduino-mqtt It does not have much features, but its light weight and has TLS support. Im using it with my mosquito broker in cloud..!

I also get these issues with Latest release of Arduino Esp8266 core and wifimanager not working together but everytime there was some or other issue i resolved by using some best practices.

Knowing the flow of code and laying things as per it.!

For example once I was having crashing issue with it, I figured it out was due to mDns. If i do mdns before mqtt begin, it used to crash. I resolved it by putting latter.

Next i did not understood but it was unable to connect if i use string for client id and topic. So made sure to convert those string with .c_str(), which resolved issue. I dont undesrstood the exact reson behind this or might be it was related to something else but it worked.

Recently everything was ok. But my server was refusing to connect. Now my code is similar to yours. Complex and long, im using for my IoT hardware... nothing was changed from previous code, but still it was refusing to subscribe or sometime wont connect.

After lot of tries i decide to put a scheduler delay to start mqtt connection after everything finishes on boot. using library https://github.com/Toshik/TickerScheduler

And everything started working fine.

Hope this might help you!

SteveRMann commented 5 years ago

Don't know if you fixed this, but I just had the same issue.

In these lines:

WiFiClient myWifiClient;
PubSubClient mqttClient(myWifiClient);

myWifiClient must be unique within your LAN. If you have another device connecting to PubSubClient, it's client name has to also be unique.