« SE4 2022/2023 EC2 » : différence entre les versions

De wiki-se.plil.fr
Aller à la navigation Aller à la recherche
 
(53 versions intermédiaires par 2 utilisateurs non affichées)
Ligne 1 : Ligne 1 :
= Objectifs =
== Objectifs ==
Il vous est demandé de :


Il vous est demandé de :  
Cahier des charges version 1:  
* comparer la taille des binaires d'un programme affichant sur 4 lignes un même texte compiler via l'IDE arduino et via AVR-GCC;
* de réaliser un prototype de système comportant un Arduino Uno, un écran LCD 2 ou 4 lignes à contrôleur HD44780 et les quelques composants nécessaires ;
* de réaliser un prototype de système comportant un Arduino Uno, un écran LCD 2 ou 4 lignes à contrôleur HD44780 et les quelques composants nécessaires ;
* vous devez écrire un programme C pour gérer le contrôleur HD44780 à partir de l'ATMega328p, vous utilisez le compilateur <code>avr-gcc</code> pour générer l'exécutable ;
* vous devez écrire un programme C pour gérer le contrôleur HD44780 à partir de l'ATMega328p, vous utilisez le compilateur <code>avr-gcc</code> pour générer l'exécutable ;
* votre projet doit être constitué d'un répertoire comprenant un makefile et la source C, le makefile doit implanter les cibles clean, all et upload ;
* votre projet doit être constitué d'un répertoire comprenant un makefile et la source C, le makefile doit implanter les cibles clean, all et upload ;
* en utilisant vos fonctions pour le contrôleur HD44780 vous ferez en sorte que les données reçues sur le port série de l'Arduino soient affichées sur l'écran ;
* en utilisant vos fonctions pour le contrôleur HD44780 vous ferez en sorte que les données reçues sur le port série de l'Arduino soient affichées sur l'écran ;
* vous sélectionnerez les 5 séquences VT100 qui vous paraissent les plus importantes et vous les implanterez dans votre code.
* vous sélectionnerez les cinq séquences VT100 qui vous paraissent les plus importantes et vous les implanterez dans votre code.
Ajout au cours du projet (l'élève s'est permis d'ajouter ce paragraphe) :
* comparer la taille des binaires d'un programme affichant sur 4 lignes un même texte compilé via l'IDE Arduino et via AVR-GCC ;
* factorisation du code (en aucun cas un ajout, l'écriture de code propre donc factorisé va de soi) ;
* calcul de la valeur de configuration du registre de Bauds à partir de la fréquence en entrée d'initialisation de l'UART (en aucun cas un ajout, l'écriture de code propre donc avec des paramètres de fonction compréhensibles par l'utilisateur va de soi) ;
* librairie disponible aussi pour les écrans 1 ligne (en aucun cas un ajout, la compréhension des documents techniques va de soi).


= Matériel nécessaire =
== Matériel nécessaire ==
Le matériel nécessaire consiste en un kit Arduino Uno.


Le matériel nécessaire consiste en un kit Arduino Uno.
== Travail réalisé ==


= Travail réalisé =
=== <u><big>Câblage</big></u> ===
[[Fichier:LCD dos.jpg|vignette|200x200px|Photo des composants sur l'écran]]
[[Fichier:LCD face.jpg|alt=|vignette|200x200px|Photo du banc d'essai vue de face]]J'utilise ici un Arduino Nano et un écran LCD WH2004L-YYH-JT


ReX : Pas de photo du banc d'essai.
Le montage est constitué d'un potentiomètre 10k entre VSS et VDD afin de sélectionner la tension VO qui permet de gérer le contraste de l'écran.


ReX : Pas de vidéo de démonstration.
Un groupe de quatre résistances en parallèles (pas de résistances de plus haute puissance à ma disposition) permettent de limiter le courant et contrôler la tension du rétroéclairage de l'écran et donc sa luminosité.  
{| class="wikitable"
|+
!Ecran LCD
!ATMEGA328p
!Arduino Nano
|-
|VSS
|GND
|GND
|-
|VDD
|5V
|5V
|-
|VO
|X
|X
|-
|RS
|PD2
|2
|-
|RW
|PD3
|3
|-
|E
|PD4
|4
|-
|DB0
|PD5
|5
|-
|DB1
|PD6
|6
|-
|DB2
|PD7
|7
|-
|DB3
|PB0
|8
|-
|DB4
|PB1
|9
|-
|DB5
|PB2
|10
|-
|DB6
|PB3
|11
|-
|DB7
|PB4
|12
|-
|A
|X
|X
|-
|K
|GND
|GND
|}


=== <u><big>Comparaison:</big></u> ===
=== <u><big>Comparaison</big></u> ===
Les fichiers utilisés pour faire la comparaison se trouvent dans le dossier <code>Compare/</code>.


==== <u><big>Texte à afficher:</big></u> ====
==== <u><big>Texte à afficher</big></u> ====
Lorem ipsum dolor
[[Fichier:EcranLcd.jpg|vignette|Écran avec affichage du texte]]Lorem ipsum dolor


sit amet,consectetur
sit amet,consectetur
Ligne 29 : Ligne 108 :


do eiusmod tempor
do eiusmod tempor
[[Fichier:EcranLcd.jpg|vignette]]
==== <u><big>Tailles</big></u> ====


==== <u><big>Tailles :</big></u> ====
===== Arduino IDE =====
1820 octets de stockage flash


ReX : taille de programme ? taille du programme plus taille RAM ?
125 octets de RAM


ReX : taille RAM utilisée ?
26 248 octets <code>PrintLoremArduino.ino.elf</code>


===== Arduino IDE: =====
5 135 octets <code>PrintLoremArduino.ino.hex</code>
1820 octets de stockage flash


===== AVR-GCC: =====
===== AVR-GCC =====
958 octets de stockage flash
958 octets de stockage flash


=== Séquences VT100: ===
82 octets de RAM
Les séquences VT100 que j'ai sélectionnées sont:
 
8 304 <code>lcd_lorem_program.elf</code>
 
2 709 <code>lcd_lorem_program.hex</code>
 
=== Séquences VT100 ===
Les séquences VT100 que j'ai sélectionnées sont :


<blockquote>cursorhome    Move cursor to upper left corner      Echap+H
<blockquote>cursorhome    Move cursor to upper left corner      Echap+H
Ligne 55 : Ligne 140 :


cursorlf            Move cursor left one char                Echap+D
cursorlf            Move cursor left one char                Echap+D
</blockquote>
</blockquote>Elles proviennent du site internet https://espterm.github.io/docs/VT100%20escape%20codes.html
 
=== <big><u>Architecture du projet</u></big> ===
Le projet se trouve final se trouve dans le GitHub mise en lien dans le dossier <code>src/</code> et comporte un fichier <code>hd_44780.h</code> permettant de configurer l'écran à l'application. Un fichier <code>hd_44780.c</code> contenant toutes les fonctions permettant de contrôler l'écran et de l'initialiser. Et un fichier <code>main.c</code> contenant la partie lecture des données reçus sur le port série et l'affichage de celle-ci ainsi que la détection des commandes VT100 et l'exécution des fonctions correspondantes.
 
==== <u>Librairie HD44780 pour AVRGCC et AVR uC</u> ====
La librairie permet dans le fichier <code>hd44780.h</code> :
 
* Choisir les pins pour chaque broche de données.
* Choisir le mode 2 lignes ou 4 lignes pour l'écran.
* Choisir le mode 4 bits ou 8 bits pour le bus de données parallèles.
* Choisir le type de curseur entre :
** <code>"no_CURSOR"</code> qui n'affiche rien sur la position où l'on se trouve sur l'écran.
** <code>"underlined"</code> qui affiche un soulignage de la position actuelle.
** <code>"blinking"</code> qui fait clignoter la case sur laquelle on se trouve.
** <code>"underlined_blinking"</code> la somme de underlined et blinking.
* Implémenter une fonction <code>LCDSetup()</code> qui permet d'initialiser l'écran avec les paramètres ci-dessus.
* Implémenter une fonction <code>ShiftUp()</code> qui permet de se déplacer vers le haut sur l'écran
* Implémenter une fonction <code>ShiftDwon()</code> qui permet de se déplacer vers le bas sur l'écran.
* Implémenter une fonction <code>ShiftRight()</code> qui permet de se déplacer vers la droite sur l'écran.
* Implémenter une fonction <code>ShiftLeft()</code> qui permet de se déplacer vers la gauche sur l'écran.
* Implémenter une fonction <code>LCDon()</code> qui permet d'activer l'affichage.
* Implémenter une fonction <code>LCDoff()</code> qui permet de désactiver l'affichage.
* Implémenter une fonction <code>NewLine()</code> qui permet de passer au début de la ligne suivante.
* Implémenter une fonction <code>WriteChar()</code> qui permet d'écrire un caractère sur la case sur laquelle on se trouve.
* Implémenter une fonction <code>LCDgotoXY()</code> qui permet de se déplacer à une position voulue sur l'écran.
 
La configuration doit être faite dans le fichier <code>lcd_hd44780.h</code>
 
La librairie fonctionne avec une majorité de microcontrôleur AVR, car la librairie permet de configurer les pins une à une, port à port.
 
==== <u>Main</u> ====
[[Fichier:Presentation.mp4|vignette|Présentation du test final]]
 
Le programme <code>main.c</code> contient les fonctions d'initialisation et de lecture des données sur le port série. Une boucle tant que permet d'attendre constamment un octet sur le port série puis lorsqu'il arrive le traiter et attendre un nouvel octet sur le port série.
 
La fonction <code>USART_init()</code> permet d'initialiser le port série en 7 bits de données et 1 bit de stop. 103 correspond à 9600 bauds pour une fréquence d'horloge processeur de 16 MHz (À modifier en fonction de la configuration du microcontrôleur et les besoins).
 
Les séquences VT100 sont détectés de la manière suivante :
 
* Si le caractère ascii correspondant à échap arrive (27) on n'affiche pas tout de suite et on attend de voir le caractère suivant.
* Si le caratère suivant n'est pas <code>[</code> alors on affiche 27 (soit rien).
* Sinon, on attend le caractère suivant et s'il s'agit de A, B, C, D ou H, on peut alors activer la fonction correspondante car il s'agit d'une séquence VT100 sinon on affiche les caractères reçus jusqu'ici.
 
== Documents Rendus ==
[[Fichier:SE4 2022 2023 EC2.zip]]
 
[https://github.com/TH0L3F/HD44780_avrgcc_lib HD44780_avrgcc_lib]
 
Etat au premier août : [[Fichier:SE4_2022_2023_EC2_010823.zip]]
 
== <big>Discussions</big> ==
<u>Code supprimé :</u>
 
<blockquote>ReX : <s>Pourquoi avoir supprimé l'archive avec le code ?</s>
 
Thomas : Le nom n'était pas bon et je n'ai pas trouvé le moyen de le modifier directement. Comme le code n'était pas bon, je n'ai pas trouvé judicieux de reposter directement l'ancien code sous le nouveau nom
 
CLOSED</blockquote>
 
<u>Archive GIT :</u>
 
<blockquote>ReX : Explication pour l'archive GIT.
 
Thomas : Parce que je le peux. Aussi si des personnes proposes des modifications dans le futur depuis GIT après utilisation de mon travail cela permettra de faire le suivi sur GIT pour un étudiant de Polytech.
 
ReX : Vous répondez à quelle question là ?</blockquote>
 
<u>Explication architecture :</u>
 
<blockquote>ReX : <s>Vous n'expliquez pas l'architecture du code dans votre Wiki.</s>
 
ReX : un code rendu sans explication de la structure puis retiré, puis remis.
 
Thomas : Structure ajoutée et fichiers remis avec le bon nom.</blockquote>
 
<u>Banc d'essai :</u>
 
<blockquote> ReX : <s>rien dans le Wiki sur le banc d'essai câblage en particulier, ce qui rend le test de vérification pénible</s>
 
Thomas : Le pin out de l'ATMEGA328P se trouve dans le fichier <code>lcd_44780.h</code> ligne 5 à 47 et a été conçu pour être facilement modifiable.
 
ReX : Le câblage a été ajouté dans le Wiki, le code n'est pas facilement modifiable.</blockquote>


ReX : Je ne vois pas où les séquences ci-dessus sont implantées dans le code.
<u>Demande de correction :</u> <blockquote>


ReX : Dans le <code>main</code> du répertoire <code>FINAL</code>.
ReX : un code imparfait, des demandes de correction, aucun retour


=== <u>Librairie HD44780 pour AVRGCC et AVR uC:</u> ===
Thomas : Réponse donnée par mail (rien n'est parfait).
La librairie permet de :


* choisir les pins pour chaques broches de données.
ReX : Dans votre courriel vous indiquez ne pas souhaiter effectuer les modifications, il faudra pourtant les faire.
* choisir le mode 2 lignes ou 4 lignes pour l'écran.
* choisir le mode 4bits ou 8bits pour le bus de données parralèles.
* choisir le type de curseur entre :
** "no_CURSOR" qui n'affiche rien sur la position où l'on se trouve sur l'écran.
** "underlined" qui affiche un soulignage de la position actuelle.
** "blinking" qui fait clignoter la case sur laquelle on se trouve.
** "underlined_blinking" la somme de underlined et blinking.
* implémenter une fonction LCDSetup qui permet d'initialiser l'écran avec le paramètres ci-dessus.
* implémenter une fonction ShiftUp qui permet de se déplacer vers le haut sur l'écran
* implémenter une fonction ShiftDwon qui permet de se déplacer vers le bas sur l'écran.
* implémenter une fonction ShiftRight qui permet de se déplacer vers la droite sur l'écran.
* implémenter une fonction ShiftLeft qui permet de se déplacer vers la gauche sur l'écran.
* implémenter une fonction LCDon qui permet d'activer l'affichage.
* implémenter une fonction LCDoff qui permet de désactiver l'affichage.
* implémenter une fonction NewLine qui permet de passer au début de la ligne suivante.
* implémenter une fonction WriteChar qui permet d'écrire un caractère sur la case où l'on se trouve.
* implémenter une fonction LCDgotoXY qui permet de se déplacer à une position voulue sur l'écran.


La configuration doit être faite dans le fichier lcd_hd44780.h
Thomas : Je n'ai pas indiqué ne pas vouloir faire le travail, j'ai juste demandé des explications suite à une incompréhension. Aussi, je précise pour le premier message que les retours ont été donnés après une semaine parce que j'ai été occupé par mon stage. Comme indiqué par mail.


La librairie fonctionne avec une majorité de microcontrôlleurs AVR car la librairie permet de configurer les pins une à une, port à port.
ReX : Explications données par courriel. Modifications non apportées.</blockquote>


ReX : factoriser le code de la fonction <code>DataPortWrite4bits</code> en particulier en transformant les 4 écritures en une boucle de 4 itérations, optimisez en comparant avec des constantes de type <code>1 << 7</code> plutôt qu'en décalant une variable. Même chose pour la fonction <code>DataPortWrite8bits</code>.
<u>Mode 8 bits non fonctionnel 1 :</u>


ReX : Factoriser le code de l'initialisation des registres DDR.
<blockquote>ReX : Comment le contrôleur LCD sait-il qu'il faut utiliser le mode 4 bits ou 8 bits ? je ne vois rien dans le code pour lui indiquer le mode ?


ReX : Comment le contrôleur LCD sait-il qu'il faut utiliser le mode 4 bits ou 8 bits ? je ne vois rien dans le code pour lui indiquer le mode ?
Thomas : Réponse en bas de page


ReX : C'est confirmé par le test avec un WH2004L-TMI-JT, le mode 8 bits n'est pas fonctionnel.
ReX : C'est confirmé par le test avec un WH2004L-TMI-JT, le mode 8 bits n'est pas fonctionnel.


ReX : Pour la fonction <code>LCDgotoXY</code> écrire une macro permettant de garder un nombre entre deux bornes, factorisez le code avec cette macro. Dans la même fonction factorisez le code en utilisant un tableau des adresses de lignes.
Thomas : Réponse en bas de page.
 
ReX : Mettez des liens sur vos réponses. En bas de page est imprécis.</blockquote>
 
<u>Mode 8 bits non fonctionnel 2 :</u>
 
<blockquote>Rex : un code fonctionnel en mode 4 bits, mais pas en mode 8 bits.


=== <u>Main:</u> ===
Thomas : Il faut respecter le pin out présent dans <code>lcd_44780.h</code> et changer le mode ligne 59 du même fichier.
Le main contient les fonctions d'initialisation et de lecture des données sur le port série. une boucle tant que permet d'attendre constamment un octet sur le port série puis lorsqu'il arrive le traiter et attendre un nouveau octet sur le port série.


la fonction USART_init permet d'initialiser le port série en 7 bits de données et 1 bit de stop. 103 correpond à 9600bauds pour une fréquence d'horloge processeur de 16MHz (A modifier en fonction de la configuration du microcontrôlleur et les besoins).
ReX : Oui, et ça ne fonctionne pas et c'est logique vu que votre code ne passe d'un mode à l'autre.


ReX : Merci d'effectuer le calcul dans le code à partir d'un paramètre en bauds.
Thomas : Vous devez vouloir dire "ne passe pas d'un code à l'autre" hors (l'élève veut dire or, coquille présente dans toute la page) des instructions <code>if(LCD_MODE){...}else{ }</code> se trouvent partout dans le fichier<code>lcd_44780.c</code>. La définition quand à elle se fait dans <code>lcd_44780.h</code> avec <code>#define LCD_MODE 0</code> .


Les séquences VT100 sont détectés de la manière suivante:
ReX : Votre code ne fait pas passer le contrôleur LCD du mode 4 bits (défaut) ou mode 8 bits (voir ma première remarque sur le sujet).</blockquote>


* Si le caractère ascii correspondant à échap arrive (27) on n'affiche pas tout de suite et on attend de voir le caractère suivant.
<u>Taille d'écran non adaptable : </u>
* Si le caratère suivant n'est pas <code>[</code> alors on affiche 27 (soit rien)  
 
* Sinon on attend le caractère suivant et si il s'agit de A, B, C, D ou H on peut alors activer la fonction correspondante car il s'agit d'une séquence VT100 sinon on affiche les caractères reçus jusqu'ici.
<blockquote>ReX : le code fonctionne pour un écran 4 lignes de 20 caractères, mais n'est pas adaptable à un écran d'un autre nombre de lignes,
 
Thomas : Il faut modifier la définition du nombre de lignes et de colonnes dans <code>lcd_44780.h</code> ligne 50 et 51.
 
ReX : Oui, et ça ne fonctionne pas et c'est logique vu que le cas 1 ligne n'est pas prévu, rendez votre code générique et factorisez-le.
 
Thomas : Compliqué de rendre le code générique pour la raison suivante : Pour un écran deux lignes 20 caractères l'adresse de départ de la ligne 1 sera 0x00 et la ligne 2 sera 0x14 hors pour un écran 4 lignes l'adresse 0x14 correspond à la troisième ligne (lire datasheet). Possibilité de créer définition différentes pour chaques types d'écran en fonction des besoins. Le cas des une lignes n'était pas prévu dans le cahier des charges initiales. Possibilité de modifier la taille de l'écran dans le fichier <code>lcd_44780.h</code> avec les lignes suivantes : <code>#define LCD_N_COL 20</code> qet <code>#define LCD_N_ROW 4</code>.
 
ReX : Ce qui était demandé était juste de calculer les décalages en mémoire des lignes. Pour un écran de n lignes (n<=4) et de m colonnes (m<=20), ces décalages sont : <code>si n>=1 alors ligne[0]=0x00</code>, <code>si n>=2 alors ligne[1]=0x40</code>, <code>si n>=3 alors ligne[2]=m</code>, <code>si n>=4 alors ligne[3]=0x40+m</code>.</blockquote>
 
<u>Taille d'écran non adaptable 2 :</u>
 
<blockquote>ReX : Un test effectué avec un WH2004L-TMI-JT, un autre test effectué avec un WH601A-NYG-JT (1 ligne, 16 caractères).
 
Thomas : La consigne était écran 2 ou 4 lignes. Même si ce n'est pas prévu, le code devrait fonctionner tous de même avec un écran une ligne.
 
ReX : L'élève n'a pas voulu corriger son code.</blockquote>
 
<u>Code VT100 1 :</u>
 
<blockquote>
ReX : <s>Pas de test sur ESC dans <code>main.c</code> pas plus dans <code>lcd_hd44780.c</code></s>.


ReX : Pas de test sur ESC dans <code>main.c</code> pas plus dans <code>lcd_hd44780.c</code>.
Thomas : Dans le fichier <code>main.c</code> ligne 41 le code ASCII 27 fait référence à la touche ECHAP


ReX : Voir dans le répertoire <code>FINAL</code>.
ReX : Voir dans le répertoire <code>FINAL</code>.
Ligne 116 : Ligne 291 :
ReX : Vous n'avez pas compris la séquence des codes VT100. Ils ne sont préfixés que d'un caractère : ESC. Aucun caractère <code>[</code>. Du coup votre code n'est pas fonctionnel concernant les code VT100.
ReX : Vous n'avez pas compris la séquence des codes VT100. Ils ne sont préfixés que d'un caractère : ESC. Aucun caractère <code>[</code>. Du coup votre code n'est pas fonctionnel concernant les code VT100.


= Documents Rendus =
Thomas : Vous retrouverez ici [http://www.braun-home.net/michael/info/misc/VT100_commands.htm] les commandes VT100 sur lesquels je me suis basé et elles sont préfixès d'un <code>ESC</code> et <code>[</code> puis une lettre.
 
ReX : OK pour <code>ESC [ H</code> (mais erreur plus haut dans la liste des séquences VT100 choisies, non pour les 4 autres, relis bien ton document.
 
Thomas : J'ai pris le lien du mauvais site, mise à jour effectuer dans la section VT100 avec ajout d'une lien redirigent vers un site repertoriant les bonnes séquences VT100. Après plusieurs test je confirme que je reçois bien un <code>[</code> lorsque j'effectue l'une des commandes VT100. Une fois encore les tests montrent que le code actuel prend bien en compte ces commandes et execute les fonctions correspondantes.
 
ReX : OK, vous avez confondu les séquences VT100 avec les touches spéciales qui envoyent des codes particulier au PC (les touches de direction). De plus la partie du Wiki "Séquences VT100" n'est pas correcte.
</blockquote>
 
<u>Code VT100 2: </u>
 
<blockquote>ReX : Une confusion dans la compréhension des codes VT100, programme non conforme de ce côté.
 
Thomas : Les commandes VT100 fonctionnent correctement. Preuve en vidéo.
 
ReX : Non, voir commentaire plus haut.
 
ReX : Vous n'avez fait qu'interpréter les codes VT100 des touches de direction, ce n'est pas ce qui était demandé. Vous pouvez vous en convaincre avec le test suivant : lancez un terminal sans shell <code>xterm -e "tty;sleep 1d" & stty -F /dev/pts/8 raw -echo</code> puis écoutez ce qu'envoye le terminal VT102 avec <code>od -tx1  -Ax < /dev/pts/8</code> ou envoyez des séquences avec <code>echo -n ^[[4B > /dev/pts/8</code>. Le fichier spécial <code>/dev/pts/8</code> est celui écrit dans le terminal <code>xterm</code> par la commande <code>tty</code>. Attention il ne faut pas envoyer les deux caractères <code>^[</code> mais le caractère ESC, pour cela tapez CTRL-v puis ESC.
</blockquote>
 
<u>Macro GoTo :</u>
 
<blockquote>
ReX : Pour la fonction <code>LCDgotoXY</code> écrire une macro permettant de garder un nombre entre deux bornes, factorisez le code avec cette macro. Dans la même fonction, factorisez le code en utilisant un tableau des adresses de lignes.</blockquote>
 
<u>Factorisation de code :</u>
 
<blockquote>
ReX : factoriser le code de la fonction <code>DataPortWrite4bits</code> en particulier en transformant les 4 écritures en une boucle de 4 itérations, optimisez en comparant avec des constantes de type <code>1 << 7</code> plutôt qu'en décalant une variable. Même chose pour la fonction <code>DataPortWrite8bits</code>.
 
ReX : Factoriser le code de l'initialisation des registres DDR.</blockquote><u>Calcul de Baud :</u><blockquote>ReX : Merci d'effectuer le calcul dans le code à partir d'un paramètre en bauds.</blockquote>
 
<u>Commentaire personnel :</u>
<blockquote>
ReX : Dommage, vos trop nombreuses approximations et votre mauvaise volonté font oublier le succès de programmation du contrôleur d'affichage.
 
ReX : Succès s'entendait dans les conditions limitées que vous vous êtes vous même fixées.
</blockquote>

Version actuelle datée du 8 août 2023 à 07:01

Objectifs

Il vous est demandé de :

Cahier des charges version 1:

  • de réaliser un prototype de système comportant un Arduino Uno, un écran LCD 2 ou 4 lignes à contrôleur HD44780 et les quelques composants nécessaires ;
  • vous devez écrire un programme C pour gérer le contrôleur HD44780 à partir de l'ATMega328p, vous utilisez le compilateur avr-gcc pour générer l'exécutable ;
  • votre projet doit être constitué d'un répertoire comprenant un makefile et la source C, le makefile doit implanter les cibles clean, all et upload ;
  • en utilisant vos fonctions pour le contrôleur HD44780 vous ferez en sorte que les données reçues sur le port série de l'Arduino soient affichées sur l'écran ;
  • vous sélectionnerez les cinq séquences VT100 qui vous paraissent les plus importantes et vous les implanterez dans votre code.

Ajout au cours du projet (l'élève s'est permis d'ajouter ce paragraphe) :

  • comparer la taille des binaires d'un programme affichant sur 4 lignes un même texte compilé via l'IDE Arduino et via AVR-GCC ;
  • factorisation du code (en aucun cas un ajout, l'écriture de code propre donc factorisé va de soi) ;
  • calcul de la valeur de configuration du registre de Bauds à partir de la fréquence en entrée d'initialisation de l'UART (en aucun cas un ajout, l'écriture de code propre donc avec des paramètres de fonction compréhensibles par l'utilisateur va de soi) ;
  • librairie disponible aussi pour les écrans 1 ligne (en aucun cas un ajout, la compréhension des documents techniques va de soi).

Matériel nécessaire

Le matériel nécessaire consiste en un kit Arduino Uno.

Travail réalisé

Câblage

Photo des composants sur l'écran
Photo du banc d'essai vue de face

J'utilise ici un Arduino Nano et un écran LCD WH2004L-YYH-JT

Le montage est constitué d'un potentiomètre 10k entre VSS et VDD afin de sélectionner la tension VO qui permet de gérer le contraste de l'écran.

Un groupe de quatre résistances en parallèles (pas de résistances de plus haute puissance à ma disposition) permettent de limiter le courant et contrôler la tension du rétroéclairage de l'écran et donc sa luminosité.

Ecran LCD ATMEGA328p Arduino Nano
VSS GND GND
VDD 5V 5V
VO X X
RS PD2 2
RW PD3 3
E PD4 4
DB0 PD5 5
DB1 PD6 6
DB2 PD7 7
DB3 PB0 8
DB4 PB1 9
DB5 PB2 10
DB6 PB3 11
DB7 PB4 12
A X X
K GND GND

Comparaison

Les fichiers utilisés pour faire la comparaison se trouvent dans le dossier Compare/.

Texte à afficher

Écran avec affichage du texte

Lorem ipsum dolor

sit amet,consectetur

adipiscing elit, sed

do eiusmod tempor

Tailles

Arduino IDE

1820 octets de stockage flash

125 octets de RAM

26 248 octets PrintLoremArduino.ino.elf

5 135 octets PrintLoremArduino.ino.hex

AVR-GCC

958 octets de stockage flash

82 octets de RAM

8 304 lcd_lorem_program.elf

2 709 lcd_lorem_program.hex

Séquences VT100

Les séquences VT100 que j'ai sélectionnées sont :

cursorhome Move cursor to upper left corner Echap+H

cursorup Move cursor up one line Echap+A

cursordn Move cursor down one line Echap+B

cursorrt Move cursor right one char Echap+C

cursorlf Move cursor left one char Echap+D

Elles proviennent du site internet https://espterm.github.io/docs/VT100%20escape%20codes.html

Architecture du projet

Le projet se trouve final se trouve dans le GitHub mise en lien dans le dossier src/ et comporte un fichier hd_44780.h permettant de configurer l'écran à l'application. Un fichier hd_44780.c contenant toutes les fonctions permettant de contrôler l'écran et de l'initialiser. Et un fichier main.c contenant la partie lecture des données reçus sur le port série et l'affichage de celle-ci ainsi que la détection des commandes VT100 et l'exécution des fonctions correspondantes.

Librairie HD44780 pour AVRGCC et AVR uC

La librairie permet dans le fichier hd44780.h :

  • Choisir les pins pour chaque broche de données.
  • Choisir le mode 2 lignes ou 4 lignes pour l'écran.
  • Choisir le mode 4 bits ou 8 bits pour le bus de données parallèles.
  • Choisir le type de curseur entre :
    • "no_CURSOR" qui n'affiche rien sur la position où l'on se trouve sur l'écran.
    • "underlined" qui affiche un soulignage de la position actuelle.
    • "blinking" qui fait clignoter la case sur laquelle on se trouve.
    • "underlined_blinking" la somme de underlined et blinking.
  • Implémenter une fonction LCDSetup() qui permet d'initialiser l'écran avec les paramètres ci-dessus.
  • Implémenter une fonction ShiftUp() qui permet de se déplacer vers le haut sur l'écran
  • Implémenter une fonction ShiftDwon() qui permet de se déplacer vers le bas sur l'écran.
  • Implémenter une fonction ShiftRight() qui permet de se déplacer vers la droite sur l'écran.
  • Implémenter une fonction ShiftLeft() qui permet de se déplacer vers la gauche sur l'écran.
  • Implémenter une fonction LCDon() qui permet d'activer l'affichage.
  • Implémenter une fonction LCDoff() qui permet de désactiver l'affichage.
  • Implémenter une fonction NewLine() qui permet de passer au début de la ligne suivante.
  • Implémenter une fonction WriteChar() qui permet d'écrire un caractère sur la case sur laquelle on se trouve.
  • Implémenter une fonction LCDgotoXY() qui permet de se déplacer à une position voulue sur l'écran.

La configuration doit être faite dans le fichier lcd_hd44780.h

La librairie fonctionne avec une majorité de microcontrôleur AVR, car la librairie permet de configurer les pins une à une, port à port.

Main

Le programme main.c contient les fonctions d'initialisation et de lecture des données sur le port série. Une boucle tant que permet d'attendre constamment un octet sur le port série puis lorsqu'il arrive le traiter et attendre un nouvel octet sur le port série.

La fonction USART_init() permet d'initialiser le port série en 7 bits de données et 1 bit de stop. 103 correspond à 9600 bauds pour une fréquence d'horloge processeur de 16 MHz (À modifier en fonction de la configuration du microcontrôleur et les besoins).

Les séquences VT100 sont détectés de la manière suivante :

  • Si le caractère ascii correspondant à échap arrive (27) on n'affiche pas tout de suite et on attend de voir le caractère suivant.
  • Si le caratère suivant n'est pas [ alors on affiche 27 (soit rien).
  • Sinon, on attend le caractère suivant et s'il s'agit de A, B, C, D ou H, on peut alors activer la fonction correspondante car il s'agit d'une séquence VT100 sinon on affiche les caractères reçus jusqu'ici.

Documents Rendus

Fichier:SE4 2022 2023 EC2.zip

HD44780_avrgcc_lib

Etat au premier août : Fichier:SE4 2022 2023 EC2 010823.zip

Discussions

Code supprimé :

ReX : Pourquoi avoir supprimé l'archive avec le code ?

Thomas : Le nom n'était pas bon et je n'ai pas trouvé le moyen de le modifier directement. Comme le code n'était pas bon, je n'ai pas trouvé judicieux de reposter directement l'ancien code sous le nouveau nom

CLOSED

Archive GIT :

ReX : Explication pour l'archive GIT.

Thomas : Parce que je le peux. Aussi si des personnes proposes des modifications dans le futur depuis GIT après utilisation de mon travail cela permettra de faire le suivi sur GIT pour un étudiant de Polytech.

ReX : Vous répondez à quelle question là ?

Explication architecture :

ReX : Vous n'expliquez pas l'architecture du code dans votre Wiki.

ReX : un code rendu sans explication de la structure puis retiré, puis remis.

Thomas : Structure ajoutée et fichiers remis avec le bon nom.

Banc d'essai :

ReX : rien dans le Wiki sur le banc d'essai câblage en particulier, ce qui rend le test de vérification pénible

Thomas : Le pin out de l'ATMEGA328P se trouve dans le fichier lcd_44780.h ligne 5 à 47 et a été conçu pour être facilement modifiable.

ReX : Le câblage a été ajouté dans le Wiki, le code n'est pas facilement modifiable.

Demande de correction :

ReX : un code imparfait, des demandes de correction, aucun retour

Thomas : Réponse donnée par mail (rien n'est parfait).

ReX : Dans votre courriel vous indiquez ne pas souhaiter effectuer les modifications, il faudra pourtant les faire.

Thomas : Je n'ai pas indiqué ne pas vouloir faire le travail, j'ai juste demandé des explications suite à une incompréhension. Aussi, je précise pour le premier message que les retours ont été donnés après une semaine parce que j'ai été occupé par mon stage. Comme indiqué par mail.

ReX : Explications données par courriel. Modifications non apportées.

Mode 8 bits non fonctionnel 1 :

ReX : Comment le contrôleur LCD sait-il qu'il faut utiliser le mode 4 bits ou 8 bits ? je ne vois rien dans le code pour lui indiquer le mode ?

Thomas : Réponse en bas de page

ReX : C'est confirmé par le test avec un WH2004L-TMI-JT, le mode 8 bits n'est pas fonctionnel.

Thomas : Réponse en bas de page.

ReX : Mettez des liens sur vos réponses. En bas de page est imprécis.

Mode 8 bits non fonctionnel 2 :

Rex : un code fonctionnel en mode 4 bits, mais pas en mode 8 bits.

Thomas : Il faut respecter le pin out présent dans lcd_44780.h et changer le mode ligne 59 du même fichier.

ReX : Oui, et ça ne fonctionne pas et c'est logique vu que votre code ne passe d'un mode à l'autre.

Thomas : Vous devez vouloir dire "ne passe pas d'un code à l'autre" hors (l'élève veut dire or, coquille présente dans toute la page) des instructions if(LCD_MODE){...}else{ } se trouvent partout dans le fichierlcd_44780.c. La définition quand à elle se fait dans lcd_44780.h avec #define LCD_MODE 0 .

ReX : Votre code ne fait pas passer le contrôleur LCD du mode 4 bits (défaut) ou mode 8 bits (voir ma première remarque sur le sujet).

Taille d'écran non adaptable :

ReX : le code fonctionne pour un écran 4 lignes de 20 caractères, mais n'est pas adaptable à un écran d'un autre nombre de lignes,

Thomas : Il faut modifier la définition du nombre de lignes et de colonnes dans lcd_44780.h ligne 50 et 51.

ReX : Oui, et ça ne fonctionne pas et c'est logique vu que le cas 1 ligne n'est pas prévu, rendez votre code générique et factorisez-le.

Thomas : Compliqué de rendre le code générique pour la raison suivante : Pour un écran deux lignes 20 caractères l'adresse de départ de la ligne 1 sera 0x00 et la ligne 2 sera 0x14 hors pour un écran 4 lignes l'adresse 0x14 correspond à la troisième ligne (lire datasheet). Possibilité de créer définition différentes pour chaques types d'écran en fonction des besoins. Le cas des une lignes n'était pas prévu dans le cahier des charges initiales. Possibilité de modifier la taille de l'écran dans le fichier lcd_44780.h avec les lignes suivantes : #define LCD_N_COL 20 qet #define LCD_N_ROW 4.

ReX : Ce qui était demandé était juste de calculer les décalages en mémoire des lignes. Pour un écran de n lignes (n<=4) et de m colonnes (m<=20), ces décalages sont : si n>=1 alors ligne[0]=0x00, si n>=2 alors ligne[1]=0x40, si n>=3 alors ligne[2]=m, si n>=4 alors ligne[3]=0x40+m.

Taille d'écran non adaptable 2 :

ReX : Un test effectué avec un WH2004L-TMI-JT, un autre test effectué avec un WH601A-NYG-JT (1 ligne, 16 caractères).

Thomas : La consigne était écran 2 ou 4 lignes. Même si ce n'est pas prévu, le code devrait fonctionner tous de même avec un écran une ligne.

ReX : L'élève n'a pas voulu corriger son code.

Code VT100 1 :

ReX : Pas de test sur ESC dans main.c pas plus dans lcd_hd44780.c.

Thomas : Dans le fichier main.c ligne 41 le code ASCII 27 fait référence à la touche ECHAP

ReX : Voir dans le répertoire FINAL.

ReX : Vous n'avez pas compris la séquence des codes VT100. Ils ne sont préfixés que d'un caractère : ESC. Aucun caractère [. Du coup votre code n'est pas fonctionnel concernant les code VT100.

Thomas : Vous retrouverez ici [1] les commandes VT100 sur lesquels je me suis basé et elles sont préfixès d'un ESC et [ puis une lettre.

ReX : OK pour ESC [ H (mais erreur plus haut dans la liste des séquences VT100 choisies, non pour les 4 autres, relis bien ton document.

Thomas : J'ai pris le lien du mauvais site, mise à jour effectuer dans la section VT100 avec ajout d'une lien redirigent vers un site repertoriant les bonnes séquences VT100. Après plusieurs test je confirme que je reçois bien un [ lorsque j'effectue l'une des commandes VT100. Une fois encore les tests montrent que le code actuel prend bien en compte ces commandes et execute les fonctions correspondantes.

ReX : OK, vous avez confondu les séquences VT100 avec les touches spéciales qui envoyent des codes particulier au PC (les touches de direction). De plus la partie du Wiki "Séquences VT100" n'est pas correcte.

Code VT100 2:

ReX : Une confusion dans la compréhension des codes VT100, programme non conforme de ce côté.

Thomas : Les commandes VT100 fonctionnent correctement. Preuve en vidéo.

ReX : Non, voir commentaire plus haut.

ReX : Vous n'avez fait qu'interpréter les codes VT100 des touches de direction, ce n'est pas ce qui était demandé. Vous pouvez vous en convaincre avec le test suivant : lancez un terminal sans shell xterm -e "tty;sleep 1d" & stty -F /dev/pts/8 raw -echo puis écoutez ce qu'envoye le terminal VT102 avec od -tx1 -Ax < /dev/pts/8 ou envoyez des séquences avec echo -n ^[[4B > /dev/pts/8. Le fichier spécial /dev/pts/8 est celui écrit dans le terminal xterm par la commande tty. Attention il ne faut pas envoyer les deux caractères ^[ mais le caractère ESC, pour cela tapez CTRL-v puis ESC.

Macro GoTo :

ReX : Pour la fonction LCDgotoXY écrire une macro permettant de garder un nombre entre deux bornes, factorisez le code avec cette macro. Dans la même fonction, factorisez le code en utilisant un tableau des adresses de lignes.

Factorisation de code :

ReX : factoriser le code de la fonction DataPortWrite4bits en particulier en transformant les 4 écritures en une boucle de 4 itérations, optimisez en comparant avec des constantes de type 1 << 7 plutôt qu'en décalant une variable. Même chose pour la fonction DataPortWrite8bits.

ReX : Factoriser le code de l'initialisation des registres DDR.

Calcul de Baud :

ReX : Merci d'effectuer le calcul dans le code à partir d'un paramètre en bauds.

Commentaire personnel :

ReX : Dommage, vos trop nombreuses approximations et votre mauvaise volonté font oublier le succès de programmation du contrôleur d'affichage.

ReX : Succès s'entendait dans les conditions limitées que vous vous êtes vous même fixées.