[SOLVED] 64x32 LED matrix Library recommendation ?!

OS: Linux Mint 17.1
Board: ESP32 Wrover-B DevKitV4 https:/ /i.postimg.cc/LsxKbjWC/20190405-135731-1.jpg
Display: 2727 SMD P5 64x32 1/8 scan: https:/ /www.aliexpress.com/item/SMD-2727-P5-outdoor-Video-wall-led-module-high-brightness-5500-nits-1-8-scan-64/32788680216.html

Links have a added white space between the 2 backslashes: http:/ / because as a new user I can’t have more than 2 links on a post.

Hello !

I’ve just found this awesome community ! I hope I will be able to find the answers I’m looking for.

Short story:

What library can I use together with SPIFFS, ESPAsyncWebServer and HTTPClient ? And eventually I will need to link up to 16 displays.

Long story (for maximum effect reading the linked issues is advised):

For the past 3 weeks I’ve been trying to integrate a 64x32 LED Display into my project, which uses SPIFFS + ESPAsyncWebServer to serve some web-pages while in AP Mode and some other web-pages while in STA Mode.

First, I’ve tried using NeoCat’s library: https:/ /github.com/NeoCat/ESP32-P3RGB64x32MatrixPanel
but with no luck.

Then I found and used PxMatrix: https:/ /github.com/2dom/PxMatrix . But this also has it’s problems.

Now I’ve found this: https:/ /community.pixelmatix.com/t/has-anyone-used-https-github-com-2dom-pxmatrix/384 and this http:/ /marc.merlins.org/perso/arduino/post_2019-04-01_SmartMatrix_-SmartMatrix-Shield-v4-for-Teensy_-ESP32-shield-with-level-shifter_-and-SmartMatrix_GFX.html and learned that both of the above mentioned libraries aren’t good.

Is there any library that can be used with my project ?

Thank you !

I posted this to the GitHub issue you also opened:

I don’t know about PxMatrix or ESPAsyncWebServer, sorry.

Marc Merlin runs his AnimatedGIFs sketch with SPIFFS, and I think found some issues with it, but worked around them. Take a look at this: New AnimatedGifs with FFat support on ESP32

1 Like

It’s interesting that google took you to those two other projects first, likely because they mention “ESP32” in their description while SmartMatrix doesn’t?
@Louis I know that ESP32 isn’t production quality from your point of view, but honestly I use it quite a bit and it works well enough for me once I figured out the memory issues. I do limit myself to drawpixel though and don’t use your APIs at all. The backend driver works great though.
Would you consider adding a blurb in https://github.com/pixelmatix/SmartMatrix about ESP32 so that people can find you right away?
In the meantime, I guess my connex page that does mention both, does help people find you :slight_smile:
Feel free to take anything from the ESP32 section of that page: http://marc.merlins.org/perso/arduino/post_2019-04-01_SmartMatrix_-SmartMatrix-Shield-v4-for-Teensy_-ESP32-shield-with-level-shifter_-and-SmartMatrix_GFX.html#ESP32

From what I’ve seen, it’s an inferior library to SmartMatrix on ESP32

the only reason to use this lib is if you are stuck with ESP8266. When it works, it is 6 times slower.

Indeed, you’ll want to use SmartMatrix. Try just the basic example that comes with the lib (but switch to the teensylc branch or ESP32 will not work). Then see the tips I gave in my post under the ESP32 section on wiring and which file to change for the pin mapping.
Once you get a basic display working, install my SmartMatrix::GFX library and you’ll get GFX support on top of SmartMatrix.

For SPIFFS, it does work, but if you are reading a lot of data from it, it stalls a bit in my experience. This may not be an issue for you though, so for now concentrate on getting SmartMatrix and SmartMatrix::GFX working.

Good luck

1 Like

I’ve found SmartMatrix when looking for a LED Library but the ReadMe there is very hard to follow. It’s a lot of theory, but without actual instructions.

I avoided the library because I had no idea how to do the wiring. And I still don’t !
Which one is the basic example ?
Will it work with a 64x32 with 1/8 scan Matrix ?
Is there any: " This is how you do it, step-by-step guide " ?

It also states very clearly that it still has problems with RAM Usage.
Yet, I believe that every Matrix Library running on ESP32 has problems with RAM Usage.

Still seeing some crashes related to memory usage early in sketch when other memory intensive objects (e.g. WiFi library) are included in the sketch? Need to reproduce and track down

  • May see a rolling reset before the sketch can do much
    • This is hopefully fixed now. Please post to the SmartMatrix Community or create a GitHub Issue if you see this error: “Guru Meditation Error: Core 1 panic’ed (Cache disabled but cached memory region accessed)”

And it seems like a lot MORE work to make it work than the PxMatrix, for example.
Reading around the github and the forum I’ve found A LOT of libraries and APIs and it’s very confusing. There are SmartMatrix, FastLED, NeoMatrix, LEDMatrix, SmartMatrix_GFX…
It’s very confusing. There isn’t ONE guide that explains where should you start and what to actually use for your project. Everything is thrown at you. For a newcomer like me it doesn’t make any sense.
Also, there are shields and no shields versions. I need direct wiring because I am working with a breadboard.

I would really like to know if I can use it within my project, which, as I said, contains a lot of SPIFFS interactions like reading from and writing to a file and serving web-pages; contains a lot of Strings; going from AP to STA using ESPAsyncWebServer, constantly checking in loop for a URL’s body, parsing it and displaying 2 digits and greater-than sign on a LED Matrix.

I don’t find PxMatrix stable, because I have to do some workarounds, since it isn’t compatible with ESPAsyncWebServer, HTTPClient or SPIFFS, I am not sure which one. I also have to close the display each time I access a SPIFFS file or a web-page and then open it, and this produces an ugly effect or flicker.

Here is a sample of my project, in STA mode, currently using PxMatrix:

#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>
#include <SPIFFS.h>
#include <HTTPClient.h>
#include <PxMatrix.h>

#define P_LAT 22
#define P_A 19
#define P_B 23
#define P_C 18
#define P_D 4
#define P_E 15
#define P_OE 25
hw_timer_t * timer = NULL;

#define matrix_width 64
#define matrix_height 32

PxMATRIX display(matrix_width,matrix_height,P_LAT, P_OE,P_A,P_B,P_C,P_D,P_E);

uint8_t display_draw_time= 40;

uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myBLACK = display.color565(0, 0, 0);

void IRAM_ATTR display_updater(){
  // Increment the counter and set the time of ISR

void display_update_enable(bool is_enable){
  if (is_enable) {
    timer = timerBegin(0, 80, true);
    timerAttachInterrupt(timer, &display_updater, true);
    timerAlarmWrite(timer, 2000, true);
  else  {

void fileReadLines(File file, String x[]) {
  int i = 0;
        String line= file.readStringUntil('\n');
        x[i] = line;

unsigned int number = 0;
String IPAddr = "";
const char* ssid = "ssid";
const char* password = "password";

AsyncWebServer server(80);

void setup() {
  WiFi.begin(ssid, password);
  int k = 0;
  while (WiFi.status() != WL_CONNECTED && k<20) {
    Serial.println((String)"Attempt " + k + " - Connecting to WiFi..");


  if(WiFi.status() == WL_CONNECTED) {
    IPAddr = WiFi.localIP().toString();
    Serial.println((String)"Connected to " + ssid + " with IP addres: " + IPAddr);
  } else {
      Serial.println("Couldn't connect to WiFi Network. Restarting in 5 seconds...");
      display.print("Error 1 - Restarting in 5 sec!");

  if (!SPIFFS.begin(true)) {
    Serial.println("An Error has occurred while mounting SPIFFS ! Formatting in progress");

  server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/url_page.html", "text/html");
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
  server.on("/logs", HTTP_GET, [](AsyncWebServerRequest* request){
    request->send(SPIFFS, "/events.html", "text/html");
  server.on("/jquery-1.12.4.min.js", HTTP_GET, [](AsyncWebServerRequest* request){
    request->send(SPIFFS, "/jquery-1.12.4.min.js", "text/javascript");
  server.on("/style_url.css",HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/style_url.css", "text/css");
  server.on("/master.css", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/master.css", "text/css");
  server.on("/back-image.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/back-image.jpg", "image/jpeg");
  server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/logo.png", "image/png");
  server.on("/url", HTTP_POST, [](AsyncWebServerRequest * request){
    int params = request->params();
    String URL;
    for(int i=0;i<params;i++){
      AsyncWebParameter* p = request->getParam(i);
          Serial.println((String)"POST[" + p->name().c_str() + "]: " + p->value().c_str() + "\n");             
          URL = p->value();      
        } else {
            Serial.println((String)"GET[" + p->name().c_str() + "]: " + p->value().c_str() + "\n"); 
    } // for(int i=0;i<params;i++)
    if(URL != NULL && URL.length() != 0) {
      File urlWrite = SPIFFS.open("/urlFile.txt", "w");
      if(!urlWrite) Serial.println((String)"ERROR_INSIDE_URL_POST ! Couldn't open file to write URL !");
    } else {


void show_on_display(unsigned int nr) {
  display.setCursor(44,5); //- cursor for 1 digit number
  if(nr == 0) {
  } else if(nr >9) {
    display.setCursor(26,5); //- cursor for 2 digits number

void parse_URL(String string) {
  int f = string.indexOf("FREE");
  String Free = string.substring(f);
  Free.remove(0, 4);
  number = Free.toInt();

void loop() {
  display_update_enable(false); // close before accessing SPIFFS file
  if (WiFi.status() == WL_CONNECTED) {  //Check the current connection status 
    File urlRead = SPIFFS.open("/urlFile.txt");
    if(!urlRead) Serial.println((String)"ERROR_INSIDE_loop ! Couldn't open file to read !");

    if(urlRead.size() > 10) {      
      HTTPClient http;
      String URL;
      Serial.println((String)"URL: ");
      fileReadLines(urlRead, &URL);
      http.begin(URL); //Specify the URL
      display_update_enable(true); // open after we've finished accessing SPIFFS file
      int httpCode = http.GET(); //Make the request
      if (httpCode > 0) { //Check for the returning code
        Serial.println((String)"[HTTP] GET... code: " + httpCode);
        if(httpCode == HTTP_CODE_OK) {
          String payload = http.getString();
      } else {
          Serial.println((String)"[HTTP] GET... failed, error: " + http.errorToString(httpCode).c_str());
      http.end(); //Free the resources
      } else {
        Serial.println("URL Link is invalid ! Please enter another URL");

Also, another question I had was what is the maximum numbers of display I can use with either library ?

Thank you !

I agree that the SmartMatrix page could do a better job helping people who don’t use the SmartMatrix Shield for teensy. If you use that shield, there are clear instructions, but basically you just plug it in :slight_smile:

For ESP32, I gave you a link of what I wrote which itself points you to

That should be pretty clear wiring-wise, what you need to do.

It’s not a problem with 64x32, or likely 64x64, but once you go beyond that, yes, you’re starting to hit limits.
My page, again, gives details on how to deal with it but I’d say 96x64 is likely a limit for SmartMatrix (actually 128x64 may be possible if you don’t have other code running, like I do). I think another lib could use less RAM, for one, I would be perfectly fine with 16bpp instead of 24bpp

I am not using Wifi yet, but I’ve seen Wifi cause problems with many libraries that use both cores, be it SmartMatrix or FastLED, or others.

A few thoughts

  1. No one is centrally in charge, everyone writes their own bit :slight_smile:
  2. I actually spent many hours writing documentation to try to clear things up for the newcomer.
    https://github.com/marcmerlin/SmartMatrix_GFX goes into details about the multiple libraries out there as well as APIs and basically lets you run all the APIs on top of SmartMatrix
    http://marc.merlins.org/perso/arduino/post_2019-04-01_SmartMatrix_-SmartMatrix-Shield-v4-for-Teensy_-ESP32-shield-with-level-shifter_-and-SmartMatrix_GFX.html gives more details.
    All in all, I spent close to 2 days writing all this up to help people like you.

I see no reason why it shouldn’t work, outside of possible conflicts with Wifi.

Are you using ESP8266 with PxMatrix ? This is because ESP8266 is single core and SPIFFS takes interrupts that stop the RGBPanel refresh.
Either way, I have seen some issues with SPIFFS a while ago and I switched to FatFS.
http://marc.merlins.org/perso/arduino/post_2019-03-30_Using-FatFS-FFat-on-ESP32-Flash-With-Arduino.html but I doubt it will work better on ESP8266. The chip is just too slow and resource constrained.

For ESP32, my patch in https://github.com/espressif/arduino-esp32 was accepted, you can simply select FatFS in the partition type if you use git master

It’s not a question of how many displays, but size of total display.
I expect PxMATRIX to not be great because it’s 6 times slower with its single color wire used for all 6 color components. I’m not sure what its actual limit is, but the refresh rate will be a problem that will make you want not to use it on 64x64 or bigger (IMO)
SmartMatrix can barely reach 128x128 with teensy 3.6 on some displays, and 96x128 on other ones (depends how they are run).
On ESP32, I think the limit is 96x96 or 128x64 but I haven’t tried past 96x64.

1 Like


OMG, great answer, thank you ! I have a lot of reading to do.

I am using a ESP32 Wrover-B DevKitV4.

I am dependent on SPIFFS. Learning to use another file system and also implementing it in my project will take too much time. It will be like starting all over and I don’t really have time left for that. I should’ve finished this project a long time ago.

This is how I serve web-pages from SPIFFS using ESPAsyncWebServer:

  server.on("/url", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/url_page.html", "text/html");
  server.on("/jquery-1.12.4.min.js", HTTP_GET, [](AsyncWebServerRequest* request){
    request->send(SPIFFS, "/jquery-1.12.4.min.js", "text/javascript");
  server.on("/style_url.css",HTTP_GET, [](AsyncWebServerRequest *request){
    request->send(SPIFFS, "/style_url.css", "text/css");
  server.on("/master.css", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/master.css", "text/css");
  server.on("/back-image.jpg", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/back-image.jpg", "image/jpeg");
  server.on("/logo.png", HTTP_GET, [](AsyncWebServerRequest *request) {
    request->send(SPIFFS, "/logo.png", "image/png");

I don’t know if ESPAsyncWebServer will be able to do this with FatFS.
Also, I am using Arduino IDE and/or Platformio IDE, not esptool and I don’t know what changing to FatFS implies.

You’re saying that 128x64 is the absolute limit of the ESP32 when using SmartMatrix. But how do people use those 2 meters long LED Matrixes outside their shops ? (This is for another project)

FatFS is meant to work like SPIFFS API-wise, it took me very little work to switch. That said, forget about switching to FatFS for now, worry about other issues first. SPIFFS may just work well enough on ESP32 for you (when it doesn’t on the single core ESP8266)

I use the arduino IDE too, I only used esptool once to upload my FatFS filesystem.
See https://github.com/marcmerlin/AnimatedGIFs/blob/master/Makefile

I didn’t test it, but that’s my understanding. SmartMatrix is very memory hungry. It uses 6 times the size of the framebuffer due to how it does things.

They use FPGA based solutions. That said a Raspberry Pi should also do the job.
https://github.com/hzeller/rpi-rgb-led-matrix is what I’m looking at next given the lack of drivers for newer panels in SmartMatrix and the size limits.

There are still some things that I don’t get:


    #pragma message "ESP32 forum wiring"

    // ADDX is output directly using GPIO
    #define CLKS_DURING_LATCH   0 
    #define MATRIX_DATA_STORAGE_TYPE uint16_t

This is the one I should use right ?

It says: #define MATRIX_DATA_STORAGE_TYPE uint16_t, but in the ReadMe it’s:

With the addition of the external latch, there are only 8 bits of data to output via I2S, and so each clock cycle’s data fits into a uint8_t instead of uint16_t. With the I2S peripheral in 8-bit mode instead of 16-bit mode, the amount of RAM used to store refresh buffers is cut in half

In this case which one is it: uint8_t or uint16_t ?

Aso, there are pins that I can’t use, like 0 (This is the BOOT button, you can’t put a wire to it),12(this is a bootstrap pin) ,16,17( these two aren’t accessible on my Wrover-B).
I only have 14 pins available.
Can I change the pins to other GPIO ? Can I make my own wiring ?

I’ve ended up changing all GPIO inside #elif (GPIOPINOUT == ESP32_FORUM_PINOUT) as follows :

    #define R1_PIN  25
    #define G1_PIN  5
    #define B1_PIN  26
    #define R2_PIN  27
    #define G2_PIN  23
    #define B2_PIN  14

    #define A_PIN   13
    #define B_PIN   21
    #define C_PIN   18
    #define D_PIN   19
    #define E_PIN   22
    #define LAT_PIN 15
    #define OE_PIN  4

    #define CLK_PIN 2

I hope it’s ok. I also removed MatrixHardware_KitV1.h and MatrixHardware_KitV4.h from src folder.

What are these ?

    #define GPIO_PWM0A_OUT GPIO_NUM_32
    #define GPIO_SYNC0_IN  GPIO_NUM_34

Are these wires ?

I also don’t know what’s ADDX, I Googled it and apparently it’s a DJ…

Also, @marcmerlin, your blog appears to be down. I couldn’t reach it today at all.



const uint8_t kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels

Is there any kPanelType option for 64x32 with 1/8 scan display ?

Answer: there isn’t ! I need to make one, but only God understands these instructions: https://github.com/pixelmatix/SmartMatrix/blob/teensylc/examples/MultiRowRefreshMapping/MultiRowRefreshMapping.ino

I’ve put the library in Arduino and it compiles, but it asks me to update it to 3.2 and I have no idea if 3.2 will work on a ESP32.
I’ve put this library in PlatformIO and it does not compile :

In file included from .piolibdeps/SmartMatrix3/src/SmartMatrix3.h:175:0,
from src/main.cpp:15:
.piolibdeps/SmartMatrix3/src/SmartMatrix_Impl.h:26:24: fatal error: DMAChannel.h: No such file or directory

I use the ESP32_JC_RIBBON_PINOUT because that’s what my shield has, but doesn’t matter which one you pick as long as you wire accordingly.

you don’t need to change that if you’re doing direct wiring without latch, which is what I did.

yes you can use other pins or use ESP32_JC_RIBBON_PINOUT

I don’t know, didn’t touch that. I just defined the 14 wires I needed in ESP32_JC_RIBBON_PINOUT and wired them.

The datacenter was down a few hours while I was sleeping apparently, but it came back before I woke up.

can’t help with that bit, sorry. I’d say don’t worry about that for now and see whether you get any output at all. If you do, you can fix the panel type.

No idea what library you’re talking about, I don’t use platformIO, I just use the arduino env with esp32-arduino from git master

Not sure about this. I can see it’s included in my source too, and it’s not provided by anything but teensyduino which should not be visible when I’m compiling for ESP32.
Honestly I have no idea how this one works. @Louis may be able to help.

Seems like the released Teensy-only version of the SmartMatrix library is being compiled. Try removing it

@Louis, see https://github.com/pixelmatix/SmartMatrix/blob/teensylc/src/SmartMatrixAPA102RefreshEsp32_Impl.h#L26
this seems wrong in an Esp32_Impl file.

@GeorgeFlorian you are however getting this error in SmartMatrix_Impl.h which shows that you are likely using the master branch which does not support ESP32, instead of the teensylc branch which does support ESP32.

Maybe that’s the problem ! The library that I’ve used in Arduino IDE is SmartMatrix-teensylc.
The problem with Platformio IDE is that I’ve referenced the link to the library https://github.com/pixelmatix/SmartMatrix.git which is the same for all the branches and probably it links the master branch.

But it’s beside the point.

My main problem is that I have no idea how to use this library with my display.

@marcmerlin, @Louis
Please take a look at this post. This is what’s actually important ! I’ve posted a video and a lot of details of what my issues are.

I would really love an answer there.

Please ! Thank you !

I saw your other post. There are several panel types that aren’t supported by SmartMatrix yet and Louis hasn’t had time to add support for them, but does accept pull requests.
That said, it sounds like the panel you mention should at least light up somewhat, but not completely.
I would recommend you get at least the panel to light up first (use the arduino platform first and once that works you can try switching back to platformio), and then worry about the panel details.

It does light up. As shown in the video, while running MultiRowRefreshMapping
I’ve also tried FastLED_Functions.ino. The image is split in 4. It’s like a puzzle that doesn’t match.

Sorry, I missed that part (many Emails and replies to deal with).
Ok, so you got the compile working and ESP32 wiring working.
So now you’re indeed left with a mapping issue.
I’ll be honest with you, from what I’ve seen in the last 6 months here, @Louis doesn’t have a lot of spare time, especially to work on panels he doesn’t own.
So, your 3 reasonable options are

  1. look at his post on supporting other mappings that he made https://github.com/pixelmatix/SmartMatrix/blob/teensylc/examples/MultiRowRefreshMapping/32x16-MOD4-panel-map.jpg for and figure out the code needed for your panels
  2. send him a panel and money to have him do it for you (as contract work basically), or find someone else here willing/able to do it
  3. switch to rPi and https://github.com/hzeller/rpi-rgb-led-matrix which is more likely to support your panel


I am sorry that I’ve been insisting / obsessing over this, but it’s my internship project and it would help me a lot to finish it.
You’ve been of great help and I am really grateful for that.

I’ve been trying to decipher that for the past couple of days, but I had no luck. There are a lot of things I don’t understand.

I don’t think I can do that…

I’ve just learned a few things on ESP32. I had no previous experience with programming on other micro-controllers. Getting a new micro-controller to code on will mean to start the project all over and I can’t do that. The thing is that my project is not only about being able to control a LED Display. It has to do a lot more. I’ve explained this in my other post.

The only option available to me is to get a new display that actually works with this library.

Is there a list of “officially” supported LED Displays/Matrixes ?

Yes, getting a new panel would be a lot simpler indeed.
Having an exact list of supported panels is hard because chinese vendors change them all the time without changing the description.
You can know for sure that the ones from adafruit and sparkfun will work, but they cost a fair amount more, there.
I bought this one, but it’s already out of stock: https://www.amazon.com/dp/B07F2JW8D3?tag=bizzi0d-20
Then I have these on my shirt but they’ll take 2 weeks to ship from china: https://www.amazon.com/dp/B07F87CM6Y?tag=bizzi0d-20

You can look amazon for other ones an read the comments.
Basically if it works with the adafruit library, it’ll work with SmartMatrix (SmartMatrix supports more than adafruit)

So only 64x32 with 1/16 and 32x16 with 1/8 are supported ?

kPanelType = SMARTMATRIX_HUB75_32ROW_MOD16SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels


works on most panels.

You set the size with
const uint8_t kMatrixWidth = 32; // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32; // known working: 16, 32, 48, 64

The 3 panel types are here AFAIK

So only 64x32 with 1/16 ,32x16 with 1/8 and 128x64 1/32 are supported ?


And there is no way to define your own scan pattern ?

I assume that this panel has 1/16 scan, right ?