Utiliser une shield LCD de DFRobots avec une carte Arduino / Genuino et la bibliothèque LiquidCrystal

Simple mais efficace

Image d'entête

par skywodd | | Licence (voir pied de page)

Catégories : Tutoriels Arduino | Mots clefs : Arduino Genuino LCD Bouton Shield


Dans ce tutoriel, nous allons apprendre ensemble à utiliser une shield "LCD Keypad" de DFRobots avec une carte Arduino / Genuino et la bibliothèque LiquidCrystal fournie de base avec le logiciel Arduino. En bonus, nous verrons comment faire varier la puissance du rétroéclairage de l'écran LCD.

Sommaire

Bonjour à toutes et à tous !

Dans ce tutoriel, nous allons apprendre à utiliser un grand classique dans le monde de l'Arduino : la shield LCD de DFRobots, aussi disponible pour une dizaine d'euros sur eBay, DealExtreme, Amazon, etc.

PS La carte utilisée pour cet article est une copie chinoise à 12$. C'est cependant exactement la même carte que l'original de DFRobots d'un point de vue fonctionnel.

La shield

Shield Arduino LCD + Keypad

La shield

Cette shield est conçue et fabriquée par DFRobots. Elle est redistribuée / clonée par de nombreux fournisseurs sur divers sites tels que eBay ou DealExtreme. Il existe deux versions : la 1.0, présentée dans cet article et la 1.1, identique à la 1.0 à quelques modifications esthétiques prés.

La carte est très basique ce qui limite son prix. Celle-ci est composée d’un écran LCD alphanumérique de 2 x 16 caractères, d'un potentiomètre de réglage du contraste et d'une série de 6 boutons (haut, bas, droite, gauche, sélection, reset). Ni plus ni moins.

Cette shield est idéale pour quiconque souhaite ajouter un écran LCD et des boutons de contrôle (pour un menu par exemple) à son projet et ceci à moindre coût et surtout sans câblage.

L’écran est de type caractères blanc sur fond bleu. Celui est compatible HD44780 et s'utilise avec la bibliothèque LiquidCrystal fournie de base avec le logiciel Arduino. Aucune installation additionnelle n'est donc nécessaire.

PS Le rendu visuel de l'écran est vraiment très sympa. Le blanc sur bleu est ma couleur de LCD préférée (en plus d'être la plus lisible) :)

La connectique

Cela peut paraitre un peu bizarre de parler de connectique pour une shield Arduino qui ne fait que s'enficher dans une carte Arduino. Cependant, comme toute shield Arduino, la shield LCD utilise un certain nombre de broches pour fonctionner.

Commençons tout d'abord par la partie-écran LCD. L'écran LCD est câblé comme suit :

Broche écran

Broche Arduino

D4 (données)

D4

D5 (données)

D5

D6 (données)

D6

D7 (données)

D7

RS (signal de contrôle données / commandes)

D8

EN (signal début transmission)

D9

Rétro-éclairage

D10 (PWM)

Comme vous pouvez le voir dans le tableau ci-dessus, l'écran LCD utilise les broches D4 à D10 (incluses). Il est donc important de bien faire attention qu'aucune autre shield n'utilise ces broches.

L'utilisation des broches D4 et D10 pose par exemple des problèmes connus de compatibilité avec diverses shields comme la shield Ethernet officielle qui utilise la broche D4 pour le lecteur de carte SD et la broche D10 par le module Ethernet. Le même genre de problème se pose avec les shields SD de Sparkfun et Adafruit qui utilisent la broche D4 pour la communication avec la carte SD. Faites donc bien attention aux broches que vos shield utilisent pour éviter les conflits.

N.B. La broche D10 est utilisée pour la gestion en PWM du rétroéclairage. Par défaut, le rétroéclairage est actif. Vous n'avez donc rien à faire pour l'activer.

La gestion des boutons se fait via la broche A0. Cela peut paraitre un peu bizarre, mais les boutons sont câblés via un réseau de résistances qui permet de "lire" l'état des boutons sous la forme d'une tension analogique. Cette astuce permet de réduire le nombre de broches nécessaire pour les boutons. Attention cependant si votre application ou une de vos shield utilise la broche A0.

PS Le potentiomètre multitours en haut à gauche de la shield permet de régler le contraste de l'écran LCD. Si l'écran LCD vous paraitre trop sombre ou au contraire trop clair, il s'agit d'ajuster ce potentiomètre avec un petit tournevis.

N.B. La shield comporte aussi un port ICSP déporté pour les bricoleurs dans l’âme qui voudraient brancher leur programmateur AVR sur leur Arduino, ou brancher un module SPI via un câble flexible. Je passerai volontairement sous silence l'utilisation de ce connecteur qui est réservé aux utilisateurs expérimentés.

Les boutons

Attardons-nous un instant sur les boutons poussoirs.

Gros plan sur les boutons de la shield Arduino Keypad + LCD

Gros plan sur les boutons de la shield

Comme précisé dans le chapitre précédent, leur câblage est un peu spécial. En réalité, chaque bouton poussoir est câblé à un réseau de résistances qui forment un pont diviseur de tension relativement complexe.

Pour savoir quel bouton a été appuyé, il suffit de faire appel à la fonction analogRead() sur la broche A0 et comparer la valeur lue par rapport à une fourchette de valeurs types.

À titre d'exemple, avec ma shield, j'obtiens les valeurs suivantes :

Bouton

Valeur lue avec analogRead(A0)

aucun

1023

UP (haut)

135

DOWN (bas)

312

LEFT (gauche)

485

RIGHT (droite)

727

SELECT (sélection)

2

Afin de s'accommoder des possibles variations d'une carte à une autre, voici le tableau de valeurs à employer :

Valeur lue avec analogRead(A0)

Bouton

0 <= valeur < 50

RIGHT (droite)

50 <= valeur < 250

UP (haut)

250 <= valeur < 450

DOWN (bas)

450 <= valeur < 650

LEFT (gauche)

650 <= valeur < 850

SELECT (sélection)

>= 850

aucun

PS L'avantage de cette méthode de câblage des boutons est qu'il suffit d’une broche analogique pour lire tous les boutons poussoir. Cependant, cette solution comporte un gros désavantage puisqu’il est impossible de savoir si deux boutons sont appuyés simultanément.

N.B. Le bouton RST (reset) n’est pas utilisable par l’utilisateur. Ce bouton est directement câblé sur la broche RESET de la carte Arduino est permet de redémarrer la carte Arduino ci-besoin.

Le montage de démonstration

Ce montage de démonstration est ci simple, que je ne vais même pas avoir à le décrire ;)

Assemblage shield LCD Keypad + carte Arduino UNO

Assemblage shield LCD Keypad + carte Arduino UNO

Pour réaliser ce montage, il va nous falloir :

  • Une carte Arduino UNO (et son câble USB),

  • Une shield LCD de DFRobots ou similaire.

Prenez la shield, enfichez là par dessus la carte Arduino. Et voilà !

Le code de base avec l'écran seul

Photographie "Hello World !" shield LCD

Hello World !

Commençons par l'utilisation de l'écran LCD seul. Nous allons afficher le classique message "Hello World !".

1
2
/* Dépendances */
#include <LiquidCrystal.h>

Tout d'abord, il est nécessaire d'inclure la bibliothèque LiquidCrystal fournie de base avec le logiciel Arduino dans notre code. Celle-ci va nous permettre de communiquer avec l'écran LCD au moyen de fonctions simples d'usage.

1
2
/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

On va ensuite déclarer une instance de la bibliothèque LiquidCrystal avec les numéros de broches vus dans les chapitres précédents.

PS Vous remarquerez que la gestion de la broche D10 pour le rétroéclairage n'est pas réalisée par la bibliothèque LiquidCrystal. C'est à l'utilisateur de s'en occuper.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
/** Fonction setup() */
void setup() {
 lcd.begin(16, 2);
 lcd.print("Hello World !");
}

/** Fonction loop() */
void loop() {
  // Rien à faire
}

Viennent ensuite les classiques fonction setup() et loop().

La fonction setup() configure l'écran LCD en mode 2 x 16 caractères et affiche le texte "Hello World !". La fonction loop() quant à elle ne fait rien.

Le code complet avec commentaires :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
 * Code de base pour l'utilisation de la shield Arduino LCD de DFRobots (LCD uniquement).
 */

/* Dépendances */
#include <LiquidCrystal.h>


/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


/** Fonction setup() */
void setup() {
 lcd.begin(16, 2);
 lcd.print("Hello World !");
}

/** Fonction loop() */
void loop() {
  // Rien à faire
}

L'extrait de code ci-dessus est disponible en téléchargement sur cette page (le lien de téléchargement en .zip contient le projet Arduino prêt à l'emploi).

N.B On verra plus tard dans un (ou plusieurs) article(s) comment utiliser les diverses fonctions fournies par la bibliothèque LiquidCrystal. Les articles en question seront en liens en bas de page dès que disponibles.

Le code de base avec lire des boutons

Photographie "Exemples boutons" shield LCD

Exemples de code pour les boutons

Maintenant que l'écran LCD est fonctionnel, on va passer à la lecture des boutons.

1
2
3
4
5
/* Dépendances */
#include <LiquidCrystal.h>

/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

Le début du code est identique à celui du chapitre précédent.

1
2
3
4
5
6
7
8
9
/** Énumération des boutons utilisables */
enum {
  BUTTON_NONE,  /*!< Pas de bouton appuyé */
  BUTTON_UP,    /*!< Bouton UP (haut) */
  BUTTON_DOWN,  /*!< Bouton DOWN (bas) */
  BUTTON_LEFT,  /*!< Bouton LEFT (gauche) */
  BUTTON_RIGHT, /*!< Bouton RIGHT (droite) */
  BUTTON_SELECT /*!< Bouton SELECT */
};

première modification, on déclare une énumération de constantes pour nos divers boutons.

PS On pourrait déclarer à la main BUTTON_NONE = 0, BUTTON_UP = 1, etc. Ce serait long et ennuyeux à faire. La syntaxe C nous offre la possibilité de faire cela automatiquement avec les énumérations, autant en profiter ;)

1
2
3
4
5
/** Fonction setup() */
void setup() {
  lcd.begin(16, 2);
  lcd.print("Bouton:");
}

Seconde modification, la fonction setup() va afficher "Bouton:" sur la première ligne de l'écran au lieu de "Hello World !".

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
/** Retourne le bouton appuyé (si il y en a un) */
byte getPressedButton() {

  /* Lit l'état des boutons */
  int value = analogRead(A0);

  /* Calcul l'état des boutons */
  if (value < 50)
    return BUTTON_RIGHT;
  else if (value < 250)
    return BUTTON_UP;
  else if (value < 450)
    return BUTTON_DOWN;
  else if (value < 650)
    return BUTTON_LEFT;
  else if (value < 850)
    return BUTTON_SELECT;
  else
    return BUTTON_NONE;
}

Les choses sérieuses commencent.

La fonction getPressedButton() - dont le code est représenté ci-dessus - permet de lire l'état des boutons de la shield. Cette fonction utilise analogRead(A0) pour lire la tension sur la broche A0 et utilise une série de if else pour tester la valeur lue.

N.B. Les if else sont ordonnés de la plus petite à la plus grande valeur haute.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/** Fonction loop() */
void loop() {

  /* Affiche le bouton appuyé */
  lcd.setCursor(0, 1);
  switch (getPressedButton()) {
  case BUTTON_NONE:
    lcd.print(F("      "));
    break;

  case BUTTON_UP:
    lcd.print(F("UP    "));
    break;

  case BUTTON_DOWN:
    lcd.print(F("DOWN  "));
    break;

  case BUTTON_LEFT:
    lcd.print(F("LEFT  "));
    break;

  case BUTTON_RIGHT:
    lcd.print(F("RIGHT "));
    break;

  case BUTTON_SELECT:
    lcd.print(F("SELECT"));
    break;
  }

  /* Délai pour l'affichage */
  delay(100);
}

Pour cet exemple, j'ai modifié la fonction loop() pour y inclure un switch case (équivalent d'une série de if else) qui permet d'afficher un petit texte lors de l'appui d'un bouton.

N.B. J'ai ajouté des espaces vides en fin de certains textes pour éviter que le texte d'un affichage précédent ne vienne poser problème par la suite.

Le complet avec commentaires :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
/**
 * Code de base pour l'utilisation de la shield Arduino LCD de DFRobots (LCD + boutons).
 */

/* Dépendances */
#include <LiquidCrystal.h>


/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


/** Énumération des boutons utilisables */
enum {
  BUTTON_NONE,  /*!< Pas de bouton appuyé */
  BUTTON_UP,    /*!< Bouton UP (haut) */
  BUTTON_DOWN,  /*!< Bouton DOWN (bas) */
  BUTTON_LEFT,  /*!< Bouton LEFT (gauche) */
  BUTTON_RIGHT, /*!< Bouton RIGHT (droite) */
  BUTTON_SELECT /*!< Bouton SELECT */
};


/** Fonction setup() */
void setup() {
  lcd.begin(16, 2);
  lcd.print("Bouton:");
}

/** Fonction loop() */
void loop() {

  /* Affiche le bouton appuyé */
  lcd.setCursor(0, 1);
  switch (getPressedButton()) {
  case BUTTON_NONE:
    lcd.print(F("      "));
    break;

  case BUTTON_UP:
    lcd.print(F("UP    "));
    break;

  case BUTTON_DOWN:
    lcd.print(F("DOWN  "));
    break;

  case BUTTON_LEFT:
    lcd.print(F("LEFT  "));
    break;

  case BUTTON_RIGHT:
    lcd.print(F("RIGHT "));
    break;

  case BUTTON_SELECT:
    lcd.print(F("SELECT"));
    break;
  }

  /* Délai pour l'affichage */
  delay(100);
}


/** Retourne le bouton appuyé (si il y en a un) */
byte getPressedButton() {

  /* Lit l'état des boutons */
  int value = analogRead(A0);

  /* Calcul l'état des boutons */
  if (value < 50)
    return BUTTON_RIGHT;
  else if (value < 250)
    return BUTTON_UP;
  else if (value < 450)
    return BUTTON_DOWN;
  else if (value < 650)
    return BUTTON_LEFT;
  else if (value < 850)
    return BUTTON_SELECT;
  else
    return BUTTON_NONE;
}

L'extrait de code ci-dessus est disponible en téléchargement sur cette page (le lien de téléchargement en .zip contient le projet Arduino prêt à l'emploi).

Bonus : Ajuster la luminosité du rétroéclairage

Pour certaines applications, le rétroéclairage n'est pas nécessaire, ou du moins, pas tout le temps.

Avec la shield LCD, il est possible, via la broche D10, de contrôler le rétroéclairage. Vous pouvez l'éteindre, l'allumer ou réduire sa luminosité. Pour ce faire, il suffit d'utiliser la fonction analogWrite() sur la broche D10. Une valeur de 0 éteint le rétroéclairage, une valeur de 255 l'allume, et toutes valeurs entre ces deux extrêmes réduisent la luminosité proportionnellement.

1
2
3
4
5
6
7
8
/* Dépendances */
#include <LiquidCrystal.h>

/** Broche pour le contrôle du rétroéclairage */
const byte BACKLIGHT_PWM_PIN = 10;

/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

Pour utiliser cette fonctionnalité, il suffit de déclarer une constante avec le numéro de broche D10.

1
2
3
4
5
6
7
8
/** Fonction setup() */
void setup() {
 analogWrite(BACKLIGHT_PWM_PIN, 0); // Pas de rétroéclairage
 //analogWrite(BACKLIGHT_PWM_PIN, 255); // Rétro-éclairage 100%
 
 lcd.begin(16, 2);
 lcd.print("Hello World !");
}

Ensuite dans la fonction setup(), il convient d'appeler la fonction analogWrite() avec la valeur souhaitée.

N.B. Si vous souhaitez complètement éteindre le rétroéclairage, sans l'utiliser par la suite, placer l'appel à analogWrite() AVANT l'appel à lcd.begin().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
/** Fonction loop() */
void loop() {
  for (int i = 0; i <= 255; ++i) {
    analogWrite(BACKLIGHT_PWM_PIN, i);
    delay(10);
  }
  for (int i = 255; i >= 0; --i) {
    analogWrite(BACKLIGHT_PWM_PIN, i);
    delay(10);
  }
}

Pour l'exemple, j'ai inclus dans la fonction loop() deux boucles qui allument puis éteignent progressivement le rétroéclairage.

Dans une "vraie" application, la modification du rétroéclairage pourrait être conditionnée par un délai sans appui sur un bouton, par un menu, ou autre. À vous d'être créatif ;)

N.B. Une fois l'appel à analogWrite() effectué, la valeur est gardée en mémoire. Inutile donc de périodiquement appeler analogWrite() avec la même valeur.

Le complet avec commentaires :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
 * Code de base pour l'utilisation de la shield Arduino LCD de DFRobots (LCD avec PWM).
 */

/* Dépendances */
#include <LiquidCrystal.h>


/** Broche pour le contrôle du rétroéclairage */
const byte BACKLIGHT_PWM_PIN = 10;

/** Objet LiquidCrystal pour communication avec l'écran LCD */
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);


/** Fonction setup() */
void setup() {
 analogWrite(BACKLIGHT_PWM_PIN, 0); // Pas de rétroéclairage
 //analogWrite(BACKLIGHT_PWM_PIN, 255); // Rétro-éclairage 100%
 
 lcd.begin(16, 2);
 lcd.print("Hello World !");
}

/** Fonction loop() */
void loop() {
  for (int i = 0; i <= 255; ++i) {
    analogWrite(BACKLIGHT_PWM_PIN, i);
    delay(10);
  }
  for (int i = 255; i >= 0; --i) {
    analogWrite(BACKLIGHT_PWM_PIN, i);
    delay(10);
  }
}

L'extrait de code ci-dessus est disponible en téléchargement sur cette page (le lien de téléchargement en .zip contient le projet Arduino prêt à l'emploi).

Conclusion

Ce tutoriel est désormais terminé.

Si ce tutoriel vous a plu, n'hésitez pas à le commenter sur le forum, à le partager sur les réseaux sociaux et à soutenir le site si cela vous fait plaisir.