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.73k stars 1.18k forks source link

64x64 P2.5 LED panels #120

Closed KentWalker closed 6 years ago

KentWalker commented 8 years ago

I have had a quick look at some 64x64 P2.5 panels and discovered there is an additional decode line 'E' on the HUB75 interface. This is pin 8, which is currently pulled to ground on the Raspberry Pi adapter.

I would like to add this to the GPIO using either GPIO0 or GPIO1 (since we never are going to use the auto ID, I thought these might be safe). Earlier model B's have a P5 port which brought out GPIOs 28..31 but they don't seem accessible on the R.Pi 2 version. How do I go about mapping the GPIO (in the gpio.cc file) and what do I need to change in the framebuffer.cc file to add an extra row? (DumpToMatrix() only, or is there something else I need to do?)

U2 on the adapter board has a spare buffer (A0/B0), so not much to change on the PCB.

jpasqua commented 8 years ago

I accidentally ended up with one of these as well. Any chance you'll be adding this as an option?

I'm using an Adafruit Hat with HW PWM using the jumper between pins 4 and 18.

hzeller commented 8 years ago

Sorry for the delay.

Interesting, I have not come across these panels yet. So they have essentially a 5 bit address for the rows [A, B, C, D, E] ? I can give some generic advice below, but since I have not have hands on these yet, you have to do the experiments. Do you guys have a link to the vendor ? (I think I need to start to collect donations for rpi-rgb-led-matrix so that I can keep buying new panels :) ).

It sounds odd though, as I have seen the trend go more towards 1:8 multiplexing from 1:16. This would mean that there is 1:32 multiplexing so the refresh rate might suffer.

So what you need to do:

PCB changes should be simple. Yes, there is a spare buffer and we just need to free GND from the respective pin.

If this works, please send a patch or pull request, so that I can integrate that. And please, if you have a link to the source of that panel let me know so that I can get one for my experiments.

jpasqua commented 8 years ago

Here's a link to the unit I bought: http://www.aliexpress.com/item/p2-5-led-display-module-2-5mm-pixel-indoor-rgb-full-color-led-display-1-16/32533038333.html It was originally labelled as 1/16 scan but when it arrived and I connected it, I found out otherwise. After contacting the seller he admitted that the ad was incorrect and updated it to say 1/32.

hzeller commented 8 years ago

Thanks for the update, I'll try to get one of these. In the meantime, you could experiment with the suggestions above.

jpasqua commented 8 years ago

I think we are local to one another. If you want it, you can have my module. I won't have a chance to work on this for quite some time. Feel free to contact me at joe AT noroomattheinn dot org.

KentWalker commented 8 years ago

I originally bought a couple of these panels via AliExpress: http://www.aliexpress.com/item/Free-Shipping-P2-5-LED-module-64x64-smd-led-p2-5-module-HD-Indoor-Full-Color/32538463676.html It appears this company is no longer supplying P2.5 modules via AliExpress but are still available directly from them: http://www.fullcolorled-display.com/sale-7549960-hd-p2-5-indoor-full-color-led-module-16-scan-smd-2121-3in1-rgb-160-160mm.html

I've just got my hands on a Raspberry Pi 3 so this will be a good candidate for testing as it is a 1.2GHz 64 bit quad core CPU. I'm not sure how that is going to affect the refresh rate or other timing yet. I guess I have a bit of reading and experimentation to do :) Will keep you all posted

nbJosh commented 8 years ago

I just received one of these.

http://www.aliexpress.com/store/product/RGX-64x64-rgb-led-matrix-RGB-P2-5-indoor-led-backlight-panel-led-display-module-size/1359923_32395610982.html

currentlysober commented 8 years ago

Hi, I have also bought the type 64x64 and I do not have line 'E'. Moreover, they do not have 'D' line. The photo of connector below:

img_9577

So I changed one line because I was told that scan is 1/32: assert(rows_ <= 64); but I guess this is not enough because the result is like that (I wrote "HELLO" in 0,0 point): type: 64, chain: 2, parallel: 1

img_9582

Any idea? :) Regards

hzeller commented 8 years ago

@currentlysober your panel looks like a different panel even: it only has A and B, so it is actually 1:4 multiplexing; Can you try with -r 8 -c 8 to see what happens with the demos ?

@jpasqua Can you have a look at your panel on the back if it as well has only [A, B] marked or if it goes up to E ? The picture in your Alibaba listing looks like it only goes to B, so this might be what @currentlysober got.

@KentWalker Today, I want to implement the 'E' line support. Can you give me a picture of the connector on the back to double-check ? I want to know where the E line is connected so that I can put it on the right pin on the adapter board. You said it is Pin 8, so I suppose it is the opposite pin to B2, correct ? I ask because I got a picture from another user of the library where the E pin was on Pin 4 (and there was some strange 'BLK' - labelled pin which I don't know what it is).

currentlysober commented 8 years ago

Hi! Thanks, I did what you wrote me.

  1. when I put -r8 -c8, I didn't see anything on panel.
  2. then I put -r8 -c2 and I had this (text HELLO as previously):

r8c2

Moreover, I wrote to the company of led modules and they told me that it had 1/32 scanning (this is why I believed -r64 would be correct). It would be nice to make it working because with 3 parallel panels, it would look like LCD screen from longer distance. Do you have some idea? We can see that the text is correct horizontally, but there is some problem perpendicularly. Thank you!

KentWalker commented 8 years ago

@hzeller Sorry taking so long, I'm in one place and the panels are in another. Will have a photo in a day or two

hzeller commented 8 years ago

I don't have such a module @currentlysober, so I can't play with it. Looks like you might almost have gotten it working but need to deduce the pixel-mapping by carefully crafting pixel patterns to understand the internal structure of how the panel is mapping its pixels, so that you can reverse map.

ghost commented 8 years ago

Hello,

I got exactly the same panels as @currentlysober 's. I have tried many different options (chain. rows, subpanels etc.) but nothing seem to work. Maybe someone has resolved this issue?

doldroyd commented 7 years ago

I just received a panel with identical markings as @currentlysober and @marcinzdunek . I have not connected it to anything electrically yet, but upon inspection of the board it appears that the address is controlled via shift register, with "A" being the clock and "B" the data. I do not have a "normal" board to play with to confirm the different control strategy, but I will be working on some control code (microcontroller, not rpi) for this over the next few weeks and will report back if I get it to work.

hzeller commented 7 years ago

That would be cool. If you have figured out the way things are controlled on these boards, I can add the relevant code in the library.

VadimSotskov commented 7 years ago

Hey! So have anyone dealt with the 64x64 led matrix? I'm using it with arduino uno, and connect this additional 'E' pin to the ground on my arduino (as for 32x32 leds), but the result is so far from what I've expected. I've expected to get one smile on the top left. But eventually it dublicates it to another section. Like it divides my matrix into four 32x32 sections. Is the problem with 'E' pin only? Or there is something else? photo_2017-03-28_20-26-41

hzeller commented 7 years ago

What are the parameters you gave ? Note that the 64x64 display is essentially two chained displays 32 wide and 64 high. So you need to give --led-chain=2 as parameter.

hzeller commented 7 years ago

An update on this bug:

noorabrar1 commented 7 years ago

Hello sir,

I'm working on HUB75 for a project, the connectivity with pi3, and i am using your client server code. using 3 different scan rate HUB75 board each four 32x32 panel connected in series and parallel

code:

Server: sudo ./ft-server --led-parallel=2 --led-rows=64 -D64x64 --led-chain=2

Client: sudo ./send-text -g64X64+0-0+1 -h localhost "hello" -f fonts/6x12.bdf -c ff0000

HUB75- P2.5-32S-64X64 consist of additional E data line, wiring is properly connected(Not working properly, some set of upper led wont glow even i made correction -D128x128) HUB75- P5-8S-32x32 ABC data lines(Not working properly, multiple prints appear )

Please help me to set different scan rate. is there any other libraries has to downloaded or any other arguments i need to give.. ??

hzeller commented 7 years ago

@noorabrar1 please don't hijack an existing thread with a completely different question, open a separate issue instead.

maitredede commented 7 years ago

Hi,

In my case, I have a single 64x64 matrix. I don't know which arguments I have to configure to properly run the demos.

For wiring, I have plugged the panel's connector pins to gpio using "regular" pinout (pi 3 gpio). Then I launched demo 0 (rotating square) with sudo ./demo --led-no-hardware-pulse --led-show-refresh --led-rows=64 --led-gpio-mapping=regular-pi1 --led-slowdown-gpio=2 -D 0 --led-chain=2. You can see resulting video here : https://youtu.be/lv6C89j0i1M

What can be the problem, and how may I fix it ? Thanks.

hzeller commented 7 years ago

@MaitreDede this panel does not have the A, B, C, D, E address lines as usual with 64x64 panels, but according to the picture on aliexpress only A, B which indicates entirely different controlling.

It is known that these panels exist, but I don't have one to reverse engineer how that works, so they are not supported by this library. You want to get one with 1:32 multiplexing (and all the address lines) to work with this library.

maitredede commented 7 years ago

Thanks @hzeller, I am with the same kind of panel @currentlysober has (line A, B, and NC).

If I would like to start writing my own driver, do you know where I can found a doc explaining how theorically I have to play with pins to display something ? Thanks.

hzeller commented 7 years ago

If there was a documentation, it was simple. So you have to do reverse engineering to figure out how it works internally.

maitredede commented 7 years ago

I would be pleased to reverse engineer and make a pull request if I knew where to start. Even contribute to your wiki for docs, and also maintain a c# wrapper... I will try something when I am back home. Does the data need to be constantly refreshed ? Or can it be transmitted once and the display stay "as is" ?

hzeller commented 7 years ago

The display constantly has to be refreshed (at least the ones that are supported currently; not sure how the A/B displays work, but pretty sure they have to be updated as well).

There is already a c# wrapper, check out bindings/c#.

maitredede commented 7 years ago

Sorry for bothering :) If you prefer to talk privately, or another channel (gitter ?)...

I am trying to figure the principle of how a HUB75 should work. I found this page that may explain the bases.

If I understand well, a physical panel is divided in half (because of two RGB lines). The lines A, B, C... are the address of a row. In my case, I have only A and B, so only 4 rows can be addressed. The data I can send to the panel is only pixel "on" or "off". This bit is transmitted each rise on clock signal. I transmit one full data row (64 bits) on each 4 addresses. Then I pulse a latch to "go one row down", so in my case, all 4 rows are shifted down by 4. The OE signal is up when displaying image, and down when shifting data. Do you aggree ? :)

hzeller commented 7 years ago

In the regular panels OE can also be on while you shift data, but not while switching rows. Also you use the lenght of the OE to do the PWM simulation. In general, the description is right with the A,B,C,... lines, but I don't know how the A, B lines behave.

maitredede commented 7 years ago

Hi, My investigations so far for the 64x64 panel, 1/32 scan, with A, B and NC line :

maitredede commented 7 years ago

@hzeller , on the panels you have managed to drive, is is right that the behavior is : clock a row, set address, stobe, repeat for each address ?

hzeller commented 7 years ago

NC as description to some input usually means not connected - so I guess it does not mean anything in this case.

Yes - the strobing takes over the shift register content to the visible LEDs. So at that point it is important that output enable is off (logic high) to not have glitches. Similar when changing the address (The current address is the one that is displayed, its value is not taken over with the strobing.).

You can also see that in the relevant loop in framebuffer.cc.

For the A/B panels, I suspect that they have some kind of internal way to advance the address on each strobe, at least this is what the visual inspection of the artifacts seem to indicate.

maitredede commented 7 years ago

Hi, Strange things for the 1/32S AB 64x64 panel... I have started to write a console application to manually keyboard send data to the panel (through socket interface of pigpiod). So when panel is lit (oe=false), I send bit-bang data. (first pixel on, others off). Due to socket latency, I can see my pixel scroll from right to left, accross all 64 columns. It seams that the A line move buffer down one row, But when transmitting a new line, I can see all the screen moving... I don't understand what I see... Also seams that B does nothing, and Latch seams obvious to me... If someone that has the same kind of panel could give it a try to figure out which sequence of signals to send to "get something working", that would help a lot... The program sources are here.

maitredede commented 7 years ago

Hi @currentlysober @doldroyd Did you managed to get your 64x64 1/32 AB panel working ?

I am convinced that a stobe on A moves lines down. When I have B up, it seams that a stobe on A puts an empty line, even if I transmited data. When I transmit one pixel, all the lines get this pixel pushed.

@hzeller, do you think that the pannel may be driven this way :

Do you think you can easily branch a POC with the demo 0 (rotating square) to test ? I would be pleased to show you the result...

maitredede commented 7 years ago

@hzeller I applied my theory, I think I have it... chesspattern

 while (true)
            {
                Console.Write(".");
                for (int scan = 0; scan < 32; scan++)
                {
                    g.Write(drv.Layout.OE, true);
                    for (int row = 0; row < 32; row++)
                    {
                        if (row == scan)
                        {
                            for (int col = 0; col < 64; col++)
                            {
                                SetC1(board[row][col]);
                                SetC2(board[row + 32][col]);
                                Clock();
                            }
                            g.Write(drv.Layout.A, true);
                            g.Write(drv.Layout.A, false);
                        }
                        else
                        {
                            g.Write(drv.Layout.B, true);
                            g.Write(drv.Layout.A, true);
                            g.Write(drv.Layout.A, false);
                            g.Write(drv.Layout.B, false);
                        }
                    }
                    Strobe();
                    g.Write(drv.Layout.OE, false);
                    Thread.Sleep(1);
                }
            }

Black lines are the flickering...

doldroyd commented 7 years ago

This is in line with the investigation I did earlier this year but ran out of time to complete. A and B are the clock and data (respectively) to a chain of shift register chips, so you clock in an "on" signal at the first row, then clock in an "off" signal for each subsequent row which pushes the "on" row down. It has been a while since I looked at mine, but I seem to recall the signals were active low (on = 0, off = 1), but it has been a while and there could be different versions of these boards.

The code I wrote was for a specialized silicon peripheral, but I can wire my display up to a pi this weekend and try the code you posted.

maitredede commented 7 years ago

Hi @hzeller ,

I would like to try to update your lib with my panel. Which function should I update to implement my panel's behavior ? Thanks.

hzeller commented 7 years ago

So it sounds like the clocking the data into the matrix is a little different than with the regular matrix @MaitreDede .

The place to put this in would be in Framebuffer::DumpToMatrix() https://github.com/hzeller/rpi-rgb-led-matrix/blob/master/lib/framebuffer.cc#L405 This is the function that does the clocking for the 'regular' matrix currently.

I would suggest to first try to make it work with your matrix and then we can see how we can make it work that it works with either type; depending this might end up being an #ifdef of something that we simply switch with a flag (probably the latter so that it is simple to do). But I can take care of it.

If you can send me a pull request that just replaces things to work with the A/B matrix, I can take care of the rest. Thanks!

maitredede commented 7 years ago

@hzeller I have troubles getting the right data value to send. Can it be a problem of coordinate transformation with ValueAt() ? Then, I have troubles undertanding how to correctly strobe OE.

I have barely translated my C# code to your C/C++ code. Can you take a look on what may be wrong please ? https://github.com/MaitreDede/rpi-rgb-led-matrix/tree/dev-maxtrix-ab

To easily show changes, you can take a look at commits after the "code formatting" one. I am editing the code with Visual Studio Code, and it automatically formats the code on save.

hzeller commented 7 years ago

ValueAt() returns the color values for the two sub-panels (I suspect the organization of this panel is still two sub-panels, i.e. there are two rows that are clocked in in parallel ?). It essentially contains the (RGB)(RGB) of both these rows. If it doesn't clock quite as you expect, maybe this is just a matter of pixel-mapping ? In that case, try a test program in which you run a single pixel all around to see what is happening.

I don't really understand what you are doing in the if (row == scan) block. You are essentially only doing something once when going through all the 64 rows if it happens to match the scan (which only goes to 32 anyway) but most of the time nothing but just wiggle the a/b bits ? This doesn't sound right.

maitredede commented 7 years ago

This panel is not 2 sub-panels, it is one 64 columns panel, split in two half (top and bottom). I may dig into your code to see if I can add it easily. The first code I wrote takes more from the POC that final code. The if(row==scan) was to only produce the right line on one scan, and putting black lines on the other. Now that I have figured how the panels works, I will try an other approach.

hzeller commented 7 years ago

So from what you are saying it sounds like instead of supplying a binary address at A, B, C, D, we just toggle B to inrease an internal counter in the panels, while A just resets the counter ?

maitredede commented 7 years ago

When I first wrote my working code, I believed that the A line pushes the data down one line, and B up/down is to choose between data/black line to be pushed by A pulses. That why in my original code, I push black lines (to remove previous line), pushes the row data (row==scan) and push more black lines to put it on the right line. Now that you are asking me questions, I think that I can try an other way to display data. Instead of pushing a lot of blank lines, I will check if I can reduce them. I will also try to use a real image with my original code, I suspect that the color order is RBG...

hzeller commented 7 years ago

Ok, so from what it sounds like putting various posts on this thread together, it sounds like the A=clock and B=current-row-bit that is used to select the current row, which allows for more rows than just setting the address with A, B, C, D, E ...

So it sounds like everything could stay the same except the way how we set the address ?

I put this together in an experimental patch; I have to order an A/B panel myself for testing, so could someone who has such a panel see if this is closer to an image ? @MaitreDede @doldroyd

Patch attached: ab-test.patch.gz

maitredede commented 7 years ago

I think the roles of pins : A : strobing pushes display one row down. B : down, pushed row (by A strobe) is lit, down pushed row is black. Clocking data set it on all rows. So for each scan, I clock the data, and push only one lit row (with A and B). So I push down first row as lit, and the remainings as black, so the "lit" row moves down.

I have made a second attempt : https://github.com/MaitreDede/rpi-rgb-led-matrix/commit/ef98f7c98ed8d51346fb754b3261bac6601979bf Result is : https://www.youtube.com/watch?v=nhu1mROnUaU

In my code I compute row number from scan number, because the first test I made displayed my pattern shifted by 1 one row.

A strange behavior I seen is that once per second, I may see the "expected" image. You can see it in the video of demo 0. The same behavior occurs also on demo "game of life".

I am going to test your patch...

maitredede commented 7 years ago

@hzeller Here is the result of your patch :) https://www.youtube.com/watch?v=uIaaOFzX9KU sudo ./examples-api-use/demo --led-show-refresh --led-rgb-sequence=RBG -D 0 --led-pwm-bits=11 --led-rows=64 --led-chain=2 Diplays at ~110Hz.

Slowing down GPIO shows different results, the best one I got is with --led-slowdown-gpio=3. 4 also works. FIY, my panel is plugged with dupont cables ~10cm, on a breadboard plugged to the pi with a flat 40pins ribbon of ~10cm.

Here it is : https://www.youtube.com/watch?v=6DPjLiq-gyI

maitredede commented 7 years ago

I have retested my code with --led-slowdown-gpio=3... And guesse what... 🥇 Demo 0 : a nice rotating colored cube... I tested all other demos (3 and up), working nicely too. Refresh rate does not go below 80Hz.

hzeller commented 7 years ago

Alright, that sounds promising. I think the reason why my patch created more artifacts is that I attempted to set the row address not where it usually is set. This might have messed with the interleaving output enable pulse. Here is another attempt for a minimal change; this time clocking in the active row where the address is usually set.

Applies against a clean master branch:

ab-test2.patch.gz

maitredede commented 7 years ago

Patch 2 result : https://www.youtube.com/watch?v=ogb4_5wNlu4 sudo ./examples-api-use/demo --led-rows=64 --led-pwm-bits=11 --led-show-refresh --led-chain=2 --led-rgb-sequence=RBG --led-slowdown-gpio=4 -D 0

hzeller commented 7 years ago

Alright, looks like it is essentially does the right sequence, but has some timing glitches. Can you fiddle with this version and see what is needed to change to make it work with your board ?

Maybe swapping instances of io->WriteMaskedBits(0, my_clk); and io->WriteMaskedBits(my_clk, my_clk); ? Maybe commenting out row_address_change = false; to always force setting the value ?

A friend just came back to me and said that it works perfectly with his A/B matrix and --led-gpio-slowdown=1 so we need to see what makes it more robust so that it works on your and his.

Do you have level shifters between your Raspberry Pi and the board to generate proper 5V logic levels to make sure it can deal with faster signals ? Also breadboarding is not going to be stable with the speeds involved.

maitredede commented 7 years ago

I don't have level shifters. The panel is wired directly on the pi, there was only a breadboard between for easier wiring. I have rewired to connect directly on the pi. It has reduced the need to use --led-gpio-slowdown. Do you know where I can buy a soldered active-3 adapter ? (I can't do SMD soldering). I will check various changes based on your code, but so far the only acceptable result was my code.

But with your code and mine, I still have seen same kind of arfifacts : like if pixels left a trail. For example, one steady lit pixel on game of life has a gradient line from it to the top, but not easy to see. I will take a photo next time, I have to double-check my wiring (G2 and B2 seams swapped), then I will retry patch 1 and 2, and some changes.