[PYTHON] Contrôlez librement l'affichage du tableau d'affichage RGB LED Matirix Lightning avec Raspberry Pi 3B +

environnement

Razpai 3B + (y compris la carte SD) Matrice LED RVB (pas de 6 mm 32 x 32) 6 feuilles Connecteur pour matrice LED Alimentation à découpage MAXWELL 3 cordons d'alimentation pour panneau LED 6 câbles plats IDC 50 fils de saut, mâles et femelles, et 50 mâles et femelles planche à pain Je l'ai acheté au bâtiment LED Picari à Akihabara, sauf pour la tarte aux râpes. LED Pikarikan

Ce que vous voulez réaliser

Je veux changer librement l'affichage du score de la matrice LED à l'aide de Raspeye. Si LEDmatrix peut être manipulé avec Raspeye, il sera possible de passer d'un smartphone via une connexion Internet, donc la gamme d'applications devrait être large!

Qu'est-ce que LEDmatrix?

La matrice LED est une collection de LED (rires comme ça) C'est le même que le tableau d'affichage électrique que vous voyez souvent dans les gares. Il existe différents types, mais la différence réside essentiellement dans le pas (distance entre les LED), la couleur qui peut être exprimée et le nombre de LED verticales et horizontales disposées. Cette fois, j'ai utilisé une matrice de 6 LED RVB (toutes les couleurs peuvent être exprimées) 32x32 avec un pas de 6 mm.

câblage

Tout d'abord, nous allons câbler. Assurez-vous d'avoir tout ce dont vous avez besoin.

Câblage autour de l'alimentation et entre la matrice LED

L'alimentation utilise une alimentation à découpage. Le courant requis pour chaque carte est d'environ 2A, donc si vous utilisez plusieurs cartes, achetez une alimentation qui correspond à cela. J'ai utilisé 6 feuilles cette fois, donc j'avais besoin de 12A ou plus. Ce n'est pas grave tant que vous ne confondez pas GND avec V㏄. Suivez la notation sur la prise de courant arrière comme indiqué dans l'image ci-dessous. Câblez les matrices uniquement horizontalement avec un câble plat. iOS の画像.jpg

Câblage à tarte et à matrice LED

Ce câblage a été réalisé selon le site suivant. hzeller github Pour expliquer en citant ce site, le côté connecteur doit être câblé à chacun des 16 emplacements de la photo ci-dessous. コネクタの写真 Chaque destination de connexion est un tableau manuscrit ci-dessous. dsc_5857.jpg Les deux rangées du milieu pointent vers la broche 40 de la tarte à la râpe. Chaque destination de connexion est écrite à côté. Dans cette bibliothèque, LEDmatrix peut afficher jusqu'à 3 niveaux. Les destinations de connexion de la première à la troisième ligne sont entrées dans l'ordre du haut. Câblez la matrice LED à l'extrémité droite de chaque rangée à la tarte à la râpe comme indiqué dans l'image ci-dessous. ラズパイ接続 Il est possible de se connecter au connecteur tel quel avec un fil de saut s'il s'agit d'un étage, mais s'il s'agit de deux étages ou plus, une planche à pain est nécessaire. Si le câblage est en désordre, il ressemblera à l'image ci-dessous. IMG_1177.JPG

Matrice LED contrôlée par rasp pie

J'ai utilisé la bibliothèque suivante. Bibliothèque de contrôle LEDmatrix

Installation

Installez immédiatement la bibliothèque depuis github. Veuillez vous déplacer vers le répertoire de la bibliothèque installée et compiler.

git clone https://github.com/hzeller/rpi-rgb-led-matrix/
cd rpi-rgb-led-matrix
make -C examples-api-use

Pour activer python, exécutez la commande suivante.

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)

Exécutez le programme de démonstration

Vous pouvez exécuter le programme de démonstration en allant dans le répertoire rpi-rgb-led-matrix. Procédez comme suit:

cd rpi-rgb-led-matrix
sudo examples-api-use/demo

Ensuite, les options de fonctionnement suivantes s'affichent. Suivez ces options. Laissez-moi vous expliquer les plus importants. Spécifiez la matrice de la matrice LED par feuille avec --led-rows, --led-cols. Lorsque vous utilisez plusieurs étapes, spécifiez --led-parallel pour le nombre d'étapes et --led-chain pour le nombre connecté horizontalement. La luminosité est spécifiée par --led-bright et la durée d'affichage est spécifiée par -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

Par conséquent, pour exécuter la démo, vous pouvez taper la commande suivante (modifier le cas échéant selon votre propre numéro). De par sa conception, une erreur se produira si vous ne l'exécutez pas avec sudo. Vous pouvez également modifier la démo en modifiant le nombre après le dernier -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

Affichage du texte japonais en Python

Cette bibliothèque contient également un exemple de code pour python, nous allons donc recréer le programme afin qu'il puisse afficher le texte japonais en s'y référant. Puisqu'il s'agit d'une bibliothèque pour les étrangers, il existe un exemple de programme pour afficher du texte, mais il ne peut afficher que des alphabets. À la suite de diverses recherches, j'ai fait une spécification pour convertir le texte japonais en une image et l'afficher, en me référant à cet article. Toute police japonaise convient, mais veuillez la télécharger sur Razpai. La police utilisée cette fois a été téléchargée depuis ce 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)



#Binarisation d'image de personnage
def to_bin(img, w, h, color = '#FFFFFF'):
    #R pour chaque valeur de pixel,g,Trouvez la moyenne de b
    means = np.array([[img.getpixel((x,y)) for x in range(w)] for y in range(h)]).mean(axis=2).reshape(w * h,)
    #Faire un histogramme
    hist = np.array([np.sum(means == i) for i in range(256)])
    max_v = 0
    threshold = 0
    #Calculez de 0 à 255 pour trouver le seuil approprié
    #Une valeur de pixel supérieure au seuil est classée dans la classe 1 et une valeur de pixel inférieure au seuil est classée dans la classe 2.
    for th in range(256):
        n1 = sum(hist[:th])                                 #Nombre de classe 1
        m1 = np.dot(hist[:th], np.array(range(256))[:th])   #Moyenne des valeurs de classe 1
        n2 = sum(hist[th:])                                 #Nombre de classe 2
        m2 = np.dot(hist[th:], np.array(range(256))[th:])   #Moyenne des valeurs de classe 2
        if n1 == 0 or n2 == 0:
            v = 0
        else:
            #Trouvez la molécule de dispersion interclasse
            v = n1 * n2 * (m1 / n1 - m2 / n2) ** 2
        #Mettre à jour le seuil auquel le numérateur de la dispersion interclasse est maximal
        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
#Connectez les images côte à côte
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


#Connectez les images verticalement
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)#La modification de cette valeur modifiera la vitesse de défilement.
    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"Il est possible d'afficher de cette manière")

Vous pouvez maintenant afficher et faire défiler le texte avec les deux fonctions définies ci-dessous. Veuillez modifier la partie numérique en fonction de la taille de votre matrice LED. De plus, comme je l'expliquerai dans la seconde moitié de l'article cette fois, comme l'affichage est commuté en lisant et en écrivant le fichier texte (programme débutant), j'ai lu "clear.txt" et j'ai décidé de le supprimer. .. iOS の画像 (1).jpg ezgif.com-video-to-gif (1).gif

Ce à quoi j'ai été autorisé à me référer

En contrôlant la matrice LED avec Raspeye cette fois, je me suis référé à l'article suivant. Merci pour le merveilleux 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/

en conclusion

Il est maintenant possible de préparer la matrice LED, de la câbler et d'afficher du texte japonais. À partir de la prochaine fois, j'essaierai de lier Raspeye et Slack afin que ce soit plus facile à manipuler.

Recommended Posts

Contrôlez librement l'affichage du tableau d'affichage RGB LED Matirix Lightning avec Raspberry Pi 3B +
Utilisez python sur Raspberry Pi 3 pour éclairer la LED avec le contrôle du commutateur!
Prenez la valeur du thermo-hygromètre SwitchBot avec Raspberry Pi
Changer les valeurs du thermo-hygromètre Bot avec Raspberry Pi
Production de système de contrôle de température avec tarte aux framboises et ESP32 (1)
Classification en temps réel de plusieurs objets dans les images de la caméra avec apprentissage en profondeur de Raspberry Pi 3 B + et PyTorch
Contrôlez le moteur avec un pilote de moteur en utilisant python sur Raspberry Pi 3!
J'ai appris comment la télécommande infrarouge fonctionne avec Raspberry Pi
Affichage graphique de la consommation électrique des ménages avec 3GPI et Raspeye
Consigner périodiquement les valeurs des capteurs d'environnement Omron avec Raspberry Pi
Commande de servomoteur avec Raspberry Pi
[Explication AtCoder] Contrôlez les problèmes A, B, C d'ABC182 avec Python!
Enregistrement des valeurs du capteur d'environnement Omron avec Raspberry Pi (type USB)
[Explication AtCoder] Contrôle ABC184 Problèmes A, B, C avec Python!
Production d'un système de contrôle de température avec tarte aux framboises et ESP32 (2) Production d'un appareil de transmission
Connectez-vous à la console Raspberry PI et affichez les informations IP et SD locales
[Explication AtCoder] Contrôlez les problèmes A, B, (C), D de ABC165 avec Python!
[Explication AtCoder] Contrôlez les problèmes A, B, C, D d'ABC183 avec Python!
Informer périodiquement l'état de traitement de Raspberry Pi avec python → Google Spreadsheet → LINE
[Explication AtCoder] Contrôlez les problèmes A, B, C, D d'ABC181 avec Python!
Contrôlez l'écran EL organique connecté I2C d'Akizuki à partir de Raspberry Pi
Sortie CSV des données d'impulsion avec Raspberry Pi (sortie CSV)
Observez le groupe de météores Futago avec RaspberryPi4
Obtenez des informations sur le processeur de Raspberry Pi avec Python
Suivi GPS avec Raspeye 4B + BU-353S4 (Python)
Mesurer la température du processeur de Raspeye avec Python