Closed currentlysober closed 6 years ago
I have not seen these displays, so I can't give definitive answer. However, Kent, one of the users of this library, faced a similar problem and he did a remapping using the transformer technique. A transformer is a way to re-map pixels in a way that they are useful. See
https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/include/canvas.h#L51
Also some implementations are here: https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/lib/transformer.cc
The following is what kent wrote. Let me know if this works for you, I might just add this transformer to the general distribution as this seems to be a newer trend in these displays.
--- Kent wrote ------
I managed to work out the pixel mapping and created a transformer to remap the pixels. It was remarkably simple (once I figured out what I was doing). I basically copied and modified your LargeSquare64x64Transformer:
int Snake8x2Transformer::TransformCanvas::width() const {
return delegatee_->width() / 2;
}
int Snake8x2Transformer::TransformCanvas::height() const {
return delegatee_->height() * 2;
}
void Snake8x2Transformer::TransformCanvas::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
int new_x;
int new_y;
new_x = ((x / 8) * 16) + (x % 8);
if ((y & 4) == 0) {
new_x += 8;
}
new_y = ((y / 8) * 4) + (y % 4);
delegatee_->SetPixel(new_x, new_y, red, green, blue);
}
I also had to set rows=8, chains=6, parallel=3 as the panels appear to be using 1:4 multiplexing
(hence the width/2 and height*2 in the transform).
The very limited info on these panels refers to the multiplexing as "snake" and is supposed to minimise flicker.
For a single panel, the 16 8x4 pixel blocks are arranged thus:
2 | 4 | 6 | 8 y = 0..3 (lines 1..4 uses second set of rgb data pins)
1 | 3 | 5 | 7 y = 0..3 (lines 5..8 uses first set of rgb data pins)
10 | 12| 14| 16 y = 4..7 (lines 9..12 uses second set of rgb data pins)
9 | 11| 13| 15 y = 4..7 (lines 13..16 uses first set of rgb data pins)
+--- x = 48..55 (odd blocks) or x = 56..63 (even blocks)
+------- x = 32..39 (odd blocks) or x = 40..47 (even blocks)
+----------- x = 16..23 (odd blocks) or x = 24..31 (even blocks)
+--------------- x = 0..7 (odd blocks) or x = 8..15 (even blocks)
so the mapping for the corners is as follows: 0,0 -> 8,0 31,0 -> 63,0 0,15 -> 0,7 31,15 -> 31,7
I hope someone finds this useful.
Can you tell me where you got this panel ? I might want to try getting one as well for experiments and maintenance of the library.
If you have 1:8, then you probably need to start out with a setting of -r 16 (because it has 8 rows doubled up) and -c 2 (as it internally requires 64 pixels to push through to have 64x16 = 32x32 pixels.
In order to figure out the snake mapping for this, you should light one row after the other to see how things are 'folded' on the screen. So on your 64x16 screen, fill the first 64 pixels (maybe the first half with red, the second half with blue or so so that you can better trace what is happening). You will see how the line is folded on the screen. Then do that for each line and get an idea. After that, you can easily write a transformer.
Looking at your picture, it looks like the lower middle quarter is the first 16 pixels, folled by the top quarter.
How do you know that your display is a 1:8 ? If there is some documentation for it, then it should probably say as well something about the pixel mapping. Does the display only have two connectors on the back (one in, one out) ? Are the connectors labelled ? If it is 1:8, then the A, B, C, D lines should have the 'D' missing.
Did you get your display remapped correctly ?
Hi, unfortunately I bought the same display. I only read 32 x 32 and ignored the 1:8 scan. I made the same experience. Electrical this modules are 16 x 64. There are twice the amount of shift register on the module. The Information is shifted through the the upper half and then trough the lower half. So it works like two 16 x 32 Matrixes which are chained but arranged below each other.
Sorry I sent this to fast: With the rearranged Pixels You have to use -r16 -c 6 instead of -r32 -c3
Can you write a transformer that can properly re-map these pixels to be contributed to the project with a pull request ?
Any progress on this ? Did you write a transformer that works with your display ? Other people that have such a display could possibly benefit.
Am 12.11.2015 um 18:05 schrieb Henner Zeller:
Any progress on this ? Did you write a transformer that works with your display ? Other people that have such a display could possibly benefit.
— Reply to this email directly or view it on GitHub https://github.com/hzeller/rpi-rgb-led-matrix/issues/66#issuecomment-156167704.
Sorry for late response, but there was so much trouble at work. Till now I don't have a transformer. There are 2 main reasons: 1) I didn't have programmed anything for the last decade and I have allmost none experience in programming c++. Even reading and understanding is sometimes difficult. 2) I think a transformer won't work with every kind of picture. The ppm to show has to be expanded to have a size modulo 32 in both directions.
So when i find time in next week(s) I'll write a offline transformer ( in C not C++) because that will be much easier (for me) The transformed ppm can be converted back to png and so I can see easily if the transformer has done its job.
I'll keep You informed. Best regards Thomas
The transformer is only there to do the basic pixel mapping that determines where a SetPixel(x, y) shows up on the screen. This essentially provides you a new canvas where pixels show up where you expect them :)
Once you have that, you can display any image you want, including other things you want to do with the image to be displayed. So your point (2) is just what you want to do in your application.
In order to get started and understand how the mapping is now, you can write a simple application that moves a pixel, one by one, to each location
for (int y = 0; y < matrix->height(); ++y) {
for (int x = 0; x < matrix->width(); ++x) {
matrix->SetPixel(x, y, 255, 255, 255);
}
}
Then you can see how pixels 'jump around' and write a tranformer that counters that.
Dear Henner and Thomas, I will send the solution I worked out to Henner - and Henner, maybe in the next update you could include it...? So people won´t have trouble with this kind of matrix. Sadly, so far it works with simple text. I didn´t have time to fight to display images (jpg, gif) correctly (and some time ago I noticed that remapping doesn´t work with images). Regards! Daniel
Don't worry about the images, I think I never properly added the remapping code to the image app. Will do that soon.
FYI, I've added the necessary scaffolding to the image viewer last week that it can easily accept a Transformer. So once you have the transformer, the image viewer will work with it as well.
Dear all, thank you, I will check image viewer today. I sent the code to you Henner, so that maybe it would appear in next updates. Anyway, here is the way of transforming:
int LargeSquare64x64Transformer::TransformCanvas::width() const {
return delegatee_->width() / 2; }
int LargeSquare64x64Transformer::TransformCanvas::height() const {
return delegatee_->height() * 2; }
void LargeSquare64x64Transformer::TransformCanvas::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
int new_x, new_y;
new_x = ((x / 16) * 32) + (x % 16);
if ((y & 8) == 0) {
new_x += 16; }
new_y = ((y / 16) * 8) + (y % 8);
delegatee_->SetPixel(new_x, new_y, red, green, blue); }
Regards
HI all,
Another issue with the 32x32 displays is they may be 4 sub panels (instead of two). You might need to change the define in framebuffer.cc to SUBPANELS 4.
rows will be 32, chain will be twice the number of panels linked.
Hope this is helpful
Hi, back again after a while. Last few weeks we spent to build a frame for the moduls. With the help from currentlysober I could modify the shown transformer a little bit and now it works great.
int myTransformer::TransformCanvas::width() const { return delegatee->width() / 2; } int myTransformer::TransformCanvas::height() const { return delegatee->height() * 2; }
void myTransformer::TransformCanvas::SetPixel(int x, int y, uint8_t red, uint8_t green, uint8_t blue) {
int new_x, new_y;
new_x = ((x / 32) * 64) + (x % 32);
if ((y & 8) == 0) {
new_x += 32; }
newy = ((y / 16) * 8) + (y % 8);
delegatee->SetPixel(new_x, new_y, red, green, blue); }
For 3 chains of 8 modules I have to call
sudo ./ledmatrix -r16 -c16 -P3 -D1 xyz.ppm
Thanks a lot, I'm so happy
Dear All, I managed to contact the seller of my LED modules and I was told that the modules have 1/4 scanning. It is funny because I managed to run those modules with 1/8 scanning. However, with 1/8 they are significantly less bright than when I run with 1/4 scanning. This is why in some other thread I asked about led's brightness. And running with correct 1/4 scanning is highly important to me. Maybe some other users will use this modules too. I am writing here because Kent managed to program 1/4 scan modules. Sadly, my LED modules work in a little bit different way. And I cannot make them working. I will update you with my progress but so far I have no results.
When I run it without transformer (with text "ABCDEFGHIJKLMNO" from 0,0 point), I have this:
As you can see, the module contains 16 areas, each 16x4 leds: XXXXXX | XXXXXX XXXXXX | XXXXXX YYYYYY| XXXXXX XXXXXX | XXXXXX XXXXXX | XXXXXX XXXXXX | XXXXXX ZZZZZZ | XXXXXX XXXXXX | XXXXXX
What is interesting, upper part of first characters (ABCD) is visible in area YYYYY and bottom part in ZZZZZ area. Moreover, some parts do not show data even if I write in various positions....
Could you please share any idea with me to help me out with this issue? Thank you in advance.
Hi currentlysober,
Try this transform which has worked for my batch of 32x32 panels:
new_x = ((x / 16) * 32) + (x % 16); if ((y & 8) == 0) { new_x += 16; } new_y = ((y / 16) * 16) + (y % 8);
Also in your transform class have:
int myTransformer::TransformCanvas::width() const { return delegatee->width() / 2; } int myTransformer::TransformCanvas::height() const { return delegatee->height() ; }
Change the define in framebuffer.cc to SUBPANELS 4 and remake the librgbmatrix library.
Try row = 32 and chains = double the number of panels in a chain.
Let me know how that works. Cheers
Hi Kent,
thank you for the answer! Below the results. According to the supplier, panels P5 and P6 which are outdoor panels should have 1/4 scanning because of brightness requirements. It would be really good to make them working and later put the code in Henner's library.
int LargeSquare64x64Transformer::TransformCanvas::width() const { return delegatee->width() / 2; } int LargeSquare64x64Transformer::TransformCanvas::height() const { return delegatee->height() ; }
Results below. If we join parts of characters with keeping row=8 (higher brightness) scanning, it will be perfect:
Regards!
An update: I think there is some missing part in a source code in case of row=8 because there is no way to light-up pixels in blind spots (left photo). I light up all pixels from point 0,0 to 96,96 (3x3 panels) and still there are blind spots (theoretically there shouldn't be any). Am I right?
What do you get when rows=4 and sub_panel=1? Or even rows=2 and sub_panels=1?
Hi, interesting thing happens: both with row=4 sub_panel=1 and row=2 sub_panel=1 the brightness is about 70% of maximum. still, the best result gives row=8, sub_panel=2 (100% brightness) but I cannot find a way to light up the rest of leds.
quite weird.
I had a similar issue with this panel which was laid out as a chain of two 8x64 panels, the layout was the following:
Panel 1, Y=0, X=32->X=63 Panel 1, Y=1, X=32->X=63 Panel 1, Y=2, X=32->X=63 Panel 1, Y=3, X=32->X=63 Panel 1, Y=4, X=32->X=63 Panel 1, Y=5, X=32->X=63 Panel 1, Y=6, X=32->X=63 Panel 1, Y=7, X=32->X=63 Panel 1, Y=0, X=0->X=31 Panel 1, Y=1, X=0->X=31 Panel 1, Y=2, X=0->X=31 Panel 1, Y=3, X=0->X=31 Panel 1, Y=4, X=0->X=31 Panel 1, Y=5, X=0->X=31 Panel 1, Y=6, X=0->X=31 Panel 1, Y=7, X=0->X=31 Panel 2, Y=0, X=32->X=63 Panel 2, Y=1, X=32->X=63 Panel 2, Y=2, X=32->X=63 Panel 2, Y=3, X=32->X=63 Panel 2, Y=4, X=32->X=63 Panel 2, Y=5, X=32->X=63 Panel 2, Y=6, X=32->X=63 Panel 2, Y=7, X=32->X=63 Panel 2, Y=0, X=0->X=31 Panel 2, Y=1, X=0->X=31 Panel 2, Y=2, X=0->X=31 Panel 2, Y=3, X=0->X=31 Panel 2, Y=4, X=0->X=31 Panel 2, Y=5, X=0->X=31 Panel 2, Y=6, X=0->X=31 Panel 2, Y=7, X=0->X=31
. Wilton
I'm afraid this this different module with different scanning. And different pixels map.
To sum up, there are blank spots and there is no possibility to turn those pixels on. I marked those blank spots in red frames. Maybe someone managed to deal with 1:4 scan modules?
Hi Experts, Any updates on this case? I have same issue with this scan rate :(. To be honest i'm not a developer at all so looking forward to hear some good improvement :)
Thanks justin
Hi @hzeller @ts4pi
I written class as myTransformer, I am calling these calls in main like
myTransformer *transformer = new myTransformer(); matrix->SetTransformer(transformer);
before Canvas *canvas = matrix;
. I want to know that is this the correct way? because i tried with this but i am not getting proper output .My panel have 1:8 scan rate 32x32. How i can modify in demo-main and text.cc?
Regards, Praveen
@currentlysober I'm pretty sure you're wired for HUB75, not HUB75E. That's why you're getting blank areas. WIth HUB75 there's four address lines: A,B,C,D. Four bits gets you 16 lines, which is what your pictures show. HUB75E has FIVE address lines, A-E. Address line E is on pin 8, which is tied to GND on HUB75. Fix your wiring, because no amount of code fiddling is going to get you there!
Hello Everyone I am using P5 32x32 8S HUB75 with A B C lines with HZeller libraries. I have used ts4pi transformer and also tried with currentlysober Jun 24, 2016 transformer changes but nothing worked for me. I have tried to change number of rows and chains but in vain. Have tried both on a single board as well on a 9 chained 2 parallel boards and obviously have the same issue. I have attached images for your ref.. Please let me know if you need any inputs to help me to solve my issue.
P.S- HZeller and team seriously great work and helping lots of ppl around the globe. Thank you.
![Uploading IMG_20180110_181501.jpg…]()
![Uploading IMG_20180110_181457.jpg…]()
![Uploading IMG_20180110_181450.jpg…]()
Please check out the new option --led-multiplexing
https://github.com/hzeller/rpi-rgb-led-matrix#multiplexing
It does the mapping built into the library (and can also be used from Python.)
(You need to do a fresh checkout and compile, this just went in).
The transformer is only there to do the basic pixel mapping that determines where a SetPixel(x, y) shows up on the screen. This essentially provides you a new canvas where pixels show up where you expect them :)
Once you have that, you can display any image you want, including other things you want to do with the image to be displayed. So your point (2) is just what you want to do in your application.
In order to get started and understand how the mapping is now, you can write a simple application that moves a pixel, one by one, to each location
for (int y = 0; y < matrix->height(); ++y) { for (int x = 0; x < matrix->width(); ++x) { matrix->SetPixel(x, y, 255, 255, 255); } }
Then you can see how pixels 'jump around' and write a tranformer that counters that.
@hzeller, i have some problem with my 64*32 rgb panel - 4 mm pitch, --> i think like this, but its totally different https://www.adafruit.com/product/3826
i dont know scan rate for my panel, i try your code (but in arduino, and i use Mega).
the result is two pixel move together (not a pixel) , dont know why.
if i use adafruit library, the result is like this
you can see on "G" char, there is one gap. can you explain what should i do? thanks for your help.
Dear Henner,
a few days ago I found matrixes 32x32 with 1:8 scan rate. I received one piece to try to use it but I have a big problem to print out complete information. Completely strange things show up - text is visible in higher part of the panel and first characters are below, following characters over the first ones. I use 1:8 to use normal 16x32 panels but I do not know how to change paramteres or modify the library a little to use those panels. I would like to program a little to have them in the way that later we connect 3 chains in parallel and they still work fine. So I guess -r and -P cannot help in this moment (I tried :) ) I was trying to understand idea of variables
const int rows; // Number of rows. 16 or 32. const int parallel; // Parallel rows of chains. 1 or 2. const int height; // rows * parallel const int columns; // Number of columns. Number of chained boards * 32.
but I'm afraid it's a dead end and I do not want to break the panel with blind shots. Yes, I saw another issue regarding various scan rate but it was mostly about 1:4. The panels I found have only info regarding 1:8 scan rate - and I guess the rest is as in 'normal' 32x32 panels. Could you please help me and give me some tips, information, how to program 32x32 panels with 1:8 scan rate? I will be really grateful. Best regards Daniel.
Dear Henner, here is what shows up after setting -r32 -P1 -c1 and printing "ABCDEFGHIJ" - photo attached. It seems that not only it has scan rate 1:8 in rows but also some 1:16 in columns. Am I right? Could you please tell me which part of library is responsible for maintaining this? I will be really grateful. It seems that new type of panels start to be available. Best regards!