Raspberry Pi 3B + (including SD card) RGB LED matrix (6mm pitch 32x32) 6 sheets Connector for LED matrix MAXWELL switching power supply 3 power cords for LED panel 6 IDC flat cables 50 jump wires, male and female, and 50 male and female bread board Except for Raspberry Pi, I bought it at LED Picari Hall in Akihabara. LED Picarikan
I want to freely switch the score display of LEDmatrix using Raspberry Pi. If you can handle LEDmatrix with Raspberry Pi, you can switch from your smartphone by connecting to the Internet, so the range of applications should be wide!
LED matrix is a collection of LEDs (laughs as it is) It is the same as the electric bulletin board that you often see at stations. There are various types, but basically the difference is the pitch (distance between LEDs), the color that can be expressed, and the number of vertical and horizontal LED arrangements. This time, I used 6 RGB (all colors can be expressed) 32x32 LED matrix with 6mm pitch.
First of all, we will wire. Make sure you have everything you need.
The power supply uses a switching power supply. The current required for each card is about 2A, so if you use multiple cards, buy a power supply that corresponds to that. I used 6 sheets this time, so I needed 12A or more. As long as you don't mistake GND for V㏄, it's okay. Follow the notation on the power outlet on the back as shown in the picture below. Wire the matrices only horizontally with a flat cable.
This wiring was done according to the following site. hzeller github To explain by quoting this site, the connector side must be wired to each of the 16 locations in the photo below. Each connection destination is a handwritten table below. The two rows in the middle point to the 40 pin of the Raspberry Pi. Each connection destination is written next to it. In this library, LEDmatrix can display up to 3 levels. The connection destinations from the first to the third row are entered in order from the top. Wire the LED matrix on the far right of each row to the Raspberry Pi as shown in the picture below. It is possible to connect to the connector as it is with a jump wire if it is one stage, but if it is two or more stages, a breadboard is required. If the wiring is messy, it will look like the picture below.
I used the following library. LEDmatrix Control Library
Install the library from github immediately. Please move to the directory of the installed library and build.
git clone https://github.com/hzeller/rpi-rgb-led-matrix/
cd rpi-rgb-led-matrix
make -C examples-api-use
To enable python, execute the following command.
sudo apt-get update && sudo apt-get install python3-dev python3-pillow -y
cd rpi-rgb-led-matrix/python
make build-python PYTHON=$(which python3)
sudo make install-python PYTHON=$(which python3)
You can run the demo program by going to the rpi-rgb-led-matrix directory. Do the following:
cd rpi-rgb-led-matrix
sudo examples-api-use/demo
Then, the following operation options will be displayed. Follow these options. Let me explain what is important. Specify the matrix of LED matrix per LED matrix with --led-rows, --led-cols. When using multiple stages, specify --led-parallel for the number of stages and --led-chain for the number connected horizontally. Brightness is specified by --led-brightness and display time is specified by -t.
Expected required option -D <demo>
usage: examples-api-use/demo <options> -D <demo-nr> [optional parameter]
Options:
-D <demo-nr> : Always needs to be set
-t <seconds> : Run for these number of seconds, then exit.
--led-gpio-mapping=<name> : Name of GPIO mapping used. Default "regular"
--led-rows=<rows> : Panel rows. Typically 8, 16, 32 or 64. (Default: 32).
--led-cols=<cols> : Panel columns. Typically 32 or 64. (Default: 32).
--led-chain=<chained> : Number of daisy-chained panels. (Default: 1).
--led-parallel=<parallel> : Parallel chains. range=1..3 (Default: 1).
--led-multiplexing=<0..9> : Mux type: 0=direct; 1=Stripe; 2=Checkered; 3=Spiral; 4=ZStripe; 5=ZnMirrorZStripe; 6=coreman; 7=Kaler2Scan; 8=ZStripeUneven; 9=P10-128x4-Z (Default: 0)
--led-pixel-mapper : Semicolon-separated list of pixel-mappers to arrange pixels.
Optional params after a colon e.g. "U-mapper;Rotate:90"
Available: "Rotate", "U-mapper". Default: ""
--led-pwm-bits=<1..11> : PWM bits (Default: 11).
--led-brightness=<percent>: Brightness in percent (Default: 100).
--led-scan-mode=<0..1> : 0 = progressive; 1 = interlaced (Default: 0).
--led-row-addr-type=<0..2>: 0 = default; 1 = AB-addressed panels; 2 = direct row select(Default: 0).
--led-show-refresh : Show refresh rate.
--led-inverse : Switch if your matrix has inverse colors on.
--led-rgb-sequence : Switch if your matrix has led colors swapped (Default: "RGB")
--led-pwm-lsb-nanoseconds : PWM Nanoseconds for LSB (Default: 130)
--led-pwm-dither-bits=<0..2> : Time dithering of lower bits (Default: 0)
--led-no-hardware-pulse : Don't use hardware pin-pulse generation.
--led-slowdown-gpio=<0..2>: Slowdown GPIO. Needed for faster Pis/slower panels (Default: 1).
--led-daemon : Make the process run in the background as daemon.
--led-no-drop-privs : Don't drop privileges from 'root' after initializing the hardware.
Demos, choosen with -D
0 - some rotating square
1 - forward scrolling an image (-m <scroll-ms>)
2 - backward scrolling an image (-m <scroll-ms>)
3 - test image: a square
4 - Pulsing color
5 - Grayscale Block
6 - Abelian sandpile model (-m <time-step-ms>)
7 - Conway's game of life (-m <time-step-ms>)
8 - Langton's ant (-m <time-step-ms>)
9 - Volume bars (-m <time-step-ms>)
10 - Evolution of color (-m <time-step-ms>)
11 - Brightness pulse generator
Example:
examples-api-use/demo -t 10 -D 1 runtext.ppm
Scrolls the runtext for 10 seconds
Therefore, to run the demo, you can type the following command (change as appropriate according to your own number). By design, an error will occur if you do not run it with sudo. You can also change the demo by tweaking the number after the last -D.
sudo examples-api-use/demo --led-no-hardware-pulse --led-rows=32 --led-cols=32 --led-chain=3 -t 10 --led-brightness=80 --led-parallel=2 -D 0
The sample code of python is also included in this library, so I will remodel the program so that it can display Japanese text with reference to it. Since it is a library for foreigners, there is a sample program for displaying text, but it can only display alphabets. As a result of various searches, I made a specification to convert Japanese text into an image and display it, referring to this article. Any Japanese font is fine, but please download it to Raspberry Pi. The font used this time was downloaded from this site.
text_image_ledmatrix.py
#!/usr/bin/env python
# -*- encoding:utf8 -*-
import time
import sys
import os
import numpy as np
from PIL import Image, ImageFont, ImageDraw
from rgbmatrix import RGBMatrix, RGBMatrixOptions
import subprocess, os, sys, re
def imaged_text(text, fontfile, fontsize, color, scale_bias=4):
font = ImageFont.truetype(fontfile, fontsize * scale_bias)
image = Image.new('RGBA', (1, 1))
draw = ImageDraw.Draw(image)
w,h = draw.textsize(text, font=font)
del draw
image = Image.new('RGBA', (w, h))
draw = ImageDraw.Draw(image)
draw.text((0, 0), text, font=font, fill=color)
del draw
return image.resize((w // scale_bias, h // scale_bias), Image.ANTIALIAS)
def draw_text_to(target, position, text, fontfile, fontsize, color):
image = imaged_text(text, fontfile, fontsize, color)
target.paste(image , position, image)
def select_color(threshold, color, destcolor = '#FFFFFF'):
mean = np.array(color).mean()
if mean > threshold:
#return (255, 255, 255)
return (int(destcolor[1:3],16),int(destcolor[3:5],16),int(destcolor[5:7],16))
else:
return (0, 0, 0)
#Character image binarization
def to_bin(img, w, h, color = '#FFFFFF'):
#R for each pixel value,g,Find the average of b
means = np.array([[img.getpixel((x,y)) for x in range(w)] for y in range(h)]).mean(axis=2).reshape(w * h,)
#Make a histogram
hist = np.array([np.sum(means == i) for i in range(256)])
max_v = 0
threshold = 0
#Calculate from 0 to 255 in order to find the appropriate threshold
#Pixel values larger than the threshold are classified as class 1, and pixel values smaller than the threshold value are classified as class 2.
for th in range(256):
n1 = sum(hist[:th]) #Number of class 1
m1 = np.dot(hist[:th], np.array(range(256))[:th]) #Average of class 1 values
n2 = sum(hist[th:]) #Number of class 2
m2 = np.dot(hist[th:], np.array(range(256))[th:]) #Average of class 2 values
if n1 == 0 or n2 == 0:
v = 0
else:
#Find the molecule of interclass dispersion
v = n1 * n2 * (m1 / n1 - m2 / n2) ** 2
#Update the threshold at which the numerator of interclass variance is maximum
if max_v < v:
max_v = v
threshold = th
bin_img = Image.new('RGB', (w, h))
np.array([[bin_img.putpixel((x, y), select_color(threshold, img.getpixel((x,y)), color)) for x in range(w)] for y in range(h)])
return bin_img
#Connect images side by side
def get_concat_h(im1, im2):
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
#Connect images vertically
def get_concat_w(im1, im2):
dst = Image.new('RGB', (im1.width,im1.height + im2.height,))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
def get_text(str, width, separator = u"", col = '#B5E61D'):
image = Image.new("RGB", (width, 16))
draw_text_to(image, (0, 0), separator + str, 'KH-Dot-Kodenmachou-16.ttf', 16, col)
bin = to_bin(image, image.width, image.height, col)
return bin
def get_large_text(str, width, separator = u"", col = '#B5E61D'):
image = Image.new("RGB", (width,64))
draw_text_to(image, (0, 16), separator + str, 'KH-Dot-Kodenmachou-16.ttf', 32, col)
bin = to_bin(image, image.width, image.height, col)
return bin
def add_text(tex):
filename='clear.txt'
with open(filename,'a') as file_object:
file_object.write(tex+'\n')
def clearmatrix():
f=open('clear.txt')
line=f.readline()
while line:
ans=line
line=f.readline()
f.close()
ans=ans.strip()
if ans=='clear':
return True
else:
return False
# Configuration for the matrix
options = RGBMatrixOptions()
options.rows = 32
options.chain_length = 3
options.parallel = 2
options.hardware_mapping = 'regular'
options.brightness = 40
options.pwm_lsb_nanoseconds = 100
matrix = RGBMatrix(options = options)
def textscroll(text):
add_text("on")
width=full_width_decision(text)+32*6
text1=" "
left=0
right=96
result = Image.new("RGB", (96, 32))
text=text1+text
text_im = get_large_text(text, width, u"", '#FF7F27')
while clearmatrix()==False:
result=text_im.crop((left,0,right,64))
left+=1
right=left+96
if left>=width:
left=0
matrix.SetImage(result)
time.sleep(0.005)#Changing this value will change the scroll speed.
matrix.Clear()
add_text("off")
def ledprint(text):
add_text("on")
length=len(text)
row=int((length-1)/6)
text1=" "
text2=" "
text3=" "
text4=" "
if row==0:
text1=text
if row==1:
text1=text[0:6]
text2=text[6:]
if row==2:
text1=text[0:6]
text2=text[6:12]
text3=text[12:]
if row>=3:
text1=text[0:6]
text2=text[6:12]
text3=text[12:18]
text4=text[18:]
text1_im = Image.new("RGB", (96, 16))
text2_im = Image.new("RGB", (96, 16))
text3_im = Image.new("RGB", (96, 16))
text4_im = Image.new("RGB", (96, 16))
while clearmatrix()==False:
text1_im = get_text(text1, 96, u"", '#FF7F27')
text2_im = get_text(text2, 96, u"", '#FF7F27')
text3_im = get_text(text3, 96, u"", '#FF7F27')
text4_im = get_text(text4, 96, u"", '#FF7F27')
result = get_concat_w(text1_im,text2_im)
result = get_concat_w(result,text3_im)
result = get_concat_w(result,text4_im)
matrix.SetImage(result)
time.sleep(1)
matrix.Clear()
add_text("off")
if __name__ == '__main__':
ledprint(u"It is possible to display in this way")
You can now view and scroll the text with the two functions defined below. Please change the number part according to the size of your LED matrix. Also, as I will explain in the latter half of the article this time, since the display is switched by reading and writing the text file (program beginner), I read'clear.txt' and decide whether to delete it. ..
In controlling LED matrix with Raspberry Pi this time, I referred to the following article. Thank you for the wonderful article. https://qiita.com/sousan/items/19425d5eac43786003a7/ https://qiita.com/t_slash_k/items/35ccf49ce85e5cbd045b/ https://qiita.com/eucalyhome/items/e871e297bfd527ccaf2c/ https://www.buildinsider.net/small/raspisinage/01/ https://yomon.hatenablog.com/entry/2018/09/p3rgbdisplay/
Now it is possible to prepare and wire LEDmatrix and display Japanese text. From the next time, I will try to link Raspberry Pi and Slack so that it will be easier to handle.
Recommended Posts