Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1/8 Scan Panel support - 64 x 32 panel horizontal lines doubled #154

Closed
donnersm opened this issue Jul 21, 2021 · 73 comments
Closed

1/8 Scan Panel support - 64 x 32 panel horizontal lines doubled #154

donnersm opened this issue Jul 21, 2021 · 73 comments
Labels
not an issue with library This library is working as it should, but something else causes an issue to be aware of. workaround exists A workaround exists for this. Read the issue comments.

Comments

@donnersm
Copy link

I just tested a panel i just received today. Its a 64 x 32 panel.
It looks like the horizontal is not working, lines are doubled in an array of 8
Anyone recognise this or is this a defective panel?
(Beside from the defective pixel near one corner)

IMG_4341.mp4
@mrcodetastic
Copy link
Owner

Can you draw a single diagonal line as well?

Looks like some address line issue, check the A,B,C,D pin mapping - perhaps the pins may have moved? Who knows. There seems to be a few of these issues being raised recently.

@donnersm
Copy link
Author

I Checked the pins on the display and all is "standard" except the LAT pin is called STB.
I tried a vertical line and a circle:

dma_display->clearScreen();
dma_display->drawLine(dma_display->width()-1, 0, 0, dma_display->height()-1, dma_display->color444(15, 0, 0));
dma_display->clearScreen();
delay(500);
dma_display->fillCircle(40, 21, 10, dma_display->color444(15, 0, 15));

Here are the photo's of that result:
vertical
circle

@mrcodetastic
Copy link
Owner

Closing this issue as it's superseded by #164

@AlfioSaitta
Copy link

I Checked the pins on the display and all is "standard" except the LAT pin is called STB. I tried a vertical line and a circle:

dma_display->clearScreen();
dma_display->drawLine(dma_display->width()-1, 0, 0, dma_display->height()-1, dma_display->color444(15, 0, 0));
dma_display->clearScreen();
delay(500);
dma_display->fillCircle(40, 21, 10, dma_display->color444(15, 0, 15));

Here are the photo's of that result: vertical circle

I have the exact same problem. Have you finally solved it?

@DarrylStrong
Copy link

Do you have a picture of the back of the PCB? Connectors and driver ICs?

@donnersm
Copy link
Author

donnersm commented Oct 6, 2021

I didnt solve it. It turned out to be a 1/8 scan panel which is not supported by the library. We should be able to change the libary because it is al telated to the way the data is sorted bitwise before sending it to the panel but my knowledge of this lib is limited

@AlfioSaitta
Copy link

Do you have a picture of the back of the PCB? Connectors and driver ICs?

  • The ICs are some ICN2037BP
  • The connections are direct from my AZ-Delivery DevKitC V4 to the HUB75 connector on the panel

My simple code with the git version of the library:

#define MATRIX_WIDTH 64
#define MATRIX_HEIGHT 32
#define CHAIN_LENGTH 1
#define MATRIX_ROWS_IN_PARALLEL 2
#define PIXEL_COLOR_DEPTH_BITS 8

#define R1_PIN  2
#define G1_PIN  15
#define B1_PIN  4
#define R2_PIN  16
#define G2_PIN  27
#define B2_PIN  17

#define A_PIN   5
#define B_PIN   18
#define C_PIN   19
#define D_PIN   -1 // Connected to GND on panel (21 if exist)
#define E_PIN   -1 // Connected to GND on panel

#define LAT_PIN 26
#define OE_PIN  25
#define CLK_PIN 22

#include <Arduino.h>
#include <Wire.h>
#include <SPI.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;

void setup() {

  Serial.begin(115200);

  delay(1000);

  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };

  // Module configuration
  HUB75_I2S_CFG mxconfig(
      MATRIX_WIDTH, // module width
      MATRIX_HEIGHT, // module height
      CHAIN_LENGTH, // Chain length
      _pins);

  //mxconfig.driver = HUB75_I2S_CFG::SHIFTREG;
  //mxconfig.double_buff = true;
  //mxconfig.clkphase = false;
  //mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);

  dma_display->begin();
  dma_display->setBrightness8(100); //0-255
  dma_display->clearScreen();

  // First Half Display
  dma_display->drawLine(0, 0, 15, 0, dma_display->color444(0, 15, 0));
  dma_display->drawLine(0, 1, 31, 1, dma_display->color444(15, 0, 0));
  dma_display->drawLine(0, 2, 63, 2, dma_display->color444(0, 0, 15));

  // Second Half Display
  dma_display->drawLine(0, 16, 15, 16, dma_display->color444(0, 15, 15));
  dma_display->drawLine(0, 17, 31, 17, dma_display->color444(15, 15, 0));
  dma_display->drawLine(0, 18, 63, 18, dma_display->color444(15, 0, 15));
}

void loop() {
    //delay(20); 
}

IMG_20211009_152437

IMG_20211009_151858

IMG_20211009_151833

IMG_20211009_151749

@mrcodetastic
Copy link
Owner

mrcodetastic commented Oct 9, 2021

Looks like a pretty simple issue to fix with your own custom code, looks like 2 X 1/4th of the panel rows chained together, for both the top and bottom halves of the display.

Change the width of the display of the library to double the physical width and play around?

@AlfioSaitta
Copy link

Looks like a pretty simple issue to fix with your own custom code, looks like 2 X 1/4th of the panel rows chained together, for both the top and bottom halves of the display.

Change the width of the display of the library to double the physical width and play around?

#define MATRIX_WIDTH 128
#define MATRIX_HEIGHT 32
#define CHAIN_LENGTH 1
#define MATRIX_ROWS_IN_PARALLEL 2
#define PIXEL_COLOR_DEPTH_BITS 8

Result with these settings:
IMG_20211009_155330

@AlfioSaitta
Copy link

AlfioSaitta commented Oct 9, 2021

Looks like a pretty simple issue to fix with your own custom code, looks like 2 X 1/4th of the panel rows chained together, for both the top and bottom halves of the display.

Change the width of the display of the library to double the physical width and play around?

Eureka... very strange settings... but work :D

IMG_20211010_005725

My code:

#define CHAIN_LENGTH 2

#define R1_PIN  2
#define G1_PIN  15
#define B1_PIN  4
#define R2_PIN  16
#define G2_PIN  27
#define B2_PIN  17

#define A_PIN   5
#define B_PIN   18
#define C_PIN   19
#define D_PIN   -1 // Connected to GND on panel (21 if exist)
#define E_PIN   -1 // Connected to GND on panel

#define LAT_PIN 26
#define OE_PIN  25
#define CLK_PIN 22

#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;

void testScreen() {
  // Red 8 Rows
  for (int x=0; x <= 64; x++) {
    dma_display->drawPixel(63+x,0,dma_display->color565(255, 0, 0)); // ROW 1
    dma_display->drawPixel(63+x,1,dma_display->color565(210, 0, 0)); // ROW 2
    dma_display->drawPixel(63+x,2,dma_display->color565(180, 0, 0)); // ROW 3
    dma_display->drawPixel(63+x,3,dma_display->color565(150, 0, 0)); // ROW 4
    dma_display->drawPixel(63+x,4,dma_display->color565(125, 0, 0)); // ROW 5
    dma_display->drawPixel(63+x,5,dma_display->color565(90, 0, 0)); // ROW 6
    dma_display->drawPixel(63+x,6,dma_display->color565(60, 0, 0)); // ROW 7
    dma_display->drawPixel(63+x,7,dma_display->color565(40, 0, 0)); // ROW 8
  }

  // Green 8 Rows
  for (int x=0; x <= 63; x++) {
    dma_display->drawPixel(0+x,8,dma_display->color565(0, 255, 0)); // ROW 9
    dma_display->drawPixel(0+x,9,dma_display->color565(0, 210, 0)); // ROW 10
    dma_display->drawPixel(0+x,10,dma_display->color565(0, 180, 0)); // ROW 11
    dma_display->drawPixel(0+x,11,dma_display->color565(0, 150, 0)); // ROW 12
    dma_display->drawPixel(0+x,12,dma_display->color565(0, 125, 0)); // ROW 13
    dma_display->drawPixel(0+x,13,dma_display->color565(0, 90, 0)); // ROW 14
    dma_display->drawPixel(0+x,14,dma_display->color565(0, 60, 0)); // ROW 15
    dma_display->drawPixel(0+x,15,dma_display->color565(0, 40, 0)); // ROW 16
  }

  // Blue 8 Rows
  for (int x=0; x <= 63; x++) {
    dma_display->drawPixel(64+x,16,dma_display->color565(0, 0, 255)); // ROW 17
    dma_display->drawPixel(64+x,17,dma_display->color565(0, 0, 210)); // ROW 18
    dma_display->drawPixel(64+x,18,dma_display->color565(0, 0, 180)); // ROW 19
    dma_display->drawPixel(64+x,19,dma_display->color565(0, 0, 150)); // ROW 20
    dma_display->drawPixel(64+x,20,dma_display->color565(0, 0, 125)); // ROW 21
    dma_display->drawPixel(64+x,21,dma_display->color565(0, 0, 90)); // ROW 22
    dma_display->drawPixel(64+x,22,dma_display->color565(0, 0, 60)); // ROW 23
    dma_display->drawPixel(64+x,23,dma_display->color565(0, 0, 40)); // ROW 24
  }

  // White 8 Rows
  for (int x=0; x <= 63; x++) {
    dma_display->drawPixel(0+x,24,dma_display->color565(255, 255, 255)); // ROW 25
    dma_display->drawPixel(0+x,25,dma_display->color565(210, 210, 210)); // ROW 26
    dma_display->drawPixel(0+x,26,dma_display->color565(180, 180, 180)); // ROW 27
    dma_display->drawPixel(0+x,27,dma_display->color565(150, 150, 150)); // ROW 28
    dma_display->drawPixel(0+x,28,dma_display->color565(125, 125, 125)); // ROW 29
    dma_display->drawPixel(0+x,29,dma_display->color565(90, 90, 90)); // ROW 30
    dma_display->drawPixel(0+x,30,dma_display->color565(60, 60, 60)); // ROW 31
    dma_display->drawPixel(0+x,31,dma_display->color565(40, 40, 40)); // ROW 32
  }
}

void setup() {

  Serial.begin(115200);
  delay(1000);

  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };
  HUB75_I2S_CFG mxconfig( 64, 32, CHAIN_LENGTH, _pins);

  mxconfig.double_buff = true;
  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->setBrightness8(20); //0-255
  dma_display->clearScreen();
}

void loop() {
    delay(20); 
    testScreen();
}

@mrcodetastic
Copy link
Owner

mrcodetastic commented Oct 10, 2021

Good work on figuring that out. As expected, it's actually a chain of panels, with some weird chaining going on there between the 1/4ths of the panel, with the 2nd 1/4th being chained to the first (top) 1/4th of the panel.

What happens when you set:
HUB75_I2S_CFG mxconfig( 64, 32, CHAIN_LENGTH, _pins);
to
HUB75_I2S_CFG mxconfig( 64, 16, CHAIN_LENGTH, _pins);

Because if you do the math, 8 pixels of each 'half' of the panel don't actually get used given this library is designed for 1/2 scan panels, and these panels actually chain the 2nd 1/4th with the 1st 1/4.

@mrcodetastic
Copy link
Owner

mrcodetastic commented Oct 10, 2021

All you need to do is make your own wrapper to this library, like the 'Virtual Display' cpp file, which will override the operation of the drawPixel() function based on the value of the x-coord - then you have yourself a working library for these 1/4 scan panels.

Feel free to contribute then :-)

@mrcodetastic mrcodetastic changed the title 64 x 32 panel horizontal lines doubled 1/4 (or 1/8?) Scan Panel - 64 x 32 panel horizontal lines doubled Oct 10, 2021
@mrcodetastic mrcodetastic added the not an issue with library This library is working as it should, but something else causes an issue to be aware of. label Oct 10, 2021
@mrcodetastic mrcodetastic reopened this Oct 10, 2021
@mrcodetastic mrcodetastic added the workaround exists A workaround exists for this. Read the issue comments. label Oct 10, 2021
@AlfioSaitta
Copy link

Good work on figuring that out. As expected, it's actually a chain of panels, with some weird chaining going on there between the 1/4ths of the panel, with the 2nd 1/4th being chained to the first (top) 1/4th of the panel.

What happens when you set: HUB75_I2S_CFG mxconfig( 64, 32, CHAIN_LENGTH, _pins); to HUB75_I2S_CFG mxconfig( 64, 16, CHAIN_LENGTH, _pins);

Because if you do the math, 8 pixels of each 'half' of the panel don't actually get used given this library is designed for 1/2 scan panels, and these panels actually chain the 2nd 1/4th with the 1st 1/4.

Result with your settings and corrected the math a bit:

IMG_20211010_120358

#define CHAIN_LENGTH 2 // 2 Chained panels
#define PANEL_WIDHT 64
#define PANEL_HEIGHT 16 // 1/8 Scan in the specifics ???

#define R1_PIN  2
#define G1_PIN  15
#define B1_PIN  4
#define R2_PIN  16
#define G2_PIN  27
#define B2_PIN  17

#define A_PIN   5
#define B_PIN   18
#define C_PIN   19
#define D_PIN   -1 // Connected to GND on panel (21 if exist)
#define E_PIN   -1 // Connected to GND on panel

#define LAT_PIN 26
#define OE_PIN  25
#define CLK_PIN 22

#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;

void testScreen() {
  
  for (int x=0; x <= 63; x++) {

    // Red 8 Rows
    dma_display->drawPixel(64+(x),0,dma_display->color565(255, 0, 0)); // ROW 1
    dma_display->drawPixel(64+(x),1,dma_display->color565(210, 0, 0)); // ROW 2
    dma_display->drawPixel(64+(x),2,dma_display->color565(180, 0, 0)); // ROW 3
    dma_display->drawPixel(64+(x),3,dma_display->color565(150, 0, 0)); // ROW 4
    dma_display->drawPixel(64+(x),4,dma_display->color565(125, 0, 0)); // ROW 5
    dma_display->drawPixel(64+(x),5,dma_display->color565(90, 0, 0)); // ROW 6
    dma_display->drawPixel(64+(x),6,dma_display->color565(60, 0, 0)); // ROW 7
    dma_display->drawPixel(64+(x),7,dma_display->color565(40, 0, 0)); // ROW 8

    // Blue 8 Rows
    dma_display->drawPixel(0+x,0,dma_display->color565(0, 0, 255)); // ROW 9
    dma_display->drawPixel(0+x,1,dma_display->color565(0, 0, 210)); // ROW 10
    dma_display->drawPixel(0+x,2,dma_display->color565(0, 0, 180)); // ROW 11
    dma_display->drawPixel(0+x,3,dma_display->color565(0, 0, 150)); // ROW 12
    dma_display->drawPixel(0+x,4,dma_display->color565(0, 0, 125)); // ROW 13
    dma_display->drawPixel(0+x,5,dma_display->color565(0, 0, 90)); // ROW 14
    dma_display->drawPixel(0+x,6,dma_display->color565(0, 0, 60)); // ROW 15
    dma_display->drawPixel(0+x,7,dma_display->color565(0, 0, 40)); // ROW 16

    // White 8 Rows
    dma_display->drawPixel(64+x,8,dma_display->color565(255, 255, 255)); // ROW 17
    dma_display->drawPixel(64+x,9,dma_display->color565(210, 210, 210)); // ROW 18
    dma_display->drawPixel(64+x,10,dma_display->color565(180, 180, 180)); // ROW 19
    dma_display->drawPixel(64+x,11,dma_display->color565(150, 150, 150)); // ROW 20
    dma_display->drawPixel(64+x,12,dma_display->color565(125, 125, 125)); // ROW 21
    dma_display->drawPixel(64+x,13,dma_display->color565(90, 90, 90)); // ROW 22
    dma_display->drawPixel(64+x,14,dma_display->color565(60, 60, 60)); // ROW 23
    dma_display->drawPixel(64+x,15,dma_display->color565(40, 40, 40)); // ROW 24

    // Green 8 Rows
    dma_display->drawPixel(0+x,8,dma_display->color565(0, 255, 0)); // ROW 25
    dma_display->drawPixel(0+x,9,dma_display->color565(0, 210, 0)); // ROW 26
    dma_display->drawPixel(0+x,10,dma_display->color565(0, 180, 0)); // ROW 27
    dma_display->drawPixel(0+x,11,dma_display->color565(0, 150, 0)); // ROW 28
    dma_display->drawPixel(0+x,12,dma_display->color565(0, 125, 0)); // ROW 29
    dma_display->drawPixel(0+x,13,dma_display->color565(0, 90, 0)); // ROW 30
    dma_display->drawPixel(0+x,14,dma_display->color565(0, 60, 0)); // ROW 31
    dma_display->drawPixel(0+x,15,dma_display->color565(0, 40, 0)); // ROW 32
  }
}

void setup() {

  Serial.begin(115200);
  delay(1000);

  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };

  HUB75_I2S_CFG mxconfig( PANEL_WIDHT, PANEL_HEIGHT, CHAIN_LENGTH, _pins);

  mxconfig.double_buff = true; // ????
  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->setBrightness8(200); //0-255
  dma_display->clearScreen();
}

void loop() {
    //delay(40); 
    testScreen();
}

After researching in various Chinese retailers and factories, i found some more information on the panel:

Pixel Pitch: P4
Dimension: 128X256
Lamp bead: RGB
LED Type: SMD1921
Scanning Mode: 1/8

@mrcodetastic
Copy link
Owner

Hi @AlfioSaitta - thanks again for the great work with trying this out, really helps me understand what's going on here!

I did notice one thing with you photo, what's the go on the top left? Looks to be a row of missing pixels? Or is the pixels broken in that area?

image

@mrcodetastic mrcodetastic changed the title 1/4 (or 1/8?) Scan Panel - 64 x 32 panel horizontal lines doubled 1/8 Scan Panel support - 64 x 32 panel horizontal lines doubled Oct 10, 2021
@AlfioSaitta
Copy link

Hi @AlfioSaitta - thanks again for the great work with trying this out, really helps me understand what's going on here!

I did notice one thing with you photo, what's the go on the top left? Looks to be a row of missing pixels? Or is the pixels broken in that area?

I think it's a power problem. I'm using the raspberry power supply to power the panel 👯

VID_20211010_125932.mp4

@mrcodetastic
Copy link
Owner

Good work. I've created a 'VirtualDisplay' like class that does co-ordinate re-mapping, like it seems you have coded manually.

I don't have one of these 1/8 scan panels - can you try this out?

https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/tree/master/examples/One_Eighth_1_8_ScanPanel

@AlfioSaitta
Copy link

Good work. I've created a 'VirtualDisplay' like class that does co-ordinate re-mapping, like it seems you have coded manually.

I don't have one of these 1/8 scan panels - can you try this out?

https://github.com/mrfaptastic/ESP32-HUB75-MatrixPanel-I2S-DMA/tree/master/examples/One_Eighth_1_8_ScanPanel

Yes, of course

@mrcodetastic
Copy link
Owner

Whoops. I've fixed that.

@AlfioSaitta
Copy link

Something went wrong!!!

IMG_20211010_224105

#define PANEL_WIDHT 64
#define PANEL_HEIGHT 32

#define PANEL_CHAIN NUM_ROWS*NUM_COLS    // total number of panels chained one to another
  
// Change this to your needs, for details on VirtualPanel pls read the PDF!
#define SERPENT true
#define TOPDOWN false

#define R1_PIN  2
#define G1_PIN  15
#define B1_PIN  4
#define R2_PIN  16
#define G2_PIN  27
#define B2_PIN  17

#define A_PIN   5
#define B_PIN   18
#define C_PIN   19
#define D_PIN   -1 // Connected to GND on panel (21 if exist)
#define E_PIN   -1 // Connected to GND on panel

#define LAT_PIN 26
#define OE_PIN  25
#define CLK_PIN 22

#include <Arduino.h>
//#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>
#include <OneEighthScanMatrixPanel.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;
OneEighthMatrixPanel *virtualDisp = nullptr;

void setup() {

  Serial.begin(115200);
  delay(100);

  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };

  HUB75_I2S_CFG mxconfig( PANEL_WIDHT*2, PANEL_HEIGHT/2, PANEL_CHAIN, _pins);

  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->setBrightness8(30); //0-255
  dma_display->clearScreen();

  // create VirtualDisplay object based on our newly created dma_display object
  virtualDisp = new OneEighthMatrixPanel((*dma_display), 1, 1, PANEL_WIDHT, PANEL_HEIGHT, SERPENT, TOPDOWN);

  virtualDisp->setTextColor(virtualDisp->color565(0, 0, 255));
  virtualDisp->setCursor(0, virtualDisp->height()/2); 

  // Red text inside red rect (2 pix in from edge)
  virtualDisp->print("  1234");
  virtualDisp->drawRect(1,1, virtualDisp->width()-2, virtualDisp->height()-2, virtualDisp->color565(255,0,0));

  // White line from top left to bottom right
  virtualDisp->drawLine(0,0, virtualDisp->width()-1, virtualDisp->height()-1, virtualDisp->color565(255,255,255));

}

void loop() {
  //delay(40); 
}

@mrcodetastic
Copy link
Owner

@AlfioSaitta
Copy link

AlfioSaitta commented Oct 10, 2021

Some tests with lines before your last changes:

  virtualDisp->drawLine(0, 0, 63, 0, virtualDisp->color565(255,255,255)); // VISIBLE ON ROW 1
  virtualDisp->drawLine(0, 8, 63, 8, virtualDisp->color565(255,255,0)); // VISIBLE ON ROW 13 (WITH LAST PIXEL RED)
  virtualDisp->drawLine(0, 9, 63, 9, virtualDisp->color565(255,0,0)); // VISIBLE ON ROW 13 (COVERS THE PREVIOUS ROW)
  virtualDisp->drawLine(0, 17, 63, 17, virtualDisp->color565(255,0,255)); // VISIBLE ON ROW 17
  virtualDisp->drawLine(0, 31, 63, 31, virtualDisp->color565(0,255,0)); // VISIBLE ON ROW 32

IMG_20211010_230950

@mrcodetastic
Copy link
Owner

I have never made such a thing or ever looked a frame rates.

@AlfioSaitta
Copy link

With your last changes:

#define PANEL_WIDHT 64
#define PANEL_HEIGHT 32

#define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS
#define NUM_COLS 3 // Number of INDIVIDUAL PANELS per ROW

#define PANEL_CHAIN NUM_ROWS*NUM_COLS
  
#define SERPENT true
#define TOPDOWN false

setup() {
  ....
  HUB75_I2S_CFG mxconfig( PANEL_WIDHT*2, PANEL_HEIGHT/2, PANEL_CHAIN, _pins);

  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->setBrightness8(30); //0-255
  dma_display->clearScreen();
  ....
}

loop() {
  virtualDisp->drawLine(0,1,191,1,virtualDisp->color565(255,255,255));

  virtualDisp->drawLine(0,0,63,0,virtualDisp->color565(255,0,0));
  virtualDisp->drawLine(0,8,63,8,virtualDisp->color565(255,0,0));
  virtualDisp->drawLine(0,16,63,16,virtualDisp->color565(255,0,0));
  virtualDisp->drawLine(0,31,63,31,virtualDisp->color565(255,0,0));

  virtualDisp->drawLine(64,0,127,0,virtualDisp->color565(0,255,0));
  virtualDisp->drawLine(64,8,127,8,virtualDisp->color565(0,255,0));
  virtualDisp->drawLine(64,16,127,16,virtualDisp->color565(0,255,0));
  virtualDisp->drawLine(64,31,127,31,virtualDisp->color565(0,255,0));

  virtualDisp->drawLine(128,0,191,0,virtualDisp->color565(0,0,255));
  virtualDisp->drawLine(128,8,191,8,virtualDisp->color565(0,0,255));
  virtualDisp->drawLine(128,16,191,16,virtualDisp->color565(0,0,255));
  virtualDisp->drawLine(128,31,191,31,virtualDisp->color565(0,0,255));
}

IMG_20211012_141901

@AlfioSaitta
Copy link

AlfioSaitta commented Oct 19, 2021

After several tests, i still don't understand how the chain works and i haven't been able to solve the problem.

#define PANEL_WIDHT 64
#define PANEL_HEIGHT 32

#define NUM_ROWS 1
#define NUM_COLS 3

#define PANEL_CHAIN NUM_ROWS*NUM_COLS
  
#define SERPENT true
#define TOPDOWN false

#include <OneEighthScanMatrixPanel.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;
OneEighthMatrixPanel *virtualDisp = nullptr;

void setup() {
  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };

  HUB75_I2S_CFG mxconfig( PANEL_WIDHT*2, PANEL_HEIGHT/2, PANEL_CHAIN, _pins);

  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();

  virtualDisp = new OneEighthMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_WIDHT, PANEL_HEIGHT, SERPENT, TOPDOWN);
  virtualDisp->clearScreen();
}

X=0 Y=0
IMG_20211019_192622

X=65 Y=0
IMG_20211019_194813

X=65 Y=8
IMG_20211019_192718

Some times for a 2048px Image:

Fill picture time: 9ms on core 1 (extract from a json)
Draw picture time: 4ms on core 1 (draw to the matrix)

My Web Application:
192 168 1 214_8000_(HalfHD)

@mrcodetastic
Copy link
Owner

Made another change, not sure if it fixes the issue.

Experiment with lines 158-164 of 'OneEighthScanMatrixPanel.h' to see what works.

@macduyhai
Copy link

Good work on figuring that out. As expected, it's actually a chain of panels, with some weird chaining going on there between the 1/4ths of the panel, with the 2nd 1/4th being chained to the first (top) 1/4th of the panel.
What happens when you set: HUB75_I2S_CFG mxconfig( 64, 32, CHAIN_LENGTH, _pins); to HUB75_I2S_CFG mxconfig( 64, 16, CHAIN_LENGTH, _pins);
Because if you do the math, 8 pixels of each 'half' of the panel don't actually get used given this library is designed for 1/2 scan panels, and these panels actually chain the 2nd 1/4th with the 1st 1/4.

Result with your settings and corrected the math a bit:

IMG_20211010_120358

#define CHAIN_LENGTH 2 // 2 Chained panels
#define PANEL_WIDHT 64
#define PANEL_HEIGHT 16 // 1/8 Scan in the specifics ???

#define R1_PIN  2
#define G1_PIN  15
#define B1_PIN  4
#define R2_PIN  16
#define G2_PIN  27
#define B2_PIN  17

#define A_PIN   5
#define B_PIN   18
#define C_PIN   19
#define D_PIN   -1 // Connected to GND on panel (21 if exist)
#define E_PIN   -1 // Connected to GND on panel

#define LAT_PIN 26
#define OE_PIN  25
#define CLK_PIN 22

#include <Arduino.h>
#include <ESP32-HUB75-MatrixPanel-I2S-DMA.h>

MatrixPanel_I2S_DMA *dma_display = nullptr;

void testScreen() {
  
  for (int x=0; x <= 63; x++) {

    // Red 8 Rows
    dma_display->drawPixel(64+(x),0,dma_display->color565(255, 0, 0)); // ROW 1
    dma_display->drawPixel(64+(x),1,dma_display->color565(210, 0, 0)); // ROW 2
    dma_display->drawPixel(64+(x),2,dma_display->color565(180, 0, 0)); // ROW 3
    dma_display->drawPixel(64+(x),3,dma_display->color565(150, 0, 0)); // ROW 4
    dma_display->drawPixel(64+(x),4,dma_display->color565(125, 0, 0)); // ROW 5
    dma_display->drawPixel(64+(x),5,dma_display->color565(90, 0, 0)); // ROW 6
    dma_display->drawPixel(64+(x),6,dma_display->color565(60, 0, 0)); // ROW 7
    dma_display->drawPixel(64+(x),7,dma_display->color565(40, 0, 0)); // ROW 8

    // Blue 8 Rows
    dma_display->drawPixel(0+x,0,dma_display->color565(0, 0, 255)); // ROW 9
    dma_display->drawPixel(0+x,1,dma_display->color565(0, 0, 210)); // ROW 10
    dma_display->drawPixel(0+x,2,dma_display->color565(0, 0, 180)); // ROW 11
    dma_display->drawPixel(0+x,3,dma_display->color565(0, 0, 150)); // ROW 12
    dma_display->drawPixel(0+x,4,dma_display->color565(0, 0, 125)); // ROW 13
    dma_display->drawPixel(0+x,5,dma_display->color565(0, 0, 90)); // ROW 14
    dma_display->drawPixel(0+x,6,dma_display->color565(0, 0, 60)); // ROW 15
    dma_display->drawPixel(0+x,7,dma_display->color565(0, 0, 40)); // ROW 16

    // White 8 Rows
    dma_display->drawPixel(64+x,8,dma_display->color565(255, 255, 255)); // ROW 17
    dma_display->drawPixel(64+x,9,dma_display->color565(210, 210, 210)); // ROW 18
    dma_display->drawPixel(64+x,10,dma_display->color565(180, 180, 180)); // ROW 19
    dma_display->drawPixel(64+x,11,dma_display->color565(150, 150, 150)); // ROW 20
    dma_display->drawPixel(64+x,12,dma_display->color565(125, 125, 125)); // ROW 21
    dma_display->drawPixel(64+x,13,dma_display->color565(90, 90, 90)); // ROW 22
    dma_display->drawPixel(64+x,14,dma_display->color565(60, 60, 60)); // ROW 23
    dma_display->drawPixel(64+x,15,dma_display->color565(40, 40, 40)); // ROW 24

    // Green 8 Rows
    dma_display->drawPixel(0+x,8,dma_display->color565(0, 255, 0)); // ROW 25
    dma_display->drawPixel(0+x,9,dma_display->color565(0, 210, 0)); // ROW 26
    dma_display->drawPixel(0+x,10,dma_display->color565(0, 180, 0)); // ROW 27
    dma_display->drawPixel(0+x,11,dma_display->color565(0, 150, 0)); // ROW 28
    dma_display->drawPixel(0+x,12,dma_display->color565(0, 125, 0)); // ROW 29
    dma_display->drawPixel(0+x,13,dma_display->color565(0, 90, 0)); // ROW 30
    dma_display->drawPixel(0+x,14,dma_display->color565(0, 60, 0)); // ROW 31
    dma_display->drawPixel(0+x,15,dma_display->color565(0, 40, 0)); // ROW 32
  }
}

void setup() {

  Serial.begin(115200);
  delay(1000);

  HUB75_I2S_CFG::i2s_pins _pins = {
    R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
    A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
    LAT_PIN, OE_PIN, CLK_PIN
  };

  HUB75_I2S_CFG mxconfig( PANEL_WIDHT, PANEL_HEIGHT, CHAIN_LENGTH, _pins);

  mxconfig.double_buff = true; // ????
  mxconfig.i2sspeed = HUB75_I2S_CFG::HZ_20M;

  dma_display = new MatrixPanel_I2S_DMA(mxconfig);
  dma_display->begin();
  dma_display->setBrightness8(200); //0-255
  dma_display->clearScreen();
}

void loop() {
    //delay(40); 
    testScreen();
}

After researching in various Chinese retailers and factories, i found some more information on the panel:

Pixel Pitch: P4
Dimension: 128X256
Lamp bead: RGB
LED Type: SMD1921
Scanning Mode: 1/8

This code on your brand ?? patch-1 or legacy-1.2.4 ?? thanks

@macduyhai
Copy link

macduyhai commented Nov 3, 2021

Thank you @mrfaptastic but I try example "One_Eighth_1_8_ScanPanel" and change GPIO define
Link git : https://github.com/AlfioSaitta/ESP32-HUB75-MatrixPanel-I2S-DMA/tree/patch-1

` // Panel configuration
#define PANEL_RES_X 64 // Number of pixels wide of each INDIVIDUAL panel module.
#define PANEL_RES_Y 32 // Number of pixels tall of each INDIVIDUAL panel module.

#define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS
#define NUM_COLS 1 // Number of INDIVIDUAL PANELS per ROW
#define PANEL_CHAIN NUM_ROWS*NUM_COLS // total number of panels chained one to another

// Change this to your needs, for details on VirtualPanel pls read the PDF!
#define SERPENT true
#define TOPDOWN false

// GPIO Configuration
#define R1_PIN 25
#define G1_PIN 26
#define B1_PIN 27
#define R2_PIN 14
#define G2_PIN 12
#define B2_PIN 13

#define A_PIN 23
#define B_PIN 19
#define C_PIN 5
#define D_PIN 35 // Connected to GND on panel (21 if exist)
#define E_PIN -1 // Connected to GND on panel

#define LAT_PIN 4
#define OE_PIN 15
#define CLK_PIN 33

#include "OneEighthScanMatrixPanel.h" // Virtual Display to re-map co-ordinates such that they draw correctly on a32x16 1/4 Scan panel

// placeholder for the matrix object
MatrixPanel_I2S_DMA *dma_display = nullptr;

// placeholder for the virtual display object
OneEighthMatrixPanel *virtualDisp = nullptr;

/******************************************************************************

  • Setup!
    ******************************************************************************/
    void setup() {
delay(2000);
Serial.begin(115200);
Serial.println(""); Serial.println(""); Serial.println("");
Serial.println("*****************************************************");
Serial.println("*         1/8 Scan Panel Demonstration              *");
Serial.println("*****************************************************");


/******************************************************************************
 * Create physical DMA panel class AND virtual (chained) display class.   
 ******************************************************************************/

HUB75_I2S_CFG::i2s_pins _pins = {
	R1_PIN, G1_PIN, B1_PIN, R2_PIN, G2_PIN, B2_PIN, 
	A_PIN, B_PIN, C_PIN, D_PIN, E_PIN, 
	LAT_PIN, OE_PIN, CLK_PIN
 };


HUB75_I2S_CFG mxconfig(
			PANEL_RES_X*2,   	// DO NOT CHANGE THIS
			PANEL_RES_Y/2,   	// DO NOT CHANGE THIS
			PANEL_CHAIN    		// DO NOT CHANGE THIS
			//,_pins			// Uncomment to enable custom pins
);

//mxconfig.driver = HUB75_I2S_CFG::FM6126A;     // in case that we use panels based on FM6126A chip, we can set it here before creating MatrixPanel_I2S_DMA object

// OK, now we can create our matrix object
dma_display = new MatrixPanel_I2S_DMA(mxconfig);

// let's adjust default brightness to about 75%
dma_display->setBrightness8(50);    // range is 0-255, 0 - 0%, 255 - 100%

// Allocate memory and start DMA display
if( not dma_display->begin() )
  Serial.println("****** !KABOOM! I2S memory allocation failed ***********");

// create VirtualDisplay object based on our newly created dma_display object
virtualDisp = new OneEighthMatrixPanel((*dma_display), NUM_ROWS, NUM_COLS, PANEL_RES_X, PANEL_RES_Y, SERPENT, TOPDOWN);

// virtualDisp->setTextColor(virtualDisp->color565(0, 0, 255));
// virtualDisp->setCursor(0, virtualDisp->height()/2);

// Red text inside red rect (2 pix in from edge)
virtualDisp->setCursor(0, 0); 
virtualDisp->print("  1234");

// virtualDisp->drawRect(1,1, virtualDisp->width()-2, virtualDisp->height()-2, virtualDisp->color565(255,0,0));

// White line from top left to bottom right

// virtualDisp->drawLine(0,0, virtualDisp->width()-1, virtualDisp->height()-1, virtualDisp->color565(255,255,255));
}

void loop() {

} // end loop`

--> There's something incorrect here ?????

image

@mrcodetastic
Copy link
Owner

Unfortunately the 1/8 Scan panel workaround was never completed. I do not have one of these panels either so I cannot test.

Can you try drawing a line from pixel 0,0 to 32,63 without the use of the virtualDisp library and tell me what it looks like?

@donnersm
Copy link
Author

donnersm commented Nov 9, 2021

Unfortunately the 1/8 Scan panel workaround was never completed. I do not have one of these panels either so I cannot test.

Can you try drawing a line from pixel 0,0 to 32,63 without the use of the virtualDisp library and tell me what it looks like?

Since i have one of those panels and without working lib its useless to me.., might as well put a stamp on it and ship it to someone @mrfaptastic pm me if your interested

@mrcodetastic
Copy link
Owner

If you want i can send you various panels of different sizes and with different scan rates.

If you are happy to donate then I certainly won't say no. Mark is kindly sending a 1/8 which I can use to get those panels working properly (and that will help you as well with your 3 x 1/8 scan panel display).

Feel free to send what you think is of value to get supported and is most used. Can start continue expanding support in the library.

@dickshaydle
Copy link

I have a 64x32 RGB Panel that worked with a setting for 1/8 scan with another library so i guess it is an 1/8 scan display.
image

I couldn't get it to run with current master branch of mrfaptastic but with the patch-1 branch of Alfio.

But there were a some errors in the displayed image.
image

After a lot of trial and error i found some changes to the OneEighthScanMatrixPanel.h
image

if(   ( _s_chain_party && !_chain_top_down && (row % 2 == 0) )  // serpentine vertically stacked chain starting from bottom row (i.e. ESP closest to ground), upwards
      ||
      ( _s_chain_party && _chain_top_down  && (row % 2 != 0) )  // serpentine vertically stacked chain starting from the sky downwards
)
{
  // First portion gets you to the correct offset for the row you need
  // Second portion inverts the x on the row
	coords.x = ((y / panelResY) * (virtualResX)) + (virtualResX - x) - 1;

  // inverts the y the row
  coords.y = panelResY - 1 - (y % panelResY);  
} 
else 
{
// Normal chain pixel co-ordinate
  coords.x = x + ((y / panelResY) * (virtualResX)) +1 ;
  coords.y = y % panelResY;
}

/* *******
* START: 1/8 Scan Panel Pixel Re-Mapping
*
* We have calculated the x, y co-ordinates as if we have a chain of standard panels this library is designed 
* for, this being 1/8 or 1/16 scan panels. We have to do some further hacking to convert co-ords to the 
* double length and 1/2 physical dma output length that is required for these panels to work electronically.
*/

 if ( (coords.y /8) % 4 == 0) { // 1st 8 rows
    coords.x += 64;
 }
 if ( (coords.y /8) % 4 == 1) { // 2nd 8 rows
    coords.y -= 8;
 }

 if ( (coords.y /8) % 4 == 2) { // returns true/1 for the 1st and 3rd 8-pixel 1/4th of a 32px high panel
    coords.x += 64;
    coords.y -= 8;
 }
 
 if ( (coords.y /8) % 4 == 3) { // returns true/1 for the 1st and 3rd 8-pixel 1/4th of a 32px high panel
    coords.y -= 16;
 }

/* 
 * END: 1/8 Scan Panel Pixel Re-Mapping
 * *******
 */

Any ideas why it behaves this way?

What is needed to make this run with the aurora demo or with displaying images?
The aurora demos looks like it has double 8row blocks. The blocks are not equal but look very similar,

@mrcodetastic
Copy link
Owner

Hi @dickshaydle. I am working on a fix for 1/8 scan panels as @donnersm has kindly provided me a 1/8 scan panel to test with.

I hope to have something that works with chaining as well, soon.

mrcodetastic added a commit that referenced this issue Nov 22, 2021
#154 #204

Also supports chaining.
@mrcodetastic
Copy link
Owner

mrcodetastic commented Nov 22, 2021

You can't use the Aurora demo as is, it uses the underlying library which is 1/16 only.

You will need to merge the Aurora demo code with the new '1_8_ScanPanel.h' example and call this object instead of the underlying dma_display object which is designed electrically for 1/16 panels only.

@danieldecesaro
Copy link

danieldecesaro commented Nov 22, 2021

Hello @mrfaptastic,
I'm using 1/8 scan panels and I'm testing two types of panels with their example firmware.
In one of them everything works as expected, but in another there is an error in the coordinates.

The video of the two panels follows.

  1. This one works:
    IMG_20211122_143101
WhatsApp.Video.2021-11-22.at.14.36.21.mp4
  1. This one has problems:
    IMG_20211122_143122
WhatsApp.Video.2021-11-22.at.14.36.19.mp4

I'm grateful if you can help me.

Thanks for your work!

Att.
Daniel

@mrcodetastic
Copy link
Owner

Wow. Sorry to say that is yet another 1/8 panel variant with some super weird addressing scheme. They are different panels it seems. Can't help you as I don't have one of these I'm afraid.

It's almost like these Chinese manufacturers try and make a new variant every week.

Repository owner deleted a comment from AlfioSaitta Dec 18, 2022
@board707
Copy link
Contributor

You need a kind of reverse engineering to determine scan.

@muslihrizal
Copy link

You need a kind of reverse engineering to determine scan.

can help with setting the coordinates, still confused

@board707
Copy link
Contributor

try this

inline VirtualCoords OneEightScanPanel::getCoords(int16_t &x, int16_t &y) {
  VirtualMatrixPanel::getCoords(x, y); // call to base to update coords for chaining approach

  if ( coords.x == -1 || coords.y == -1 ) { // Co-ordinates go from 0 to X-1 remember! width() and height() are out of range!
    return coords;
  }


  if ( (y / 8) == 0) { 
    coords.x += ((coords.x / 32)+1)*32; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
  }
  else {
    coords.x += (coords.x / 32)*32; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
  }

  // http://cpp.sh/4ak5u
  // Real number of DMA y rows is half reality
  // coords.y = (y / 16)*8 + (y & 0b00000111);   
  coords.y = (y >> 4)*8 + (y & 0b00000111);   


  return coords;
}

@board707
Copy link
Contributor

sorry, just typo.
try this

inline VirtualCoords OneEightScanPanel::getCoords(int16_t &x, int16_t &y) {
  VirtualMatrixPanel::getCoords(x, y); // call to base to update coords for chaining approach

  if ( coords.x == -1 || coords.y == -1 ) { // Co-ordinates go from 0 to X-1 remember! width() and height() are out of range!
    return coords;
  }


  if ( (y & 8) == 0) { 
    coords.x += ((coords.x / 32)+1)*32; // 1st, 3rd 'block' of 8 rows of pixels, offset by panel width in DMA buffer
  }
  else {
    coords.x += (coords.x / 32)*32; // 2nd, 4th 'block' of 8 rows of pixels, offset by panel width in DMA buffer
  }

  // http://cpp.sh/4ak5u
  // Real number of DMA y rows is half reality
  // coords.y = (y / 16)*8 + (y & 0b00000111);   
  coords.y = (y >> 4)*8 + (y & 0b00000111);   


  return coords;
}

@muslihrizal
Copy link

Saya mencoba 1 baris dan 2 panel kolom, sepertinya terlihat normal
Gambar 09-02-2024 pukul 23 08 20

` #define PANEL_RES_X 64 // Jumlah piksel lebar setiap modul panel INDIVIDU. #define PANEL_RES_Y 32 // Jumlah piksel tinggi setiap modul panel INDIVIDU.

  #define NUM_ROWS 1 // Number of rows of chained INDIVIDUAL PANELS
  #define NUM_COLS 2 // Number of INDIVIDUAL PANELS per ROW
  #define PANEL_CHAIN NUM_ROWS*NUM_COLS    // total number of panels chained one to another
  
  // Change this to your needs, for details on VirtualPanel pls read the PDF!
  #define SERPENT true
  #define TOPDOWN true

`

IMG_20240209_212221

@board707
Copy link
Contributor

board707 commented Feb 9, 2024

Hi
Where you added my virtual co-ordinates code that I wrote to help you two weeks ago?

@board707
Copy link
Contributor

Please show your ESP32-HUB75-VirtualMatrixPanel-I2S-DMA.h file

@board707
Copy link
Contributor

As I see, you use a ESP32-HUB75-VirtualMatrixPanel-I2S-DMA.h file from a quite old library version. This file does not include a standard coordinate transformations for connecting multiple panels. Try adding this part of the code from the latest version.

@mrfaptastic Why is getCoords() method specified as private in new versions of the library? This make it difficult to inherit from a VirtualMatrixPanel class and will not allow user to create your own variants of the method...

@mrcodetastic
Copy link
Owner

Feel free to raise a pull request to fix that. You are right, it does not make sense to have it private.

@muslihrizal
Copy link

Thank you, it can turn on normally

Uploading IMG_20240210_213940.jpg…

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not an issue with library This library is working as it should, but something else causes an issue to be aware of. workaround exists A workaround exists for this. Read the issue comments.
Projects
None yet
Development

No branches or pull requests

10 participants