LED-11. Make a very big size 384 X 512 RGB Matrix #3

 This article links to the previous two articles. Be sure to read these articles in advance.

 In the previous section, we looked at the frame assembly, LED panel connection, power connection, etc. to make a large LED signboard of 384X512 pixel size. In this blog, we will continue to check whether the connected electronic signage works properly, and if there is a problem, we will try to solve it.

 

Prepare Raspberry Pi images

LED players

I have enjoyed using Henner Zeller's library while making LED signboards using Raspberry Pi. I recommend reading his articles on GitHub.

 I will use DietPi as the OS for LED control. DietPi is a lightweight OS that removes unnecessary parts from the Raspberry Pi OS. DietPi and HZeller's library installation are explained in detail in the article below. Please refer to the article below to create 4 SD card images.

 

 LED Server

To operate the 384X512 size LED signboard, I prepared 4 LED players, a slightly different approach is required for the three LED players to act as if they were one.
Instead of creating an image to be displayed in the player, an image of 384X512 size is prepared on a standalone device.
Then, this image is divided into 4 384X128, and the image is displayed on the LED by passing it to three players.

I will call this standalone device the LED Server. Therefore, there is no need to install image processing packages such as OpenCV and PIL in the LED player.

There is no problem using any OS for LED Server, but I will use the Raspberry OS Desktop version, which is the easiest to use. And here I install OpenCV and PIL for image processing.


Player Test

After assembling the LED signage, it is necessary to test whether the three Raspberry Pi players are working properly.

Use the following simple code to check whether the screen is displayed normally. This code tests a 384 X 128 LED. Therefore, you can test the LED players located above and below the middle except for the middle.

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

parser = argparse.ArgumentParser(description="RGB LED matrix Example")
parser.add_argument("--image", type=str, required = True, help="image file name")
args = parser.parse_args()

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

VMapper = True

# 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 = 80
options.pwm_bits = 11
options.gpio_slowdown = 4.0
options.show_refresh_rate = 1
options.hardware_mapping = 'regular'  # If you have an Adafruit HAT: 'adafruit-hat'
options.pwm_dither_bits = 0

if VMapper == True:
    options.pixel_mapper_config = "V-mapper"

matrix = RGBMatrix(options = options)

if VMapper == True:
    canvas_w = PANEL_W * CHAIN_PARALLEL
    canvas_h = PANEL_H * CHAIN_LEN
else:
    canvas_w = PANEL_W * CHAIN_LEN
    canvas_h = PANEL_H * CHAIN_PARALLEL


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


im = cv2.imread(args.image, cv2.IMREAD_COLOR)
im = cv2.resize(im, (canvas_w, canvas_h))
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)
im_pil = Image.fromarray(im)

double_buffer = matrix.CreateFrameCanvas()
double_buffer.SetImage(im_pil)
#double_buffer.SetImage(im_pil, canvas_w)
double_buffer = matrix.SwapOnVSync(double_buffer)
 
while True:
    try:
        s = time.time()
        double_buffer.SetImage(im_pil)
        double_buffer = matrix.SwapOnVSync(double_buffer)
        e = time.time()
        time.sleep(0.033 + (e - s))	
    except KeyboardInterrupt:
        break   


print('End' )

<test2.py>


Now run the code!

As you can see from the screen output, the screen refresh rate Hz value is 88Hz, it is too low. And as a result, the LED screen flickers . However, the black line in the figure below is not visible to the human eye.

 

 

Flickering

You don't have to worry too much about the screen being turned upside down. This can be easily fixed using options.pixel_mapper_config options. The most important problem is flickering.
There are many causes of flickering, but the biggest reason is that the size of the LED is large. This is because it drives a large LED of 384 horizontal and 192 vertical.
It takes some sacrifice to drive such a large size LED without flickering.

Adjust the options.pwm_bits value from the default of 11 to 7. Adjusting this value reduces the number of colors that can be reproduced, resulting in image quality degradation. There is no need to keep the value of options.pwm_bits at 7. I will later test values between 7 and 11 to find the maximum in the range where flickering does not occur. If this value is low, since the color range is reduced, there is a disadvantage in that the color reproduction range of the LED signboard is reduced.

options.pwm_bits = 7

Set the options.pwm_dither_bits value to 1. If this value is set, the picture quality will also deteriorate, but the screen playback speed will increase.

options.pwm_dither_bits = 1

 Now run the code again! The Hz value more than doubled to 179Hz.


And the flicker almost disappeared as the refresh rate increased.

<Flicker free image>

Wrapping up

Test the rest of the players to check for poor connections or defective parts.
I was able to check the option values for large size LED power through unit tests.
Important option values are as follows. The description of this option value is at https://github.com/hzeller/rpi-rgb-led-matrix/tree/master/examples-api-use.

options.pwm_bits = 7
options.pwm_dither_bits = 1

Since I confirmed that the LED player is working normally, in the next article, I will look at playing the full screen using 4 LED players and an LED server.

 

 

 

 

 




댓글

  1. Did you use any algorithm to synchronize data between slaves? because I thinks if slave (1) handle data slower than slave (2/3/4) it will make the display not smooth. Thanks for your sharing.

    답글삭제
    답글
    1. Yes, slave 1 receives image first, and so on. But the time difference is very small ( < 0.1ms). The image due to this time difference cannot be recognized by human eyes. At the time of the first development, I also considered using the ON and OFF of the GPIO pins for synchronization as you said, but after actual testing, there is no need for that.

      삭제
    2. thanks for your response I got it.

      삭제

댓글 쓰기

이 블로그의 인기 게시물

LED-12. Displaying HDMI Contents

LED - 5. Raspberry Pi 4 + DietPi Buster + Electrodragon HAT - Part 1

LED-11. Make a very big size 384 X 512 RGB Matrix #6(final)