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.67k stars 1.17k forks source link

Flickering at regular intervals #1689

Open Dowanproject opened 2 months ago

Dowanproject commented 2 months ago

Hi. I ordered a board from Electrondragon Store (https://www.electrodragon.com/product/rgb-matrix-panel-drive-board-for-raspberry-pi-v2/) and tested it, but I noticed a consistent flickering (possibly) occurring at regular intervals. It feels like the panel turns off and on for 0.1 seconds. How can I resolve this? Below is the code that receives HDMI in USB format and displays it on the panel. Please understand that there may be some awkwardness in the English translation.

Panel : https://aliexpress.com/item/1005006612553395.html

Panel3Panel2Panel1__Board Port 1

Panel6Panel5Panel4__Board Port 2

X X X__Board Port 3

import argparse, sys
import cv2
import numpy as np
from PIL import Image
from PIL import ImageDraw
from rgbmatrix import RGBMatrix, RGBMatrixOptions
import time

PANEL_W = 128
PANEL_H = 64
CHAIN_LEN = 3
CHAIN_PARALLEL = 2

# Configuration for the matrix
options = RGBMatrixOptions()
options.cols = PANEL_W
options.rows = PANEL_H
options.chain_length = CHAIN_LEN
options.parallel = CHAIN_PARALLEL

options.brightness = 100
options.gpio_slowdown = 5
options.pwm_lsb_nanoseconds = 50
options.parallel = 3
options.pwm_bits = 7
options.hardware_mapping = 'regular'

#options.pixel_mapper_config = "Mirror:V;Rotate:180"

cap = cv2.VideoCapture(0)   #HDMI Input

matrix = RGBMatrix(options = options)
canvas_w = 384
canvas_h = 128

print('Matrix H:%d W:%d'%(matrix.height, matrix.width))
print('Image size H:%d W:%d'%(canvas_h, canvas_w))

if cap is None:
    print('cannot open camera')
    sys.exit(0)

double_buffer = matrix.CreateFrameCanvas()
w = double_buffer.width
print('offscreen width:' + str(w))

while cap.isOpened():
    try:
        s = time.time()
        ret, im = cap.read()
        if ret == False:
            break
        im = cv2.resize(im, (canvas_w, canvas_h))
        im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
        im_pil = Image.fromarray(im)

        double_buffer.SetImage(im_pil)
        e = time.time()
        #time.sleep(0.03)
        double_buffer = matrix.SwapOnVSync(double_buffer)
        #print('FPS:%4.2f'%(1 / (e - s)))
        #matrix.Clear()
        #matrix.SetImage(im_pil)
    except KeyboardInterrupt:
        break  

cap.release()
print('End' )
hzeller commented 2 months ago

make sure to not overload your Pi - looks like you are doing a lot of work that moves around memory a lot (the resize for instance looks problematic). Also just reading from the USB port a lot of data is known to saturate the memory bus in particular on older Pis. Scaling is a pretty expensive operation, so make sure to open a video stream in your capture that is already as low as possible resolution (also: I suggest avoid using Python, as it has its own very expensive garbage collector)

The memory bus of the Pi easily overloaded, so if there is too much going on, the writing to the panel will starve and that can result in such blips you see.

Also make sure to enable all the usual things you find in the README, such as reserving one core for the display update.

What Raspberry Pi are you using ? For this application you want a Pi4.

Dowanproject commented 2 months ago

@hzeller I'm using Raspberry Pi 4. Then is it better to configure it in C language instead of Python? I want to solve the problem that the consistent flickering occurring at regular intervals as soon as possible. Thank you for your help.

hzeller commented 2 months ago

Before switching to C++

if the video device is showing up in /dev/video , it should be possible to minimal change the C++ video-viewer to read from an avdevice.

Dowanproject commented 2 months ago

@hzeller I just tested it with video-viewer, and the same thing happens with video-viewer. (Flicker occurs once every two seconds.) ./video-viewer --led-rows=64 --led-cols=128 --led-chain=3 --led-parallel=3 --led-gpio-mapping=regular --led-pwm-bits=7 --led-pwm-lsb-nanoseconds=50 --led-slowdown-gpio=4 test.mp4

hzeller commented 2 months ago

the pwm bits and lsb nanoseconds are very low, this looks like you might starve the cpu-core from getting any time it can do book-keeping. What happens if you use the default values ?

hzeller commented 2 months ago

also, did you disable i2c and everything you don't need ? Did you make sure that no GUI is running (sometimes it is easy to forget to switch that off when running without monitor connected)

Dowanproject commented 2 months ago

@hzeller Using the default values ​​will cause more flickering. I am currently using the Raspbian GUI version. Can I solve the problem by using the Lite version or Dietpi? (I'm currently controlling it via vnc rather than using a monitor connection.) Also, NTP was also disabled

hzeller commented 2 months ago

ah, never use the GUI or VNC, that is too much load on the system. Always use a lite version and only connect via ssh.

Dowanproject commented 2 months ago

@hzeller Can I use Dietpi?

hzeller commented 2 months ago

probably, I have not installed a recent version of it to know how 'diet' it still is. Maybe start out with just a regular raspberry pi lite image. Any of these should work.

Dowanproject commented 2 months ago

@hzeller I tried it with Raspberry Pi Lite, but the same symptoms persist.

hzeller commented 2 months ago

Any periodic job that you have (e.g. just running top) can generate brightness glitches. Remove all the services you don't need (pigpio, 1-wire, etc. see Troubleshooting section)

Also you seem to run a fairly large panel, make sure that your power-supply is not glitching: if DC/DC power supplies get into overload conditions, they are known to have brief periods in which power switches off (measure with a scope). You need to plan about 2-3Ampere per panel, so for your 3x3 configuration that can be 20-30A at 5V.

hzeller commented 2 months ago

I've now added support for a video input in the vide-viewer. So if it shows up as a /dev/video*-device, you can show it https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/utils#examples-2

You need to update the dependencies and recompile.

Dowanproject commented 2 months ago

@hzeller I tested as below, but the resolution is not correct. What should I do? sudo ./video-viewer --led-rows=64 --led-cols=128 --led-chain=3 --led-parallel=2 --led-slowdown-gpio=5 -T2 --led-no-drop-privs /dev/video0 KakaoTalk_20240726_150806238

hzeller commented 2 months ago

the video viewer will scale to the size it sees. In your python code I see that you have set the pixel mapping. The corresponding flag on the video viewer is --led-pixel-mapper

If you invoke the video-viewer with -v (verbose), it shows the input stream size it sees and to what it scales it to.

Dowanproject commented 2 months ago

@hzeller I executed the same command, but when I unplugged and replugged the HDMI to USB, it showed a different resolution. How can I solve this issue? Just a moment ago, the screen size fit perfectly on the panel, but after unplugging and plugging in the HDMI to USB and executing the command again, the resolution is strange.

Log with correct screen resolution: root@DietPi:~/rpi-rgb-led-matrix/utils# sudo ./video-viewer --led-rows=64 --led-cols=128 --led-chain=2 --led-parallel=3 --led-slowdown-gpio=5 --led-pwm-bits=8 --led-pwm-lsb-nanoseconds=85 --led-brightness=90 -v -T2 --led-no-drop-privs /dev/video0 Input #0, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 17035.210097, bitrate: 147456 kb/s Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x480, 147456 kb/s, 30 fps, 30 tbr, 1000k tbn FPS: 30.000000 Scaling 640x480 -> 256x192; black border x:0 y:0

Log with strange resolution:

root@DietPi:~/rpi-rgb-led-matrix/utils# sudo ./video-viewer --led-rows=64 --led-cols=128 --led-chain=2 --led-parallel=3 --led-slowdown-gpio=5 --led-pwm-bits=8 --led-pwm-lsb-nanoseconds=85 --led-brightness=90 -v -T2 --led-no-drop-privs /dev/video0 Input #0, video4linux2,v4l2, from '/dev/video0': Duration: N/A, start: 17248.518495, bitrate: 165888 kb/s Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 1920x1080, 165888 kb/s, 5 fps, 5 tbr, 1000k tbn FPS: 5.000000 Scaling 1920x1080 -> 256x144; black border x:0 y:24

hzeller commented 2 months ago

That is probably something in the interplay of your HDMI->USB devices and the video4linux subsystem; you might need to configure that and ask it to return something close to the desired resolution after unplug/replug. Not much the video-viewer can do here, it just outputs what it sees.

v4l2-ctl -d /dev/video0 --set-fmt-video=width=256,height=192
Dowanproject commented 2 months ago

@hzeller Thanks for your help. I've been testing it for a few weeks. Noticeable flicker is almost eliminated by setting gpio-slowdown, pwm-lsb-nanoseconds, pwm-bits, but subtle flicker still occurs, especially if the colors are complex.

./video-viewer --led-rows=64 --led-cols=128 --led-chain=2 --led-parallel=3 --led-slowdown-gpio=5 --led-pwm-bits=8 --led-pwm-lsb-nanoseconds=90 -T2 --led-no-drop-privs /dev/video0