8x32 PI : interface web, matrice verticale, compatibilité Raspbian 11
- Interface web (serveur_web.py, Flask, gabarits dans web/) : dépôt de GIF, PNG animés et séquences de PNG, aperçus animés, ordre de lecture, activer / désactiver, corbeille, « jouer maintenant » et « suivante ». Service systemd vitrine-web, activé par installer.sh. - Lecteur : réagit aux demandes de la page web (post-it dans /run/vitrine-pixels), écrit l'animation en cours, éteint la matrice proprement sur SIGTERM. - Matrice posée debout : réglage ROTATION (90 = image 8 × 32) dans matrice.py ; images couchées tournées automatiquement ; exemples, animations codées, aperçus et page web adaptés au format vertical. - Compatibilité Raspbian 11 Bullseye : partition /boot, Pillow 8.1, Flask 1.1. - Doc : nouveau guide INTERFACE_WEB.md ; README, GUIDE_KRITA, MODE_VITRINE, CODER_EN_PYTHON mis à jour (format 8 × 32, adresses Wi-Fi / câble du Pi). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+62
-22
@@ -68,10 +68,25 @@ from PIL import Image
|
||||
# 1. RÉGLAGES
|
||||
# =============================================================================
|
||||
|
||||
# Taille de la matrice : 32 colonnes (largeur) × 8 lignes (hauteur).
|
||||
LARGEUR = 32
|
||||
HAUTEUR = 8
|
||||
NB_LEDS = LARGEUR * HAUTEUR # = 256
|
||||
# Le PANNEAU, tel qu'il est fabriqué : 32 colonnes × 8 lignes de LED,
|
||||
# câblées en serpentin par colonnes de 8. Ça ne change jamais.
|
||||
COLONNES_PANNEAU = 32
|
||||
LIGNES_PANNEAU = 8
|
||||
NB_LEDS = COLONNES_PANNEAU * LIGNES_PANNEAU # = 256
|
||||
|
||||
# ROTATION : comment le panneau est POSÉ dans la vitrine, en degrés.
|
||||
# 0 = couché (à l'horizontale) : l'image fait 32 de large × 8 de haut ;
|
||||
# 90 = debout (à la verticale) : l'image fait 8 de large × 32 de haut.
|
||||
# (180 et 270 existent aussi : couché à l'envers, debout dans l'autre sens.
|
||||
# Pour remettre l'image à l'endroit, INVERSER_X / INVERSER_Y suffisent.)
|
||||
ROTATION = 90
|
||||
|
||||
# Taille de l'IMAGE à dessiner (dans Krita, dans le code…), selon la rotation.
|
||||
# Tout le reste du programme utilise LARGEUR et HAUTEUR.
|
||||
if ROTATION in (90, 270):
|
||||
LARGEUR, HAUTEUR = LIGNES_PANNEAU, COLONNES_PANNEAU # 8 × 32 : debout
|
||||
else:
|
||||
LARGEUR, HAUTEUR = COLONNES_PANNEAU, LIGNES_PANNEAU # 32 × 8 : couché
|
||||
|
||||
# Broche du Raspberry Pi reliée (à travers l'adaptateur 74AHCT125) au fil
|
||||
# VERT (DIN) de la matrice. Ce numéro est le numéro « GPIO », pas le numéro
|
||||
@@ -101,10 +116,11 @@ LUMINOSITE = 40
|
||||
# (ex. : alimentation d'établi limitée à 3 A → 2500 mA ici).
|
||||
COURANT_MAX_MA = 2500
|
||||
|
||||
# ORIENTATION de la matrice (voir test_matrice.py).
|
||||
# SENS de l'image (voir test_matrice.py), une fois ROTATION choisie.
|
||||
# Le pixel ROUGE du test doit être EN HAUT À GAUCHE, le VERT EN HAUT À DROITE.
|
||||
# - rouge et vert inversés (gauche/droite) → INVERSER_X = True
|
||||
# - rouge et vert en bas au lieu d'en haut → INVERSER_Y = True
|
||||
# - les deux à la fois (image à l'envers) → les deux à True
|
||||
INVERSER_X = False
|
||||
INVERSER_Y = False
|
||||
|
||||
@@ -159,35 +175,57 @@ def teinte(t, saturation=255, valeur=255):
|
||||
# 3. DE LA POSITION (x, y) AU NUMÉRO DE LED
|
||||
# =============================================================================
|
||||
#
|
||||
# Pour dessiner, on pense en coordonnées :
|
||||
# x = colonne, de 0 (à gauche) à 31 (à droite)
|
||||
# y = ligne, de 0 (en haut) à 7 (en bas)
|
||||
# Pour dessiner, on pense en coordonnées, sur l'IMAGE telle qu'on la voit :
|
||||
# x = colonne, de 0 (à gauche) à LARGEUR - 1 (à droite)
|
||||
# y = ligne, de 0 (en haut) à HAUTEUR - 1 (en bas)
|
||||
# Le point (0, 0) est en haut à gauche, comme dans Krita.
|
||||
#
|
||||
# Mais les LED sont numérotées dans l'ordre de la chaîne, qui fait des
|
||||
# zigzags (« serpentin ») : elle descend la 1re colonne, remonte la 2e…
|
||||
# Pour trouver la LED correspondante, trois étapes :
|
||||
#
|
||||
# x=0 x=1 x=2 x=3
|
||||
# y=0 0 15 16 31 …
|
||||
# y=1 1 14 17 30
|
||||
# … … … … …
|
||||
# y=7 7 → 8 23 → 24
|
||||
# 1. Retourner l'image si besoin (INVERSER_X / INVERSER_Y).
|
||||
#
|
||||
# C'est la même fonction que dans matrice_8x32.ino, traduite en Python.
|
||||
# 2. Tourner : passer de la position sur l'IMAGE à la position sur le
|
||||
# PANNEAU (px de 0 à 31, py de 0 à 7, panneau vu couché). Exemple,
|
||||
# panneau debout (ROTATION = 90, tourné d'un quart de tour vers la
|
||||
# droite) : le haut de l'image correspond à la gauche du panneau, et la
|
||||
# droite de l'image au haut du panneau.
|
||||
#
|
||||
# 3. Le serpentin : les LED sont numérotées dans l'ordre de la chaîne, qui
|
||||
# descend la 1re colonne du panneau, remonte la 2e…
|
||||
#
|
||||
# px=0 px=1 px=2 px=3
|
||||
# py=0 0 15 16 31 …
|
||||
# py=1 1 14 17 30
|
||||
# … … … … …
|
||||
# py=7 7 → 8 23 → 24
|
||||
#
|
||||
# L'étape 3 est la même fonction que dans matrice_8x32.ino.
|
||||
|
||||
def XY(x, y):
|
||||
"""Renvoie le numéro (0 à 255) de la LED placée en colonne x, ligne y."""
|
||||
"""Renvoie le numéro (0 à 255) de la LED qui affiche le pixel (x, y) de l'image."""
|
||||
# 1. Retourner.
|
||||
if INVERSER_X:
|
||||
x = (LARGEUR - 1) - x
|
||||
if INVERSER_Y:
|
||||
y = (HAUTEUR - 1) - y
|
||||
|
||||
if x % 2 == 0:
|
||||
# Colonne paire : la chaîne DESCEND.
|
||||
return x * HAUTEUR + y
|
||||
# 2. Tourner : position (px, py) sur le panneau couché.
|
||||
if ROTATION == 90:
|
||||
px, py = y, (LIGNES_PANNEAU - 1) - x
|
||||
elif ROTATION == 180:
|
||||
px, py = (COLONNES_PANNEAU - 1) - x, (LIGNES_PANNEAU - 1) - y
|
||||
elif ROTATION == 270:
|
||||
px, py = (COLONNES_PANNEAU - 1) - y, x
|
||||
else:
|
||||
px, py = x, y
|
||||
|
||||
# 3. Le serpentin.
|
||||
if px % 2 == 0:
|
||||
# Colonne paire du panneau : la chaîne DESCEND.
|
||||
return px * LIGNES_PANNEAU + py
|
||||
else:
|
||||
# Colonne impaire : la chaîne REMONTE.
|
||||
return x * HAUTEUR + (HAUTEUR - 1 - y)
|
||||
return px * LIGNES_PANNEAU + (LIGNES_PANNEAU - 1 - py)
|
||||
|
||||
|
||||
# =============================================================================
|
||||
@@ -316,7 +354,9 @@ class MatriceReelle:
|
||||
class Simulateur:
|
||||
"""Une fenêtre sur l'ordinateur qui imite la matrice (256 ronds)."""
|
||||
|
||||
TAILLE = 26 # taille d'un pixel à l'écran, en points
|
||||
# Taille d'un pixel à l'écran, en points : plus petit si l'image est
|
||||
# haute (panneau debout), pour que la fenêtre tienne dans l'écran.
|
||||
TAILLE = min(26, 640 // max(LARGEUR, HAUTEUR))
|
||||
MARGE = 4 # espace entre deux pixels
|
||||
|
||||
def __init__(self, titre="Simulateur — matrice 8 × 32"):
|
||||
|
||||
Reference in New Issue
Block a user