Cet article décrit comment mettre en œuvre une matrice de LED avec une carte Arduino dans le but de reproduire l’animation lumineuse d’une croix de pharmacie. Il complète l’article éponyme paru dans Loco-Revue N° 875 de juin 2020. La matrice de LED utilisée dans cet article a pour référence 1588ASRG et sa taille convient bien pour l’échelle Zéro. Les principes sont les mêmes si on utilise une matrice de LED A-788BPG dont la taille convient mieux pour l’échelle H0.
Une croix de pharmacie animée avec Arduino UNO
.
Par :
DIFFICULTÉ :★★☆
La matrice de LED sera incorporée à un bâtiment représentant une pharmacie que vous aurez construite à partir d’un kit ou bien à partir de feuilles de cartons ou autres matériaux. Voici pour commencer une petite vidéo qui montre le résultat obtenu ; les différentes phases de construction ont été expliquées dans l’article de Loco-Revue.
Transformer une matrice de LED en croix de pharmacie
Des recherches sur internet montrent qu’une croix de pharmacie a généralement une envergure comprise entre 0,80 et 1,30 m. En général, la croix de pharmacie est posée perpendiculairement à la façade du bâtiment pour que ses deux faces soient visibles. Parfois, la croix n’a qu’une seule face active et elle est alors simplement posée sur le mur. Dans un tel cas, on peut la représenter en utilisant une matrice de LED vertes. On peut trouver ce genre de composant sur internet ; c’est évidemment la taille de la matrice qui dictera notre choix en fonction de l’échelle pratiquée.
Pour chaque bras, il faut utiliser au moins trois lignes ou trois colonnes pour que l’animation soit intéressante. De plus la croix doit être symétrique. Comme les matrices de LED sont généralement organisées en 8 lignes et 8 colonnes, la largeur des bras pourrait être de 4 lignes ou 4 colonnes, mais dans ce cas, la croix peut sembler trop massive par rapport à son envergure, comme le montre le tracé en bleu de la figure 1. Il est alors préférable de n’utiliser que 7 lignes et 7 colonnes de la matrice pour dessiner une croix dont la largeur des bras est de 3 lignes ou colonnes comme le montre le tracé en rouge de la figure 1. Dans ces conditions, l’envergure de la croix est 6 fois l’espace entre deux LED auxquels il faut rajouter le diamètre d’une LED et la largeur de bras est 2 fois l’espace entre deux LED auxquels il faut ajouter le diamètre d’une LED.
Quelle matrice de LED choisir ?
La première chose à faire est donc de se procurer une matrice de LED vertes à anodes communes sur les rangées (voir figure 3) dont les dimensions permettront de reproduire une croix en fonction de l’échelle pratiquée. Si vous possédez une matrice de LED à cathodes communes sur les rangées, vous pouvez l’utiliser. Le montage est le même mais il faut intervenir sur le programme, comme cela est expliqué un peu plus loin. Les explications qui suivent sont données pour une matrice à anodes communes. Ce genre de composant dispose de 16 broches reliées aux 8 lignes et aux 8 colonnes.
La référence A-788BPG convient parfaitement pour l’échelle H0 puisque sa dimension est de 20 x 20 mm et de plus, on n’utilise que 7 x 7 LED. Selon la formule mentionnée plus haut, cela représente une largeur de bras de 7,5 mm et une envergure de 17 mm, ou encore 1,47 m à l’échelle, ce qui est un peu plus que désiré tout en restant cohérent.
Comme je l’ai dit dans l’introduction, j’ai utilisé pour écrire cet article une matrice ayant pour référence 1588ASRG qui convient mieux pour l’échelle 0 puisque sa dimension est de 37,8 x 37,8 mm, ce qui donne une largeur de bras de 14 mm et une envergure de 32 mm en arrondissant, soit 1,40 m à l’échelle. La figure 3 montre la géométrie de la croix ainsi obtenue.
La matrice A-788BPG dispose de 16 broches correspondant aux 8 lignes et 8 colonnes. On peut être surpris de voir que le composant 1588ASRG dispose de 24 broches. La datasheet montre qu’il s’agit en fait de LED bicolores (vertes et rouges) en montage à anodes communes sur les 8 lignes et avec les 16 cathodes (8 rouges et 8 vertes) sur les colonnes. Dans la suite de cet article, nous n’utiliserons que les LED vertes de ce composant.
Vous pouvez utiliser d’autres références de matrices de LED à anodes communes que les deux fournies dans cet article. La seule condition est que les LED soient vertes puisque l’idée est d’utiliser ce composant pour créer une croix de pharmacie et que la taille du composant puisse donner une croix de pharmacie dont l’envergure est comprise entre 0,80 m et 1,50m. Il vous faudra alors repérer le brochage du composant en lignes et colonnes et le mieux est de taper sa référence dans un moteur de recherche pour télécharger sa datasheet à partir du site du constructeur.
Principe de commande d’une LED
La figure 3 montre notre matrice de LED. Supposons qu’on veuille allumer la LED verte située en ligne 3 et colonne 3. Il suffit de mettre la ligne 3 à l’état HIGH (+5 V) et la colonne 3 à l’état LOW (0 V) pour qu’un courant traverse la LED, courant qu’il faut calibrer à 20 mA maximum par une résistance en série dans ce circuit (par exemple en série sur la broche du composant reliée à la colonne 3). La LED est entourée par un carré sur la figure 3. Si on veut aussi allumer la LED verte située en ligne 3 et colonne 4, il suffit de mettre à l’état LOW la colonne 4 avec une résistance de limitation de courant en série. Tout cela semble assez simple pour peu qu’on connaisse la correspondance entre les broches du composant et les lignes et colonnes de la matrice de LED.
Supposons maintenant qu’on veuille allumer en même temps que ces deux LED, la LED verte située ligne 5 et colonne 5. On peut se dire qu’il suffit de mettre la ligne 5 à l’état HIGH et la colonne 5 à l’état LOW avec la résistance de limitation de courant en série, mais on se rend compte que les LED situées ligne 3, colonne 5 et ligne 5, colonnes 3 et 4 s’allument également. Ces LED sont entourées par un cercle sur la figure 3. Or, ce n’est pas ce qu’on veut.
La solution pour se sortir de cette situation est d’allumer alternativement la ligne 3, puis la ligne 5, à une fréquence suffisamment élevée pour que la persistance rétinienne fasse croire qu’elles sont allumées en même temps. En effectuant un balayage à fréquence élevée des lignes de notre matrice de LED, on peut ainsi accéder à toutes les LED. Pour allumer toutes les LED d’une ligne, il suffit de mettre la broche de la ligne à l’état HIGH et toutes les broches des colonnes à l’état LOW, avec des résistances de limitation de courant en série sur chaque broche de colonne. La broche d’Arduino reliée à la ligne de la matrice doit fournir suffisamment de courant pour alimenter toutes les LED, or cette broche est limitée à 40 mA maximum et on conseille de se limiter à 20 mA seulement. Avec cette dernière valeur, cela représente 2,5 mA par LED si on allume 8 LED et 3 mA si on n’allume que 7 LED, comme dans le cas de notre croix de pharmacie et ainsi la limitation du microcontrôleur n’est pas dépassée.
Calcul des résistances de limitation
Le calcul des résistances de limitation de courant est très simple car comme le balayage de la matrice se fait ligne par ligne, à tout moment il n’y a qu’une seule LED allumée par colonne. La tension aux bornes d’une LED verte est de 2,1 V et de 1,85 V aux bornes d’une LED rouge d’après la datasheet du composant 1588ASRG. Pour que le courant soit de 3 mA dans les LED, il faut une résistance de 967 Ω pour une LED verte et 1050 Ω pour une rouge. On optera pour des résistances de 1 kΩ. La luminosité de la LED est suffisante bien que le courant qui la traverse ne fasse que 3 mA.
Fréquence de balayage des lignes
Pour utiliser la persistance rétinienne, on peut partir de la fréquence des images de télévision, soit 25 images par seconde. Cela veut dire que l’ensemble de la matrice de 8 par 8 doit être balayée en 40 ms ou encore qu’une ligne reste allumée seulement 5 ms. Une ligne est donc allumée pendant 5 ms puis éteinte pendant 35 ms. Un essai avec la LED incluse sur le module UNO montre un scintillement de cette dernière avec ces valeurs. Si on monte à 30 images par seconde, la ligne reste allumée 4 ms puis éteinte pendant 29 ms (les nombres sont arrondis) et le scintillement devient imperceptible. Sur la matrice de LED reliées à des résistances de 1 kΩ, il faut au moins 40 images par seconde pour ne plus voir de scintillement. Dans ce cas, les LED restent allumées 3 ms et éteintes 22 ms.
Le principe de balayage est assez simple : on met la première ligne à l’état HIGH et les colonnes nécessaires à l’état LOW, les autres colonnes étant à l’état HIGH, ce qui allume les LED voulues, on attend 3 ms, puis on éteint tout (toutes les colonnes à l’état HIGH) et on passe à la ligne suivante pour faire de même. Lorsque la dernière ligne a effectué son cycle d’allumage, on revient à la première ligne.
Toutes les LED qu’on veut allumer sur une même ligne doivent être commandées en même temps. Pour cette raison, on ne peut pas utiliser la fonction digitalWrite() d’Arduino qui ne s’applique qu’à une seule sortie à la fois. Pour commander les sorties de la carte Arduino, il faut agir directement sur les ports d’entrée-sortie du microcontrôleur (des E/S fonctionnant ensemble). Les sorties d’Arduino reliées aux colonnes de la matrice doivent donc appartenir au même port d’entrée-sortie de la carte Arduino UNO.
Les ports de la carte Arduino UNO
La carte Arduino UNO est construite autour du microcontrôleur ATmega328. Comme le montre la figure 4, nous trouvons trois ports appelés respectivement B (entouré en vert), C (entouré en bleu), et D (entouré en orange). Certaines lignes de certains ports servent à des fonctions particulières (Reset (entouré en violet), et cristal de quartz (PB6 et PB7)). Face aux broches du microcontrôleur, on trouve la correspondance en rouge des broches d’E/S du module UNO, ce qui permet de voir que la carte UNO dispose de vingt entrées-sorties (8 du port D, 6 du port C et 6 du port B). C’est donc les 8 E/S du port D (digital pin 0 à 7 de la carte UNO) que nous connecterons aux 8 colonnes de notre matrice de LED.
Affichage d’un motif sur la matrice
Comme on n’utilise que 7 lignes et 7 colonnes de la matrice, un motif est représentable par un carré de 49 pixels, chaque pixel étant une LED allumée ou non. On peut représenter une LED allumée avec un 0 (car il faut un état LOW sur la colonne) et éteinte avec un 1. Par exemple, si on souhaite allumer toute la ligne 3 et la colonne 3, notre motif est représenté comme cela :
1 1 0 1 1 1 1
1 1 0 1 1 1 1
0 0 0 0 0 0 0
1 1 0 1 1 1 1
1 1 0 1 1 1 1
1 1 0 1 1 1 1
1 1 0 1 1 1 1
Chaque ligne de ce motif est exactement ce qui doit être écrit en binaire sur le port D pour que les colonnes de la matrice soient à l’état LOW pour allumer les LED adéquates. Pour afficher le motif sur la matrice, il suffit de le reconstituer ligne par ligne comme on l’a vu plus haut, en entrant à chaque fois la bonne valeur en binaire sur le port D. Le digit le plus à droite de cette valeur en binaire correspond au bit 0 du port D, et est relié à la colonne 7 de la matrice. Le bit 7 du port D n’est pas utilisé puisqu’on se limite à 7 colonnes.
Pour écrire une valeur binaire sur le port D, il suffit d’écrire :
PORTD = 0b1101111 ;
Ici, l’exemple reprend la première ligne du motif représenté ci-dessus.
Réalisation d’une animation lumineuse sur la croix
Pour réaliser une animation lumineuse sur la croix, il suffit d’afficher plusieurs images les unes après les autres, comme le fait un film. La principale difficulté est de coder ces différentes images sans se tromper, comme cela a été expliqué au paragraphe précédent. La figure 5 montre les différentes images qui tracent le contour de la croix à partir de quatre points différents. Il ne faut que six images pour tracer tout le contour alors qu’il en aurait fallu quatre fois plus si le tracé ne partait que d’un seul point du contour.
Pour modifier la rapidité de l’animation, il suffit de jouer sur la durée d’affichage de chaque image. Pour cette raison, cette valeur n’est pas donnée sous forme numérique : on utilise une variable déclarée en début de programme, ce qui est plus facile à modifier si on veut accélérer ou ralentir le rythme. Si vous voulez profiter du dessin créé par l’animation, il faut penser à afficher plus longtemps la dernière image. Par exemple, pour l’animation de la figure 5, chaque image de 1 à 5 est affichée 50 ms, ce qui donne un rythme d’animation élevé, mais la dernière image (image 6) est affichée 500 ms.
Montage n’utilisant que les LED vertes d’une matrice 1588ASRG
La figure 6 montre le brochage de la matrice de LED 1588ASRG. Si on tient le composant pour avoir l’inscription 1588ASRG en bas et qu’on le regarde du côté LED, la broche 1 (V8) est située dans le coin inférieur gauche. On voit que les 24 broches (rectangles blancs) sont organisées en trois groupes de huit ; les lignes sont repérées par la lettre V (rectangle bleu), les colonnes par G pour les LED vertes (rectangle vert) ou R pour les LED rouges (rectangle rouge). Nous avons donc la correspondance broches-matrice mais si vous utilisez une autre référence de matrice de LED, il vous faudra déterminer le brochage du composant en examinant sa notice comme nous l’avons déjà dit.
La figure 7 montre comment relier Arduino et la matrice de LED si on n’utilise que les LED vertes d’une matrice 1588ASRG. Les 7 colonnes de la matrice sont reliées aux E/S numériques 0 à 6 de la carte UNO (7 lignes du port D). Les 7 lignes de la matrice sont reliées aux sorties numériques 8 à 13 ainsi qu’à la broche A0. Cette dernière, bien que ça ne soit pas inscrit sur la carte, porte le numéro 14 [1].
La figure 7bis montre comment relier Arduino et n’importe quelle matrice de LED. Le tableau ci-dessous donne la correspondance broches-lignes-colonnes de la matrice de LED A-788BPG plus adaptée à l’échelle H0. Pour cette matrice, la broche 1 est celle qui se trouve la plus à gauche quand on regarde la face où est inscrite la référence du composant. Si vous voulez utiliser d’autres matrices, il vous faudra reconstituer ce tableau en vous basant sur les indications de datasheet.
Ligne ou colonne | Broche |
---|---|
colonne 1 | 13 |
colonne 2 | 3 |
colonne 3 | 4 |
colonne 4 | 10 |
colonne 5 | 6 |
colonne 6 | 11 |
colonne 7 | 15 |
colonne 8 | 16 |
Ligne 1 | 9 |
Ligne 2 | 14 |
Ligne 3 | 8 |
Ligne 4 | 12 |
Ligne 5 | 1 |
Ligne 6 | 7 |
Ligne 7 | 2 |
Ligne 8 | 5 |
La figure 8 montre un prototype monté avec deux petites breadboards recevant les broches de la matrice de LED et fixées à l’adhésif double face sur une petite plaque d’époxy. On voit l’inscription 1588ASRG au bas du composant ce qui permet de repérer la broche 1 : le fil jaune qui part de la sortie A0 de la carte UNO relie la broche 2 (V7 ou encore ligne 7).
Le programme
Le programme ci-dessous donne un exemple d’animation de croix de pharmacie dont vous pouvez vous inspirer pour créer votre propre animation. Les motifs sont définis au début sous la forme de matrices binaires. La fonction affiche(,)
réalise l’affichage d’un motif sur la matrice pendant un certain temps (variable « duree »). La fonction loop()
utilise la fonction affiche(,)
pour reproduire les motifs sur la matrice de LED les uns après les autres, un peu comme les images d’un film qui se succèdent pour créer le mouvement. Le programme est très bien commenté et sa compréhension ne devrait pas poser de problème.
/* Ce programme réalise une animation de plusieurs motifs sur une matrice de LED
* par un balayage de lignes à la fréquence de 40 images par seconde.
* Dispose d'une animation complexe à 33 motifs et une à 35 motifs.
* Premier motif : remplissage centre vers extérieur
* Dernier motif : remplissage en diagonal
* Colonnes de matrice : broches 0 à 6
* Lignes de matrice : broches 8 à 14 (A0)
* résistances de limitation de courant : 1 kilo
* ------------------------------------------------------------------------------
* Version 9 - 11 mars 2018
* ------------------------------------------------------------------------------
*/
// Déclaration des variables
static const unsigned long dureeBarres = 200; // en millisecondes
static const unsigned long dureeBord = 50;
static const unsigned long dureeCentre = 100;
static const unsigned long dureeSpiral = 50;
static const unsigned long dureeCarre = 50;
static const unsigned long dureeBranche = 100;
static const unsigned long dureeCligno = 100;
static const unsigned long dureeDiago = 50;
// Les motifs de barre horizontale et verticale
const byte barres01[7] = {0b1101111, 0b1101111, 0b0000000, 0b1101111, 0b1101111, 0b1101111, 0b1101111};
const byte barres02[7] = {0b1110111, 0b1110111, 0b1110111, 0b0000000, 0b1110111, 0b1110111, 0b1110111};
const byte barres03[7] = {0b1111011, 0b1111011, 0b1111011, 0b1111011, 0b0000000, 0b1111011, 0b1111011};
// Les motifs de tracé des bords
const byte bord1[7] = {0b1101111, 0b1111111, 0b1111110, 0b1111111, 0b0111111, 0b1111111, 0b1111011};
const byte bord2[7] = {0b1100111, 0b1111111, 0b1111110, 0b0111110, 0b0111111, 0b1111111, 0b1110011};
const byte bord3[7] = {0b1100011, 0b1111111, 0b0111110, 0b0111110, 0b0111110, 0b1111111, 0b1100011};
const byte bord4[7] = {0b1100011, 0b1111011, 0b0011110, 0b0111110, 0b0111100, 0b1101111, 0b1100011};
const byte bord5[7] = {0b1100011, 0b1111011, 0b0001010, 0b0111110, 0b0101000, 0b1101111, 0b1100011};
const byte bord6[7] = {0b1100011, 0b1101011, 0b0001000, 0b0111110, 0b0001000, 0b1101011, 0b1100011};
// Le motifs de remplissage depuis le centre vers l'extérieur
const byte centre1[7] = {0b1111111, 0b1111111, 0b1111111, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte centre2[7] = {0b1111111, 0b1111111, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte centre3[7] = {0b1111111, 0b1100011, 0b1000001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte centre4[7] = {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
// Les motifs de remplissage par mouvement en spiral depuis le centre
const byte spiral01[7] = {0b1111111, 0b1111111, 0b1111111, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte spiral02[7] = {0b1111111, 0b1111111, 0b1110111, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte spiral03[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte spiral04[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1111111, 0b1111111, 0b1111111};
const byte spiral05[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1111011, 0b1111111, 0b1111111};
const byte spiral06[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1110011, 0b1111111, 0b1111111};
const byte spiral07[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral08[7] = {0b1111111, 0b1111111, 0b1110011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral09[7] = {0b1111111, 0b1111111, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral10[7] = {0b1111111, 0b1101111, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral11[7] = {0b1111111, 0b1100111, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral12[7] = {0b1111111, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral13[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte spiral14[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1100011, 0b1111111, 0b1111111};
const byte spiral15[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1100001, 0b1111111, 0b1111111};
const byte spiral16[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1100001, 0b1111011, 0b1111111};
const byte spiral17[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1100001, 0b1110011, 0b1111111};
const byte spiral18[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1100001, 0b1100011, 0b1111111};
const byte spiral19[7] = {0b1111111, 0b1100011, 0b1100001, 0b1100001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral20[7] = {0b1111111, 0b1100011, 0b1100001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral21[7] = {0b1111111, 0b1100011, 0b1000001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral22[7] = {0b1101111, 0b1100011, 0b1000001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral23[7] = {0b1100111, 0b1100011, 0b1000001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral24[7] = {0b1100011, 0b1100011, 0b1000001, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral25[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000001, 0b1000001, 0b1100011, 0b1111111};
const byte spiral26[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000001, 0b1100011, 0b1111111};
const byte spiral27[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000000, 0b1100011, 0b1111111};
const byte spiral28[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000000, 0b1100011, 0b1111011};
const byte spiral29[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000000, 0b1100011, 0b1110011};
const byte spiral30[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000000, 0b1100011, 0b1100011};
const byte spiral31[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b0000000, 0b1100011, 0b1100011};
const byte spiral32[7] = {0b1100011, 0b1100011, 0b1000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
const byte spiral33[7] = {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
// Les motifs de remplissage par carré
const byte carre01[7] = {0b1111111, 0b1111111, 0b1111111, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte carre02[7] = {0b1111111, 0b1111111, 0b1110111, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte carre03[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110111, 0b1111111, 0b1111111, 0b1111111};
const byte carre04[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1111111, 0b1111111, 0b1111111};
const byte carre05[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1111011, 0b1111111, 0b1111111};
const byte carre06[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1110011, 0b1111111, 0b1111111};
const byte carre07[7] = {0b1111111, 0b1111111, 0b1110011, 0b1110011, 0b1100011, 0b1111111, 0b1111111};
const byte carre08[7] = {0b1111111, 0b1111111, 0b1110011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre09[7] = {0b1111111, 0b1111111, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre10[7] = {0b1111111, 0b1111011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre11[7] = {0b1111111, 0b1110011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre12[7] = {0b1111111, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre13[7] = {0b1101111, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre14[7] = {0b1100111, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre15[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte carre16[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100001, 0b1111111, 0b1111111};
const byte carre17[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100001, 0b1100001, 0b1111111, 0b1111111};
const byte carre18[7] = {0b1100011, 0b1100011, 0b1100001, 0b1100001, 0b1100001, 0b1111111, 0b1111111};
const byte carre19[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100001, 0b1100001, 0b1111111, 0b1111111};
const byte carre20[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100001, 0b1111111, 0b1111111};
const byte carre21[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1111111, 0b1111111};
const byte carre22[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1101111, 0b1111111};
const byte carre23[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1100111, 0b1111111};
const byte carre24[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1100011, 0b1111111};
const byte carre25[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1100011, 0b1111011};
const byte carre26[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1100011, 0b1110011};
const byte carre27[7] = {0b1100011, 0b1100011, 0b1100000, 0b1100000, 0b1100000, 0b1100011, 0b1100011};
const byte carre28[7] = {0b1100011, 0b1100011, 0b1000000, 0b1100000, 0b1100000, 0b1100011, 0b1100011};
const byte carre29[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1100000, 0b1100011, 0b1100011};
const byte carre30[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b1000000, 0b1100011, 0b1100011};
const byte carre31[7] = {0b1100011, 0b1100011, 0b1000000, 0b1000000, 0b0000000, 0b1100011, 0b1100011};
const byte carre32[7] = {0b1100011, 0b1100011, 0b1000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
const byte carre33[7] = {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
// Les motifs de remplissage par branches verticale horizontale
const byte branche01[7] = {0b1100011, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte branche02[7] = {0b1100011, 0b1100011, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte branche03[7] = {0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte branche04[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111, 0b1111111};
const byte branche05[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111, 0b1111111};
const byte branche06[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1111111};
const byte branche07[7] = {0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011, 0b1100011};
const byte branche08[7] = {0b1100011, 0b1100011, 0b0100011, 0b0100011, 0b0100011, 0b1100011, 0b1100011};
const byte branche09[7] = {0b1100011, 0b1100011, 0b0000011, 0b0000011, 0b0000011, 0b1100011, 0b1100011};
const byte branche10[7] = {0b1100011, 0b1100011, 0b0000001, 0b0000001, 0b0000001, 0b1100011, 0b1100011};
const byte branche11[7] = {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
// Les motifs de clignotement bord-centre
const byte bord[7] = {0b1100011, 0b1101011, 0b0001000, 0b0111110, 0b0001000, 0b1101011, 0b1100011};
const byte centre[7] = {0b1111111, 0b1110111, 0b1110111, 0b1000001, 0b1110111, 0b1110111, 0b1111111};
// Les motifs de remplissage en diagonale
const byte diago01[7]= {0b1101111, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago02[7]= {0b1101111, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago03[7]= {0b1101111, 0b1111111, 0b0111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago04[7]= {0b1100111, 0b1111111, 0b0111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago05[7]= {0b1100111, 0b1101111, 0b0111111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago06[7]= {0b1100111, 0b1101111, 0b0011111, 0b1111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago07[7]= {0b1100111, 0b1101111, 0b0011111, 0b0111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago08[7]= {0b1100011, 0b1101111, 0b0011111, 0b0111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago09[7]= {0b1100011, 0b1100111, 0b0011111, 0b0111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago10[7]= {0b1100011, 0b1100111, 0b0001111, 0b0111111, 0b1111111, 0b1111111, 0b1111111};
const byte diago11[7]= {0b1100011, 0b1100111, 0b0001111, 0b0011111, 0b1111111, 0b1111111, 0b1111111};
const byte diago12[7]= {0b1100011, 0b1100111, 0b0001111, 0b0011111, 0b0111111, 0b1111111, 0b1111111};
const byte diago13[7]= {0b1100011, 0b1100011, 0b0001111, 0b0011111, 0b0111111, 0b1111111, 0b1111111};
const byte diago14[7]= {0b1100011, 0b1100011, 0b0000111, 0b0011111, 0b0111111, 0b1111111, 0b1111111};
const byte diago15[7]= {0b1100011, 0b1100011, 0b0000111, 0b0001111, 0b0111111, 0b1111111, 0b1111111};
const byte diago16[7]= {0b1100011, 0b1100011, 0b0000111, 0b0001111, 0b0011111, 0b1111111, 0b1111111};
const byte diago17[7]= {0b1100011, 0b1100011, 0b0000011, 0b0001111, 0b0011111, 0b1111111, 0b1111111};
const byte diago18[7]= {0b1100011, 0b1100011, 0b0000011, 0b0000111, 0b0011111, 0b1111111, 0b1111111};
const byte diago19[7]= {0b1100011, 0b1100011, 0b0000011, 0b0000111, 0b0001111, 0b1111111, 0b1111111};
const byte diago20[7]= {0b1100011, 0b1100011, 0b0000001, 0b0000111, 0b0001111, 0b1111111, 0b1111111};
const byte diago21[7]= {0b1100011, 0b1100011, 0b0000001, 0b0000011, 0b0001111, 0b1111111, 0b1111111};
const byte diago22[7]= {0b1100011, 0b1100011, 0b0000001, 0b0000011, 0b0000111, 0b1111111, 0b1111111};
const byte diago23[7]= {0b1100011, 0b1100011, 0b0000001, 0b0000011, 0b0000111, 0b1101111, 0b1111111};
const byte diago24[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000011, 0b0000111, 0b1101111, 0b1111111};
const byte diago25[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000001, 0b0000111, 0b1101111, 0b1111111};
const byte diago26[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000001, 0b0000011, 0b1101111, 0b1111111};
const byte diago27[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000001, 0b0000011, 0b1100111, 0b1111111};
const byte diago28[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000001, 0b0000011, 0b1100111, 0b1101111};
const byte diago29[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000011, 0b1100111, 0b1101111};
const byte diago30[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000001, 0b1100111, 0b1101111};
const byte diago31[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000001, 0b1100011, 0b1101111};
const byte diago32[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000001, 0b1100011, 0b1100111};
const byte diago33[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100111};
const byte diago34[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100111};
const byte diago35[7]= {0b1100011, 0b1100011, 0b0000000, 0b0000000, 0b0000000, 0b1100011, 0b1100011};
void setup() {
// On met toutes les broches en sorties
for (int broche=0; broche<=14; broche++){
pinMode (broche, OUTPUT);
} // fin boucle for
// On met les lignes de la matrice à l'état LOW
for (int ligne=1; ligne<=7; ligne++){
digitalWrite(ligne+7, LOW); // N° broche = N° ligne + 7
} // fin boucle for N°2
// On met les colonnes à l'état HIGH
PORTD = 0b11111111;
} // fin de setup
void affiche(const byte motif[7], const unsigned long duree){
// Réalise l'affichage d'un motif sur la matrice pendant un certain temps (duree)
unsigned long topDuree;
topDuree = millis();
while(millis() - topDuree < duree){
// tant que la durée n'est pas réalisée, on affiche une trame de 7 lignes
for(int ligne=1; ligne<=7; ligne++){
// On met la broche à l'état HIGH. N° broche = N° ligne + 7
digitalWrite(ligne+7, HIGH);
// On met les colonnes comme il se doit
PORTD = motif[ligne-1]; // la première ligne est l'indice 0 du tableau !
delay(3);
// On éteint la ligne avant de passer à la suivante
digitalWrite(ligne+7, LOW);
PORTD = 0b11111111; // On met les colonnes à l'état HIGH
} // fin de boucle for
} // fin du while
} // fin de la fonction affiche
void loop() {
// On appelle la fonction affiche avec les motifs et pour la durée d'affichage
for(int i=1; i<=3; i++){
// Remplissage depuis le centre vers l'extérieur
affiche(centre1, dureeCentre);
affiche(centre2, dureeCentre);
affiche(centre3, dureeCentre);
affiche(centre4, 200);
affiche(centre3, dureeCentre);
affiche(centre2, dureeCentre);
affiche(centre1, dureeCentre);
} // fin de boucle for
affiche(centre1, dureeCentre);
affiche(centre2, dureeCentre);
affiche(centre3, dureeCentre);
affiche(centre4, 1000);
for(int i=1; i<=3; i++){
// Barre horizontale et verticale oscillantes
affiche(barres01, dureeBarres);
affiche(barres02, dureeBarres);
affiche(barres03, dureeBarres);
affiche(barres02, dureeBarres);
} // fin de boucle for
delay(500);
for(int i=1; i<=3; i++){
// Tracé des bords de la croix
affiche(bord1, dureeBord);
affiche(bord2, dureeBord);
affiche(bord3, dureeBord);
affiche(bord4, dureeBord);
affiche(bord5, dureeBord);
affiche(bord6, 500);
} // fin de boucle for
affiche(bord6, 2000);
delay(500);
// Remplissage par carrés
affiche(carre01, dureeCarre);
affiche(carre02, dureeCarre);
affiche(carre03, dureeCarre);
affiche(carre04, dureeCarre);
affiche(carre05, dureeCarre);
affiche(carre06, dureeCarre);
affiche(carre07, dureeCarre);
affiche(carre08, dureeCarre);
affiche(carre09, dureeCarre);
affiche(carre10, dureeCarre);
affiche(carre11, dureeCarre);
affiche(carre12, dureeCarre);
affiche(carre13, dureeCarre);
affiche(carre14, dureeCarre);
affiche(carre15, dureeCarre);
affiche(carre16, dureeCarre);
affiche(carre17, dureeCarre);
affiche(carre18, dureeCarre);
affiche(carre19, dureeCarre);
affiche(carre20, dureeCarre);
affiche(carre21, dureeCarre);
affiche(carre22, dureeCarre);
affiche(carre23, dureeCarre);
affiche(carre24, dureeCarre);
affiche(carre25, dureeCarre);
affiche(carre26, dureeCarre);
affiche(carre27, dureeCarre);
affiche(carre28, dureeCarre);
affiche(carre29, dureeCarre);
affiche(carre30, dureeCarre);
affiche(carre31, dureeCarre);
affiche(carre32, dureeCarre);
affiche(carre33, 2000);
delay(500);
for(int i=1; i<=3; i++){
// Clignotement des bords de la croix
affiche(bord6, 500);
delay(500);
} // Fin de boucle for
affiche(bord6, 2000);
delay(500);
// Remplissage depuis le centre en spirale
affiche(spiral01, dureeSpiral);
affiche(spiral02, dureeSpiral);
affiche(spiral03, dureeSpiral);
affiche(spiral04, dureeSpiral);
affiche(spiral05, dureeSpiral);
affiche(spiral06, dureeSpiral);
affiche(spiral07, dureeSpiral);
affiche(spiral08, dureeSpiral);
affiche(spiral09, dureeSpiral);
affiche(spiral10, dureeSpiral);
affiche(spiral11, dureeSpiral);
affiche(spiral12, dureeSpiral);
affiche(spiral13, dureeSpiral);
affiche(spiral14, dureeSpiral);
affiche(spiral15, dureeSpiral);
affiche(spiral16, dureeSpiral);
affiche(spiral17, dureeSpiral);
affiche(spiral18, dureeSpiral);
affiche(spiral19, dureeSpiral);
affiche(spiral20, dureeSpiral);
affiche(spiral21, dureeSpiral);
affiche(spiral22, dureeSpiral);
affiche(spiral23, dureeSpiral);
affiche(spiral24, dureeSpiral);
affiche(spiral25, dureeSpiral);
affiche(spiral26, dureeSpiral);
affiche(spiral27, dureeSpiral);
affiche(spiral28, dureeSpiral);
affiche(spiral29, dureeSpiral);
affiche(spiral30, dureeSpiral);
affiche(spiral31, dureeSpiral);
affiche(spiral32, dureeSpiral);
affiche(spiral33, 2000);
delay(500);
// Remplissage par branches verticale puis horizontale
affiche(branche01, dureeBranche);
affiche(branche02, dureeBranche);
affiche(branche03, dureeBranche);
affiche(branche04, dureeBranche);
affiche(branche05, dureeBranche);
affiche(branche06, dureeBranche);
affiche(branche07, dureeBranche);
affiche(branche08, dureeBranche);
affiche(branche09, dureeBranche);
affiche(branche10, dureeBranche);
affiche(branche11, 2000);
delay(500);
// Clignotement bord-centre
for(int i=1; i<=10; i++){
affiche(bord, dureeCligno);
affiche(centre, dureeCligno);
} // Fin de boucle i
affiche(bord, 2000);
delay(500);
// Remplissage en diagonale
affiche(diago01, dureeDiago);
affiche(diago02, dureeDiago);
affiche(diago03, dureeDiago);
affiche(diago04, dureeDiago);
affiche(diago05, dureeDiago);
affiche(diago06, dureeDiago);
affiche(diago07, dureeDiago);
affiche(diago08, dureeDiago);
affiche(diago09, dureeDiago);
affiche(diago10, dureeDiago);
affiche(diago11, dureeDiago);
affiche(diago12, dureeDiago);
affiche(diago13, dureeDiago);
affiche(diago14, dureeDiago);
affiche(diago15, dureeDiago);
affiche(diago16, dureeDiago);
affiche(diago17, dureeDiago);
affiche(diago18, dureeDiago);
affiche(diago19, dureeDiago);
affiche(diago20, dureeDiago);
affiche(diago21, dureeDiago);
affiche(diago22, dureeDiago);
affiche(diago23, dureeDiago);
affiche(diago24, dureeDiago);
affiche(diago25, dureeDiago);
affiche(diago26, dureeDiago);
affiche(diago27, dureeDiago);
affiche(diago28, dureeDiago);
affiche(diago29, dureeDiago);
affiche(diago30, dureeDiago);
affiche(diago31, dureeDiago);
affiche(diago32, dureeDiago);
affiche(diago33, dureeDiago);
affiche(diago34, dureeDiago);
affiche(diago35, 2000);
delay(500);
} // fin de loop
Pour le télécharger, c’est ici :
Modification du programme pour une matrice de LED à cathodes communes
Reprenons la figure 3 et imaginons que nos LED soient inversées (cathodes communes sur les lignes). Dans ce cas, c’est un niveau bas L (au lieu de H) qu’il faut appliquer à la ligne et un niveau haut H (au lieu de L) qu’il faut appliquer à la colonne pour allumer la LED.
Le balayage se fera toujours sur les lignes, mais avec un niveau LOW et l’affichage de toute la ligne (donc les différentes colonnes) se fera avec un niveau HIGH. Il suffit de changer tout cela dans la fonction affiche(,). Oui mais dans ce cas, faut-il réécrire les motifs en changeant les 0 en 1 et les 1 en 0 ?
Heureusement non ! D’ailleurs, ce serait assez fastidieux alors que le programme peut s’en charger pour nous grâce à l’opérateur bitwise NOT (noté par un tilda) dont la propriété est d’inverser tous les bits d’une donnée binaire (les 0 sont remplacés par 1 et réciproquement). La référence de l’opérateur bitwise NOT est donnée ICI.
Voici les changements à faire dans le programme si votre matrice est à cathodes communes sur les lignes :
Dans le setup, on met les lignes de la matrice à l’état HIGH au lieu de LOW (ligne 180) et les colonnes à l’état LOW au lieu de HIGH (ligne 183).
Dans la fonction affiche(,), à la ligne 194, on commande la ligne par un état LOW et à la ligne 196, on utilise l’opérateur bitwise NOT (le caractère tilda est obtenu avec Alt Gr + 2) ce qui fait que chaque bit du motif est inversé (0 au lieu de 1 et 1 au lieu de 0). Les lignes 199 et 200 sont également changées pour normaliser la matrice en fin de traitement.
Finalement, voici la nouvelle fonction affiche(,) qui doit être mise à la place de celle figurant dans le programme que vous avez téléchargé grâce au lien donné ci-dessus (en plus des deux changements dans le setup) :
void affiche(const byte motif[7], const unsigned long duree){
// Réalise l'affichage d'un motif sur la matrice pendant un certain temps (duree)
unsigned long topDuree;
topDuree = millis();
while(millis() - topDuree < duree){
// tant que la durée n'est pas réalisée, on affiche une trame de 7 lignes
for(int ligne=1; ligne<=7; ligne++){
// On met la broche à l'état LOW. N° broche = N° ligne + 7
digitalWrite(ligne+7, LOW);
// On met les colonnes comme il se doit
PORTD = ~motif[ligne-1]; // la première ligne est l'indice 0 du tableau !
delay(3);
// On éteint la ligne avant de passer à la suivante
digitalWrite(ligne+7, HIGH);
PORTD = 0b00000000; // On met les colonnes à l'état LOW
} // fin de boucle for
} // fin du while
} // fin de la fonction affiche
Intégration de la croix dans le bâtiment
En général, les croix de pharmacie sont posées perpendiculairement à la façade du bâtiment mais il arrive parfois qu’elles soient simplement posées sur le mur. C’est ce que nous allons faire pour cette croix qui est illuminée de toute façon sur une seule face. Commencez par ouvrir le mur de la pharmacie par une ouverture en forme de croix dont les dimensions, qui dépendent de la matrice que vous avez choisie, suivent le contour rouge de la figure 1. Collez votre matrice de LED derrière le mur et un entourage de la croix sur le côté extérieur du mur. Peignez cet entourage en vert foncé. Pour ne pas voir les LED lorsqu’elles sont éteintes, collez sur cet entourage une feuille de plastique dépoli comme un papier calque (mais ne pas utiliser de papier calque trop sensible à l’hygrométrie de l’air).
Reliez ensuite les broches de la matrice de LED à votre Arduino en utilisant des câbles de liaison pour le prototypage (mâle-mâle et mâle-femelle) ou mieux des nappes de câbles multi-couleurs et des résistances de 1 kΩ (quelques soudures sont nécessaires). Si vous voulez décorer l’intérieur de la pharmacie, cachez la carte Arduino dans le toit du bâtiment et arrangez-vous pour cacher le fil d’alimentation en le faisant descendre le long d’un angle pour qu’il ne se remarque pas. Arrangez-vous tout de même pour laisser accessible la prise jack (si vous alimentez la carte Arduino par ce moyen) et la prise USB (ce qui permet de modifier le programme où d’alimenter la carte Arduino). La figure 9 montre l’ensemble du montage intégré dans le bâtiment : remarquez les rideaux en papier de soie ou papier calque qui masque cette électronique lorsqu’on regarde le bâtiment de l’extérieur.
Amélioration de ce montage
Si vous estimez que la luminosité des LED est insuffisante, vous pouvez amplifier le courant sur les lignes de la matrice avec des transistors qui amplifieront les signaux des sorties d’Arduino (8 à 13 plus A0). Ceci vous permet alors de changer les résistances de 1 kΩ par des résistances plus faibles calculées en fonction du courant que vous voulez faire passer.
Enfin, si vous utilisez une matrice de LED bicolores (cas de la matrice 1588ASRG), vous pouvez commander chaque LED soit en vert, soit en rouge, voire même les deux couleurs en même temps ce qui vous donnera du jaune. L’animation lumineuse n’en sera évidemment que plus belle (en trois couleurs) mais nécessitera un nombre plus important de broches de commande et il devient alors nécessaire d’utiliser une carte MEGA à la place de la carte UNO. En effet, il faut 21 sorties pour commander toutes les LED bicolores d’une matrice de 7 x 7, 14 si on se limite uniquement aux LED vertes, et 17 si on rajoute la couleur rouge pour le cœur de la croix uniquement (3 x 3 LED). Les deux dernières options tiennent sur une carte Arduino UNO qui dispose de 20 E/S numériques mais une carte Arduino MEGA est indispensable pour commander la totalité des 64 LED bicolores.
Faites jouer votre imagination et votre sens artistique
À vous de modifier le programme donné en exemple afin de personnaliser votre croix de pharmacie. Les plus belles animations sont celles qui font appel à un nombre élevé d’images. Cela peut paraître fastidieux de coder ces différentes images en matrices binaires, mais en prenant votre temps et en vérifiant bien ce que vous faites, vous finirez par y arriver. Votre sens artistique vous permettra de dynamiser le rythme des séquences et de les enchaîner les unes aux autres pour obtenir un résultat qui vous plaît. Quelle satisfaction ensuite quand l’animation se déroule sur votre croix de pharmacie et quelle fierté de posséder une croix qui est unique. C’est un des avantages du DIY (Do It Yourself ou faites-le vous-même) qui permet de créer ce qui n’existe pas dans le commerce.
[1] Les broches dites analogiques sont également des E/S numériques (sauf A6 et A7 sur une carte Nano) portant les numéros 14 (A0) à 19 (A5)