Attempting OTA in a sketch with SmartMatrix and BLE

I’ve succeeded in programming an ESP32-driven SmartMatrix display with demo code via OTA via Wifi (the example code OTAWebUpdater found in the Arduino IDE). I can do this repeatedly with no issue.

However, when I try to blend the web updater code into a sketch that drives my display using SmartMatrix code, and also NimBLE for phone communication, the sketch crashes with the Wifi.begin() call included at the very beginning of the OTA setup. I am calling this after performing all other SM and BLE setup code including mallocs. But I don’t think the Wifi.begin() is actually getting executed…it doesn’t seem like any code is getting executed…there are typically many Serial Monitor outputs I would normally see before this line in the code. Instead, I see repeating CPU Reset in a tight loop (about every 400ms). The start of my code includes several seconds of delay() statements for various reasons which are longer than the 400ms.

Does anyone have any experience getting OTA (Wifi.begin()) and SM and BLE to play nice together, and have suggestions for eliminating the crash? The crash is immediate. Is the Wifi library a heap hog? Before adding in the OTA I’ve got 87k of free heap when loop() begins in my normal sketch.

Summary:

  • My SM-BLE sketch that has all the OTA code commented out except for the single Wifi.begin() call crashes in a tight loop
  • If I comment out that one line of code, the sketch performs perfectly, no crashes.
  • The Wifi.begin() and the rest of the OTA code found in the demo OTAWebUpdater functions exactly as it should when that’s the only code in a sketch.

Are you already making sure to save extra memory with the matrix.begin(minMemoryToSave) parameter?

I hear BLE uses up a ton of RAM and Flash, but don’t know the details.

Try using the ESP Exception Decoder to try to narrow down what’s crashing

I made this project to solve problems like this, separating out the memory intensive SmartMatrix Library and Wifi/BLE/etc code across two ESP32s: https://github.com/Pixelvation/Pixelvation#pixelvation-engine

It’s still in early stages but has been working for me

1 Like

Also, not all memory on the ESP32 is created equal, I’m not sure what type you’re saying is free in the heap. If you look inside SmartMatrix Library, there’s some code to print out all types of memory to see what exactly is free (search for part of the string printed to serial monitor during matrix.begin() to find the right code)

Louis,

Thanks very much for your response.

In the past we’ve tried using the matrix.begin(minMemoryToSave) to set aside heap for other things but have seen problems introduced with SmartMatrix performance (I don’t recall the details, it’s been many months.) I could try this but it seems like we can’t make a huge dent in the ~60k deficit created by the Wifi allocation. (I added reporting of free heap before and after the Wifi.begin() in my working demo sketch and saw a 58k drop.)

Is it possible to use PSRAM for all the SmartMatrix buffers and layers? On my ESP32 WROVER I’ve got about 3MB of PSRAM available.

As far as the “free heap” I’m referencing, it’s what’s reported by the call Serial.println(ESP.getFreeHeap());

After the SmartMatrix allocations in my main sketch, this number is reported as 105k just after I mount LittleFS and then it drops to 87k just after launching NimBLE.

Here’s the output of my matrix.begin(). (This occurs before the LittleFS and NimBLE allocations.) The last free heap report here shows ~107k.

16:47:58.574 → Starting SmartMatrix Mallocs

16:47:58.812 → Heap/32-bit Memory Available: 181728 bytes total, 113792 bytes largest free block
16:47:58.812 → 8-bit/DMA Memory Available : 142564 bytes total, 113792 bytes largest free block
16:47:58.812 → Total PSRAM used: 0 bytes total, 4194252 PSRAM bytes free
16:47:58.812 → SmartMatrix Layers Allocated from Heap:

16:47:58.812 → Heap/32-bit Memory Available: 179716 bytes total, 113792 bytes largest free block
16:47:58.812 → Starting SmartMatrix DMA Mallocs

16:47:58.812 → sizeof framestruct: 00008000

16:47:58.812 → DMA Memory Available before ptr1 alloc: 74568 bytes total, 48224 bytes largest free block
16:47:58.812 → matrixUpdateFrames[0] pointer: 3FFE4374

16:47:58.812 → DMA Memory Available before ptr2 alloc: 74568 bytes total, 48224 bytes largest free block
16:47:58.812 → matrixUpdateFrames[1] pointer: 3FFEC384

16:47:58.812 → Frame Structs Allocated from Heap:

16:47:58.812 → Heap/32-bit Memory Available: 113732 bytes total, 48224 bytes largest free block
16:47:58.812 → 8-bit/DMA Memory Available : 74568 bytes total, 48224 bytes largest free block
16:47:58.812 → Total PSRAM used: 24576 bytes total, 4169644 PSRAM bytes free
16:47:58.812 → Allocating refresh buffer:

16:47:58.812 → lsbMsbTransitionBit of 0 requires 49152 RAM, 48224 available, leaving -928 free:

16:47:58.812 → lsbMsbTransitionBit of 1 requires 24576 RAM, 48224 available, leaving 23648 free:

16:47:58.812 → Raised lsbMsbTransitionBit to 1/7 to fit in RAM

16:47:58.812 → lsbMsbTransitionBit of 1 gives 76 Hz refresh, 240 requested:

16:47:58.812 → lsbMsbTransitionBit of 2 gives 150 Hz refresh, 240 requested:

16:47:58.812 → lsbMsbTransitionBit of 3 gives 287 Hz refresh, 240 requested:

16:47:58.812 → Raised lsbMsbTransitionBit to 3/7 to meet minimum refresh rate

16:47:58.812 → Descriptors for lsbMsbTransitionBit 3/7 with 16 rows require 6144 bytes of DMA RAM

16:47:58.812 → SmartMatrix Mallocs Complete

16:47:58.812 → Heap/32-bit Memory Available: 107556 bytes total, 48224 bytes largest free block
16:47:58.812 → 8-bit/DMA Memory Available : 68392 bytes total, 48224 bytes largest free block
16:47:58.812 → Total PSRAM used: 24576 bytes total, 4169644 PSRAM bytes free
16:47:58.812 → Setting up parallel I2S bus at I2S1

Thanks!
Rick

Before addressing any of the details in my prior post…one quick question…on an ESP32 WROVER, is there a relatively simple way to allocate all the SmartMatrix buffers and layers in PSRAM? If so, can you guide me on how to do that?

I see some code in SmartMatrix.h that seems to support this for Teensy.

Thanks
Rick

Not all memory can go to psram, most of the memory in SmartMatrix is DMA capable ram which is limited

What was your thinking behind making the input be APA102 format? Save reinventing the wheel and nice and high data rates so good for pushing high pixel counts?

Interesting to still have the rendering on a different microcontroller. My dual setups to date have been Teensy for render + FastLED and second controller for WiFi

Save reinventing the wheel and nice and high data rates so good for pushing high pixel counts?

Those, plus almost all existing LED controllers can drive APA102 LEDs, so my board will already be compatible with them. The extra GBC bit in the format can be used for non-lossy brightness control at a minimum. Or with controllers like Pixelblaze with its HDR mode, the GBC bits can be used to send pseudo 13-bit per channel colors.