SmartMatrix Library ESP32 Port

I’ve been wanting to add WiFi features to the SmartMatrix Library since I came out with the first shield. I looked at each of the recent popular WiFi platforms as they were released, e.g. Particle Photon and ESP8266, and they didn’t have the DMA capabilities that were needed to drive HUB75 panels with high color depth and high refresh rate. I was excited about the ESP32 when I learned of it, as it has a ton of memory, and DMA support. With some very relevant example code that showed how to use the ESP32’s I2S peripheral in parallel mode, plus a lot of hard work, I ported SmartMatrix Library over to the ESP32. There’s still some kinks being worked out, but it’s proving to be a very promising platform.

The SmartMatrix Library ESP32 port at a low level is based on Sprite_TM’s ESP32 I2S Parallel example. The ESP32 can continuously shift data from RAM through the I2S peripheral in parallel to GPIO pins, without using up CPU cycles. This wasn’t obvious to me from reading through the reference manual, and this peripheral doesn’t have great documentation or example code besides Sprite_TM’s example, so this was an invaluable start to the project. It was a challenge to move from the example with 21-bit color refresh to approaching the SmartMatrix Library’s performance on the Teensy with up to 48-bit color and high refresh rates. The example code didn’t scale well in RAM usage or refresh rate when increasing color depth. The architecture of the ESP32 and the Freescale processors used in the Teensy 3 family are so different a lot of the tricks I used on the Teensy 3 wouldn’t port over. There are some significant changes from the Teensy Platform, but in general, sketches that used the Teensy SmartMatrix Library should work with the ESP32 SmartMatrix Library.

ESP32 port of the SmartMatrix Library:

4 Likes

An Alpha-quality version of the library is up on GitHub

There’s still some things being worked out, see the ESP32 section at the top of the README on GitHub. Biggest issue is probably dealing with memory management on the ESP32. When adding other libraries to the project, e.g. SD or WiFi, memory issues can lead to the other libraries not working, or getting into a rolling reboot situation. Moving matrix.begin() later in the sketch, so the SmartMatrix mallocs are the last things called is a decent workaround for now.

2 Likes

Interesting, but I think it’s better to stay in the world of ARM, I mean in the new NXP RT1020 that will probably install the Teensy 4.0.

Going to the NXP RT1020, means having a Cortex M7 at 500Mhz, an extremely powerful micro within the ARM world, which would allow to manage large LED screens with a much higher resolution. And it will be very cheap (around 5 USD in AVNET).

The WIFI can always be added with an ESP8266, it is a simple and inexpensive solution.

I’m not replacing the Teensy with the ESP32, just adding another option for people to use. If a Teensy 4.0 comes out and it’s reasonably easy to port SmartMatrix Library to it, I probably will.

The Teensyduino Arduino integration and Arduino libraries are much more robust than the ESP32’s, as far as I can tell from my limited use. The ESP32 SD library doesn’t conform to the Arduino SD library, and it’s not nearly as straightforward to allocate memory on the ESP32 and see how much is used by a sketch and is still free for use vs the Teensy.

ESP32 supposedly has much better bandwidth than ESP8266.

VS

TCP Socket Throughput - ESP32

1 Like

I pushed some ESP32 updates over the last few days:

  • Added code to automatically lower Frame Rate (the number of times per second the refresh buffer is loaded with a new frame) to leave CPU left for the Sketch to use. Refresh Rate can stay the same. No more blank screen when trying to drive too large of a panel with too high refresh rate or too high color depth.
  • Accurate Frame rate is now shared with layers (so scrolling text should scroll the intended speed regardless of frame rate), and is returned from matrix.getFrameRate()
  • Added argument to matrix.begin() to leave DMA-capable RAM free for other libraries to use
  • AnimatedGIFs improvements
    • now can call matrix.begin(28000) before SD.begin(), leaving 28000 bytes of DMA-capable RAM free for the SD library to use.
    • Added notes on how to use with ESP32 and how to improve performance with large panels on ESP32

Major Update - Compatibility with WiFi and Webserver

I was trying to track down some memory issues, that turned out to be cache access errors from the ISR accessing memory it’s not supposed to. After dramatically simplifying the ISR and creating a new task to handle calculating the data sent to the panel, that error - which was seen when trying to work with more Arduino libraries - is gone and I was able to put together a quick demo of SmartMatrix Library working with WiFi.

I took @Jason’s awesome ESP32 FastLED Web Server sketch, stripped out the FastLED driver code (as it uses WS2812 LEDs) and merged in the FastLED_Functions sketch from the SmartMatrix Library examples. Even after initializing SmartMatrix at the end of the sketch, it requires ~30kB memory free for mallocs used by the WiFi and web server portions of the code.

The sketch is here. If you want to try this, make sure you have the latest code downloaded from the SmartMatrix Library github (TeensyLC branch), and follow the instructions in Jason’s README:

1 Like

Big progress today in reducing the amount of DMA RAM used by the SmartMatrix Library: the RAM required for holding the I2S data is cut in half by changing I2S to 8-bit mode and storing each clock’s data in 8 bits instead of 16. For a 64x64 32-bit panel, the refresh buffer used to take 99kB of RAM, and now takes 49.5kB. This only works with the SmartMatrix Shield (circuit) as there’s an external latch used to reduce the number of GPIO needed for the I2S data down to 8.

This DMA RAM savings should hopefully allow for more applications that use WiFi and other peripherals to work with the SmartMatrix Library. I have a sketch that uses WiFi to get the time and the SD library to play Animated GIFs, and it was too much RAM to drive a 64x64 panel even with only 24-bit color before. Now it works with 64x64 and 36-bit color.

For anyone finding this post that needs ESP32 I2S Parallel working in 8-bit Mode, hopefully this GitHub commit gets you going in the right direction (it’s not well documented in the reference manual and what I have working seems like a bit of a hack!):

1 Like

Hello Louis.

Do you know a good tutorial on how to configure and use DMA with Kinetis?, A long time ago I looked for information about it for STM32, Kinetis and Atmel SAM S70.

I just found good information for STM32 in the book MASTERING STM32 by Noviello, and some information in the Teensy libraries for Kinetis.

It is really difficult to find a detailed tutorial on DMA. I think it is something extremely powerful and essential for certain developments, but there is very little information that explains in detail how to use it.

In June, the Cortex M7 i.MX RT1020 TQFP at 500 Mhz from NXP will be available, and I am very interested in new developments, I would like to be able to handle HUB75 LED panels with hardware based on the RT1020, but it will also be essential to use the DMA , I hope NXP will provide better documentation on this matter.

I am very interested in the DMA, for quite some time, but I can not find a good tutorial that explains in detail how to use it and how to configure all the parameters, especially for SPI and GPIO, with STM32, Kinetis and SAM S70.

I was very interested in the Atmel SAM S70 microcontroller, a very powerful Cortex M7, but in the end I discarded it due to lack of information to use the DMA.

Best Regards

I don’t know of any tutorials on DMA. I got my start with the Teensy DMA by looking at Paul’s DMAChannel class, the OctoWS2811 class, and the Kinetis Reference Manual for the Teensy 3.1’s CPU. I agree that DMA in general isn’t well documented so that it could be accessible by more people, and DMA implementations differ a lot between different vendors (and by different parts, e.g. Teensy 3.1’s CPU vs Teensy LC).

ok, thanks for the information, I’m going to look at those libraries to see if I can learn how to configure and use the DMA.

Hello guys, First I would like to say thanks so very much to all the contributors to this!

I found SmartMatrix today, and it’s clearly the way to go using DMA.
I have my 32x64 panel working that I got from Sparkfun (RGB LED Matrix Panel - 32x64, cant post link as new users can only post 2). So at least it confirms the wiring is good. I used logic level shifters for all the I/O.

I am a hardware design engineer by trade, and my goal is to create a PCB using either a ESP-32 WROOM module or a ESP32-WROVER module (this has 4MB ram) onto a PCB that will plug directly into these panels without any wiring (with the exception of power) for a more simplistic design. As I learn more about who are the main contributors are like (Louis) I will send them a free board when it’s done, if he would like one.

What I am having trouble understanding is that from this repo, I see there are files specifically for the esp32.
Yet I also see this GitHub here which is clear on how to wire it up via GPIO. I am confused on why there are 2 sources each of which has code for the ESP32.

I have taken the first GitHub link sources, and it compiles just fine using Platform io. I am confused as what to do next. If i use the first link, is that to only be used with the SmartMatrix SmartLED Shield (V4) ?

Would someone please shed some clarity for me please.

Hi Mike,

This is where I’m doing the esp32 dev for the SmartMatrix Library, and before the next major release I’ll merge that code into the master branch.

This other repo was my modifications to an I2S Parallel example posted on the ESP32 forum. I shared my modifications to help other people that found the thread and need I2S Parallel support. You don’t need to do anything with it.

Here’s the forum thread in case you’re interested in it.

Going from the first link, check out the hardware files in the extras/hardware directory. There’s schematics and boards for two versions (THT and SMT) you can start with. Ideally you’d wire it up following the schematic, using an external latch. I highly recommend you put that circuit on your board as future improvements to the library will depend on that circuit. In the meantime if you just want to get something working quickly, you can use a simpler circuit described in the hardware section of the README.

Your board idea sounds great. That’s the direction I’m moving toward with this project too, though I’m still in firmware mode, working out some of the kinks of getting malloc working on the ESP32 for larger panel sizes. If you want to collaborate on the board design/requirements, I’m open to that, either here in the forum or by email (my name @pixelmatix.com).

Hi Louis,
I am trying to get this working on the ESP32with a 64x64 display but I keep getting a ‘cant find DMAChannel.h’ message but I can’t find the file anywhere and google is helping.
I am using the code from here GitHub - pixelmatix/SmartMatrix at teensylc and have a ‘ESP Dev module’ selected in the compiler but cant even compile the examples.
Am I missing something?

Hope you can help,
Kev.

Are you sure you selected an ESP32 Target, and not ESP8266?

Yep, Tried most of the ESP32 boards but none compile.
I have got the PxMatrix libraries to work ok using the NodeMCU-32S board but just cant compile smartmatrix.

Thought I must be missing something in the setup but maybe not.
I grabbed another laptop and setup the latest IDE and ESP32 core and it compiled straight away, now just have to rewire to suit the parallel I/O.
I found the panel pins but can you tell me what these two pins do ?
#define GPIO_PWM0A_OUT GPIO_NUM_32
#define GPIO_SYNC0_IN GPIO_NUM_34

Hmmmm looking at the circuit, it looks like I cant connect to the led matrix without the latches etc …
Where can I buy an ESP32 shield ?

Check out the “hardware” section in the README

You can use a circuit without the latch, but the code to support it is broken at the moment. Check out the code from a few commits ago: May 4th.

It’s possible you have a SmartMatrix Library checkout somewhere else in your Arduino directory, and the IDE is compiling using the other SmartMatrix Library and not the teensylc branch.

I rewired the matrix to suit the header file, compiled the examples and viola, a picture! although it was a bit mixed up… So I rolled back the library to May 4 as per your suggestion and it works great!
This is a fantastic library, thanks for your all your work.
Now I’ve just got to find something to use it for :slight_smile:

Glad it’s working. I committed a fix, so you should be able to use the latest going forward.