Toute la partie qui suit dans ce chapitre, peut être zappée par ceux qui veulent juste utiliser le programme tel quel.
Il faudra juste vérifier les n° des broches utilisées en fonction de votre montage électronique.
ORGANISATION DE LA GRILLE[0]
L'affichage des LEDs est représenté en mémoire par un tableau de 8x8 octets (GRILLE). Un octet représente une colonne de 8 LEDs. Le bit de poids le +faible correspond à La LED la + basse. L'origine de notre grille est donc [0,0] en bas à gauche, la LED en haut à droite est codée [7,7].
TABLEAUX INTERNES AUX ARDUINO
Le module dispose de 3 zones de mémoires :
1/ Pour l'affichage des LEDs une grille[0] de 8x8 octets est nécessaire, on vient de le voir, celle-ci est accompagnée de 15 autres grilles[1 à15] qui seront affichées en fonction d'un paramètre de sélection de grille.
Il sera possible de charger chacune des 15 grilles et d'en afficher le contenu à la demande.
2/ Une zone de mémoire de données de 15x32 octets, qui correspond à 15 cellules de 32 octets. Ceci sera détaillé +loin.
3/ Une zone tampon (FIFO) de stockage des instructions reçues. En effet comme le Raspi et les Arduino fonctionnent en mode désynchronisé, il est nécessaire de laisser fonctionner chacun à son rythme. Le tampon fonctionne en mode FIFO (First In, First Out) sur 128x3 octets en mode carroussel.
Comme ce tampon FIFO stocke les instructions, j'en profite pour l'utiliser en mémoire "arrière" pour ré-exécuter des commandes déjà passées.
Format et orientation des motifs
| Tableaux internes de l’ATmega GRILLE[16][8]: 16 x 8x8 octets DONNEES[488] : 16 x 4x32 octets (CELLULE = 4 GRILLEs | 10 instructions (+2 octets)) FIFO[128] : 128 x 3 octets (cache)
|
Format des Instructions : [ level, inst.][ P2, P1 ][ P4, P3 ] [ 2 x 4 bits ][2x4bits][2x4bits] [ octet 0 ][ octet 1][ octet 2]
|
COMMUNICATION INTER-MODULES ET Raspberry Pi
J'ai choisi d'utiliser le bus I2C pour communiquer en sens unique depuis le Raspi vers l'Arduino.
Le bus est simple à utiliser, ne nécessite que 2 fils+gnd et permet d'adresser plusieurs dizaines d'équipements.
Le Raspi est paramétré en maître et les Arduino en esclaves. Chaque environnement dispose de bibliothèque facilitant la programmation.
ADRESSAGE
Chaque module 8x8 va donc recevoir une adresse différente que le Raspi utilisera pour dialoguer individuellement avec ceux-ci.
Afin d'éviter que le programme des Arduino ne soit différent pour chaque module, un adressage physique est mis en place et une lecture de cette adresse est faite après chaque reset. J'utilise pour cela, 3 des 8 broches pilotant les cathodes de la grille de LEDs. La lecture de l'état de ces 3 broches ne doit pas déranger l'utilisation par la suite des broches en sortie. Je positionne donc le temps de la lecture, les 3 broches en INPUT, une résistance de 3,3K est connectée ou non au VCC. J'obtiens un 0 ou un 1 en fonction de la présence ou non de la résistance.
Le 1er module ne reçoit aucune résistance, le dernier en a 3. L'adressage démarre à 0x8 et peut atteindre 0xF si les 3 broches sont à 1, chaque broche ayant un poids = 2^n.
Le code de lecture est simple :
const byte CATHODE[8] = {17,15,11,9,5,1,6,0}; // broches utilisées pour les CATHODEs
const byte OffsetAdd = 2; byte I2Caddress=0x8; void setup() { // la présence des straps ajoutent les poids : 4 + 2 + 1
for (byte i=0; i<3; i++) { pinMode(CATHODE[i+OffsetAdd], INPUT_PULLUP); // 3 broches des CATHODES sont utilisées en INPUT juste le temps de lire l'@ du module
I2Caddress = I2Caddress + (digitalRead(CATHODE[i+OffsetAdd]) << i); // n décalage.s à gauche = 1*2^n }
SÉLECTION DES DONNÉES / INSTRUCTIONS
Il est pratique de pouvoir différencier le type d'information envoyé aux Arduino, je vais utiliser pour ça la broche libre 2 (INT 0) :
0 (LOW) ce sont des données
1 (HIGH) ce sont des instructions
Rappelons à ce stade, que tant que le Raspi est en OUTPUT, il envoie un 3V3 sur l'entrée de l'Arduino, ce qui suffit à définir un état 1(HIGH).
DIALOGUE ENTRE MODULES ET RASPBERRY PI
Le Raspi va pouvoir envoyer aux Arduino des instructions codées sur 3 octets maximum. Ceci va permettre de réduire les temps de communication et surtout la quantité de mémoire utilisée de côté des Arduino.
a/ le 1er octet contient sur :
> 4 bits de poids fort, le niveau de grille à afficher
> 4 bits de poids faible, le code d'instruction
b/ les 2 autres octets codés eux aussi sur 2x4 bits, contiendront de 1 à 4 paramètres utiles en fonction des besoins de l'instruction.
(v. tableau ci-dessus)
Le programme IDE Arduino est ici : module8x8.2.ino
Voilà une réalisation d'un bon niveau avec une conception originale et astucieuse.
Le tutoriel est très pédagogique et précisément expliqué, bravo !