Files
vitrine-pixels/8x32 PI/CODER_EN_PYTHON.md
T
2026-10-08 15:25:14 +02:00

10 KiB
Raw Blame History

Coder ses animations en Python

Krita sert à dessiner des animations image par image. Le code sert à les calculer : du hasard, des mouvements continus, des formules, des réactions à un capteur… des choses très longues, voire impossibles, à dessiner à la main.

Ce guide s'adresse à ceux qui ont joué avec le code Arduino (matrice_8x32.ino) et veulent continuer sur le Raspberry Pi. Le fichier de travail est mes_animations.py : les mêmes animations que sur l'Arduino, traduites en Python. Ouvrez les deux côte à côte !


Sommaire

  1. Lancer un programme
  2. Python pour qui connaît l'Arduino
  3. Les outils de dessin
  4. Exercices
  5. Mélanger code et images
  6. Transformer son code en GIF
  7. Comment est construit le moteur

1. Lancer un programme

Pas de téléversement en Python : on lance le fichier directement.

Où Commande
Sur son ordinateur, avec le simulateur python3 mes_animations.py --simulateur (Windows : py au lieu de python3)
Sur le Pi, sur la vraie matrice sudo ~/vitrine-env/bin/python mes_animations.py

Ctrl + C (ou fermer la fenêtre du simulateur) pour arrêter.

Sur le Pi, si le lecteur tourne déjà en mode vitrine, arrêtez-le d'abord : sudo systemctl stop vitrine-pixels. Un seul programme à la fois peut parler à la matrice.

Pour éditer le fichier : sur l'ordinateur, n'importe quel éditeur de texte (le plus confortable : Thonny, https://thonny.org, conçu pour apprendre Python, ou VS Code). Sur le Pi : nano mes_animations.py.


2. Python pour qui connaît l'Arduino

Arduino (C++) Python
Fin d'instruction ; obligatoire rien
Bloc (dans une boucle, une fonction…) entre { } décalé de 4 espaces après un :
Commentaire // texte # texte
Variable int x = 3; x = 3
Fonction void anim() { … } def anim(): + bloc décalé
Boucle « pour » for (int x = 0; x < 32; x++) { … } for x in range(32):
Compte à rebours for (int y = 7; y > 0; y--) for y in range(7, 0, -1):
Condition if (x > 3) { … } else { … } if x > 3: … else: …
« et », « ou », « non » &&, ||, ! and, or, not
Vrai / faux true / false True / False (majuscule !)
Tableau int t[3] = {1, 2, 3}; t = [1, 2, 3] (une « liste »)
Couleur CRGB(255, 0, 0) (255, 0, 0) (un « tuple »)
Couleur par teinte CHSV(160, 255, 255) teinte(160)
Hasard random(32) random.randrange(32)
Attendre 100 ms delay(100); attendre(100)
Afficher FastLED.show(); montrer()
Boucle principale void loop() { … } while True: + bloc décalé

Le piège n° 1 de Python : l'indentation. Les espaces en début de ligne ne sont pas décoratifs, ils sont la structure du programme :

for x in range(32):
    pixel(x, 0, ROUGE)     # dans la boucle : exécuté 32 fois
    montrer()              # dans la boucle aussi
attendre(1000)             # APRÈS la boucle : exécuté une fois

Utilisez toujours 4 espaces (Thonny et VS Code le font tout seuls avec la touche Tab). Ne mélangez jamais espaces et tabulations.

Le message d'erreur est votre ami. Python indique le fichier, la ligne et la nature de l'erreur, tout en bas :

  File "mes_animations.py", line 72
    attendre(20
               ^
SyntaxError: '(' was never closed

3. Les outils de dessin

Définis dans matrice.py, disponibles dans mes_animations.py grâce à la ligne from matrice import *.

Outil Effet
pixel(x, y, couleur) colore le pixel de la colonne x (0 à 31) et de la ligne y (0 à 7). En dehors : ignoré
lire_pixel(x, y) renvoie la couleur actuelle d'un pixel
effacer() éteint toute la toile
effacer(couleur) remplit toute la toile d'une couleur
assombrir(25) assombrit toute la toile de 25 % (pour les traînées)
montrer() affiche la toile. Rien n'apparaît tant qu'on ne l'appelle pas !
montrer(image) affiche une image Pillow de 32 × 8 (voir partie 5)
attendre(100) attend 100 millisecondes
teinte(t) couleur de l'arc-en-ciel : 0 rouge, 32 orange, 64 jaune, 96 vert, 128 cyan, 160 bleu, 192 violet, 224 rose
teinte(t, saturation, valeur) idem, avec saturation (0 = blanc) et valeur (0 = noir), de 0 à 255

Couleurs nommées : NOIR, BLANC, ROUGE, ORANGE, JAUNE, VERT, CYAN, BLEU, VIOLET, MAGENTA, ROSE. Dimensions : LARGEUR (32), HAUTEUR (8).

Le point (0, 0) est en haut à gauche, comme dans Krita.


4. Exercices

Pour chaque exercice, écrivez une nouvelle fonction def anim_…(): dans mes_animations.py et ajoutez son nom dans playlist(). Testez dans le simulateur.

1. Le point qui traverse. Un pixel blanc va de gauche à droite sur la ligne 3, puis revient. (Indice : deux boucles for, la seconde avec range(31, -1, -1).)

2. Le balayage. Une colonne entière (8 pixels) balaie la matrice de gauche à droite. (Indice : une boucle sur x, et dedans une boucle sur y.)

3. Le dégradé fixe. Remplissez la matrice d'un arc-en-ciel immobile, de teinte(0) à gauche à teinte(255) à droite. Puis faites-le défiler. (Comparez avec anim_arc_en_ciel.)

4. La balle qui rebondit. Un pixel avance d'un pas en x et en y à chaque image, et change de sens quand il touche un bord.

def anim_balle():
    x, y = 0, 0          # position
    dx, dy = 1, 1        # vitesse (pas par image)
    for image in range(300):
        effacer()
        pixel(x, y, ORANGE)
        montrer()
        attendre(40)
        x = x + dx
        y = y + dy
        if x <= 0 or x >= LARGEUR - 1:
            dx = -dx     # rebond sur un bord gauche/droite
        if y <= 0 or y >= HAUTEUR - 1:
            dy = -dy     # rebond en haut/en bas

Variante : laissez une traînée en remplaçant effacer() par assombrir(30).

5. Le ciel étoilé. Des pixels blancs apparaissent au hasard, très faiblement, puis s'allument et s'éteignent doucement. (Indice : assombrir et random.randrange.)

6. Le feu. Le bas de la matrice est orange vif, des « flammes » montent au hasard en s'assombrissant et en tirant vers le rouge. (Indice : partez de anim_pluie, et faites monter au lieu de descendre.)

7. Le dessin en lettres. Modifiez DESSIN dans mes_animations.py pour faire défiler votre propre motif. Créez-en un deuxième, et faites-les défiler l'un derrière l'autre.


5. Mélanger code et images

Le code peut lire les images de l'équipe Krita et les transformer. On utilise Pillow, la bibliothèque d'images :

from PIL import Image

def anim_logo_qui_defile():
    # Remplacez par le chemin d'une image de 32 × 8 exportée depuis Krita.
    logo = Image.open("animations/logo.png").convert("RGB")
    for i in range(100):
        effacer()
        # On « colle » le logo deux fois, côte à côte, décalé de i pixels :
        # ce qui sort à droite rentre à gauche (défilement en boucle).
        toile.paste(logo, (i % LARGEUR - LARGEUR, 0))
        toile.paste(logo, (i % LARGEUR, 0))
        montrer()
        attendre(60)

Ici toile est l'image de 32 × 8 sur laquelle dessinent pixel() et effacer(). Tout ce que sait faire Pillow (coller, retourner, changer les couleurs, écrire du texte…) fonctionne dessus. Documentation : https://pillow.readthedocs.io.


6. Transformer son code en GIF

Une animation codée peut devenir un fichier GIF, que le lecteur jouera en vitrine avec les dessins de l'équipe Krita :

python3 mes_animations.py --enregistrer animations/10_mes_animations.gif

Au lieu d'afficher, le moteur enregistre chaque image montrée par montrer(), avec la durée de l'attendre() qui suit. La playlist est jouée une seule fois, puis le GIF est écrit. Vérifiez-le ensuite :

python3 outils/verifier_animation.py animations/10_mes_animations.gif

Attention au hasard : un GIF enregistre une version de l'animation. Si votre animation utilise random, elle sera identique à chaque passage dans le GIF, alors qu'en direct elle change à chaque fois.


7. Comment est construit le moteur

Pour les curieux, matrice.py est découpé comme le programme Arduino, et commenté partie par partie :

  1. Réglages : taille, broche GPIO, luminosité, limite de courant, orientation, gamma.

  2. Couleurs : les noms, et teinte() (l'équivalent de CHSV).

  3. XY() : la même fonction que sur l'Arduino, qui transforme une position (x, y) en numéro de LED dans le serpentin.

  4. Gamma et courant : preparer_valeurs() corrige les couleurs avec une table calculée au démarrage, applique la luminosité, estime le courant et assombrit l'image si elle consomme trop (comme setMaxPowerInVoltsAndMilliamps de FastLED).

  5. Les écrans : trois « classes » qui savent toutes afficher(), attendre() et eteindre() :

    • MatriceReelle : envoie les couleurs aux LED avec rpi_ws281x ;
    • Simulateur : dessine 256 ronds dans une fenêtre tkinter ;
    • Enregistreur : accumule les images dans un GIF.

    Le reste du programme ne sait pas lequel il utilise : c'est le principe d'une interface commune. Ajouter un 4e écran (une page web, une deuxième matrice…) ne demanderait pas de toucher aux animations.

  6. Outils de dessin : pixel(), effacer(), montrer()…, qui travaillent sur la toile.

Et lecteur.py n'est qu'une boucle : lister le dossier, charger chaque fichier en liste de couples (image, durée), et les montrer l'un après l'autre.

Idées pour aller plus loin

  • Un bouton branché sur une broche GPIO pour passer à l'animation suivante (bibliothèque gpiozero, déjà installée sur Raspberry Pi OS).
  • Un capteur de présence (PIR) : la matrice s'anime quand quelqu'un passe devant la vitrine.
  • L'heure ou la météo en texte défilant (la police 5 × 7 est dans outils/generer_exemples.py).
  • Une page web sur le Pi pour choisir l'animation depuis son téléphone (bibliothèque flask).