SE4 2022/2023 EC4
Objectifs
Il vous est demandé de :
- réaliser des communications SPI entre trois ATMega328p, pour cela vous utiliserez une carte comportant 3 sous-systèmes :
- un sous-système de type Arduino Uno programmable via une puce FTDI,
- un sous-système de gestion d'afficheurs 7 segments par un ATMega328p, programmable via un connecteur AVR-ISP,
- un sous-système de gestion de matrice de LEDs par un ATMega328p, aussi programmable via un connecteur AVR-ISP ;
- commencez par gérer les afficheurs et les pilotes de LED sur les sous-systèmes correspondants ;
- écrivez les fonctions de communication entre les sous-systèmes : le premier sous-système étant le maître SPI ;
- écrivez sur le sous-système maître un programme pour commander les deux autres sous-systèmes en séquence ;
- utilisez l'ordonnanceur implanté en TP, en l'étendant, pour commander les deux autres sous-systèmes par deux tâches concurrentes.
Matériel nécessaire
Vous aurez besoin de la carte de développement cité et d'un Arduino configuré en programmateur AVR ISP.
Le dernier projet sur ce sujet est disponible sur l'ancien Wiki : [1]. Vous y trouverez le schéma et le routage de la carte. Vous y trouverez même des embryons des programmes demandés.
Travail réalisé
Semaine 1
- Jusqu'à présent, je me suis concentré sur le sous-système avec les afficheurs 7 segments :
- Inspection du routage du PCB pour voir comment était câblé le connecteur au µC
- Recherche sur le fonctionnement de la programmation via un connecteur AVR-ISP
- Début de compréhension du code et du makefile
- Pour l'instant je peux sur chacun des afficheurs :
- Afficher le caractère souhaité parmi les caractères hexadécimaux (0 1 2 3 4 5 6 7 8 9 A b C d E F)
- Allumer le point
- Eteindre l'afficheur
ReX : Quel connecteur ? L'AVR-ISP comme mentionné ci-dessous ? C'est standard comme comme câblage ...
Timothé : Oui l'AVR-ISP, je n'avais encore jamais utilisé ce type de connecteur. J'ai donc fait des recherches pour savoir quelles broches étaient utilisées par ces connecteurs, et notamment laquelle de ces broches était relié au 5V de l'ATMega328p sur le PCB, pour éviter de l'envoyer là où il fallait pas et risquer de cramer quelque chose...
ReX : OK pour les fonctionnalités sur les 7 segments.
Timothé : Ok parfait.
- Je suis passé sur le sous-système avec la matrice de LED :
- Inspection du routage du PCB pour voir comment était câblé le deuxième connecteur AVR-ISP au deuxième µC
- Début de compréhension du code et du makefile
- Cependant, j'ai changé la matrice "indirect_matrix". Je l'ai retourné, puis l'ai ensuite pivoté d'un quart de tour vers la droite (Cela permet de l'avoir dans le même sens que les LED sur la carte et dans le sens de lecture des afficheurs 7 segments)
- Ce qui permettra de facilement créer et afficher des caractères sur la matrice de LED
- A ce propos... j'aurais quelques questions sur ce que vous souhaitiez que ces deux sous-systèmes puissent faire :
- Quels caractère souhaitez-vous pour la matrice (par exemple : l'alphabet, les chiffres) ?
- Plus largement, que souhaitez-vous comme fonctionnalités pour la matrice de LED (par exemple : afficher des lettres, afficher des chiffres, faire défiler des messages) ?
- Même question pour les afficheurs 7 segments, que souhaitez-vous comme fonctionnalités (par exemple : compter en décimal, en hexadécimal, faire défiler des chiffres) ?
- Dites moi également si vous préférez que je réserve cet endroit pour le travail réalisé, et que je vous pose uniquement les questions par mail, ou que je fasse une nouvelle rubrique seulement pour les questions de la même manière que pour "Semaine 1".
ReX : Pour ce qui peut être affiché sur la matrice c'est comme vous voulez, soit un caractère alphanumérique centré, soit des caractères alphanumériques avec défilement de gauche à droite soit toute figure possible en 8x8 pixels, ce qui est important c'est que l'ATMega328p puisse commander l'ATMega328p de la matrice et lui faire faire quelque chose.
Timothé : Ok ça marche.
ReX : Idem pour les afficheurs 7 segments, le plus simple étant d'envoyer les 6 "caractères" à afficher.
ReX : Pour l'organisation du Wiki, c'est à vous de décider :)
Timothé : Dans ce cas, je propose que je mette mes questions dans une rubrique à part, et pour le reste nous pouvons continuer d'interagir comme ce qu'on a fait là.
- J'ai commencé à regarder le troisième sous-système qui sera le maitre SPI
- J'ai regardé le makefile et fait quelques recherches sur la façon de programmer ce µC, afin de pouvoir le programmer par la suite via la puce FTDI
- Je suis parvenu à le flasher et à récupérer des messages sur la liaison série avec le PC
- (Dans le sous-système précédent) J'ai créer les caractères A,b,C,d,E,F,G,H,I,J ; qui sont affichable sur la matrice de LED (il est possible d'en créer d'autres facilement)
- Je me suis également penché sur le code de ce sous-système (Maitre SPI)
- J'ai pu constater que la façon de "contrôler" les autres sous-systèmes, n'est pas celle que j'avais imaginée
- Je vais faire des essais pour voir s'il est possible et intéressant de faire ce que j'avais prévu avec la communication SPI (pour contrôler les autres sous-systèmes)
ReX : L'ATMega328p maître était déjà programmable par série (comme un Arduino Uno classique).
Timothé : Oui je m'en suis rendu compte par la suite, j'avais cru comprendre que l'ATMega328p était vide et qu'il fallait commencer par l'amorcer avec l'Arduino uno, afin de pouvoir ensuite le programmer en série. Mais cela avait déjà été fait. Cependant je devrais maintenant savoir le faire si besoin.
ReX : Votre discussion sur le contrôle par SPI n'est pas claire du tout, précisez, comparez des protocoles explicités.
Timothé : En fait, j'avais simplement imaginé envoyer des "ordres" aux autres sous-systèmes au lieu d'envoyer directement ce qu'il devait afficher. Par exemple : envoyer seulement le caractère "A" à l'ATMega328p de la matrice de LED, et non pas le tableau complet contenant le "A" réellement affichable. Il faudrait donc que le sous-système lise le caractère qui lui a été envoyé et l'interprète afin d'afficher ce qui correspond. Je ne sais pas encore si cela est faisable ni si c'est pratique... Je vais essayer. Est-ce mieux expliqué, où pas du tout ?
ReX : OK.
Semaine 2
- J'ai commencé à me pencher plus sur la communication SPI :
- J'ai observé toute la connectique, et repéré où chaque broches des différents connecteurs (J18, J20, J17 et J21) étaient branchées sur les trois ATMega328p
- J'ai pu constater qu'il n'y avait pour aucun des deux sous-systèmes la broche MISO connectée, il n'est donc pas possible pour les deux esclaves d'envoyer des messages au maitre
- Cela paraissait évident, cependant j'ai vérifié quand même, les broches des connecteurs J18/J20 et J17/J21 se faisant face, sont bien connectées de la même manière à leur uC respectifs, à noter que la broche /SS de l'ATMega328p de la matrice de LED, n'est pas connectée à la broche /SS du maitre spi mais à la broche 11 (afin de sélectionner un esclave, le maitre doit avoir autant de broches de /SS que d'esclave, afin de pouvoir les adresser un à un).
ReX : OK. Si vraiment il fallait envoyer des données dans le sens esclaves vers maître, il suffirait de connecter les broches MISO des connecteur AVR-ISP.
Timothé : Oui en effet, nous pouvons passer par les connecteurs AVR-ISP qui sont chacun reliés à la broche MISO de leur ATMega328p.
Questions de la semaine 2
Timothé : Oui l'AVR-ISP, je n'avais encore jamais utilisé ce type de connecteur. J'ai donc fait des recherches pour savoir quelles broches étaient utilisées par ces connecteurs, et notamment laquelle de ces broches était relié au 5V de l'ATMega328p sur le PCB, pour éviter de l'envoyer là où il fallait pas et risquer de cramer quelque chose...
ReX : Si vous l'avez utilisé en tutorat USB en 2022/2023.
Timothé : Dans ce cas, je n'avais pas encore fait le lien entre ce que j'avais utilisé et le fait que c'était un connecteur AVR-ISP...
Timothé : En fait, j'avais simplement imaginé envoyer des "ordres" aux autres sous-systèmes au lieu d'envoyer directement ce qu'il devait afficher. Par exemple : envoyer seulement le caractère "A" à l'ATMega328p de la matrice de LED, et non pas le tableau complet contenant le "A" réellement affichable. Il faudrait donc que le sous-système lise le caractère qui lui a été envoyé et l'interprète afin d'afficher ce qui correspond. Je ne sais pas encore si cela est faisable ni si c'est pratique... Je vais essayer. Est-ce mieux expliqué, où pas du tout ?
ReX : C'est faisable et ça me va aussi.
Timothé : Ok parfait, je vais essayer les deux. Je suis pas encore rendu à l'ordonnancement, mais je me demande si raccourcir le temps de communication pour les ordres SPI, ne pourrait pas aider à avoir quelque chose de plus rapide. Après les différences seront peut-être plus que négligeables...
ReX : Non non c'est une bonne idée de raccourcir les temps de transmission.
Semaine 3
J'ai continué sur la communication SPI :
- Je me suis d'abord penché sur la communication avec le sous-système comportant les afficheurs 7 segments
- J'ai eu un peu plus de mal à mettre cela en place, ce qui m'a finalement débloqué, est de changer la fréquence de l'horloge cadencant la communication, je l'ai finalement fixée à la fréquence du µC divisé par 64 (avec une fréquence plus élevée la communication cesse de fonctionner)
- Je peux désormais ordonner l'affichage d'un tableau au sous-système des afficheurs 7 segments depuis le sous-système maître
- J'ai également commencé la programmation de la communication SPI avec le deuxième sous-système
- La matrice est capable d'afficher n'importe quelle lettre de l'alphabet, il sera donc possible d'afficher des mots (pas de défilement prévu pour l'instant cependant...)
- En revanche, la communication ne passe pas encore sur ce système, je travaille dessus en ce moment
ReX : OK, merci pour le rapport.
- La communication SPI est désormais également fonctionnelle sur la matrice de LEDs (il est possible d'écrire des mots en faisant apparaitre les lettres successivement) ;
- La commande en séquence des deux sous-systèmes est donc terminé.
ReX : Ce serait bien d'expliquer les problèmes rencontrés et les solutions apportées.
Je vais passer sur l'ordonnancement des sous-systèmes :
- Pour l'instant j'imagine faire 2 tâches, chacune s'occupant de la communication SPI d'un des deux sous-systèmes
- Cela ne correspond pas tout à fait à ce que l'on avait dit, mais cela me parait intéressant, je vais essayer...
ReX : Dans un premier temps pourquoi pas, cela mettra les problèmes en exergue.
Questions de la semaine 3
ReX : Ce serait bien d'expliquer les problèmes rencontrés et les solutions apportées.
Timothe : Depuis le début de mon travail ou seulement dernièrement ? Je vous mets ça dans une rubrique à part ?
ReX : Tout le temps ! La validation de l'EC dépend autant de la documentation régulière que du résultat.
Problèmes rencontrés et solutions apportées
Problèmes avec l'afficheur 7 segments
Pour ce sous-système, j'ai eu du mal à comprendre le code de prime à bord.
Je ne comprenais pas l'intérêt de segfont.c
puisqu'il comprenait tout les caractères ASCII, alors que les afficheurs peuvent seulement afficher 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, b, C, d, E, F.
ReX : Ce fichier contient la configuration souhaitée pour les segments (chaque bit correspond à un segment) pour chaque caractère ASCII, il est possible d'afficher au delà des caractères hexadécimaux, même si certains caractères ne sont pas très reconnaissables.
J'avais également du mal à comprendre les fonctions d'affichages display_set
, display_ascii
et display_next
.
Notamment l'utilité de display_ascii
puisque très peu de caractères de ce tableau sont finalement affichables. Ensuite, display_next
qui pouvait seulement utiliser la fonction display_ascii
.
ReX : Même remarque que ci-dessus.
Solutions :
Finalement, j'ai créé une constante dont chacune des valeurs correspond à chaque caractères affichables.
ReX : Vous avez donc redéfini segfont.c
, c'est dommage de perdre du temps.
Je n'utilise donc plus la fonction display_ascii
ni display_next
et donc je n'utilise plus non plus le fichier segfont.c
.
ReX : Même remarque, c'est une faiblesse de ne pas comprendre un code pour le réutiliser sans réinventer la roue.
Désormais, il suffit pour afficher un caractère d'utiliser la fonction display_set
, elle prend en paramètre le tableau groupes[]
, qui comprend chaque segment de tous les afficheurs 7segments, ainsi que le numéro de l'afficheur que l'on souhaite, et enfin la constante correspondant au caractère que l'on souhaite afficher.
Cela signifie que je n'utilise plus la fonction cursor_set
également, j'utilise directement le paramètre num
de la fonction pour sélectionner l'afficheur.
ReX : Même remarque.
les constantes que j'ai créées sont les suivantes :
ZERO 63 UN 6 DEUX 91 TROIS 79 QUATRE 102 CINQ 109 SIX 125 SEPT 39 HUIT 127 NEUF 111 A 119 B 124 C 57 D 94 E 121 F 113 OFF 0
ReX : OK un sous-ensemble de segfont.c
donc.
Problèmes avec la matrice de LED
Pour ce sous-système j'ai eu moins de difficultés, l'organisation est là même que l'autre sous-système et il y avait moins de choses.
J'ai voulu afficher l'alphabet sur la matrice, cependant, le tableau que l'on manipule pour contrôler la matrice de LEDs, n'était pas dans le bon "sens", c'est-à-dire, avec chacune de ses cases correspondant à la même LED sur la matrice dans l'espace.
Par exemple sur une matrice 2,2 les LEDs sont placées de la manière suivante :
1 2 3 4
tandis que les cases du tableau, serait disposées ainsi également :
1 2 3 4
Solutions :
Après quelques tests, j'ai pu constater que la matrice était pivotée de 90° vers la droite et que les cases étaient en miroir par rapport au sens de lecture.
J'ai donc de nouveau fait des tests jusqu'à ce que je parvienne retirer le miroir puis à pivoter la matrice de 90° vers la gauche.
Ensuite j'ai créé toutes les lettres de l'alphabet avec le système de tableau que j'avais fait.
Voici par exemple la lettre A :
unsigned char A[]={ 0,0,0,0,0,0,0,0, 0,0,0,ON,ON,0,0,0, 0,0,ON,0,0,ON,0,0, 0,0,ON,ON,ON,ON,0,0, 0,0,ON,0,0,ON,0,0, 0,0,ON,0,0,ON,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, };
ON
correspondant à une LED allumé et 0
une LED éteinte.
ReX : Mettons, je vous accorde le sens de la matrice.
Problèmes avec les communication SPI
J'ai commencé par établir le lien entre les afficheurs 7segments et le maitre. Je ne parvenais pas à transmettre les données, puis à les afficher correctement.
Solutions :
J'ai finalement modifié très légèrement la facon d'envoyer les données et de les recevoir.
Du côté du maitre SPI, la solution fut de sélectionner un prescaler pour l'horloge cadencant la communication. En effet, de prime à bord il n'y en avait pas, et j'ai supposé que l'horloge étant trop rapide cela ne fonctionnait pas. Puisque effectivement, après avoir tester différentes cadences d'horloge, j'ai remarquer que lorsqu'elle était trop élevée la communication ne passait plus.
ReX : C'est possible, le PCB est peut être mal optimisé pour une communication SPI à haute vitesse. Comment avez-vous connecté les broches entre elles ? Par des câbles (cela pourrait perturber le signal) ? Avec un plot de soudure ?
Timothé : Je l'ai fait avec des câbles. En effet, il sera peut-être possible d'augmenter la cadence de l'horloge une fois un plot de soudure fait. Cela réduira grandement la longueur de la ligne et donc les perturbations.
Cela m'a permit d'établir la communication avec les afficheurs 7 segments. Par la suite, j'ai légèrement modifié la façon de recevoir pour la matrice, afin que ce soit identique aux afficheurs. Ce qui ne fonctionnait pas, mais j'avais simplement oublié d'initialiser la communication SPI...
Finalement, il suffit pour les deux sous-système d'envoyer avec la communication SPI un tableau contenant les caractères souhaités. Ces caractères sont envoyés un à un et sont affiché de la manière suivante :
Afficheurs : 2 modes possibles, pour le premier, le premier caractère va au premier afficheur et ainsi de suite. Pour le second, on sélectionne d'abord l'afficheur souhaité puis on envoit son caractère, et ainsi de suite.
Matrice : les caractères sont affichés les uns après les autres avec un intervalle de 800 ms, ce qui permet d'écrire des messages.
(Les fichiers serial.c
et serial.h
ne sont pas utiles pour les sous-systèmes afficheurs et matrice puisque n'ayant pas de MISO ils ne peuvent remonter d'informations).
ReX : Je ne vois pas trop le rapport entre UART et SPI, mais effectivement les broches RX et TX des deux esclaves n'étant pas utilisées, le code pour l'UART est assez inutile sur les esclaves.
Semaine 4
Création de la rubrique "Problèmes rencontrés et solutions apportées"
Questions de la semaine 4
J'ai créé une rubrique "Problèmes rencontrés et solutions apportées".
Son contenu correspond-t-il à ce que vous souhaitiez ?
ReX : Oui cela permet de mieux comprendre ce qui t'as arrêté.
ReX : Il manque une vidéo de démonstration de l'affichage des caractères sur la matrice et sur les 7 segments.
ReX : Il manque aussi les programmes ...
Semaine 6
Comme vous avez pu le constater, j'ai malheureusement eu un peu moins de temps pour avancer sur le projet dernièrement et ai donc également été moins actif sur le wiki.
ReX : Oui c'est vu. Dommage.
- Documents rendus :
- Codes de la partie 7 segments
- Codes de la partie matrice de LED
- Codes de la partie maitre SPI (fonctionnement séquentiel)
- Vidéo démontrant le fonctionnement séquentiel
- Affichage de "bonjour" sur la matrice de LED
- Affichage de FEDCBA sur les afficheurs 7segments (en utilisant la sélection manuel des afficheurs pour afficher à l'envers ce qui est envoyé)
- Ordonnancement :
- J'ai commencé à reprendre bien en détail le fonctionnement de l'ordonnanceur que nous avions mis en place dans le TP ordonnancement du semestre précédent, pour l'adapter à mon sujet
Documents Rendus
Codes de la partie 7 segments de la maquette :
ReX : Je ne comprends pas les codes envoyés pour la position du caractère à afficher ? Pourquoi pas directement le numéro de l'afficheur ?
ReX : Même chose pour les caractères eux-mêmes.
ReX : Les deux remarques précédentes ont pour but de vous faire simplifier le code en supprimant les redondances.
ReX : Ce serait bien de gérer la ligne SS, par exemple en vérifiant que la ligne n'est pas désélectionnée entre deux octets de la même commande.
Codes de la partie matrice de LED de la maquette :
ReX : Le codage des caractères prend trop de place en mémoire, limiter à 8 octets par caractère.
ReX : Même remarque sur l'incohérence des codes que pour les 7 segments.
Codes de la partie maitre SPI de la maquette (fonctionnement séquentiel) :
ReX ; Ne pas changer l'affichage des 7 segments rend la démonstration moins convaincante.
ReX : Vous n'envoyez qu'un octet par message pour les 7 segments ? Ou est l'octet de la position du caractère ?
ReX : Il faudrait justifier les 24ms d'attente par l'analyse de la durée du code d'envoi des informations aux TLC des 7 segments.
ReX : Même remarque pour les 800ms pour la matrice.
ReX : Pour éviter tous ces problèmes de délais, le mieux serait de prévoir une commande pour demander si le périphérique SPI est libre. Si le périphérique est libre un octet particulier est retourné. Si le périphérique se lance dans un traitement autre que l'écoute SPI, il prend soin d'initialiser sa réponse SPI a autre chose que cet octet particulier.