diff --git a/8x32 PI/INTERFACE_WEB.md b/8x32 PI/INTERFACE_WEB.md index 5b7ad1d..6dd0da8 100644 --- a/8x32 PI/INTERFACE_WEB.md +++ b/8x32 PI/INTERFACE_WEB.md @@ -36,6 +36,13 @@ Prenez celle du réseau sur lequel **vous** êtes : | en **Wi-Fi** (téléphone, ordinateur portable) | **`http://172.16.50.27`** | | par **câble** (ordinateur fixe de l'école) | `http://172.16.7.199` | +> **Le plus simple : le QR code.** Le dossier [`qrcode/`](qrcode/) contient +> le QR code de la page et une **affiche A5 à imprimer** +> ([`affiche_interface_web.pdf`](qrcode/affiche_interface_web.pdf)) : on la +> scanne avec l'appareil photo du téléphone, connecté au Wi-Fi de l'école. +> Si l'adresse du Pi change, refaites-les : +> `python3 outils/generer_qrcode.py http://NOUVELLE_ADRESSE`. + > **Pourquoi deux adresses ?** Une adresse, c'est comme l'adresse postale du > Pi, mais **sur un réseau donné**. Le réseau Wi-Fi et le réseau filaire de > l'école sont deux « villes » différentes, et l'école ne fait pas passer le @@ -53,7 +60,10 @@ Prenez celle du réseau sur lequel **vous** êtes : > marchent pas : la page n'est pas sur Internet, seulement sur le réseau local. En haut de la page, en permanence : **ce que la matrice joue en ce moment** -(mis à jour toutes les 2 secondes) et le bouton **Suivante ⏭**. +(mis à jour toutes les 2 secondes), le bouton **Suivante ⏭** et le menu +**Vitesse** : ×0,5 joue toutes les animations deux fois plus lentement, ×2 +deux fois plus vite. Le choix est gardé même après un redémarrage, et +s'applique à partir de l'animation suivante. --- diff --git a/8x32 PI/README.md b/8x32 PI/README.md index d77dfe5..8161aa9 100644 --- a/8x32 PI/README.md +++ b/8x32 PI/README.md @@ -439,8 +439,10 @@ animation, pause entre deux, horaires) et de [`matrice.py`](matrice.py) : | `LUMINOSITE` | matrice.py | `40` | de 0 à 255 ; montez en plein jour, en vitrine | | `COURANT_MAX_MA` | matrice.py | `2500` | un peu **sous** la limite de l'alimentation | | `ROTATION` | matrice.py | `90` | `90` = matrice debout (image 8 × 32), `0` = couchée (32 × 8) | -| `INVERSER_X`, `INVERSER_Y` | matrice.py | `False` | sens de l'image (partie 8) | +| `INVERSER_X`, `INVERSER_Y` | matrice.py | `True` | sens de l'image (partie 8) ; réglés sur la matrice de la vitrine | +| `DECALAGE_X`, `DECALAGE_Y` | matrice.py | `1`, `0` | décale toute l'image d'un pixel (ici vers la droite : la colonne de gauche reste éteinte) | | `GAMMA` | matrice.py | `2.2` | correction des couleurs (1.0 = aucune) | +| `VITESSE` | lecteur.py | `1.0` | vitesse de lecture (0.5 = deux fois plus lent) ; le menu « Vitesse » de la page web a la priorité | | `DUREE_MINIMUM` | lecteur.py | `10` | une animation courte est rejouée pendant au moins 10 s | | `HORAIRES` | lecteur.py | `None` | ex. `("09:00", "22:30")` | @@ -475,6 +477,7 @@ navigateur, et on gère la vitrine sans terminal ni carte SD. | **Changer l'ordre** de lecture | ▲ ▼ (les fichiers sont renumérotés `01_`, `02_`…) | | **Retirer** une animation de la boucle, sans la supprimer | ⏸ (elle passe dans « Pas jouées ») ; + pour la remettre | | **Jouer tout de suite** une animation, ou **passer** à la suivante | ▶ et **Suivante ⏭** | +| **Ralentir ou accélérer** toutes les animations | menu **Vitesse** en haut (×0,25 à ×2) | | **Supprimer** | ✕ : elle va à la corbeille ; « Vider » efface pour de bon | | **Savoir ce que joue la matrice** | en haut de la page, mis à jour toutes les 2 secondes | @@ -490,7 +493,7 @@ réseau filaire de l'école ne communiquent pas entre eux : prenez celle de | Vous êtes connecté… | Adresse | |---|---| -| en **Wi-Fi** (téléphone, portable) | **http://172.16.50.27** | +| en **Wi-Fi** (téléphone, portable) | **http://172.16.50.27**, ou scannez le QR code du dossier [`qrcode/`](qrcode/) | | par **câble** | http://172.16.7.199 | Ces adresses sont distribuées par le réseau et **peuvent changer** : les @@ -640,6 +643,7 @@ Pour voir ce que fait le lecteur quand il tourne tout seul (mode vitrine) : | [`test_matrice.py`](test_matrice.py) | | test de branchement et d'orientation | | [`mes_animations.py`](mes_animations.py) | | les animations de l'Arduino, traduites en Python | | [`animations/`](animations/) | | exemples : GIF, séquence de PNG, APNG | +| [`qrcode/`](qrcode/) | tous | QR code de la page web et affiche A5 à imprimer (refaits par `outils/generer_qrcode.py`) | | [`schemas/`](schemas/) | | schémas de branchement, brochage de la puce, chaîne Krita → matrice, capture de l'interface web | | `apercus/` | design | créé par `verifier_animation.py` : aperçus « façon LED » à partager | | [`krita/palette_vitrine_pixels.gpl`](krita/palette_vitrine_pixels.gpl) | design | palette de couleurs adaptée aux LED, à importer dans Krita | diff --git a/8x32 PI/lecteur.py b/8x32 PI/lecteur.py index 03e2e53..998bf7f 100644 --- a/8x32 PI/lecteur.py +++ b/8x32 PI/lecteur.py @@ -91,6 +91,13 @@ IMAGES_PAR_SECONDE = 12 # Une image fixe reste affichée pendant cette durée. DUREE_MINIMUM = 10 +# VITESSE de lecture de toutes les animations : +# 1 = la vitesse prévue dans Krita ; +# 0.5 = deux fois plus lent ; 2 = deux fois plus vite. +# La page web peut la changer : elle l'écrit alors dans le fichier caché +# « .vitesse.txt » du dossier des animations, qui a la priorité sur ce réglage. +VITESSE = 1.0 + # Noir entre deux animations, en secondes (0 = enchaîner directement). PAUSE_ENTRE_ANIMATIONS = 0.3 @@ -256,8 +263,19 @@ def charger(chemin): # 4. JOUER UNE ANIMATION # ============================================================================= -def jouer(etapes, duree_minimum=DUREE_MINIMUM): +def lire_vitesse_de_lecture(dossier): + """La vitesse choisie sur la page web (fichier .vitesse.txt), sinon VITESSE.""" + try: + with open(os.path.join(dossier, ".vitesse.txt")) as f: + vitesse = float(f.read().strip().replace(",", ".")) + return min(4.0, max(0.1, vitesse)) # entre ×0,1 et ×4, par prudence + except (OSError, ValueError): + return VITESSE + + +def jouer(etapes, duree_minimum=DUREE_MINIMUM, vitesse=1.0): """Joue la liste d'étapes, et la rejoue jusqu'à atteindre la durée minimum. + vitesse = 0.5 : chaque image reste affichée deux fois plus longtemps. S'arrête plus tôt si le serveur web demande autre chose (partie 5).""" debut = time.monotonic() while True: @@ -265,7 +283,7 @@ def jouer(etapes, duree_minimum=DUREE_MINIMUM): moment = time.monotonic() matrice.montrer(image) # On retire le temps déjà passé à afficher, pour garder le rythme. - if not attendre_ou_interrompre(duree - (time.monotonic() - moment)): + if not attendre_ou_interrompre(duree / vitesse - (time.monotonic() - moment)): return if time.monotonic() - debut >= duree_minimum: break @@ -296,7 +314,7 @@ def jouer_animation(chemin, dossier): print(f" ✗ impossible de lire ce fichier ({erreur}) : on passe au suivant") return if etapes: - jouer(etapes) + jouer(etapes, vitesse=lire_vitesse_de_lecture(dossier)) if PAUSE_ENTRE_ANIMATIONS > 0: matrice.effacer() matrice.montrer() diff --git a/8x32 PI/matrice.py b/8x32 PI/matrice.py index ae1858e..216b8af 100644 --- a/8x32 PI/matrice.py +++ b/8x32 PI/matrice.py @@ -121,8 +121,16 @@ COURANT_MAX_MA = 2500 # - 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 +INVERSER_X = True +INVERSER_Y = True + +# DÉCALAGE de l'image sur la matrice, en pixels (après INVERSER_X / Y). +# DECALAGE_X = 1 : toute l'image glisse d'un pixel vers la DROITE ; +# la colonne de gauche reste éteinte, la dernière colonne de l'image sort +# de la matrice. Utile si un bord de la matrice est caché dans la vitrine. +# (Valeurs négatives : vers la gauche ; DECALAGE_Y : vers le bas.) +DECALAGE_X = 1 +DECALAGE_Y = 0 # CORRECTION GAMMA (voir partie 4). 2.2 = comme un écran d'ordinateur. # 1.0 = pas de correction (les couleurs sombres paraîtront trop claires). @@ -526,9 +534,18 @@ def assombrir(pourcentage): for (r, v, b) in pixels_de(toile)]) +def decaler(image): + """Applique DECALAGE_X / DECALAGE_Y : l'image glisse, le vide est noir.""" + if DECALAGE_X == 0 and DECALAGE_Y == 0: + return image + decalee = Image.new("RGB", (LARGEUR, HAUTEUR)) + decalee.paste(image, (DECALAGE_X, DECALAGE_Y)) + return decalee + + def montrer(image=None): - """Affiche la toile (ou une autre image de 32 × 8) sur l'écran.""" - _ecran.afficher(image if image is not None else toile) + """Affiche la toile (ou une autre image de la taille de la matrice) sur l'écran.""" + _ecran.afficher(decaler(image if image is not None else toile)) def attendre(millisecondes): diff --git a/8x32 PI/outils/generer_qrcode.py b/8x32 PI/outils/generer_qrcode.py new file mode 100644 index 0000000..48ff639 --- /dev/null +++ b/8x32 PI/outils/generer_qrcode.py @@ -0,0 +1,328 @@ +#!/usr/bin/env python3 +""" +============================================================================= + QR CODE ET AFFICHE D'ACCÈS À L'INTERFACE WEB + Workshop « Vitrine pixels » +============================================================================= + +Fabrique, dans le dossier « qrcode » : + - qrcode_interface_web.png : le QR code seul (pour un message, un diaporama) ; + - qrcode_interface_web.svg : le même, en vectoriel (pour l'imprimer en grand) ; + - affiche_interface_web.svg : une affiche A5 à imprimer et à poser à côté + de la vitrine ou dans l'atelier, avec deux + compositions inspirées des animations de + l'équipe (qrcode/sources : « cascade », « tetris ») ; + - affiche_interface_web.pdf : la même, prête à imprimer (si rsvg-convert + est installé : paquet « librsvg2-bin »). + +On scanne le QR code avec l'appareil photo du téléphone : la page web de la +vitrine s'ouvre. ⚠️ Le téléphone doit être connecté au Wi-Fi de l'école +(la page n'est pas sur Internet). + +L'adresse du Pi peut changer (voir INTERFACE_WEB.md) : il suffit alors de +relancer ce programme avec la nouvelle adresse : + python3 outils/generer_qrcode.py http://172.16.50.27 + +Il faut le logiciel « qrencode » : + sudo apt install qrencode (Debian, Ubuntu, Raspberry Pi OS) + sudo pacman -S qrencode (Arch) + brew install qrencode (macOS) +""" + +import os +import shutil +import subprocess +import sys + +ICI = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +SORTIE = os.path.join(ICI, "qrcode") +ADRESSE_PAR_DEFAUT = "http://172.16.50.27" + + +def modules_du_qrcode(texte): + """Demande à qrencode le QR code en texte : une ligne par rangée, + « # » = case noire. Renvoie une liste de lignes de booléens.""" + # -t ASCII : dessin en caractères (2 caractères par case) ; -m 0 : sans marge ; + # -l M : correction d'erreur moyenne (le code reste lisible s'il est un peu abîmé). + resultat = subprocess.run(["qrencode", "-t", "ASCII", "-m", "0", "-l", "M", texte], + capture_output=True, text=True, check=True) + lignes = [l for l in resultat.stdout.splitlines() if l.strip()] + return [[ligne[i] == "#" for i in range(0, len(ligne), 2)] for ligne in lignes] + + +def cases_svg(modules, x0, y0, taille): + """Les cases noires du QR code, en rectangles SVG.""" + return "".join( + f'' + for y, ligne in enumerate(modules) for x, noir in enumerate(ligne) if noir) + + +def qrcode_svg(modules, marge=4): + n = len(modules) + 2 * marge + return (f'' + f'' + f'{cases_svg(modules, marge, marge, 1)}\n') + + +# ============================================================================= +# L'AFFICHE : deux compositions inspirées des animations de l'équipe +# ============================================================================= +# +# En haut, une coulée inspirée de « cascade » : un liquide bleu glacier qui +# déborde du haut de la page, en strates séparées par de l'écume, avec des +# stalactites qui gouttent. En bas, une partie de « tetris » : des pièces de +# couleurs vives empilées sur toute la largeur, deux pièces encore en chute. +# +# Les deux compositions sont dessinées sur une grille de « LED » de 48 colonnes, +# et leurs couleurs sont prises dans les fichiers de l'équipe (qrcode/sources). +# Le hasard est « graine fixe » : on obtient la même affiche à chaque fois. + +import random + +SOURCES = os.path.join(SORTIE, "sources") +COLONNES = 48 # largeur de la grille de pixels de l'affiche +PAS = 148 / COLONNES # taille d'un pixel, en mm (≈ 3,1) +REMPLISSAGE = 0.88 # un pixel = un carré un peu plus petit que le pas + +BLEUS_CASCADE = [(170, 199, 254), (119, 179, 254), (118, 218, 254)] +COULEURS_TETRIS = [(255, 38, 38), (255, 127, 0), (255, 214, 0), (0, 214, 60), + (0, 220, 230), (255, 0, 255)] + + +def couleurs_de(chemin, garder): + """Les couleurs d'une animation de l'équipe, triées par fréquence, + filtrées par la fonction « garder ». [] si le fichier est absent.""" + try: + sys.path.insert(0, ICI) + import lecteur # noqa: E402 + compte = {} + for image, _ in lecteur.charger(chemin): + for c in lecteur.matrice.pixels_de(image): + compte[c] = compte.get(c, 0) + 1 + return [c for c, _ in sorted(compte.items(), key=lambda kv: -kv[1]) if garder(c)] + except Exception: + return [] + + +def hexa(c): + return f"#{c[0]:02x}{c[1]:02x}{c[2]:02x}" + + +def pixel(x, y, couleur, y0=0.0): + """Un pixel de la grille de l'affiche, en colonne x, rangée y (depuis y0 mm).""" + marge = PAS * (1 - REMPLISSAGE) / 2 + return (f'') + + +def composition_cascade(bleus): + """Le liquide qui coule du haut de la page (sur fond blanc).""" + import math + hasard = random.Random(11) + clair, moyen, vif = (bleus + BLEUS_CASCADE)[:3] + cases = {} + # Profondeur du liquide dans chaque colonne : une ondulation lente. + profondeur = [int(5.2 + 1.6 * math.sin(x / 6.0) + 0.9 * math.sin(x / 2.7 + 2)) + for x in range(COLONNES)] + for x in range(COLONNES): + for y in range(profondeur[x] + 1): + distance = profondeur[x] - y # distance au bord du liquide + # Deux traits d'écume blancs (des « trous ») qui suivent le bord, + # interrompus de temps en temps, comme dans l'animation. + if distance in (2, 5) and hasard.random() < 0.8: + continue + cases[(x, y)] = clair if distance <= 1 else moyen if distance <= 4 else vif + # Les coulures : des filets de 1 ou 2 pixels de large, terminés par une goutte. + x = hasard.randint(0, 2) + while x < COLONNES: + largeur = hasard.choice([1, 1, 2]) + longueur = hasard.choice([1, 2, 2, 3, 4, 5]) + haut = max(profondeur[min(x + i, COLONNES - 1)] for i in range(largeur)) + 1 + for i in range(largeur): + for y in range(haut, haut + longueur): + cases[(x + i, y)] = clair + if longueur >= 3: # la goutte, plus large, en bas + for i in range(-1, largeur + 1): + cases[(x + i, haut + longueur)] = clair + for i in range(largeur): + cases[(x + i, haut + longueur + 1)] = clair + if hasard.random() < 0.35: # une goutte déjà détachée + cases[(x, haut + longueur + hasard.randint(3, 4))] = moyen + x += largeur + hasard.randint(2, 5) + return "".join(pixel(x, y, c) for (x, y), c in cases.items() if 0 <= x < COLONNES) + + +PIECES = { # les 7 pièces de Tetris, (colonne, rangée) de chaque carré + "I": [(0, 0), (1, 0), (2, 0), (3, 0)], "O": [(0, 0), (1, 0), (0, 1), (1, 1)], + "T": [(0, 0), (1, 0), (2, 0), (1, 1)], "S": [(1, 0), (2, 0), (0, 1), (1, 1)], + "Z": [(0, 0), (1, 0), (1, 1), (2, 1)], "J": [(0, 0), (0, 1), (1, 1), (2, 1)], + "L": [(2, 0), (0, 1), (1, 1), (2, 1)], +} + + +def tourner(cases, fois): + for _ in range(fois): + cases = [(-y, x) for x, y in cases] + mx, my = min(x for x, _ in cases), min(y for _, y in cases) + return [(x - mx, y - my) for x, y in cases] + + +def bloc(x, y, couleur, y0): + """Un carré de Tetris : la couleur, avec un petit reflet clair en haut à gauche.""" + clair = tuple(int(c + (255 - c) * 0.55) for c in couleur) + marge = PAS * (1 - REMPLISSAGE) / 2 + cote = PAS * REMPLISSAGE + gx, gy = x * PAS + marge, y0 + y * PAS + marge + return (f'' + f'') + + +def composition_tetris(couleurs, y_bas): + """Une partie de Tetris sur toute la largeur, le bas de la pile en y_bas (mm).""" + hasard = random.Random(5) + hauteur_max = 7 + plateau = {} # (x, y) → couleur ; y = 0 en bas + + def poser(forme, x0, y): + return [(x0 + x, y + dy) for x, dy in forme] + + def atterrissage(forme, x0): + y = hauteur_max + 4 + while y > 0 and all(c not in plateau for c in poser(forme, x0, y - 1)): + y -= 1 + return y + + for _ in range(400): + forme = tourner(PIECES[hasard.choice(list(PIECES))], hasard.randint(0, 3)) + forme = [(x, max(y for _, y in forme) - y) for x, y in forme] # y vers le haut + largeur = max(x for x, _ in forme) + 1 + essais = [] + for x0 in range(COLONNES - largeur + 1): + y = atterrissage(forme, x0) + cases = poser(forme, x0, y) + # Les trous laissés sous la pièce (un bon joueur les évite). + trous = sum(1 for (cx, cy) in cases + if cy > 0 and (cx, cy - 1) not in plateau and (cx, cy - 1) not in cases) + essais.append((y + 3 * trous + hasard.random() * 1.5, x0, cases)) + _, x0, cases = min(essais) + # L'horizon reste dentelé : plus haut au centre-gauche, plus bas ailleurs. + limite = hauteur_max - (2 if (x0 // 6) % 3 == 1 else 0) + if max(cy for _, cy in cases) >= limite: + continue + # Une couleur différente de celles des pièces qui la touchent. + voisines = {plateau[(cx + dx, cy + dy)] for cx, cy in cases + for dx, dy in ((1, 0), (-1, 0), (0, 1), (0, -1)) + if (cx + dx, cy + dy) in plateau} + libres = [c for c in couleurs if c not in voisines] or couleurs + couleur = hasard.choice(libres) + for c in cases: + plateau[c] = couleur + + morceaux = [bloc(x, -y - 1, c, y_bas) for (x, y), c in plateau.items()] + # Deux pièces encore en train de tomber, au-dessus de la pile. + sommet = max(y for _, y in plateau) + 1 + for nom, x0, au_dessus, tour, couleur in (("T", 4, 3, 2, couleurs[0]), + ("L", 41, 4, 1, couleurs[-1])): + for x, y in tourner(PIECES[nom], tour): + morceaux.append(bloc(x0 + x, -(sommet + au_dessus) + y, couleur, y_bas)) + return "".join(morceaux) + + +def titre_en_pixels(texte, y0, taille, couleurs, depart=0): + """Écrit un texte avec la police 5 × 7 des exemples, centré, + une couleur par lettre (on fait le tour de la liste « couleurs »).""" + sys.path.insert(0, os.path.join(ICI, "outils")) + from generer_exemples import POLICE # noqa: E402 + largeur = sum(len(POLICE[c][0]) + 1 for c in texte) - 1 + x = (148 - largeur * taille) / 2 + morceaux, n = [], depart + for c in texte: + couleur = hexa(couleurs[n % len(couleurs)]) + if c != " ": + n += 1 + for ligne, motif in enumerate(POLICE[c]): + for dx, p in enumerate(motif): + if p == "#": + morceaux.append(f'') + x += (len(POLICE[c][0]) + 1) * taille + return "".join(morceaux) + + +def affiche_svg(modules, adresse): + """Affiche A5 (148 × 210 mm).""" + l, h = 148, 210 + encre, gris = "#141414", "#6b665d" + + bleus = couleurs_de(os.path.join(SOURCES, "cascade.gif"), + lambda c: c[2] > 200 and c[0] < 200) # les bleus + vives = couleurs_de(os.path.join(SOURCES, "tetris"), + lambda c: max(c) - min(c) > 180) # les saturées + # Une couleur par teinte (l'animation en contient des nuances très proches). + tetris = [] + for c in vives + COULEURS_TETRIS: + if all(sum(abs(a - b) for a, b in zip(c, t)) > 120 for t in tetris): + tetris.append(c) + + y_titre = 49 + cote_qr = 56 + x_qr, y_qr = (l - cote_qr) / 2, y_titre + 37 + taille = cote_qr / len(modules) + y_texte = y_qr + cote_qr + 12 + etapes = ["1. Connectez-vous au Wi-Fi de l'école.", + "2. Visez le QR code avec l'appareil photo.", + "3. Déposez vos animations, choisissez l'ordre."] + textes = (f'' + f'{adresse.replace("http://", "")}' + + "".join(f'{e}' + for i, e in enumerate(etapes)) + + f'Uniquement sur le Wi-Fi de l\'école (pas en 4G / 5G).') + + return f""" + Vitrine pixels : accès à l'interface web + + {composition_cascade(bleus)} + {titre_en_pixels("VITRINE", y_titre, 2.0, tetris)} + {titre_en_pixels("PIXELS", y_titre + 16, 2.0, tetris, depart=1)} + + {cases_svg(modules, x_qr, y_qr, taille)} + {textes} + {composition_tetris(tetris, h)} + +""" + + +def main(): + adresse = sys.argv[1] if len(sys.argv) > 1 else ADRESSE_PAR_DEFAUT + if not adresse.startswith("http"): + adresse = "http://" + adresse + os.makedirs(SORTIE, exist_ok=True) + + modules = modules_du_qrcode(adresse) + with open(os.path.join(SORTIE, "qrcode_interface_web.svg"), "w") as f: + f.write(qrcode_svg(modules)) + with open(os.path.join(SORTIE, "affiche_interface_web.svg"), "w") as f: + f.write(affiche_svg(modules, adresse)) + # Le PNG, directement par qrencode : 12 pixels par case, marge de 4 cases. + subprocess.run(["qrencode", "-o", os.path.join(SORTIE, "qrcode_interface_web.png"), + "-s", "12", "-m", "4", "-l", "M", adresse], check=True) + # Le PDF de l'affiche, si l'outil de conversion est là. + if shutil.which("rsvg-convert"): + subprocess.run(["rsvg-convert", "-f", "pdf", + "-o", os.path.join(SORTIE, "affiche_interface_web.pdf"), + os.path.join(SORTIE, "affiche_interface_web.svg")], check=True) + print(f"QR code pour {adresse} écrit dans {SORTIE}") + + +if __name__ == "__main__": + main() diff --git a/8x32 PI/qrcode/affiche_interface_web.pdf b/8x32 PI/qrcode/affiche_interface_web.pdf new file mode 100644 index 0000000..f0fa659 Binary files /dev/null and b/8x32 PI/qrcode/affiche_interface_web.pdf differ diff --git a/8x32 PI/qrcode/affiche_interface_web.svg b/8x32 PI/qrcode/affiche_interface_web.svg new file mode 100644 index 0000000..c6d39b8 --- /dev/null +++ b/8x32 PI/qrcode/affiche_interface_web.svg @@ -0,0 +1,12 @@ + + Vitrine pixels : accès à l'interface web + + + + + + + 172.16.50.271. Connectez-vous au Wi-Fi de l'école.2. Visez le QR code avec l'appareil photo.3. Déposez vos animations, choisissez l'ordre.Uniquement sur le Wi-Fi de l'école (pas en 4G / 5G). + + diff --git a/8x32 PI/qrcode/qrcode_interface_web.png b/8x32 PI/qrcode/qrcode_interface_web.png new file mode 100644 index 0000000..b14636e Binary files /dev/null and b/8x32 PI/qrcode/qrcode_interface_web.png differ diff --git a/8x32 PI/qrcode/qrcode_interface_web.svg b/8x32 PI/qrcode/qrcode_interface_web.svg new file mode 100644 index 0000000..980db8e --- /dev/null +++ b/8x32 PI/qrcode/qrcode_interface_web.svg @@ -0,0 +1 @@ + diff --git a/8x32 PI/qrcode/sources/cascade.gif b/8x32 PI/qrcode/sources/cascade.gif new file mode 100644 index 0000000..d6ca39e Binary files /dev/null and b/8x32 PI/qrcode/sources/cascade.gif differ diff --git a/8x32 PI/qrcode/sources/tetris/images_par_seconde.txt b/8x32 PI/qrcode/sources/tetris/images_par_seconde.txt new file mode 100644 index 0000000..f599e28 --- /dev/null +++ b/8x32 PI/qrcode/sources/tetris/images_par_seconde.txt @@ -0,0 +1 @@ +10 diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0000.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0000.png new file mode 100644 index 0000000..0ccfa64 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0000.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0001.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0001.png new file mode 100644 index 0000000..efee28a Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0001.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0002.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0002.png new file mode 100644 index 0000000..ecb7944 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0002.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0003.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0003.png new file mode 100644 index 0000000..af5ce9d Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0003.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0004.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0004.png new file mode 100644 index 0000000..e62df07 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0004.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0005.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0005.png new file mode 100644 index 0000000..143b1d4 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0005.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0006.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0006.png new file mode 100644 index 0000000..741e840 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0006.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0007.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0007.png new file mode 100644 index 0000000..338042e Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0007.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0008.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0008.png new file mode 100644 index 0000000..fbf7f38 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0008.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0009.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0009.png new file mode 100644 index 0000000..399bf27 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0009.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0010.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0010.png new file mode 100644 index 0000000..af22627 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0010.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0011.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0011.png new file mode 100644 index 0000000..a62a588 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0011.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0012.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0012.png new file mode 100644 index 0000000..7ba31ba Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0012.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0013.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0013.png new file mode 100644 index 0000000..765cdd4 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0013.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0014.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0014.png new file mode 100644 index 0000000..154c43c Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0014.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0015.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0015.png new file mode 100644 index 0000000..2320c61 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0015.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0016.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0016.png new file mode 100644 index 0000000..fa3cad3 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0016.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0017.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0017.png new file mode 100644 index 0000000..7d2182b Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0017.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0018.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0018.png new file mode 100644 index 0000000..99c8781 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0018.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0019.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0019.png new file mode 100644 index 0000000..593d760 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0019.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0020.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0020.png new file mode 100644 index 0000000..7126491 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0020.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0021.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0021.png new file mode 100644 index 0000000..177b725 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0021.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0022.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0022.png new file mode 100644 index 0000000..4ddefb6 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0022.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0023.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0023.png new file mode 100644 index 0000000..a99521b Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0023.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0024.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0024.png new file mode 100644 index 0000000..f7ad7bd Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0024.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0025.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0025.png new file mode 100644 index 0000000..95ac753 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0025.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0026.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0026.png new file mode 100644 index 0000000..6ef5789 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0026.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0027.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0027.png new file mode 100644 index 0000000..81294fd Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0027.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0028.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0028.png new file mode 100644 index 0000000..c57d813 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0028.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0029.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0029.png new file mode 100644 index 0000000..ee32430 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0029.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0030.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0030.png new file mode 100644 index 0000000..828d226 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0030.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0031.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0031.png new file mode 100644 index 0000000..818bcab Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0031.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0032.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0032.png new file mode 100644 index 0000000..a52b81d Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0032.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0033.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0033.png new file mode 100644 index 0000000..1aa63c6 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0033.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0034.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0034.png new file mode 100644 index 0000000..367ad6f Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0034.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0035.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0035.png new file mode 100644 index 0000000..c4448c1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0035.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0036.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0036.png new file mode 100644 index 0000000..c4448c1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0036.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0037.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0037.png new file mode 100644 index 0000000..18bfa1d Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0037.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0038.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0038.png new file mode 100644 index 0000000..2581982 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0038.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0039.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0039.png new file mode 100644 index 0000000..b75b5c0 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0039.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0040.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0040.png new file mode 100644 index 0000000..e250147 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0040.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0041.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0041.png new file mode 100644 index 0000000..44fc601 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0041.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0042.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0042.png new file mode 100644 index 0000000..02f0c52 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0042.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0043.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0043.png new file mode 100644 index 0000000..c667586 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0043.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0044.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0044.png new file mode 100644 index 0000000..387cbe1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0044.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0045.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0045.png new file mode 100644 index 0000000..387cbe1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0045.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0046.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0046.png new file mode 100644 index 0000000..debe80e Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0046.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0047.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0047.png new file mode 100644 index 0000000..d47142b Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0047.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0048.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0048.png new file mode 100644 index 0000000..d5560af Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0048.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0049.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0049.png new file mode 100644 index 0000000..54a780b Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0049.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0050.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0050.png new file mode 100644 index 0000000..cded2da Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0050.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0051.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0051.png new file mode 100644 index 0000000..f375eec Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0051.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0052.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0052.png new file mode 100644 index 0000000..67ead31 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0052.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0053.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0053.png new file mode 100644 index 0000000..497b5fe Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0053.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0054.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0054.png new file mode 100644 index 0000000..da538ec Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0054.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0055.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0055.png new file mode 100644 index 0000000..dadf31a Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0055.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0056.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0056.png new file mode 100644 index 0000000..d1ac7a1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0056.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0057.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0057.png new file mode 100644 index 0000000..fafb20e Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0057.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0058.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0058.png new file mode 100644 index 0000000..aaf62e9 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0058.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0059.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0059.png new file mode 100644 index 0000000..ec3c717 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0059.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0060.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0060.png new file mode 100644 index 0000000..0b1a8c7 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0060.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0061.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0061.png new file mode 100644 index 0000000..773cc60 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0061.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0062.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0062.png new file mode 100644 index 0000000..773cc60 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0062.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0063.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0063.png new file mode 100644 index 0000000..773cc60 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0063.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0064.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0064.png new file mode 100644 index 0000000..4560c1c Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0064.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0065.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0065.png new file mode 100644 index 0000000..8f79ca0 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0065.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0066.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0066.png new file mode 100644 index 0000000..ab75a77 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0066.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0067.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0067.png new file mode 100644 index 0000000..46611d9 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0067.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0068.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0068.png new file mode 100644 index 0000000..5d9b874 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0068.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0069.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0069.png new file mode 100644 index 0000000..c9d13df Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0069.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0070.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0070.png new file mode 100644 index 0000000..5e777cb Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0070.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0071.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0071.png new file mode 100644 index 0000000..34f243c Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0071.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0072.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0072.png new file mode 100644 index 0000000..d5f686d Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0072.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0073.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0073.png new file mode 100644 index 0000000..b04a0c3 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0073.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0074.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0074.png new file mode 100644 index 0000000..962e119 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0074.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0075.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0075.png new file mode 100644 index 0000000..d400d2a Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0075.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0076.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0076.png new file mode 100644 index 0000000..d8640d5 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0076.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0077.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0077.png new file mode 100644 index 0000000..2be17c2 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0077.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0078.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0078.png new file mode 100644 index 0000000..e6d6857 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0078.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0079.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0079.png new file mode 100644 index 0000000..31f2c81 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0079.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0080.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0080.png new file mode 100644 index 0000000..31f2c81 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0080.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0081.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0081.png new file mode 100644 index 0000000..19cde57 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0081.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0082.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0082.png new file mode 100644 index 0000000..b8be795 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0082.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0083.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0083.png new file mode 100644 index 0000000..b59374d Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0083.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0084.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0084.png new file mode 100644 index 0000000..0416a64 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0084.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0085.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0085.png new file mode 100644 index 0000000..3a3a1b5 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0085.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0086.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0086.png new file mode 100644 index 0000000..8e78eec Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0086.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0087.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0087.png new file mode 100644 index 0000000..1eb9ac4 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0087.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0088.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0088.png new file mode 100644 index 0000000..c4fd968 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0088.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0089.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0089.png new file mode 100644 index 0000000..419078e Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0089.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0090.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0090.png new file mode 100644 index 0000000..2e5a5a1 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0090.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0091.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0091.png new file mode 100644 index 0000000..2df2951 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0091.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0092.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0092.png new file mode 100644 index 0000000..7c0b5fd Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0092.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0093.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0093.png new file mode 100644 index 0000000..112ad89 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0093.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0094.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0094.png new file mode 100644 index 0000000..773aa32 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0094.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0095.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0095.png new file mode 100644 index 0000000..f9fdb19 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0095.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0096.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0096.png new file mode 100644 index 0000000..24e1347 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0096.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0097.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0097.png new file mode 100644 index 0000000..4cd8ad4 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0097.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0098.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0098.png new file mode 100644 index 0000000..69288cf Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0098.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0099.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0099.png new file mode 100644 index 0000000..1aea368 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0099.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0100.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0100.png new file mode 100644 index 0000000..1aea368 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0100.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0101.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0101.png new file mode 100644 index 0000000..24f7b7a Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0101.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0102.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0102.png new file mode 100644 index 0000000..c006968 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0102.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0103.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0103.png new file mode 100644 index 0000000..298aff8 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0103.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0104.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0104.png new file mode 100644 index 0000000..49f2987 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0104.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0105.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0105.png new file mode 100644 index 0000000..3195d32 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0105.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0106.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0106.png new file mode 100644 index 0000000..ce67bb4 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0106.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0107.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0107.png new file mode 100644 index 0000000..00407e5 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0107.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0108.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0108.png new file mode 100644 index 0000000..02765b2 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0108.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0109.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0109.png new file mode 100644 index 0000000..6726d7e Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0109.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0110.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0110.png new file mode 100644 index 0000000..a9c54be Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0110.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0111.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0111.png new file mode 100644 index 0000000..a043ba2 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0111.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0112.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0112.png new file mode 100644 index 0000000..dc7e909 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0112.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0113.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0113.png new file mode 100644 index 0000000..1707042 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0113.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0114.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0114.png new file mode 100644 index 0000000..d766732 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0114.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0115.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0115.png new file mode 100644 index 0000000..fef3f46 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0115.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0116.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0116.png new file mode 100644 index 0000000..8fc5081 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0116.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0117.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0117.png new file mode 100644 index 0000000..4562731 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0117.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0118.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0118.png new file mode 100644 index 0000000..62ad5e9 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0118.png differ diff --git a/8x32 PI/qrcode/sources/tetris/tetris_final_0119.png b/8x32 PI/qrcode/sources/tetris/tetris_final_0119.png new file mode 100644 index 0000000..263c6c5 Binary files /dev/null and b/8x32 PI/qrcode/sources/tetris/tetris_final_0119.png differ diff --git a/8x32 PI/serveur_web.py b/8x32 PI/serveur_web.py index 23a3b70..b615ab0 100644 --- a/8x32 PI/serveur_web.py +++ b/8x32 PI/serveur_web.py @@ -350,6 +350,9 @@ def accueil(): actives=[fiche(n) for n in actives()], desactivees=[fiche(n, DESACTIVEES) for n in desactivees()], en_cours=lire_en_cours(), + vitesse=lecteur.lire_vitesse_de_lecture(DOSSIER), + vitesses=[(0.25, "×0,25 (très lent)"), (0.5, "×0,5 (lent)"), (0.75, "×0,75"), + (1.0, "×1 (normal)"), (1.5, "×1,5"), (2.0, "×2 (rapide)")], nb_corbeille=nb_corbeille, dossier=DOSSIER, adresses=adresses_du_pi(), @@ -507,6 +510,18 @@ def action(): ranger_dans(CORBEILLE, nom, depuis=os.path.join(DOSSIER, DESACTIVEES)) flash(f"« {nom} » est dans la corbeille.", "ok") + elif quoi == "vitesse": + try: + vitesse = float(request.form.get("vitesse", "1")) + assert 0.1 <= vitesse <= 4 + except (ValueError, AssertionError): + abort(400) + # Un petit fichier caché dans le dossier des animations : il est lu par + # le lecteur au début de chaque animation, et survit aux redémarrages. + with open(os.path.join(DOSSIER, ".vitesse.txt"), "w") as f: + f.write(f"{vitesse:g}\n") + flash(f"Vitesse de lecture : ×{vitesse:g} (à partir de la prochaine animation).", "ok") + elif quoi == "vider_corbeille": shutil.rmtree(os.path.join(DOSSIER, CORBEILLE), ignore_errors=True) flash("Corbeille vidée.", "ok") diff --git a/8x32 PI/web/page.html b/8x32 PI/web/page.html index 0b1a1e8..a700bd7 100644 --- a/8x32 PI/web/page.html +++ b/8x32 PI/web/page.html @@ -22,6 +22,18 @@ + {# Vitesse : le formulaire s'envoie tout seul dès qu'on change la valeur. #} +
+ + + +
diff --git a/8x32 PI/web/style.css b/8x32 PI/web/style.css index d9e913a..92e46db 100644 --- a/8x32 PI/web/style.css +++ b/8x32 PI/web/style.css @@ -61,6 +61,11 @@ h1 { margin: 0; font-size: 1.3rem; display: flex; align-items: center; gap: 10px } .statut { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; } .statut form { margin: 0; } +.vitesse label { display: flex; align-items: center; gap: 6px; } +.vitesse select { + font: inherit; padding: 6px 8px; border-radius: 8px; + background: #2a2826; color: #f1ede6; border: 1px solid #3d3935; +} .pastille { width: 10px; height: 10px; border-radius: 50%; background: #4cc283; box-shadow: 0 0 8px #4cc283; diff --git a/CLAUDE.md b/CLAUDE.md index 565134a..831af29 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -80,7 +80,7 @@ Le projet avance en deux temps : - Matériel : Pi 3B+ / 4 / Zero 2 W (pas le Pi 5 : `rpi_ws281x` ne le gère pas), GPIO 18 (patte 12) → **74AHCT125** (3,3 V → 5 V, VCC pris sur le fil rouge de la fiche DIN) → 330 Ω → DIN. Audio désactivé (`dtparam=audio=off`). - Installation : `installation/installer.sh` (venv `~/vitrine-env`, services systemd `vitrine-pixels` (lecteur) et `vitrine-web` (interface)). Docs : README, INSTALLATION_PI, GUIDE_KRITA, MODE_VITRINE (overlay FS), INTERFACE_WEB, CODER_EN_PYTHON. - Interface web `serveur_web.py` (Flask, port 80, gabarits dans `web/`) : dépôt GIF/PNG/séquences, ordre (renommage `01_…`), activer/désactiver (`.desactivees/`), corbeille (`.corbeille/`), « jouer maintenant » via post-it `/run/vitrine-pixels/demande` lu par le lecteur. -- Pi installé : Raspberry Pi 3 Model B, Raspbian 11 Bullseye 32 bits (dossier boot = `/boot`, Pillow 8.1, Flask 1.1), Ethernet débranché : accès uniquement en Wi-Fi, `ssh devel@172.16.50.27` (clé ESADHaR) ; l'ancienne adresse câble était 172.16.7.199. Le Wi-Fi et le filaire de l'école ne se voient pas : depuis le Wi-Fi, page web sur http://172.16.50.27 (adresses DHCP, affichées en bas de la page). Matrice posée debout : `ROTATION = 90`, image 8 × 32. Pas de 74AHCT125 pendant le workshop : **montage A** (GPIO 18 → 330 Ω → DIN, matrice en 4,4 V) testé et validé ; montage B (transistor 2N3904 inverseur) essayé : échec, trop lent (temps de stockage ≈ 0,2 µs face à un « 0 » de 0,4 µs), seule la 1re LED s'allume au hasard. Lecteur `vitrine-pixels` activé au démarrage le 2026-10-08. +- Pi installé : Raspberry Pi 3 Model B, Raspbian 11 Bullseye 32 bits (dossier boot = `/boot`, Pillow 8.1, Flask 1.1), Ethernet débranché : accès uniquement en Wi-Fi, `ssh devel@172.16.50.27` (clé ESADHaR) ; l'ancienne adresse câble était 172.16.7.199. Le Wi-Fi et le filaire de l'école ne se voient pas : depuis le Wi-Fi, page web sur http://172.16.50.27 (adresses DHCP, affichées en bas de la page). Matrice posée debout : `ROTATION = 90`, image 8 × 32 ; sur la vitrine `INVERSER_X = INVERSER_Y = True` (demi-tour) et `DECALAGE_X = 1` (image décalée d'un pixel vers la droite). Vitesse de lecture réglable depuis la page web (`.vitesse.txt`, ×0,5 actuellement). QR code et affiche A5 : `outils/generer_qrcode.py` → `qrcode/`. Pas de 74AHCT125 pendant le workshop : **montage A** (GPIO 18 → 330 Ω → DIN, matrice en 4,4 V) testé et validé ; montage B (transistor 2N3904 inverseur) essayé : échec, trop lent (temps de stockage ≈ 0,2 µs face à un « 0 » de 0,4 µs), seule la 1re LED s'allume au hasard. Lecteur `vitrine-pixels` activé au démarrage le 2026-10-08. - Schémas générés par `outils/schemas.py`, exemples et palette Krita par `outils/generer_exemples.py`. ### Chiffres clés