Monochrome 32*16 P10 HUB12 LED matrix control with ESP32

@BodoMinea I think you have a different issue with your panel. I can’t reproduce it here. If you can get me a sample of your panel (I’m in the UK) or let me know where you got it, I can try to reproduce the issue.

(I didn’t see your other post update when I posted this, maybe you’ve gotten it to work now?)

Nope, that’s another type of panel. HUB75 and RGB. There are two separate topics for the two types I am testing. For those I found the control voltage to be the issue and my level shifts to not be working. Will investigate the shifters you pointed me to, otherwise the issue is software-wise closed as the library is driving them as intended.

But the panels we´re talking about here are HUB12, monochrome and 3v3 friendly (tested with rpi-rgb-led-matrix on Pi 1, 3 and 4, directly connected) but light up the wrong pixels - as seen in the above pictures/videos.

I currently cannot obtain the information regarding their sourcing (I didn’t buy those myself) and also cannot send you one because I am not at my office until later next week. When I get back there I will do that and also test multiple panels I have (I think I also have some red ones with the same arrangement, or at least some red ones that are tested with rpi-rgb-led-matrix as working), test all hardware combinations and if I don’t uncover anything I’ll ask for your details in order to have one delivered to you.

@BodoMinea you might want to lower the clock speed to see if that helps:

Apologies if I already suggested this or you already tried this, I have limited time to help out with these things and can’t keep all the details in my head.

Hi, thank you for your reply. The patch does not work on any version of the display. Also version 3 after pixel negation behaves the same. It is not visible without negation. I also reduced ESP32_I2S_CLOCK_SPEED - nothing. Can I invert a font written with USE_ADAFRUIT_GFX_LAYERS? So I don’t know what to do next.

@renda71 So SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK doesn’t work on any version of the display? What changes if anything?

It doesn’t make any sense that removing pixel negation on version 3 doesn’t change anything. It should invert the pixels on all panels, and you could verify that with one of your other panels.

Can I invert a font written with USE_ADAFRUIT_GFX_LAYERS?

You can make the font color black, and set the background to white. You may find it useful to disable color correction on the layers so that the exact colors you set are sent to the panel instead of applying color (gamma) correction.

@renda71 while I have the HUB12 panels pulled out I’m trying to add support to Teensy 4. The panels I have require OE to be inverted, which isn’t easy to do, so I haven’t done it yet. The result looks inverted like your version 3 video. You may want to try combinations of enabling and disabling OE, R1, and CLK inversion to try to get your version 3 working.

I tried that at an earlier stage, only the ‘flicker’ changes, but the wrong lit up pixels are still at their places.

No worries :slight_smile: I know you’re doing your best to support the widest range of panels but sometimes the Chinese manage to surprise us all.

I am sorry. I described it incorrectly. My English is bad. So after changing (SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK) display versions 1 and 2, the mapping test is unchanged. The version 3 display has changed. This display is inverted hardware. I wanted to try to change it, so my question in the previous post. I can’t change the color of the text. I am doing something wrong.

code:

#define USE_ADAFRUIT_GFX_LAYERS
#include <Wire.h>
#include <MatrixHardware_ESP32_V0.h>
#include <SmartMatrix.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

#define COLOR_DEPTH 24                  // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 32;        // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 32 (untuk 1 baris), 64 (untuk 2 baris)
const uint8_t kRefreshDepth = 24;       // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 2;       // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB12_16ROW_32COL_MOD4SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
//const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_HUB12_MODE);      // see http://docs.pixelmatix.com/SmartMatrix for options
const uint32_t kMatrixOptions = (SMARTMATRIX_OPTIONS_HUB12_MODE | SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK);

const uint8_t kIndexedLayerOptions = (SMARTMATRIX_OPTIONS_HUB12_MODE);
SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);
SMARTMATRIX_ALLOCATE_INDEXED_LAYER(indexedLayer, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);

const uint8_t kMonoLayerOptions = (SM_GFX_MONO_OPTIONS_NONE);
const rgb24 defaultBackgroundColor = {0,0,0};

void setup() {
  
  
  matrix.addLayer(&indexedLayer); 
  matrix.setBrightness(10);
  matrix.begin();
  
  //indexedLayer.fillScreen(0xff); //  this works background is off
  indexedLayer.fillScreen(0x00);
  indexedLayer.setFont(&FreeMonoBoldOblique12pt7b);
  indexedLayer.setTextColor(0x0000); //  the color setting does not work to change the invert pixel
  indexedLayer.drawString(0, -7, 0, "He"); // Tes Vertikal
  indexedLayer.swapBuffers();
 
}

void loop() 
  {

        delay(1000);
  
  }

You’re using the indexed layer which is more complicated. It only has two colors: 0 and 1. 0 is transparent. 1 is whatever color you set with indexedLayer.setIndexedColor().

This code won’t work, 0xff isn’t a valid indexed color for this layer: indexedLayer.fillScreen(0xff);

This code sets the layer color to black:

indexedLayer.setIndexedColor(1, {0,0,0});

indexedLayer.setTextColor(0x0000) doesn’t work as you intended as you’re setting the color to index 0 which is transparent.

This code draws text to the screen with indexed color 1, which is black:

indexedLayer.drawString(0, -7, 1, "He");

You can’t see it though because the transparent pixels see through to the default black color underneath, and you can’t change the default color. You’ll need to add another layer underneath, that could be backgroundLayer, or it could be another indexedLayer with index color 1 set to white, and the screen filled with indexed color 1.

I hope this is not too confusing.

I’m not sure what to suggest for your panels 1 and 2. If you paste the code that you used to test SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK I might be able to spot a bug. e.g. this is incorrect: const uint8_t kIndexedLayerOptions = (SMARTMATRIX_OPTIONS_HUB12_MODE);, HUB12 mode is not an option for the indexed layer

I made a new branch for testing that has two new kMatrixOptions defines:

SM_HUB75_OPTIONS_INVERT_DATA and SM_HUB75_OPTIONS_INVERT_OE are available

SMARTMATRIX_OPTIONS_HUB12_MODE has the same effect as (SM_HUB75_OPTIONS_INVERT_DATA | SM_HUB75_OPTIONS_INVERT_OE) and you can enable either one of them to test different combinations

Thanks for the directions. I have something wrong. I don’t know how to determine the order of the layers.

const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);

SMARTMATRIX_ALLOCATE_INDEXED_LAYER(background, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);
SMARTMATRIX_ALLOCATE_INDEXED_LAYER(layer1, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);

void setup() {

matrix.addLayer(&background);
matrix.addLayer(&layer1);
matrix.setBrightness(10);
matrix.begin();
background.setIndexedColor(1,{0xff,0xff,0xff});
background.fillScreen(1);
background.swapBuffers();
layer1.setIndexedColor(1,{0x00,0x00,0x00});
layer1.setFont(&FreeMonoBoldOblique12pt7b);
layer1.drawString(0, -7, 1, “He”); // Tes Vertikal
layer1.swapBuffers();

}

I don’t see any issues, but I didn’t try it myself. You have the order of the layers correct.

Hi, I have „re-done” all of my tests and will reiterate the information here. I have swapped the matrix for an older but similar one, red LEDs this time, swapped the ESP32 board and set up the wiring again.

Unfortunately the links for buying either of this panels are not up anymore, but I have the specifications of the seller claimed they are saved.

LED Matrix Panel specs
Pixel LED SMD
Pixel Configuration 1 Red
Module Size 320mm × 160mm
Drive Mode Constant Current drive 1/4 scan
Drive IC 74HC595
I searched for these parameters on Aliexpress (the original source for my modules) and found this - https://www.aliexpress.com/item/32958466621.html It is not the listing or seller that I bought from but they seem identical.

This particular matrix is tested as being 3.3v input signal tolerant as it has been properly driven by rpi-rgb-led-matrix with the custom mapping described here - Monochrome 32*16 P10 HUB12 LED matrix control with ESP32 - #10 by BodoMinea

It is also usable with the DMD2 library, at least with the older Arduinos, albeit those output 5V so it doesn’t really help as an arguent - GitHub - freetronics/DMD2: Beta release of a new Dot Matrix Display Arduino library

Picture of the panel’s back side


Chip namings correspond to what the seller listed.

Wiring
Please note that the sides of the connector as I see them are flipped because I am doing the wiring to the ribbon connector.

ESP32 HUB12 ESP32
GPIO5 A 1 - 2 OE GPIO25
GPIO18 B 3 - 4 GND GND
GPIO19 C 5 - 6 GND NC
GPIO22 CLK 7 - 8 GND NC
GPIO26 SCK 9 - 10 GND NC
GPIO2 R 11 - 12 GND NC
NC E 13 - 14 GND NC
NC D 15 - 16 GND NC

Various test sketches
All of them start like this:

const uint16_t kMatrixWidth = 32;
const uint16_t kMatrixHeight = 16*2;

#define USE_ADAFRUIT_GFX_LAYERS

#include <MatrixHardware_ESP32_V0.h>
#include <SmartMatrix.h>
#define COLOR_DEPTH 24
const uint8_t kRefreshDepth = 36;
const uint8_t kDmaBufferRows = 4;

Also, all of them use the mono layer:

SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);

const uint8_t kGFXMonoLayerOptions = (SM_GFX_MONO_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_GFX_MONO_LAYER(backgroundLayer, kMatrixWidth, kMatrixHeight, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kGFXMonoLayerOptions);

#define BLACK   0x0000
#define RED     0xF800

The following test results are different attempts to understand what’s going on by displaying different things with different kMatrixOptions. kPanelType is always SMARTMATRIX_HUB12_16ROW_32COL_MOD4SCAN.

backgroundLayer.setTextSize(2);
backgroundLayer.setTextColor(RED);
backgroundLayer.println("123");

with
SMARTMATRIX_OPTIONS_HUB12_MODE:


same with
SMARTMATRIX_OPTIONS_HUB12_MODE | SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK:

same with
SM_HUB75_OPTIONS_INVERT_DATA:

same with
SM_HUB75_OPTIONS_INVERT_OE:

for(int j=0; j<kMatrixHeight; j++) {
      
    for(int i=0; i<kMatrixWidth; i++) {
      backgroundLayer.drawPixel(i,j,RED);
      backgroundLayer.swapBuffers();   
      delay(250);  

      backgroundLayer.fillScreen(BLACK);
    }
  }

with SMARTMATRIX_OPTIONS_HUB12_MODE:

same with SMARTMATRIX_OPTIONS_HUB12_MODE | SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK:

backgroundLayer.drawLine(0,0,kMatrixWidth,kMatrixHeight/2,RED); with either SMARTMATRIX_OPTIONS_HUB12_MODE or SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK:

Changing the clock speed only affects the extent of flickering and ghosting on the panels which tend to vary a bit between panels, but the bottom line is that no matter what I change - matrix options, the matrix itself, the esp32 etc. the stray/incorrect pixels are still there. However, the same ESP32 can correctly drive HUB75 panels using this library and these panels can be controlled with a Raspberry Pi. So I am at a loss, I cannot seem to isolate the issue.
Do you have any other ideas? Would you like to have one of these modules arranged to be shipped to you?

Thank you again for your time and work.

Hi, I have exactly the same panel as you, it’s version 2. Version 3 works great for me. In the evening I will write what I came up with and send it.

Hi, panels version 1 and 3 work well. The video shows a difference in voltage levels of 3.3 v - 5V. It’s good up to 4.5V. Then you need a level converter. The difference in brightness between 4.5 - 5V is minimal. Version 2 of the panel behaves exactly like you. I used the library I have for it (slow digitalWrite) and it works well. So the mapping has the same as version 1 or 2. I don’t know maybe a small time shift of clk and R1. Thank you very much for your help.

version 1:

version 2:

version 2 library DMD3 ESP32 same connection MatrixHardware_ESP32_V0 Arduino forum:

//#define ESP32_I2S_CLOCK_SPEED (16000000UL)
#define USE_ADAFRUIT_GFX_LAYERS
#include <Wire.h>
#include <MatrixHardware_ESP32_V0.h>
#include <SmartMatrix.h>
#include <Fonts/FreeMonoBoldOblique12pt7b.h>

#define COLOR_DEPTH 24                  // known working: 24, 48 - If the sketch uses type `rgb24` directly, COLOR_DEPTH must be 24
const uint8_t kMatrixWidth = 32;        // known working: 32, 64, 96, 128
const uint8_t kMatrixHeight = 32;       // known working: 32 (untuk 1 baris), 64 (untuk 2 baris)
const uint8_t kRefreshDepth = 24;       // known working: 24, 36, 48
const uint8_t kDmaBufferRows = 2;       // known working: 2-4, use 2 to save memory, more to keep from dropping frames and automatically lowering refresh rate
const uint8_t kPanelType = SMARTMATRIX_HUB12_16ROW_32COL_MOD4SCAN;   // use SMARTMATRIX_HUB75_16ROW_MOD8SCAN for common 16x32 panels
const uint8_t kMatrixOptions = (SMARTMATRIX_OPTIONS_HUB12_MODE);      //  led version 1  10 - 248
//const uint32_t kMatrixOptions = (SMARTMATRIX_OPTIONS_ESP32_INVERT_CLK); //  led version 3 matrix.setBrightness(100) invert 0 max 250 min  5 - 248 

const uint8_t kIndexedLayerOptions = (SM_INDEXED_OPTIONS_NONE);
SMARTMATRIX_ALLOCATE_BUFFERS(matrix, kMatrixWidth, kMatrixHeight, kRefreshDepth, kDmaBufferRows, kPanelType, kMatrixOptions);

SMARTMATRIX_ALLOCATE_INDEXED_LAYER(layer1, kMatrixWidth, kMatrixHeight, COLOR_DEPTH, kIndexedLayerOptions);

void setup() 
  {
  
      matrix.addLayer(&layer1);
      matrix.setBrightness(50); // max 10 - 248 min
      matrix.begin();
      
      layer1.setIndexedColor(1,{0xff,0xff,0xff});
      layer1.setFont(&FreeMonoBoldOblique12pt7b);
      layer1.drawString(0, -7, 1, "Ce"); 
      layer1.swapBuffers();
  
  }

void loop()

  {


  }

Applies to the post below:

You can create and import the fonts you want. Install Java if you don’t have it.

Can you share the ESP32 DMD3 library? I only find the ones for regular Arduino. I’m talking about the one shown working fine in your last video from the post. I would like to test it with my panel. Have you tried chaining two or more version 2 panels with dmd3?

I would really appreciate a link or zip of DMD3 for ESP32 as I cannot seem to find it.

Thanks

Update
Currently found this DMD2 fork - GitHub - swdmnd/DMD2 at esp32_support and this port - GitHub - Qudor-Engineer/DMD32: A library for driving the Freetronics 512 pixel dot matrix LED display "DMD", a 32 x 16 layout using ESP32.

I will be testing both ASAP and then report back

2nd Update
Wow, finally seeing this matrix work with the ESP for the first time. I have found that GitHub - Qudor-Engineer/DMD32: A library for driving the Freetronics 512 pixel dot matrix LED display "DMD", a 32 x 16 layout using ESP32. is working perfectly with the wiring described in the Readme. It’s a little bit of a pain to convert sketches to work with it because it is not Adafruit-GFX compatible but otherwise it runs nice. Refresh rate is OK, smooth scrolling, no flickering or randomly lit up pixels. Looks just like when the panels are controlled with a RasPi. Shame that the library isn’t that well documented and it’s a ‘hard fork’, basically code cloned and new repo made so it can’t really be included in proper pull requests, etc.

Anyway, this is how it looks:
ezgif.com-gif-maker
All my HUB12 panels work great with it! Maybe @Louis can do some magic and use the driver code from that library to widen the support of HUB12 withing SmartMatrix, but that’s up to him :wink:

I have one other idea: lowering the color depth and refresh rate (and maybe the CLK speed too) to reduce the amount of transitions that are sent to the panel.

// use this for 24 updates per row instead of 36
const uint8_t kRefreshDepth = 24;

// in setup, try half the normal 120Hz refresh rate
matrix.setRefreshRate(60);

I’m glad you found an alternate solution, and thanks for sharing details here!

Unfortunately that made no difference for the wrongly lit up pixels.

Thanks for the effort anyway!