534 lines
21 KiB
Arduino
534 lines
21 KiB
Arduino
/*
|
||
* =============================================================================
|
||
* MATRICE LED RGB 3 x 3 MULTIPLEXÉE — Arduino Uno
|
||
* Workshop « Vitrine pixels »
|
||
* =============================================================================
|
||
*
|
||
* CE QUE FAIT CE PROGRAMME
|
||
* ------------------------
|
||
* Il affiche des animations de couleur sur un petit écran de 9 pixels
|
||
* (3 lignes × 3 colonnes). Chaque pixel est une LED RGB : une seule LED
|
||
* qui contient en réalité 3 petites LED, une rouge (R), une verte (G pour
|
||
* « green ») et une bleue (B). En les allumant ensemble, on mélange la lumière :
|
||
*
|
||
* rouge + vert = jaune
|
||
* rouge + bleu = magenta
|
||
* vert + bleu = cyan
|
||
* rouge + vert + bleu = blanc
|
||
*
|
||
* (C'est la synthèse ADDITIVE, celle des écrans — à l'inverse de la peinture,
|
||
* où mélanger les couleurs assombrit.)
|
||
*
|
||
*
|
||
* LE PROBLÈME : PAS ASSEZ DE BROCHES (PINS)
|
||
* ----------------------------------------
|
||
* 9 LED × 3 couleurs = 27 petites LED à commander.
|
||
* L'Arduino Uno n'a que 20 broches utilisables… et on veut, plus tard,
|
||
* construire une matrice de 7 × 39 = 273 pixels !
|
||
* Impossible de brancher chaque LED sur sa propre broche.
|
||
*
|
||
*
|
||
* LA SOLUTION : LE MULTIPLEXAGE (ou « balayage »)
|
||
* -----------------------------------------------
|
||
* On n'allume JAMAIS toute l'image en même temps. On allume UNE SEULE LIGNE
|
||
* à la fois, très vite, l'une après l'autre :
|
||
*
|
||
* temps → ligne 0 | ligne 1 | ligne 2 | ligne 0 | ligne 1 | ...
|
||
* 1 ms 1 ms 1 ms 1 ms 1 ms
|
||
*
|
||
* Chaque ligne est allumée environ 333 fois par seconde. L'œil est trop
|
||
* lent pour voir le clignotement : c'est la PERSISTANCE RÉTINIENNE, le même
|
||
* principe que le cinéma (24 images/seconde) ou les vieux écrans cathodiques.
|
||
* Le cerveau « recolle » les trois lignes et voit une image fixe.
|
||
*
|
||
* Grâce à ça, il suffit de :
|
||
* - 9 broches pour les couleurs : 3 colonnes × (R, G, B)
|
||
* - 3 broches pour choisir quelle ligne est allumée
|
||
* = 12 broches au lieu de 27.
|
||
*
|
||
*
|
||
* LE CÂBLAGE EN DEUX MOTS
|
||
* -----------------------
|
||
* Nos LED sont à « CATHODE COMMUNE » : les 3 couleurs d'une LED partagent
|
||
* la même patte « moins » (la cathode, la patte la plus longue).
|
||
*
|
||
* - Les 3 cathodes d'une même LIGNE sont reliées ensemble, puis vers le GND
|
||
* (le « moins » de l'Arduino) à travers un TRANSISTOR. Le transistor est
|
||
* un interrupteur électronique : quand l'Arduino envoie du courant sur sa
|
||
* patte « base », il laisse passer le courant de la ligne vers le GND.
|
||
* → broche de ligne à HIGH = ligne allumée.
|
||
* (On utilise un transistor car une ligne entière en blanc consomme
|
||
* ~180 mA, bien trop pour une broche d'Arduino qui supporte ~20-40 mA.)
|
||
*
|
||
* - Les anodes (« plus ») de même couleur dans une même COLONNE sont reliées
|
||
* ensemble, puis vers une broche de l'Arduino à travers une RÉSISTANCE
|
||
* (220 Ω pour le rouge, 150 Ω pour le vert et le bleu). La résistance
|
||
* limite le courant pour ne pas griller la LED.
|
||
* → broche couleur à HIGH = cette couleur est allumée dans la colonne.
|
||
*
|
||
* Un pixel s'allume donc quand SA ligne est active ET que SA colonne
|
||
* envoie de la couleur. C'est le croisement des deux qui choisit le pixel.
|
||
*
|
||
*
|
||
* ORGANISATION DU PROGRAMME
|
||
* -------------------------
|
||
* 1. Réglages : quelles broches, combien de lignes/colonnes.
|
||
* 2. Les couleurs, codées par des nombres.
|
||
* 3. L'IMAGE : un tableau de 3 × 3 cases qui contient la couleur de chaque
|
||
* pixel. C'est notre « toile ».
|
||
* 4. Le BALAYAGE : une fonction déclenchée automatiquement toutes les
|
||
* millisecondes, qui recopie l'image sur les LED, ligne par ligne.
|
||
* 5. Des fonctions pour DESSINER dans l'image (effacer, remplir, pixel).
|
||
* 6. Les ANIMATIONS : elles ne font que modifier l'image ; le balayage
|
||
* s'occupe de l'afficher tout seul, en arrière-plan.
|
||
*
|
||
* → Pour créer vos propres animations, vous n'avez à toucher qu'aux
|
||
* parties 5 et 6. Le reste est le « moteur » de l'écran.
|
||
*
|
||
*
|
||
* BIBLIOTHÈQUE NÉCESSAIRE : TimerOne
|
||
* ----------------------------------
|
||
* Dans l'IDE Arduino : menu Outils → Gérer les bibliothèques…
|
||
* → chercher « TimerOne » → Installer.
|
||
*/
|
||
|
||
|
||
// Une « bibliothèque » est un morceau de code écrit par quelqu'un d'autre,
|
||
// qu'on réutilise. TimerOne sert à déclencher une fonction à intervalle
|
||
// régulier, comme un métronome, sans bloquer le reste du programme.
|
||
// (Elle utilise le « Timer1 » du Uno : du coup analogWrite() ne marche plus
|
||
// sur les broches 9 et 10. Ici on ne s'en sert pas, donc pas de souci.)
|
||
#include <TimerOne.h>
|
||
|
||
|
||
// =============================================================================
|
||
// 1. RÉGLAGES DE LA MATRICE
|
||
// =============================================================================
|
||
|
||
// #define donne un nom à une valeur. Partout où le programme lit NB_LIGNES,
|
||
// c'est comme s'il lisait 3. Avantage : pour changer la taille de la
|
||
// matrice, on ne modifie qu'un seul endroit.
|
||
#define NB_LIGNES 3
|
||
#define NB_COLONNES 3
|
||
|
||
// Numéros des broches qui commandent les couleurs, rangés dans un tableau
|
||
// à deux dimensions : pinsCouleur[numéro de colonne][couleur]
|
||
// couleur 0 = rouge, 1 = vert, 2 = bleu
|
||
//
|
||
// Exemple : pinsCouleur[1][2] = 7 → le bleu de la colonne 1 est sur la broche 7.
|
||
//
|
||
// « const » veut dire que ces valeurs ne changeront jamais pendant le programme.
|
||
// « byte » est un petit nombre entier entre 0 et 255 (1 octet de mémoire).
|
||
//
|
||
// ⚠ Si votre câblage est différent, c'est ICI qu'il faut corriger.
|
||
const byte pinsCouleur[NB_COLONNES][3] = {
|
||
// R G B
|
||
{ 2, 3, 4 }, // colonne 0 (à gauche)
|
||
{ 5, 6, 7 }, // colonne 1 (au milieu)
|
||
{ 8, 9, 10 } // colonne 2 (à droite)
|
||
};
|
||
|
||
// Broches reliées aux bases des transistors (une par ligne, via une
|
||
// résistance de 1 kΩ). pinsLigne[0] = ligne du haut.
|
||
// Remarque : la broche 13 est aussi reliée à la petite LED soudée sur
|
||
// la carte Arduino. Elle va scintiller doucement : c'est normal.
|
||
const byte pinsLigne[NB_LIGNES] = { 11, 12, 13 };
|
||
|
||
// Temps pendant lequel chaque ligne reste allumée, en MICROsecondes
|
||
// (1000 µs = 1 ms = un millième de seconde).
|
||
// - Plus petit → image plus stable, mais l'Arduino travaille davantage.
|
||
// - Plus grand (essayez 10000 !) → on commence à voir le scintillement,
|
||
// et à 200000 on voit carrément les lignes s'allumer une par une.
|
||
// C'est une bonne expérience pour comprendre le multiplexage.
|
||
#define DUREE_LIGNE_US 1000
|
||
|
||
|
||
// =============================================================================
|
||
// 2. LES COULEURS
|
||
// =============================================================================
|
||
//
|
||
// Chaque couleur est un nombre de 0 à 7. Pourquoi ces nombres-là ?
|
||
// Parce qu'on les écrit en BINAIRE (en 0 et 1), sur 3 chiffres (« bits ») :
|
||
// chaque bit dit si une des trois LED est allumée (1) ou éteinte (0).
|
||
//
|
||
// bit 2 bit 1 bit 0
|
||
// BLEU VERT ROUGE valeur
|
||
// NOIR 0 0 0 → 0
|
||
// ROUGE 0 0 1 → 1
|
||
// VERT 0 1 0 → 2
|
||
// JAUNE 0 1 1 → 3 (rouge + vert)
|
||
// BLEU 1 0 0 → 4
|
||
// MAGENTA 1 0 1 → 5 (rouge + bleu)
|
||
// CYAN 1 1 0 → 6 (vert + bleu)
|
||
// BLANC 1 1 1 → 7 (tout allumé)
|
||
//
|
||
// Astuce : une couleur mélangée = la SOMME des couleurs qui la composent.
|
||
// JAUNE = ROUGE + VERT = 1 + 2 = 3
|
||
// BLANC = ROUGE + VERT + BLEU = 1 + 2 + 4 = 7
|
||
//
|
||
// Pour l'instant chaque LED est soit allumée, soit éteinte (« tout ou rien »),
|
||
// donc on n'a que ces 8 couleurs. Pour faire des dégradés (orange, rose
|
||
// pâle…), il faudra faire varier l'intensité : ce sera l'étape suivante
|
||
// (le « PWM »).
|
||
|
||
#define NOIR 0
|
||
#define ROUGE 1
|
||
#define VERT 2
|
||
#define JAUNE 3
|
||
#define BLEU 4
|
||
#define MAGENTA 5
|
||
#define CYAN 6
|
||
#define BLANC 7
|
||
|
||
// Une « palette » : la liste des 7 couleurs (sans le noir), dans l'ordre
|
||
// de l'arc-en-ciel. Pratique pour les parcourir avec une boucle :
|
||
// couleurs[0] = ROUGE, couleurs[1] = JAUNE, … couleurs[6] = BLANC.
|
||
const byte couleurs[] = { ROUGE, JAUNE, VERT, CYAN, BLEU, MAGENTA, BLANC };
|
||
#define NB_COULEURS 7
|
||
|
||
|
||
// =============================================================================
|
||
// 3. L'IMAGE (la « toile »)
|
||
// =============================================================================
|
||
//
|
||
// Un tableau de 3 × 3 cases. Chaque case contient la couleur d'un pixel.
|
||
// On y accède par image[ligne][colonne] :
|
||
//
|
||
// colonne 0 colonne 1 colonne 2
|
||
// ligne 0 image[0][0] image[0][1] image[0][2]
|
||
// ligne 1 image[1][0] image[1][1] image[1][2]
|
||
// ligne 2 image[2][0] image[2][1] image[2][2]
|
||
//
|
||
// Attention : en informatique on compte à partir de 0, pas de 1 !
|
||
//
|
||
// « volatile » prévient l'Arduino que cette variable peut changer
|
||
// « dans son dos » : elle est modifiée par les animations et lue en même
|
||
// temps par le balayage. Sans ce mot, l'Arduino pourrait garder une vieille
|
||
// copie de l'image et ne pas voir les changements.
|
||
volatile byte image[NB_LIGNES][NB_COLONNES];
|
||
|
||
// Numéro de la ligne actuellement allumée (0, 1 ou 2).
|
||
volatile byte ligneCourante = 0;
|
||
|
||
|
||
// =============================================================================
|
||
// 4. LE BALAYAGE (le « moteur » de l'écran)
|
||
// =============================================================================
|
||
//
|
||
// Cette fonction n'est jamais appelée directement par nous : c'est TimerOne
|
||
// qui la déclenche automatiquement toutes les DUREE_LIGNE_US microsecondes.
|
||
// On appelle ça une INTERRUPTION : l'Arduino met en pause ce qu'il est en
|
||
// train de faire (même au milieu d'un delay !), exécute cette fonction,
|
||
// puis reprend là où il en était.
|
||
//
|
||
// À chaque appel, elle passe à la ligne suivante. Il faut 3 appels pour
|
||
// afficher l'image complète une fois.
|
||
//
|
||
// Règle d'or d'une interruption : être COURTE et RAPIDE. Pas de delay(),
|
||
// pas de Serial.print() ici.
|
||
|
||
void rafraichirLigne() {
|
||
|
||
// --- Étape 1 : éteindre la ligne actuellement allumée ---
|
||
// Il faut le faire AVANT de changer les couleurs. Sinon, pendant un très
|
||
// court instant, la ligne actuelle s'afficherait avec les couleurs de la
|
||
// ligne suivante : on verrait des « fantômes », de légers reflets de
|
||
// couleur aux mauvais endroits.
|
||
digitalWrite(pinsLigne[ligneCourante], LOW);
|
||
|
||
// --- Étape 2 : passer à la ligne suivante ---
|
||
// ligneCourante++ ajoute 1 : 0 → 1 → 2 → 3…
|
||
// Arrivé à 3 (qui n'existe pas), on revient à 0 : on boucle.
|
||
ligneCourante++;
|
||
if (ligneCourante >= NB_LIGNES) {
|
||
ligneCourante = 0;
|
||
}
|
||
|
||
// --- Étape 3 : préparer les couleurs de cette ligne ---
|
||
// On parcourt les 3 colonnes. Pour chacune, on lit la couleur dans
|
||
// l'image et on allume ou éteint les broches R, G et B correspondantes.
|
||
for (byte col = 0; col < NB_COLONNES; col++) {
|
||
|
||
// Couleur du pixel (ligne courante, colonne col), entre 0 et 7.
|
||
byte c = image[ligneCourante][col];
|
||
|
||
// Le symbole & (« ET bit à bit ») permet de tester UN bit de la couleur.
|
||
// Exemple avec c = MAGENTA = 5 = 101 en binaire :
|
||
// 5 & ROUGE (001) = 001 → non nul → le rouge est allumé
|
||
// 5 & VERT (010) = 000 → nul → le vert est éteint
|
||
// 5 & BLEU (100) = 100 → non nul → le bleu est allumé
|
||
//
|
||
// L'écriture (condition) ? HIGH : LOW veut dire :
|
||
// « si la condition est vraie, HIGH, sinon LOW ».
|
||
digitalWrite(pinsCouleur[col][0], (c & ROUGE) ? HIGH : LOW);
|
||
digitalWrite(pinsCouleur[col][1], (c & VERT) ? HIGH : LOW);
|
||
digitalWrite(pinsCouleur[col][2], (c & BLEU) ? HIGH : LOW);
|
||
}
|
||
|
||
// --- Étape 4 : allumer la nouvelle ligne ---
|
||
// Les couleurs sont prêtes, on ouvre le transistor de la ligne :
|
||
// le courant circule, les LED de cette ligne s'allument.
|
||
// Elles resteront allumées jusqu'au prochain appel (dans 1 ms).
|
||
digitalWrite(pinsLigne[ligneCourante], HIGH);
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// 5. LES OUTILS DE DESSIN
|
||
// =============================================================================
|
||
//
|
||
// Ces petites fonctions modifient l'image. Elles n'allument rien
|
||
// directement : c'est le balayage qui affichera le résultat à son prochain
|
||
// passage (moins de 3 ms plus tard, donc instantané pour l'œil).
|
||
|
||
// Remplit toute l'image avec une seule couleur.
|
||
// Deux boucles imbriquées : pour chaque ligne l, pour chaque colonne c…
|
||
void remplir(byte couleur) {
|
||
for (byte l = 0; l < NB_LIGNES; l++) {
|
||
for (byte c = 0; c < NB_COLONNES; c++) {
|
||
image[l][c] = couleur;
|
||
}
|
||
}
|
||
}
|
||
|
||
// Éteint tout (= remplir en noir).
|
||
void effacer() {
|
||
remplir(NOIR);
|
||
}
|
||
|
||
// Colore un seul pixel.
|
||
// x = colonne (horizontal, de gauche à droite : 0, 1, 2)
|
||
// y = ligne (vertical, de haut en bas : 0, 1, 2)
|
||
// Comme sur un écran d'ordinateur, le point (0, 0) est en HAUT à gauche.
|
||
//
|
||
// x=0 x=1 x=2
|
||
// y=0 (0,0) (1,0) (2,0)
|
||
// y=1 (0,1) (1,1) (2,1)
|
||
// y=2 (0,2) (1,2) (2,2)
|
||
//
|
||
// Le « if » vérifie qu'on ne dessine pas en dehors de la matrice :
|
||
// écrire image[5][5] irait abîmer d'autres données en mémoire.
|
||
// Attention à l'ordre : on écrit image[y][x] (ligne d'abord) !
|
||
void pixel(byte x, byte y, byte couleur) {
|
||
if (x < NB_COLONNES && y < NB_LIGNES) {
|
||
image[y][x] = couleur;
|
||
}
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// 6. LES ANIMATIONS
|
||
// =============================================================================
|
||
//
|
||
// Une animation, c'est une suite d'images, comme un flip-book :
|
||
// on dessine une image → on attend un peu (delay) → on dessine la suivante…
|
||
//
|
||
// delay(150) met le programme en pause 150 millisecondes. Pendant ce temps,
|
||
// le balayage continue de tourner grâce à l'interruption : l'image reste
|
||
// affichée. (Sans interruption, l'écran s'éteindrait pendant le delay !)
|
||
//
|
||
// Chaque animation dure quelques secondes puis se termine ; loop() lance
|
||
// alors la suivante.
|
||
//
|
||
// À VOUS DE JOUER : copiez une de ces fonctions, renommez-la, modifiez-la,
|
||
// puis ajoutez son nom dans loop() tout en bas.
|
||
|
||
|
||
// --- Animation 1 : test du câblage ---
|
||
// Allume chaque pixel, un par un, en rouge, puis en vert, puis en bleu.
|
||
// À lancer en premier sur une nouvelle maquette : si un pixel ne s'allume
|
||
// pas, ou s'allume au mauvais endroit / dans la mauvaise couleur, vous savez
|
||
// exactement quel fil vérifier.
|
||
void animTestPixels() {
|
||
const byte primaires[] = { ROUGE, VERT, BLEU }; // les 3 couleurs de base
|
||
|
||
for (byte p = 0; p < 3; p++) { // pour chaque couleur de base
|
||
for (byte y = 0; y < NB_LIGNES; y++) { // pour chaque ligne
|
||
for (byte x = 0; x < NB_COLONNES; x++) { // pour chaque colonne
|
||
effacer(); // on éteint tout
|
||
pixel(x, y, primaires[p]); // on allume un seul pixel
|
||
delay(150); // on laisse le temps de voir
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// --- Animation 2 : aplats de couleur ---
|
||
// Toute la matrice prend successivement les 7 couleurs de la palette.
|
||
void animCouleursPleines() {
|
||
for (byte i = 0; i < NB_COULEURS; i++) { // i va de 0 à 6
|
||
remplir(couleurs[i]); // la i-ème couleur de la palette
|
||
delay(400); // 0,4 seconde par couleur
|
||
}
|
||
}
|
||
|
||
|
||
// --- Animation 3 : la chenille ---
|
||
// Un petit serpent de 2 pixels fait le tour du bord de la matrice, pendant
|
||
// que le pixel central reste blanc. Il change de couleur à chaque tour.
|
||
void animChenille() {
|
||
|
||
// Les 8 cases du bord, dans l'ordre des aiguilles d'une montre.
|
||
// Chaque case est donnée par ses coordonnées {x, y}.
|
||
//
|
||
// 0 → 1 → 2
|
||
// ↑ ↓
|
||
// 7 · 3
|
||
// ↑ ↓
|
||
// 6 ← 5 ← 4
|
||
const byte tour[8][2] = {
|
||
{0, 0}, {1, 0}, {2, 0}, // le haut, de gauche à droite
|
||
{2, 1}, // le côté droit
|
||
{2, 2}, {1, 2}, {0, 2}, // le bas, de droite à gauche
|
||
{0, 1} // le côté gauche
|
||
};
|
||
|
||
for (byte t = 0; t < 4; t++) { // 4 tours complets
|
||
byte couleur = couleurs[t % NB_COULEURS]; // une couleur différente par tour
|
||
// (% = reste de la division : garde
|
||
// le numéro entre 0 et 6)
|
||
|
||
for (byte i = 0; i < 8; i++) { // 8 étapes par tour
|
||
effacer();
|
||
pixel(1, 1, BLANC); // le centre, fixe
|
||
|
||
// La tête du serpent, sur la case i du tour.
|
||
pixel(tour[i][0], tour[i][1], couleur);
|
||
|
||
// La queue, sur la case juste avant.
|
||
// (i + 7) % 8 donne « i - 1 », mais en revenant à 7 quand i vaut 0 :
|
||
// la queue de la case 0 est la case 7, on boucle autour du carré.
|
||
byte prec = (i + 7) % 8;
|
||
pixel(tour[prec][0], tour[prec][1], couleur);
|
||
|
||
delay(100); // vitesse du serpent
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// --- Animation 4 : le damier ---
|
||
// Un damier cyan / magenta qui s'inverse régulièrement.
|
||
void animDamier() {
|
||
for (byte n = 0; n < 8; n++) { // 8 images
|
||
for (byte y = 0; y < NB_LIGNES; y++) {
|
||
for (byte x = 0; x < NB_COLONNES; x++) {
|
||
|
||
// L'astuce du damier : on additionne x et y.
|
||
// Si le résultat est pair, une couleur ; s'il est impair, l'autre.
|
||
// (0,0) → 0 pair (1,0) → 1 impair (2,0) → 2 pair …
|
||
// En ajoutant n (qui augmente à chaque image), pair et impair
|
||
// s'échangent à chaque fois : le damier s'inverse.
|
||
if ((x + y + n) % 2 == 1) {
|
||
pixel(x, y, MAGENTA);
|
||
} else {
|
||
pixel(x, y, CYAN);
|
||
}
|
||
}
|
||
}
|
||
delay(300);
|
||
}
|
||
}
|
||
|
||
|
||
// --- Animation 5 : balayages ---
|
||
// Une barre verticale traverse la matrice de gauche à droite, puis une barre
|
||
// horizontale de haut en bas. On recommence avec chaque couleur de la palette.
|
||
void animBalayages() {
|
||
for (byte i = 0; i < NB_COULEURS; i++) {
|
||
byte couleur = couleurs[i];
|
||
|
||
// Barre verticale : on allume toute la colonne x, puis on avance.
|
||
for (byte x = 0; x < NB_COLONNES; x++) {
|
||
effacer();
|
||
for (byte y = 0; y < NB_LIGNES; y++) {
|
||
pixel(x, y, couleur);
|
||
}
|
||
delay(120);
|
||
}
|
||
|
||
// Barre horizontale : on allume toute la ligne y, puis on descend.
|
||
for (byte y = 0; y < NB_LIGNES; y++) {
|
||
effacer();
|
||
for (byte x = 0; x < NB_COLONNES; x++) {
|
||
pixel(x, y, couleur);
|
||
}
|
||
delay(120);
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
// --- Animation 6 : scintillement aléatoire ---
|
||
// À chaque étape, un pixel pris au hasard prend une couleur au hasard
|
||
// (le noir compris, pour que des pixels s'éteignent aussi).
|
||
// random(3) donne un nombre au hasard parmi 0, 1, 2.
|
||
// random(8) donne un nombre au hasard entre 0 et 7 = une de nos 8 couleurs.
|
||
void animAleatoire() {
|
||
for (int n = 0; n < 40; n++) { // 40 changements
|
||
pixel(random(NB_COLONNES), random(NB_LIGNES), random(8));
|
||
delay(80);
|
||
}
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// SETUP : exécuté UNE SEULE FOIS, à l'allumage de l'Arduino
|
||
// =============================================================================
|
||
void setup() {
|
||
|
||
// Toutes nos broches servent à ENVOYER du courant (sortie = OUTPUT),
|
||
// pas à en lire (ce serait INPUT, pour un bouton par exemple).
|
||
// On les met toutes à LOW au départ pour que tout soit éteint.
|
||
|
||
// Les 3 broches de lignes
|
||
for (byte l = 0; l < NB_LIGNES; l++) {
|
||
pinMode(pinsLigne[l], OUTPUT);
|
||
digitalWrite(pinsLigne[l], LOW);
|
||
}
|
||
|
||
// Les 9 broches de couleurs (3 colonnes × 3 couleurs)
|
||
for (byte c = 0; c < NB_COLONNES; c++) {
|
||
for (byte k = 0; k < 3; k++) {
|
||
pinMode(pinsCouleur[c][k], OUTPUT);
|
||
digitalWrite(pinsCouleur[c][k], LOW);
|
||
}
|
||
}
|
||
|
||
// On part d'une image toute noire.
|
||
effacer();
|
||
|
||
// Le hasard d'un ordinateur n'est pas vraiment du hasard : c'est une
|
||
// longue suite de nombres calculée à partir d'un point de départ
|
||
// (la « graine »). Si la graine est toujours la même, la suite aussi.
|
||
// On lit donc la broche A0, qui n'est branchée à rien : elle capte du
|
||
// bruit électrique, différent à chaque démarrage → vrai point de départ
|
||
// imprévisible.
|
||
randomSeed(analogRead(A0));
|
||
|
||
// On démarre le métronome : toutes les DUREE_LIGNE_US microsecondes,
|
||
// TimerOne appellera rafraichirLigne(). À partir de maintenant, l'écran
|
||
// s'affiche tout seul, en arrière-plan.
|
||
Timer1.initialize(DUREE_LIGNE_US);
|
||
Timer1.attachInterrupt(rafraichirLigne);
|
||
}
|
||
|
||
|
||
// =============================================================================
|
||
// LOOP : exécutée EN BOUCLE, à l'infini, après setup()
|
||
// =============================================================================
|
||
//
|
||
// C'est la « playlist » : les animations s'enchaînent dans cet ordre, puis
|
||
// on recommence au début.
|
||
// Pour ne garder qu'une animation, mettez les autres en commentaire en
|
||
// ajoutant // devant la ligne. Pour ajouter la vôtre, écrivez son nom ici.
|
||
void loop() {
|
||
animTestPixels(); // 1. test du câblage (à retirer une fois validé)
|
||
animCouleursPleines(); // 2. aplats de couleur
|
||
animChenille(); // 3. serpent autour du bord
|
||
animDamier(); // 4. damier qui s'inverse
|
||
animBalayages(); // 5. barres qui traversent
|
||
animAleatoire(); // 6. scintillement aléatoire
|
||
}
|