Accueil Articles Arduino en pratique - Partie 1 : Manipulation du module d'affichage

Arduino en pratique - Partie 1 : Manipulation du module d'affichage

module d'affichage

Fonctionnement de base du module d'affichage LCD Arduino

L'appareil fini se compose de blocs fonctionnels qui peuvent souvent être utilisés plusieurs fois. Par exemple, si nous construisons un fréquencemètre avec un microcontrôleur - alors, à part le bloc amplificateur - nous aurons besoin à peu près des mêmes composants que pour construire une minuterie. Nous nous référons à un microcontrôleur avec un "environnement" (résistances, condensateurs, quartz et autres), écran, boutons et connecteurs. Bien sûr, le compteur de fréquence n'aura pas besoin d'un relais pour commuter l'appareil externe et la minuterie de l'amplificateur d'entrée à large bande, mais le noyau sera toujours le même. Par conséquent, la clé du développement autonome des applications consiste à comprendre les principes de fonctionnement des blocs fonctionnels individuels, puis à assembler leurs fonctionnalités.

Les plates-formes comme Arduino n'exigent pas que l'utilisateur connaisse le principe de fonctionnement des composants individuels. Vous pouvez simplement connecter la carte principale au module d'extension/couvercle et exécuter une application fonctionnelle. En revanche, si nous n'avons pas au moins une connaissance de base sur les composants, alors en cas de problème de fonctionnement de notre appareil, nous sommes condamnés à errer dans le noir. Pendant ce temps, lorsque nous recherchons des composants Arduino, la plupart du temps, nous nous attendons à un effet rapide. Il est assez difficile de concilier de tels espoirs avec la nécessité d'acquérir les connaissances appropriées, puisqu'il suffit d'entrer certaines commandes pour pouvoir voir les premiers effets à l'écran, mais comprendre pourquoi cela s'est produit prend parfois beaucoup de temps.

Compte tenu des divergences décrites précédemment, chacun des articles de cette série sera divisé en 2 parties. Dans le premier, nous allons vous montrer comment obtenir l'effet. La deuxième partie présentera le fonctionnement d'un certain composant ou d'une solution.

Nous allons commencer par le module d'affichage LCD, car grâce à lui, vous pouvez voir l'effet du travail effectué plus rapidement. Maintenant, nous allons nous intéresser aux autres éléments de l'interface utilisateur puis aux systèmes externes sélectionnés : capteurs et actionneurs. En attendant, nous nous familiariserons également avec certaines astuces et méthodes de programmation. Et tout cela basé sur la plate-forme Arduino, qui est bon marché, facile d'accès et, en plus, cela vous permettra d'utiliser les connaissances acquises pour construire des appareils préfabriqués ou leurs prototypes.

Module d'affichage de caractères LCD Arduino

L'interface de base entre le microcontrôleur et l'utilisateur se compose généralement d'un écran et d'un bouton ou de boutons. Comme vous pouvez facilement le deviner, le premier est utilisé pour informer l'utilisateur sur les activités du microcontrôleur, tandis que les boutons, parfois remplacés par le bouton poussoir, peuvent être utilisés pour entrer des commandes ou des données. Vous pouvez trouver de nombreux écrans en vente (y compris ceux avec un pavé tactile), mais les affichages de caractères avec le moniteur HD44780 sont devenus une norme informelle.

Dans le premier exemple de programmation, nous utiliserons une carte Arduino UNO R3, une planche à pain, un module LCD de caractères avec deux lignes de seize caractères chacune, et quelques câbles de connexion. Bien sûr, ce n'est qu'une suggestion : l'écran peut être connecté de n'importe quelle manière, par exemple en le soudant au PCB. Ici, la procédure qui offre la plus grande possibilité de modifier et de changer la conception de la connexion a été utilisée.

Si le module d'affichage a des broches soudées à l'or, connectez-le simplement à la carte de contact. Ensuite, nous connectons l'écran avec la carte Arduino UNO, comme décrit dans le tableau 1.

Nombre de contacts d'écran Afficher le nom du signal Nom du connecteur Arduino Nom du signal Arduino
1 VSS Puissance GND
2 VDD Puissance + 5V
3 V0 Puissance GND
4 RS Entrée analogique A4 (PC4)
5 R / W Puissance GND
6 E Entrée analogique A5 (PC5)
7 DB0 - -
8 DB1 - -
9 DB2 - -
10 DB3 - -
11 DB4 Entrée analogique A0 (PC0)
12 DB5 Entrée analogique A1 (PC1)
13 DB6 Entrée analogique A2 (PC2)
14 DB7 Entrée analogique A3
15 (facultatif) LED + Puissance 3.3V
16 (facultatif) LED Puissance GND

 

Tableau 1. Connexions de l'afficheur de caractères avec la carte Arduino UNO

N'oubliez pas que, par exemple, en ayant GND connecté de la prise d'alimentation à la carte d'en-tête, vous pouvez établir des connexions sur la carte d'en-tête et nous n'avons pas à nous connecter à la prise d'alimentation à chaque fois.

L'utilisation du connecteur qualifié d'Alimentation est précise car il permettra d'alimenter l'écran. Le connecteur Analogi In est monté juste à côté, donc pour plus de commodité, il a été décidé d'utiliser les broches libres du microcontrôleur. Cependant, ne laissez pas le nom nous tromper : les sorties numériques sont nécessaires pour surveiller le module d'affichage, pas les E/S analogiques. Le connecteur est appelé Analog In car il dispose d'entrées analogiques en option, qui peuvent cependant également être configurées pour fonctionner dans d'autres modes, y compris les sorties numériques. Et de cette façon, l'entrée analogique A0 est le port PC0, A1 - PC1, etc. (voir: câbles du microcontrôleur ATmega328PU).

Parmi les nombreuses possibilités de pilotes logiciels libres pour Arduino, une bibliothèque a été choisie pour surveiller le fonctionnement de l'écran LiquidCrystal. Après avoir créé l'esquisse, nous l'inclurons dans la première ligne du programme avec une directive #include. Avec l'écran connecté au microcontrôleur comme décrit précédemment, vous pouvez commencer à faire votre premier croquis de contrôle du module d'affichage LCD.

Nous connectons la carte Arduino au port USB de notre ordinateur. Dans le menu Arduino, choisissez Fichier puis Nouveau (Ctrl+N). Une fenêtre similaire à celle de la figure 1 apparaîtra.Le mot-clé void nous indique que c'est ici qu'une fonction sera créée qui ne renverra aucune valeur. Le mot void est suivi du nom de la fonction, et l'accolade ouvrante fermante "undefined" marque sa fin.

Lors de la création d'un nouveau sketch, l'environnement Arduino signale la nécessité de délimiter 2 fonctions spéciales : un void setup(), qui décrit la configuration du microcontrôleur et contient des instructions exécutées une fois au début du programme, et void loop() , qui contient des activités effectuées dans une boucle sans fin.

Arduino
Figure 1. Nouvelle fenêtre de croquis pour Arduino

Pourquoi un programme d'application devrait-il s'exécuter dans une boucle infinie ? Les applications Windows ou Linux s'exécutent sous le contrôle du système d'exploitation. Si nous exécutons l'application sous Windows, une fois le travail terminé, il revient à l'endroit où il a été appelé et, par conséquent, plus fréquemment pour afficher l'appel sur le bureau, la ligne de commande, etc. À partir de ce moment, le système d'exploitation prend le contrôle du processeur. Le microcontrôleur de la carte Arduino UNO n'a pas de système d'exploitation chargé, le programmeur doit donc s'assurer que l'application s'arrête en toute sécurité. Cela peut être fait en éteignant le microcontrôleur (par exemple, en le mettant en mode veille) ou en bouclant l'exécution des instructions pour éviter d'exécuter des instructions en dehors de la plage de mémoire requise. Cela peut être fait dans la fonction void loop() ou dans une autre procédure, dont un exemple est donné ci-dessous.

Avant d'afficher des informations à l'écran, le microcontrôleur doit être configuré. Dans ce scénario, il vous suffit de configurer correctement les sorties de contrôle d'affichage.

Au début de notre esquisse, nous avons inclus une bibliothèque de fonctions d'affichage :

#include <LiquidCrystal.h>

Ainsi, pour notre commodité et la lisibilité du programme, en utilisant la directive #define nous définissons les noms des broches - sorties du port C du microcontrôleur :

//purto PC
#define pc0  A0
#define pc1  A1
#define pc2  A2
#define pc3  A3
#define pc4  A4
#define pc5  A5

Maintenant, nous informons le microcontrôleur des broches auxquelles l'écran est connecté. Pour ce faire, la fonction lcd() est utilisée, dans laquelle la liste de raisonnement indique au processeur où va chaque signal. Lors du remplacement des broches, maintenez le bon ordre : LCD LiquidCrystal (RS, Enable, D4, D5, D6, D7). Lors de la création d'une liste de raisonnement, nous utiliserons le tableau 1, qui contient une liste de connexions entre l'Arduino et le module LCD : LiquidCrystal lcd(pc4, pc5, pc0, pc1, pc2, pc3).

Vous devez maintenant vous occuper de la configuration du mode de fonctionnement des broches; vous devez les configurer pour fonctionner comme des sorties numériques. Cette configuration est enregistrée dans la fonction void setup() :

pinMode(pc0, OUTPUT);
pinMode(pc1, OUTPUT);
pinMode(pc2, OUTPUT);
pinMode(pc3, OUTPUT);
pinMode(pc4, OUTPUT);
pinMode(pc5, OUTPUT);

Nous effectuons donc l'initialisation de l'écran, en définissant le nombre de colonnes, de lignes et dans l'étape initiale, en effaçant l'écran. Après l'initialisation, l'écran LCD doit être vide, mais pour des raisons de sécurité et de principe de fonctionnement pratique, il vaut la peine de suivre ces instructions plus en détail :

lcd.begin(16, 2);
lcd.clear();

Après tout, une commande suffit pour afficher le message :

lcd.print("Hello!");

Nous ne mettons aucune commande dans la fonction loop(). Après avoir affiché le message, le programme "tournera" simplement dans une boucle sans fin, faisant perdre du temps CPU. Pour commencer, il serait possible à ce stade, par exemple, d'entrer en mode d'économie d'énergie, car le message à l'écran ne changerait pas de toute façon, mais cela nécessiterait plus de recherche de matériel, ce qui n'est pas pratique à ce stade. .

L'ensemble du programme qui affiche le message "Hello!" peuvent être trouvés dans les matériaux supplémentaires de ce texte. Si la description précédente et l'effet obtenu sont satisfaisants, vous pouvez supprimer la lecture du reste du texte. Dans le prochain article, nous couvrirons des opérations un peu plus avancées sur le contenu affiché que le simple affichage du message.

Fonctionnement du module d'affichage LCD

Une analyse plus détaillée du sujet devrait commencer par discuter de la structure du microcontrôleur qui est monté sur la carte Arduino, mais c'est un sujet très vaste. Par conséquent, nous allons d'abord examiner le fonctionnement du module LCD.

Une connaissance de base des puces mémoire et des puces numériques est généralement requise pour comprendre comment surveiller le module LCD. La connaissance de termes tels que logique haut, logique bas, forme d'onde, données, huit bits, octet, bit, front montant et descendant est essentielle. Ceci est nécessaire car, du point de vue du manipulateur, le module d'affichage est vu comme une sorte de mémoire numérique avec laquelle le microcontrôleur peut communiquer de manière bidirectionnelle. Alors qu'en fait, le module d'affichage LCD possède son microcontrôleur (c'est celui mentionné au début HD44780 ou similaire), qui non seulement reçoit les données à afficher, mais exécute également les commandes liées au fonctionnement du module LCD. et il est compatible avec l'écran. Du fait que dans le système, le microcontrôleur intégré au module d'affichage a une fonction autonome strictement spécialisée, de tels systèmes sont souvent appelés esclaves ou esclaves. Le microcontrôleur intégré à la carte Arduino remplit une fonction de contrôle supérieure. En général, ces systèmes sont appelés enseignant ou enseignant. Nous rencontrerons ces concepts à plusieurs reprises dans les descriptions de plusieurs appareils connectés au microcontrôleur.

"0" et "1" logiques

Revenons un instant aux fondamentaux. Dans les circuits CMOS, et la plupart des circuits intégrés modernes sont utilisés dans cette technologie, le "1" logique correspond à au moins quatre-vingt-quinze pour cent de la tension d'alimentation et le "0" logique est soit une tension inférieure, soit égale à 0.3 V. Si le circuit du processeur a une alimentation intégrée, ce qui est souvent le cas avec des processeurs plus complexes, le "1" logique est défini en référence à l'alimentation interne. Cela peut aussi être différent – ​​si le système CMOS a des entrées compatibles avec les niveaux TTL, alors le « 1 » logique est une tension supérieure à 4 V. Par conséquent, en cas de doute, il vaut la peine de consulter la fiche technique d'un système donné. On le trouve facilement sur Internet.

Pente ascendante et descendante

Un changement de niveau logique provoque un changement de tension. Ce changement est généré par des étapes excessives, mais néanmoins, dans le temps. Lorsque le niveau passe de "0" à "1", c'est un front montant, et lorsqu'il passe de "1" à "0", c'est un front descendant. La durée de la transition est appelée respectivement temps de montée ou temps de descente. Généralement, il s'agit de quelques nanosecondes, mais ce n'est pas forcément le cas.

Dans un microcontrôleur, une seule ligne portant le niveau "0" ou "1" est appelée un bit de données. huit de ces lignes font un octet. Un microcontrôleur AVR, comme l'Arduino UNO intégré, a un mot de données de huit \ bits, il peut donc traiter des mots de 1 octet, décimal 0...XNUMX. Si le nombre est supérieur à XNUMX, vous devez le diviser en "morceaux", effectuer une opération dessus, puis aplatir le résultat. Cependant, nous ne devrions pas nous en soucier, car le compilateur Arduino le fait en arrière-plan. Cependant, vous devez garder à l'esprit que plus une certaine variable nécessite de bits, plus elle sera traitée par le microcontrôleur.

Contrôle du module d'affichage LCD

Dans ce cas, le microcontrôleur de l'enseignant contrôle le module d'affichage LCD avec des signaux de sortie. En commutant ses signaux de sortie, il contrôle les niveaux logiques aux entrées du module d'affichage. Grâce à cela, vous pouvez choisir quand enregistrer les données et la zone mémoire dans laquelle les données doivent être enregistrées :

Le "1" logique à l'entrée RS (Record Select) enregistre les données dans la mémoire d'image, tandis que le "0" logique enregistre les données dans le registre de contrôle du module d'affichage. Le microcontrôleur enseignant doit pouvoir superviser cette entrée afin de bien envoyer les commandes au superviseur d'affichage (RS=0) et les données à afficher (RS=1). Court-circuiter cette entrée à un niveau logique haut constant empêchera le module d'affichage d'exécuter des commandes de type "clear screen" et ne permettra pas une initialisation correcte (le registre de contrôle ne sera pas libre).
Le "1" logique sur l'entrée R/W (lecture/écriture) lit les données et le "0" logique écrit.

Dans notre exemple, nous forçons en permanence cette entrée du module LCD à l'état bas en la connectant à la masse. C'est suffisant en supposant que nous allons seulement écrire des données sur l'écran et non les lire. En ajoutant cette entrée au niveau logique incessant, on perd la possibilité de lire la mémoire de l'afficheur et son registre de contrôle, et donc le signal "occupé". Le test "Busy" accélère le travail du module d'affichage et vous permet également de tester l'exactitude de la réponse de votre superviseur aux données reçues, mais il occupe également une ligne de port auxiliaire du microcontrôleur enseignant et nécessite une connexion supplémentaire et complique la programmation. servir un peu.

Le front descendant à l'entrée AND Also (Enable) réécrit les niveaux logiques (constitués de mots de données de quatre ou huit bits) des entrées DB0…DB7 vers la mémoire interne du module LCD.

Lors de la surveillance du fonctionnement du module d'affichage de caractères LCD, nous avons à notre disposition 2 modes de fonctionnement, généralement huit bits et quatre bits. Dans le premier, la connexion de l'écran nécessite au moins dix lignes de données (RS, Y également, D0…D7). Du point de vue du superviseur, ce mode est très efficace si vous pouvez connecter un écran au système hôte en tant que mémoire sur un bus de données à huit bits. L'adressage du module d'affichage définit l'entrée d'activation haute, basse ou haute (selon qu'il s'agit d'une commande ou de données à apprendre) sur RS, place les données sur le bus et modifie le niveau sur Activer bas. Dans certains systèmes, le superviseur facilite grandement cela.

En mode parfait à quatre bits, nous utilisons toujours le mot à huit bits, mais seules les entrées D4…D7 du module d'affichage sont connectées au système hôte, et les mots de données à huit bits sont divisés en 2 parties de quatre bits. chaque. Cela complique le calendrier de maintenance et ne permet pas une connexion simple du module d'affichage au système de supervision, mais économise quatre lignes GPIO du microcontrôleur.

Dans les gestionnaires de modules LCD simplifiés qui n'utilisent pas les lignes R/W a priori, on suppose que le module d'affichage fonctionne correctement. Un certain temps prédéterminé est défini, tel que l'exécution de la commande d'exécution la plus longue (généralement environ deux millisecondes), et il est supposé qu'après ce temps, l'affichage a exécuté la commande ou affiché un caractère et les données suivantes peuvent être envoyées. En général, le microcontrôleur intégré au module d'affichage est plus rapide : la simple exécution de la commande clear (nettoyage de l'écran) prend jusqu'à deux millisecondes. En revanche, si, comme dans ce cas, nous avons deux lignes de huit caractères à l'écran, alors peu importe que nous envoyions seize octets en trente-deux millisecondes ou en cent microsecondes. Aucun utilisateur ne pourra l'apprécier de toute façon. Cela ne change que dans le cas d'affichages graphiques auxquels une quantité de données considérablement plus importante est transmise.

Arduino ne nous laisse pas beaucoup de latitude pour surveiller l'écran. Le microcontrôleur ATmega328 intégré à l'Arduino UNO n'a pas de lignes d'adresse externes, il est donc hors de question de surveiller l'affichage en mode adressable huit bits comme la mémoire externe. Cependant, si nous utilisons un port GPIO, plus pour surveiller le signal R/W, nous pouvons tester le drapeau occupé et lire le contenu des registres et de la mémoire du module LCD.

La fonction du même nom, c'est-à-dire LiquidCrystal(), permet de configurer la procédure d'attachement de l'écran dans la bibliothèque LiquidCrystal.h. La manière d'ajouter l'écran est déterminée par la fonction qui appelle la liste d'arguments :

LiquidCrystal (rs, enable, d4, d5, d6, d7) - interface XNUMX bits, pas de module d'affichage, contrôle d'entrée R/W, et donc pas de lisibilité des données.
LiquidCrystal (rs, rw, enable, d4, d5, d6, d7) - Interface à quatre bits, avec contrôle de l'entrée R/W du module LCD et possibilité de lire les données de l'écran.
LiquidCrystal (rs, enable, d0, d1, d2, d3, d4, d5, d6, d7) - Interface huit bits, mais ne peut pas lire les données.
LiquidCrystal (rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7) - Interface à huit bits, données intelligibles.

Le superviseur HD44780 est un système universel, réglé pour accepter des écrans LCD avec un nombre différent de caractères (colonnes et lignes). Par conséquent, après la mise sous tension, le superviseur "ne sait pas" quel écran est connecté et doit être configuré pour un fonctionnement correct. Dans Arduino, la fonction begin() est utilisée pour cela, dont les justifications sont le nombre de colonnes et le nombre de lignes. Par exemple, si vous avez un écran avec deux lignes de seize caractères, nous appellerons begin(seize, deux).

Le programme d'exemple utilise également la fonction clear() pour effacer l'écran. Il est recommandé de l'utiliser en premier, après avoir initialisé le module LCD, car nous pouvons rencontrer des écrans affichant des caractères aléatoires après l'initialisation. Nous utilisons également la fonction print(). Son raisonnement est la donnée à afficher, comme un nombre ou du texte, et - dans le cas des nombres - une base, qui pour les nombres décimaux est "DEC", binaire "BIN", hexadécimal "HEX", octal "OCT" . La fonction print() s'occupe de transformer les nombres pour nous, si nous avons besoin de les afficher dans différents systèmes de nombres :

print(ten) ou bien print(ten, DEC) -> provoque l'affichage 10,
print(ten, BIN) -> provoque l'affichage 1010,
print(ten, HEX) -> provoque l'affichage A,
print(ten, OCT) -> provoque l'affichage 12.
print("Hello!") -> provoque l'affichage du Hello!

Imprimer définit les caractères affichés à partir de l'emplacement actuel du curseur. Habituellement, après la commande clear(), le curseur se trouve dans le coin supérieur gauche de l'écran LCD. La bibliothèque de fonctions LiquidCrystal.h contient de nombreuses autres fonctions utiles, mais nous verrons comment les utiliser dans le prochain article. En ce qui concerne le début, nous avons apporté beaucoup de connaissances, il est temps de se reposer un peu.