hzeller / rpi-rgb-led-matrix

Controlling up to three chains of 64x64, 32x32, 16x32 or similar RGB LED displays using Raspberry Pi GPIO
GNU General Public License v2.0
3.64k stars 1.16k forks source link

Understanding multiplexing #592

Open amonares opened 6 years ago

amonares commented 6 years ago

Hello, first thanks for all the work for having this software done.

I'm facing an issue. I have a panel 32x16 1:2 scan. (I started to write the issue while working) I'm very familiar with it, so I know that this mean that 256 leds are ON at once of the 512 that are the total (32x16=512). I know also the mapping, in fact for having the 256 ON at a time it turn on 128 off the upper half (rows 0-7) plus 128 from the lower half (rows 8-15). In one scan the green rows and in the other scan the blue rows of the image below. panel The connector is A-B only connector According to the knowledge that I gain only A is used to decide which rows are ON A | B 0 0 => green rows from the image above 1 0 => blue rows from the image above (Colors are to differentiate rows, the panel is RGB)

I'm using the active PCB adapter for 3 chains, but using only one at this time (Starting the problem simple) adapter

So at this time I know that Multiplex-Mappers transform to fit the scan. So, for a 32x16 1/4 scan panel, the Multiplex-Mapper generate a new Matrix 64x8, so I assume that the library ship to the panels 2 rows of the 64x8 matrix to have the 128 led ON (1/4 scan)

So to my panel the Multiplex-Mappers should generate a 128x4 matrix and obviously map the pixels right :smiley: so the library will ship out 256 pixels 128 to R1-B1-G1 and 128 to R2-B2-G2 pins.

Then I start to build my own Multiplex-Mapper with an stretch_factor of 4 to have the 128x4 matrix. After some try and error the result is this:

class Kaler2ScanMapper : public MultiplexMapperBase {
public:
  Kaler2ScanMapper() : MultiplexMapperBase("Kaler2Scan", 4) {}

  void MapSinglePanel(int x, int y, int *matrix_x, int *matrix_y) const {
    // Now we have a 128x4 matrix
    int offset = ((y%4)/2) == 0 ? -1 : 1;// Add o substract
    int deltaOffset = offset < 0 ? 7:8;
    int deltaColumn = ((y%8)/4)== 0 ? 64 : 0;

    *matrix_y = (y%2+(y/8)*2);
    *matrix_x = deltaColumn + (16 * (x/8)) + deltaOffset + ((x%8) * offset);

  }
};

Also is needed to change the assert in framebuffer.cc line 211 which want at least 8 rows to allow 4 rows as minimum.

- assert(rows_ >=8 && rows_ <= 64 && rows_ % 2 == 0);
+ assert(rows_ >=4 && rows_ <= 64 && rows_ % 2 == 0);

Finally it works for a Kaler panel like this and should be used with:

scan_mode = 1 or 0
row_address_type = 0

The final solution:

2 panels img_8473 4 panels 2 in parallel img_8485 4 panels in U shape img_8486

Like you see I solve my problem while I was writing to ask for help :rofl:

Again thanks for the great work (I just need to write the MultiplexMapper), greetings from Chile :chile:

CDR114 commented 6 years ago

Alvaro, I have the exact same display module that you have (based on your picture) I have tried your solution and I get 8 rows to display properly but get "Error in PixelMapper" for rows 0 through 3 and 8 through 16.

Example of error message: "Error in PixelMapper: (96, 8) -> (263, 2) [range 256x8]"

Any ideas? I only connected 1 panel. Do I need to connect at least 2 panels? What was your full command? I will try to post a picture tomorrow (It is late and need some sleep).

amonares commented 6 years ago

Hello, I think that you don't have do right. You said:

Example of error message: "Error in PixelMapper: (96, 8) -> (263, 2) [range 256x8]

If it's so 256x8=2048, that means that you have said in some place to the library that your panel is of that quantity of leds (2048) Better clone the repository now (Henner Zeller had merged the new MultiplexMapper two days ago) and run: sudo ./demo -D3 --led-rows=16 --led-cols=32 --led-multiplexing=7 --led-row-addr-type=0 --led-scan-mode=0

CDR114 commented 6 years ago

Alvaro, I am sorry but I am still having problems. I have cloned the new repository and also your branch but now when I run the command no pixels light up (with both clones). I have tried also all the Demo options and the Pixel-Test program (which I set up in the Demo program as option 12). I get the same result, no pixels light up on the display. I then placed a printf statement in the multiplex-mapper program and I seem to get a good mapping. See following photo

img_20180424_2050312

The output of the pixel program is as follows:

img_20180424_2049558

I then tried setting --led-rows=32 and I get pixels to light up

img_20180424_2029021

Setting --led-parallel=2 gives the following

img_20180424_2030124

If I run the Pixel-Test program everything works correctly for the first 8 rows, then the output in incorrect with --led-rows=32.

The back of my panel looks like

img_20180424_2058569

The Demo program in both clones works properly with my indoor panels at the --led-rows=16 setting.

I am a novice C programmer, but I am going to try to look at the program and see if I can find the problem. Any help would be appreciated. (Just to be clear, all the display results were before I made any code modifications for the printf statement and the Pixel-Test add. All the results were the same before and after any modifications were made). The good thing is that I am now a lot closer to success than before.

amonares commented 6 years ago

Hi. Did you understand how Multiplex-Mappers works? If not, first understand it, because if your panel is not working with the Kaler2ScanMapper (--led-multiplexing=7) then your panel is not the same. That could be, because the panel is not 1/2 scan or the pixel arrangement is different.

Assuming you have a panel 1/2 scan, then your pixel arrangement is different. So you should know how the physical pixel arrangement is to start to build your own Multiplex-Mapper. How can you start to know your mapping, defining the MapSinglePanel something like this (assuming 1/2 scan)

class CDR114Mapper : public MultiplexMapperBase {
public:
    CDR114Mapper() : MultiplexMapperBase("CDR114Mapper", 4) {}
    void MapSinglePanel(int x, int y, int *matrix_x, int *matrix_y) const {
      *matrix_y = 0; // Change between 0 to 3
      *matrix_x = 0; // Change between 0 to 127
   }
};

This will allow to know which physical led is on and so elaborate your own Multiplex-Mapper

CDR114 commented 6 years ago

Alvaro, thanks for the help and the solution. After verifying the output of the pi with a digital analyzer, I determined that I had the proper 1/2 scan output using --led-rows=16. It turned out that I have a bad P10 display panel. I replaced the panel with another one and everything works properly. The address chips in the faulty panel must be defective!

Saurav-K-Aryal commented 5 years ago

@amonares @CDR114 Thank you both for documenting the process of writing a MultiplexMapper so well. However, I was unable to adapt this understanding to my panel which has a scan of 1/20 with 48*96 pixels.

Would appreciate both your help in this matter. You can view it as an issue at https://github.com/hzeller/rpi-rgb-led-matrix/issues/738

dasebi commented 3 years ago

Hi Alvaro,

Thank you so much for making it more understandable how this multiplex mapper works. I was able to make another chinese P10 16x32 1/2 scan with icn2037bp work. my pixel order was this one: image

my mapper looks like this:

class SebiMapper : public MultiplexMapperBase {
public:
  SebiMapper() : MultiplexMapperBase("P10-128x4-Z", 4) {}
  // supports this panel: https://www.aliexpress.com/item/1005001497000507.html?spm=a2g0s.9042311.0.0.bd304c4d7mIHUd

  void MapSinglePanel(int x, int y, int *matrix_x, int *matrix_y) const {
    int yComp = 0;
    if (y == 0 || y == 1 || y == 8 || y == 9) {
      yComp = 31;
    }
    else if (y == 2 || y == 3 || y == 10 || y == 11) {
      yComp = 16;
    }
    else if (y == 4 || y == 5 || y == 12 || y == 13) {
      yComp = 15;
    }
    else if (y == 6 || y == 7 || y == 14 || y == 15) {
      yComp = 0;
    }
    if (y == 0 || y == 1 || y == 4 || y == 5 || y == 8 || y == 9 || y ==12 || y ==13) {
            if (x <= 7 ) {
              *matrix_x = yComp - x;
            }
            else if (x >=8 && x<= 15){
              *matrix_x = yComp + 40 - x;
            }
            else if (x >=16 && x<= 23){
              *matrix_x = yComp + 80 - x;
            }
            else if (x >=24 && x<= 31){
              *matrix_x = yComp + 120 - x;
            }
    }

    if (y == 2 || y == 3 || y == 6 || y == 7 || y == 10 || y == 11 || y ==14 || y ==15) {
            if (x <= 7 ) {
              *matrix_x = yComp + x ;
            }
            else if (x >=8 && x<= 15){
              *matrix_x = yComp + 24 + x;
            }
            else if (x >=16 && x<= 23){
              *matrix_x = yComp + 48 + x;
            }
            else if (x >=24 && x<= 31){
              *matrix_x = yComp + 72 + x;
            }
    }

    if (y == 0 || y == 2 || y == 4 || y == 6) {
      *matrix_y = 0;
    }
    else if (y == 1 || y == 3 || y == 5 || y == 7) {
      *matrix_y = 1;
    }
    else if (y == 8 || y == 10 || y == 12 || y == 14) {
      *matrix_y = 2;
    }
    else if (y == 9 || y == 11 || y == 13 || y == 15) {
      *matrix_y = 3;
    }
  }
};

Maybe somebody wants to add my ugly code to the github project. I have no clue how to do that.

br Sebastian

xabier8898 commented 3 years ago

Hi,

I'm using two 32x64 RGB led matrix panels and an Arduino MEGA. I tried to connect them but I see the image duplicated. I was wondering if with this MultiplexMapper I could make them work as if they were one, one big 64x64 screen.

Thank you

davemaster commented 3 years ago

Greetings, A Picture of your panels condition? Thanks

xabier8898 commented 3 years ago

1

In the picture above you can see the two panels connected to the arduino MEGA. In the picture below, the data duplicated on both panels. I would like to see the data plotted on both screens but as if it was a bigger led screen. Could the Multiplexing technique help me? The panels are P4 RGB led matrix panels 32x64.

2

davemaster commented 3 years ago

1

In the picture above you can see the two panels connected to the arduino MEGA. In the picture below, the data duplicated on both panels. I would like to see the data plotted on both screens but as if it was a bigger led screen. Could the Multiplexing technique help me? The panels are P4 RGB led matrix panels 32x64.

2

Saddly, this library is for Raspberry Pi boards... not for Arduino MEGA. For that board, You can use the adafruit rgb led panel library; here a guide