1
\$\begingroup\$

I'm having a problem with my ESP-WROOM-32. I have a web app that worked fine in my mobile phone until a page with contact information was added. This contact information page has 7 images in .png format.

The curious thing that is happening is that when I load the app from my phone, the page waits for a certain time, and after that the ESP chip resets itself.

The message it sends through the serial port is the following:

E (25998) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:    
E (25998) task_wdt:  - async_tcp (CPU 0/1)
E (25998) task_wdt: Tasks currently running:
E (25998) task_wdt: CPU 0: IDLE
E (25998) task_wdt: CPU 1: loopTask
E (25998) task_wdt: Aborting.

abort() was called at PC 0x400e5e4d on core 0

Backtrace:0x4008364d:0x3ffbe9ec |<-CORRUPTED

ELF file SHA256: 0000000000000000

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4

After this last line my program starts again and connects again, and I can access the web app until I try to load the contact page, then it doesn't load all the images and resets itself again.

NOTE: this only happens when I load the web app from my cellphone, it doesn't happen when I load the web page from my computer.

So, what could be happening here?

UPDATE 03/01/2023-7:00p.m.: I just tested the app with a phone whose Android version is version 9 and it worked perfectly, then I put my phone on the side of the other, I loaded the page from my phone and the ESP32 restarted again. I suppose it has something to do with the Android version, but I don't know.

UPDATE 04/01/2023 at 8:30a.m.

In order to complement the information with @nanofarad asked I ran the application again, this time I put debug messages on console on every request response from the server when it loads the content of the "contact" page and its images (this is the page where the problem happens) and the following was obtained

Entrando a página Contacto.
Cargando logo-empresa
Cargando logo-venapp
Cargando logo-whatsapp
Cargando logo-facebook
Cargando logo-youtube
E (20176) task_wdt: Task watchdog got 
triggered. The following tasks did not reset 
the watchdog in time:    
E (20176) task_wdt:  - async_tcp (CPU 0/1)
E (20176) task_wdt: Tasks currently running:
E (20176) task_wdt: CPU 0: IDLE
E (20176) task_wdt: CPU 1: loopTask
E (20176) task_wdt: Aborting.

abort() was called at PC 0x400e5f01 on core 0


Backtrace:0x4008364d:0x3ffbe9ec |<-CORRUPTED




ELF file SHA256: 0000000000000000

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 
(SPI_FAST_FLASH_BOOT)configsip: 0, 
SPIWP:0xee
rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4
Entrando a configuración de aplicación
Inicializado el Sistema de archivos.
Conectado a la red TP-LINK_D6BF4E
Dirección IP asignada: 192.168.1.101
Saliendo de configuración de aplicación
Cargando logo-linkedin

I also have a screenshot of the loaded page and looks like follows

Partially loaded images

if looked carefully then can be seen than in the screenshot none of the images is completely loaded when the ESP32 resets itself, then in the log can be seen by the phrase "Cargando logo-..." when the program makes any of the query's, the server supplies 6 logos if the header logo is accounted and apparently after the fifth of the social networks logos are called then the ESP32 resets, after the reset is completed, the system initializes again too and loads the Async server then the following social network logo called logo-facebook (the seventh) is called/loaded, in this moment is the instagram logo that isn't loaded and the previous logos doesn't completely loads. Note that I don't know why the logo-facebook image is loaded after the reset. I can only supose that the web browser keeps waitin until the server respond to make the remaining requests.

But important: of the three devices with which I'm testing the app, only fails with my cellphone which has installed chrome apk version 108.0.5359.128, the other too works fine.

I also readed this post and found that the ESP32 can open one socket a time so I think may be this browser tries to open more than one socket and it doesn't closes it on time so the ESP resets itself because of that.

Right now I'm researching how to print the request/response to/from the Async server.

UPDATE 04/01/2023 at 2:49p.m.

I apparently found the the explanation of whats happening in this other post from several possible solutions:

  1. One solution is to load 5 files maximum on a page and I was loading at least 8 files, that is because apparently SPIFFS library only supports 5 files open/sent at a time. I reduced the amount of files loaded and the web app worked well at all times and in at the three devices.
  2. To augment the Async TCP event queue number of events because apparently my web page in some browser generates a lot of events that the ESP32 can't handle because of the event queue limit, this event limit is set by default to 32 and in the post the person who solved the problems changed the max number of events to 256; is not mandatory to use that number but is a way to ensure some degree of freedom to load files from the file system.
  3. Some other options goes from compress several files and give instructions to the web browser through the response callback the browser to manage the descompression and uses of the files by itself.

So I applied the second options and now my web app works fine, i'll see if it doesnt fails in future.

And Thanks again for the help.

\$\endgroup\$
10
  • \$\begingroup\$ could be a bug in your program ... difficult to guess accurately \$\endgroup\$
    – jsotola
    Commented Jan 4, 2023 at 1:09
  • \$\begingroup\$ I thought that but I just tested it with other phone whose android version (9) is lower from mine (11) and it worked perfectly, I suppose the problem must be related to the chrome version itself but I don't know \$\endgroup\$
    – vram
    Commented Jan 4, 2023 at 1:18
  • \$\begingroup\$ @jsotola please read the last update I did to the post \$\endgroup\$
    – vram
    Commented Jan 4, 2023 at 1:23
  • \$\begingroup\$ Do you have request headers or any kind of packet capture showing the differences in the request and/or any partial response before the crash? \$\endgroup\$
    – nanofarad
    Commented Jan 4, 2023 at 1:29
  • \$\begingroup\$ what does this mean? ... put my phone on the side of the other \$\endgroup\$
    – jsotola
    Commented Jan 4, 2023 at 1:34

3 Answers 3

4
\$\begingroup\$

I encountered a similar problem on ESP32.

One nice aspect of Arduino environment is lots of libraries that do what you need. However, these libraries are contributions from many different people, and they are of varying quality levels. Some are excellent, some suck, some would be great but contain a few showstopping bugs, and some do not work at all.

For example, AsyncTCP will crash randomly. It depends on concurrency between requests, which depends on how your browser does requests, so it makes sense that it crashes with one browser and works with another one. Due to its asynchronous nature and extremely complex code, it is pretty much impossible to debug, and it feels like the developers have given up. This is not surprising: asynchronous is the kind of stuff that is much better handled at the language level (with built-in coroutines) or at least with the help of a solid coroutine library (like AceRoutine). This is because callbacks obscure the control flow of the program, so it is often impossible to figure out what the program is doing, even to know its state at a given time, and don't think about testing for all the corner cases... that does not tend to play well with languages with manual memory allocation.

Any programmer who is smart enough to write correct callback-based asynchronous code in C++ is also smart enough to understand why callback-based asynchronous code is absolute hell: they will most often not bother to write said code, and instead dodge or eliminate the problem by factoring it out into coroutines.

Therefore, if you see a very large codebase full of asynchronous callback-based code, it is safe to assume it was written by someone who isn't smart enough to write it, and you should run away from it.

All libraries using it will thus also crash randomly. This makes the whole thing unusable.

Apparently someone has decided to rewrite it. I wish them good luck.

Another one is delayMicroseconds() which adds a random number of microseconds to the delay due to the specific ESP32 implementation, which means any library using delayMicroseconds to bit bang protocols on GPIO will also randomly not work due to timing failures. This includes OneWire.

Doing projects with arduino usually entails using libraries to make a proof of concept, then replacing the libraries that don't work (or rewriting them), it's just a fact of life.

So I wrote a coroutine-based HTTP server, which took much less time than to debug ESPAsyncTCP, and now it works fine.

\$\endgroup\$
2
  • \$\begingroup\$ I could found the solution. Please see the last update. \$\endgroup\$
    – vram
    Commented Jan 4, 2023 at 19:07
  • \$\begingroup\$ Yes the link you posted is a good example of why asynchronous callback-based programming is hell, especially when locks get involved and no-one has no idea who's responsible for that queue. If you reduce the number of images in your page, it will still crash if two different clients request the page at the same time. A webserver is not supposed to reboot when that happens, worst case it could respond "503 overloaded try again later" XD \$\endgroup\$
    – bobflux
    Commented Jan 4, 2023 at 19:48
1
\$\begingroup\$

There are three possible solutions to this problem as I could find (found on github), more details on the last update of the original post, the possible solutions and are as follows:

  1. One solution is to load 5 files maximum on a page and I was loading at least 8 files, that is because apparently SPIFFS library only supports 5 files open/sent at a time. I reduced the amount of files loaded and the web app worked well at all times and in at the three devices.

  2. To augment the Async TCP event queue number of events because apparently my web page in some browser generates a lot of events that the ESP32 can't handle because of the event queue limit, this event limit is set by default to 32 and in the post the person who solved the problems changed the max number of events to 256; is not mandatory to use that number but is a way to ensure some degree of freedom to load files from the file system.

  3. Some other options goes from compress several files and give instructions to the web browser through the response callback the browser to manage the descompression and uses of the files by itself.

I used the first option which is by now I think what has less process capacity cost

\$\endgroup\$
0
\$\begingroup\$

Follow this checklist before

  1. Check both connection method, http/https connection methods can be different between browsers
  2. Check (if possible) response status on your browser debugger
  3. Print all the request payload (headers/content/…) in your monitor (if the program reaches this point). Also you have to compare the first one of the good working phone, and the second with yours

Then you’re may able to know if the problem comes on your program, or in your libraries, or in a wrong setup. If the first matches the issue, try to work with library versions

Looking at your logs, you can try to avoid the error by resetting manually the watchdog or disabling it for the looptask.

\$\endgroup\$
2
  • \$\begingroup\$ Right now I'm researching how to print the request payload but I added more information y you want to see \$\endgroup\$
    – vram
    Commented Jan 4, 2023 at 14:20
  • \$\begingroup\$ I could found the solution. Please see the last update. \$\endgroup\$
    – vram
    Commented Jan 4, 2023 at 19:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.