rpi-rgb-led-matrix icon indicating copy to clipboard operation
rpi-rgb-led-matrix copied to clipboard

Provide a way to extend the chain that just mirrors the first part.

Open marcmerlin opened this issue 5 years ago • 24 comments

I have a panel setup where my display is mirrored onto a 2nd display, so I use ribbon cables to plug the 2nd set of panels as output of the first ones. I don't get or want a wider display, I just use the fact that the pixels get shifted out to load the 2nd panels. This works fine, except that with FM2616A, the init sequence doesn't get sent wider than the display size, so the mirrored display doesn't get initialized.

Workaround: send a bogus frame that is twice as wide to init all the panels Better workaround, some init option to give a width init factor (default to 1, but could be 2, 3, whatever)

marcmerlin avatar Mar 10 '20 20:03 marcmerlin

Also, 1000! :)

marcmerlin avatar Mar 10 '20 20:03 marcmerlin

mmh, usually if you add another panel beyond the length, the output is very poor there: the bits are shifted there, but the timing of course does not line up (the bits are off-by-one), so colors are horrible. So to mirror, you also have to send the data twice.

Not sure how useful such feature is given that the can just declare a larger frame and set the pixels twice.

hzeller avatar Mar 11 '20 19:03 hzeller

Let me test that, I've done that with the smartmatrix driver, and it works perfectly fine. I understand however that it depends how you shift bits (at a given interval no matter what, or if you use BCM which means that the shifted bits will stay the wrong amount of time on the 2nd panel.

Here's a smartmatrix example where the panels are daisy chained and only 64x64 is sent to 192x64 (i.e. the same pattern is shifted twice and looks exactly the same on the secondary panels) image

I'll try with your driver to see how it goes

marcmerlin avatar Mar 11 '20 20:03 marcmerlin

@hzeller Check out https://photos.app.goo.gl/iH1BeCyrtAKFfLBS8 for how it looks like.

I refreshed my memory with https://github.com/hzeller/rpi-rgb-led-matrix/issues/947 The trick is that if you set FM6126A on panels that already work, and only send 128 pixels deep, it will break the init on the other panels in parallel and shut them off. So I sent them the init string, then changed chain length to 1 and removed FM6126A, and got it to work. I'm pasting the worst one below where you can tell the colors are not the same, but still close enough for me, and given that I'm doing color demos, having the exact right color isn't important anyway. It's interesting that the colors differences are more visible with your library than SmartMatrix. The white bit on the right is sun on the panel, ignore that. image SmartMatrix, 3x mirror of 96x64: image (ignore the blurriness, the picture shows 2 different diffusers)

Long story short, you are correct that the colors are not exactly the same, but they are close enough that it doesn't really matter for my use. I'm not sure how you would send the data twice without splicing cables. Is there a good way to do this? Otherwise, if I end up using my hacked up solution, I'm fine patching your library for my own use, I understand if you don't really want to add/support an option that apparently no one but me, will use.

I think I already sent you this, but in case you were wondering why the need for mirror display, it's for this use. I have the same display front and back, and to ease wiring, I simply shift the front panels into the rear ones. image

marcmerlin avatar Mar 11 '20 20:03 marcmerlin

And basically my previous comment is saying "feel free to close this issue as WONTFIX" if you don't think there is a reasonable need to support this (there probably isn't), and I'll patch my way around it (will probably send the patch to this issue if anyone finds it later with google and wants it)

marcmerlin avatar Mar 11 '20 20:03 marcmerlin

Changed this to feature request. Essentially we want a --led-repeat-chain.

hzeller avatar Mar 15 '20 00:03 hzeller

Hi @hzeller and @marcmerlin, I know this thread is from a while ago, but I'm curious, I am now wanting to do the same thing, and was wondering if there were any updates or workarounds found for this in the last 3 years?

Here's how far I got with my attempts tonight: I have a square 128x128 panel (2 x 64x128) that I want to mirror. Similar to you Marc, I'm displaying these as screens on the front and back of an outfit, so I want to mirror and not extend these squares (extending ends up being too many pixels for the CPU to display nicely)

Tonight I made some custom daisy-chained ribbon cables to try and achieve this goal:

image

This results in:

  • Chain 1 is sending out a 64x128 signal to the two top panels
  • Chain 2 is sending out a 64x128 signal to the two bottom panels

To my surprise, this actually worked pretty well. The top panels of the screens (chain 1) create an almost identical duplicate (even the colors look the same). However, the bottom panels of the screens (chain 2), display some tearing/ghosting/blinking/imperfections. It's hard to show this with a static image, but the area in the circle is aggressively flickering.

image

Any idea why this might be happening, or what steps I could take to fix it? Do the ribbon cables need to be more of a 'Y' split cable, rather than a single ribbon with a drop-off point in the middle? Any suggestions welcome, I'm pretty new to this level of LED debugging! Thanks.

andytheengineerguy avatar Aug 10 '23 05:08 andytheengineerguy

ha, right after I posted this, I experimented with changing the gpio slowdown, and seemed to have stumbled into a solution!

I was previously slowing it down to 3. Then set the value to 4 and these imperfections magically disappeared.

Out of curiousity.. Any idea why slowing down the GPIOs helped with this issue? If not, no probs, I'm happy with this as it is!

andytheengineerguy avatar Aug 10 '23 06:08 andytheengineerguy

Yes, slowing down helps.

Also, making the data cables as short as possible is probably good, but I guess given the size of the panels, that might not be possible. There can be weird reflections at the end of the cables, so playing with a y-configuration might be interesting. You use an active adapter as an interface between your Pi and the boards, right ?

Another thing to look out for is that the panels have a solid power supply. I have seen panels glitch in the way you describe if they didn't get full 5V, or the cable to the power supply was too long. Sometimes a low-ESR capacitor at each power input at the panels can help as the panels draw very spiky load from the power supply (There are some musing about this in the a word about power section).

hzeller avatar Aug 10 '23 06:08 hzeller

@andytheengineerguy : Another possible fix is to use two active boards, connected to RPI in parallel.

ledvinap avatar Aug 10 '23 07:08 ledvinap

@ledvinap I already use active board with 3 outputs to get my 128x192 at max speed, and then divide speed by 2 since I shift pixels from the first display to the 2nd one for mirroring. It would still be awesome if the driver could change the order it does BCM (I'm getting from LSB to MSB or the other way around) so that if you daisy chain it actually mostly looks ok without having to send the pixels twice, as per the smartmatrix example I gave above, but in the meantime, mirroring works for me, and I don't have a signal loss issue since the signal is reboosted from the 1st panel to the 2nd one and my ribbon cables aren't too long.

marcmerlin avatar Aug 11 '23 01:08 marcmerlin

@marcmerlin : IMO, when connected this way, you get bitplanes shifted one one PWM period on second panel. It will always ruin colors. Using 2x active boards stacked to RPI GPIO shall fix signal integrity issues, with identical image on both displays.

ledvinap avatar Aug 11 '23 07:08 ledvinap

hi @hzeller, thanks for your response. I am using an active-3 board from electrodragon yes. I might try with Y-ribbon cables, if I do I'll post results here. I indeed read your section on power and was considering experimenting with the low-ESR capacitors. The final product will be battery driven, so I'm motivated to reduce the current spikes regardless, so thanks, I'll give this a shot 💪

@marcmerlin I'm not understanding your approach just yet; if you simply want to mirror/duplicate your display, can you not just connect the data bus in parallel using custom cables as I have above (keeping all else the same)? What is the reason behind dividing the speed by 2 and then sending pixels twice?

@ledvinap I'm also not 100% sure I understand this too. Are you recommending using 1 active board per LED chain?

andytheengineerguy avatar Aug 11 '23 19:08 andytheengineerguy

@andytheengineerguy, the reason for my approach simply ease and length of cabling. It's easier to take the hub75 out connectors on the front panels and connect them to the hub75 in connectors of the rear panels image

I run 3 busses in parallel, but indeed I have to push the pixels twice for each frame, so each panel runs at half speed, but since I'm only pushing 256x64 per bus, it's still fast enough.

If I had easy to find Y cables of the right length, I would consider them, it would double my refresh rate. I'm just not equipped to make my own.

And to answer your question to @ledvinap , I recommend you use one active board chain (you have 3 on electrodragon) per chain. If at all possible, you should always use 3 chains on any layout of 3 panels or more, simply to maximize the refresh rate for each panel (that is unless you have something very small like 64x64 where it really doesn't matter)

marcmerlin avatar Aug 11 '23 20:08 marcmerlin

@marcmerlin ahhh ok, that makes sense. Given that the refresh rate is enough for your needs, it's a good call to simplify the wiring by just pushing the pixels twice / frame. Btw, if you're interested, you can use this IDC crimp tool to easily make your own cables, I bought this recently and it works great 👌

Regarding the active board chains, I see what you're saying, but for the sake of keeping the 128*128 screens 100% equal I think I'll stick with what I'm already doing, which is using 1 chain for the top 2 panels and the other chain for the bottom 2 panels. Each chain has its own logic buffer and 1 chain will be remain unused, but I seem to be getting high enough refresh rates anyway (~240).

andytheengineerguy avatar Aug 14 '23 19:08 andytheengineerguy

@andytheengineerguy totally for 128x128, 2 chains is more than plenty. And if you tweak some colors/precision settings, you should be able to get over 500Hz :)

marcmerlin avatar Aug 14 '23 19:08 marcmerlin

Hmmm I'm tryna retain as much color accuracy as I can... So even with the effectively doubled speed from these parallelized ribbon cable solution, plus dither_bits =1, plus reducing the lsb_nanoseconds to 90, I still need to reduce the PWM bits from 11 down to 8 to get ~230Hz...

Kinda off topic of the thread now, but this is my config and I'm still curious to ask for a 2nd opinion as I've been working mostly in a silo so far: image

I also found that the python bindings performed almost exactly the same as C. This was only comparing the gif and image viewer examples. Eg, using these same settings with the C image viewer + the same gif also gives me 230-240 Hz, qhich is equal to this python script.

Is this your experience too?

andytheengineerguy avatar Aug 14 '23 21:08 andytheengineerguy

Python bindings are just bindings, the actual code still runs in C++ at full speed, so you should get the same refresh rate. I care about Hz more than perfect color, so mine is tuned a bit differently: https://github.com/marcmerlin/FastLED_NeoMatrix_SmartMatrix_LEDMatrix_GFX_Demos/blob/42dc695dcf49369099f430100a9bf8f88453d0ca/neomatrix_config.h#L1321

        #elif GFXDISPLAY_M128BY192
            defaults.rows = 64;
            defaults.cols = 128;
            defaults.chain_length = 1;
            defaults.parallel = 3;
	    // 100->50: 180Hz to 333Hz refresh
            defaults.pwm_lsb_nanoseconds = 70;
            defaults.pwm_bits = 7;
	    // Time dithering of lower bits
	    // 2 changes speed from 400Hz (from 160Hz)
	    // or 520Hz with lsb_ns at 50 not 100
	    // but things are 1/3rd as bright so
	    // we go back to 0 for 333Hz with 50ns
            defaults.pwm_dither_bits = 1;
            defaults.led_rgb_sequence = "RBG";
            defaults.panel_type = "FM6126A";

	#ifdef RPI4
	    ropt.gpio_slowdown = 2;
	#else
            ropt.gpio_slowdown = 1;
	#endif

marcmerlin avatar Aug 14 '23 21:08 marcmerlin

I was always under the impression that anything above ~250Hz was diminishing returns; our eyes are good at ~100 and phone cameras never work well with this highly multiplexed scan architecture that comes with screens like ours (assuming yours is 1/64 or 1/32?). whats the reason for aiming for such high Hz? Are you filming in slow motion or something?

andytheengineerguy avatar Aug 14 '23 22:08 andytheengineerguy

eyes don't need it, cameras can take shots at 0.001s and if so, they'll see the refresh bars, or you even see some black or other issues. Having a much faster refresh rate than the camera helps with this (I'm 1/32). I have plenty of pictures of my outfit taken with cellphones that I had to throw away image

marcmerlin avatar Aug 14 '23 23:08 marcmerlin

EDIT: I meant 1/32 scan, not 1/64

Ahh I was wondering - I'm also creating some LED art to show at music festivals, and yeah, want to be able to take pictures with it. But I'm finding that we're limited by the architecture more than anything else.... This is a screenshot of 3 pics I took @ 470Hz, absolutely bonkers FPS under normal circumstances, but apparently still not good enough when only 1/32 of the screen is illuminated at once. Even when the black lines don't appear, there are noticeable white lines that make it look weird.

image

I think thats why I said the defeated-sounding "dimishing returns" comment haha - if 500Hz doesn't cut it, what will. A DSLR camera maybe?

andytheengineerguy avatar Aug 15 '23 01:08 andytheengineerguy

Mmmh, that's disappointing indeed :-/ Note that a DSLR in auto mode may be worse because if it can take a lot of light, it will snap the picture very quickly and could catch the bars. If it's darker or the sensor isn't as good, it will need more time for a shot and the bars will go away

marcmerlin avatar Aug 15 '23 01:08 marcmerlin

Just purchased some 1/16 scan rate, and also a less common 1/13 scan rate to experiment with. Will see how it goes. Happy to share results if you're interested.

andytheengineerguy avatar Aug 15 '23 01:08 andytheengineerguy

Sure thing, thanks

marcmerlin avatar Aug 15 '23 01:08 marcmerlin