Electronique > Les bases

9/ L'afficheur LCD

L'afficheur LCD

Nous allons utiliser un afficheur 2 lignes de 16 caractères. Il en existe d'autres, par exemple 4 lignes de 20 caractères.

Comme vous pouvez le voir sur cette image, l'afficheur LCD a besoin de 16 connections ! De plus il faudrait également réaliser la gestion du rétroéclairage (avec résistances, potentiomètre...). 

Pour nous simplifier la tache, nous allons utiliser un afficheur avec gestion du contraste et liaison I2C. On passe à 4 fils :

  • GND
  • VCC (5V)
  • SDA
  • SCL

Le potentiomètre permet de régler le rétroéclairage. (Penser à l'ajuster si vous ne voyez rien lors de votre premier montage).

La liaison I2C

La liaison I2C est un bus qui permet la communication entre circuits (par exemple un microprocesseur et un afficheur LCD). Plusieurs circuits peuvent être connectés sur le même bus en mode maitre ou esclave.

A retenir :

  • Sur le même bus, plusieurs maitres et esclaves peuvent cohabiter.
  • Chaque circuit possède une adresse pour pouvoir communiquer.
  • Un seul maitre communique avec 1 ou plusieurs esclaves.
  • Pas de communication entre maitre.
  • Pas de communication entre esclave.
  • Un maitre peut devenir esclave et vice versa.
  • La masse doit etre commune à tous les circuits.

 

Le branchement

Trouver l'adresse I2C de l'afficheur LCD.

La première étape consiste à trouver l'adresse I2C de notre afficheur LCD. Pour cela nous allons utiliser ce programme (Source : https://playground.arduino.cc/Main/I2cScanner).

 // --------------------------------------
// i2c_scanner
//
// Version 1
//    This program (or code that looks like it)
//    can be found in many places.
//    For example on the Arduino.cc forum.
//    The original author is not know.
// Version 2, Juni 2012, Using Arduino 1.0.1
//     Adapted to be as simple as possible by Arduino.cc user Krodal
// Version 3, Feb 26  2013
//    V3 by louarnold
// Version 4, March 3, 2013, Using Arduino 1.0.3
//    by Arduino.cc user Krodal.
//    Changes by louarnold removed.
//    Scanning addresses changed from 0...127 to 1...119,
//    according to the i2c scanner by Nick Gammon
//    http://www.gammon.com.au/forum/?id=10896
// Version 5, March 28, 2013
//    As version 4, but address scans now to 127.
//    A sensor seems to use address 120.
// Version 6, November 27, 2015.
//    Added waiting for the Leonardo serial communication.
// 
//
// This sketch tests the standard 7-bit addresses
// Devices with higher bit address might not be seen properly.
//

#include "Wire.h"

void setup()
{
  Wire.begin();

  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("nI2C Scanner");
}

void loop()
{
  byte error, address;
  int nDevices;

  Serial.println("Scanning...");

  nDevices = 0;
  for(address = 1; address < 127; address++ ) 
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();

    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");

      nDevices++;
    }
    else if (error==4) 
    {
      Serial.print("Unknown error at address 0x");
      if (address<16) 
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices foundn");
  else
    Serial.println("donen");

  delay(5000);           // wait 5 seconds for next scan
}
  1. Téléverser le programme dans votre Arduino.
  2. Ouvrer le moniteur série (Menu Outils -> Moniteur série).
  3. Vous devriez avoir un message de ce type : 
  4. Dans mon cas l'adresse de l'afficheur LCD est 0x3F.

Premier message sur l'afficheur

Nous avons besoin de la librairie LiquidCrystal I2C : https://github.com/fdebrabander/Arduino-LiquidCrystal-I2C-library

  • Télécharger la librairie en cliquant sur download et download ZIP.
  • Dézipper le fichier.
  • Renommer le dossier en LiquidCrystal_I2C
  • Copier le dossier dans votre dossier libraries :
    • Sous windows : Mes Documents/Arduino/libraries
    • Sous mac : Documents/Arduino/libraries
  • Redémarrer votre IDE Arduino.
//on charge les librairies
#include "Wire.h" 
#include "LiquidCrystal_I2C.h"


// On définit l'adresse de notre LCD (0x3F), puis le nombre de caractère par ligne (16).
// Puis le nombre de ligne (2).
LiquidCrystal_I2C lcd(0x3f, 16, 2);

void setup()
{
  // On initialise le LCD
  lcd.begin();

  // On allume le rétroéclairage
  lcd.backlight();

  //On affiche le message.
  lcd.print("Coucou DIYELEC ! ");
}

void loop()
{
}

Ecrire sur 2 lignes

Pour écrire sur la 2ème ligne on va déplacer le curseur avec la commande : 

//On affiche le message de la 1er ligne
//16 caractères max
lcd.print("Coucou");

// On se déplace sur la 2ème ligne
lcd.setCursor(0, 1);

// On affiche le message de la 2ème ligne.
lcd.print("DIYELEC");

D'autres fonctions

//Effacer l'écran et revenir en position 0
lcd.clear();

// Ne pas afficher les caractères
lcd.noDisplay();

// afficher les caractères
lcd.display();

Créer des caractères personnalisés

Vous pouvez créer vos propres caractères, dessins, symboles... Chaque caractère du LCD est composé de 8 lignes et 5 colonnes (40 points). En fonction des points que vous allez allumer, cela va créer une forme :

         
         
         
         
         
         
         
         

Il suffit de convertir chaque ligne en binaire (0: éteint, 1: allumé) dans votre code Arduino.
Exemple pour le symbole euro : 

byte euro[8]={
  B00000,
  B00110,
  B01000,
  B11110,
  B01000,
  B11110,
  B01000,
  B00110
};

Ensuite il faut déclarer le symbole dans la bibliothèque lcd grâce à la fonction createChar et l'afficher avec la fonction write : 

void setup() {
   // On initialise le LCD
  lcd.begin();

  // On allume le rétroéclairage
  lcd.backlight();
  lcd.clear();
  
  // On déclare le caractère
  lcd.createChar(0, euro); 

  // On l'affiche.
  lcd.setCursor(0,0);
  lcd.write(0);
}

Voici une adresse vous permettant de créer vos symboles facilement : 
http://alx.github.io/deuligne-custom-char/

Gérer les accents

Voici un exemple de code qui permet d'afficher correctement les accents.
Tout est expliqué dans le code.

// Caractères accentués
// Pour une meilleure lisibilité du code
// on a utilisé l'équivalent décimal au lieu de binaire
uint8_t eAigu[8] = {130,132,142,145,159,144,142,128};
uint8_t eGrave[8] = {136,132,142,145,159,144,142,128};
uint8_t eCirc[8] = {132,138,142,145,159,144,142,128};
uint8_t aGrave[8] = {136,134,128,142,145,147,141,128};
uint8_t aCirc[8] = {132,138,128,142,145,147,141,128};
uint8_t iCirc[8] = {132,138,128,140,132,132,142,128};
uint8_t uCirc[8] = {132,138,128,145,145,147,141,128};
uint8_t uGrave[8] = {136,134,128,145,145,147,141,128};

//on charge les librairies
#include "Wire.h" 
#include "LiquidCrystal_I2C.h"

// On définit l'adresse de notre LCD (0x3F), puis le nombre de caractère par ligne (16).
// Puis le nombre de ligne (2).
LiquidCrystal_I2C lcd(0x3f, 16, 2);

void setup() {
  // On initialise le LCD
  lcd.begin();

  // On allume le rétroéclairage
  lcd.backlight();
  lcd.clear();

  // On déclare les caractères spéciaux.
  lcd.createChar(0, eAigu);
  lcd.createChar(1, eGrave);
  lcd.createChar(2, eCirc);
  lcd.createChar(3, aGrave);
  lcd.createChar(4, aCirc);
  lcd.createChar(5, iCirc);
  lcd.createChar(6, uCirc);
  lcd.createChar(7, uGrave);

  // On appelle la fonction
  displayTextLcd("éssai d'accents àâçèéêîùû");
}

void loop() {

}

// Fonction qui permet de convertir les accents.
void displayTextLcd(String message) {
  // On compte le nombre de caractère de notre message
  // On ajoute 1 car un type string se termine toujours par le caractère NULL.
  int str_len = message.length()+1; 

  // On crée un tableau de caractère de la longueur du message.
  char char_array[str_len];

  // On rempli le tableau avec chaque caractère.
  message.toCharArray(char_array, str_len);

  // Va nous servir pour la position du caractère.
  int index = 0;

  // pour chaque caractère 
  for(byte i = 0; i < str_len; ++i) {
    // on place le curseur au bon endroit
    // % = Modulo.
    lcd.setCursor(index%16,index/16); 

    // On regarde le code du caractère correspondant
    // Le code du caractère spéciale est toujours précédé du code 195.
    switch((unsigned char) char_array[i]) {
       case 160:
         // à   
         lcd.write(3);
         break;
       case 162:
         // â
         lcd.write(4);
         break;
       case 167:
         // ç
         lcd.print("c");
         break;
       case 168:
         // è
         lcd.write(1);
         break;
       case 169:
         // é
         lcd.write(0);
         break;
       case 170:
         // ê
         lcd.write(2);
         break;
       case 174:
         // î
         lcd.write(5);
         break;
       case 185:
         // ù
         lcd.write(7);
         break;
       case 187:
         // û
         lcd.write(6);
         break;
       case 195:
        // cela annonce que le caractère suivant est un caractère spécial.
        // On décompte de 1, pour éviter d'afficher un espace vide.
        index--;
        break;  
       default:
        // Si c'est un caractère classique on l'affiche normalement.
        lcd.print(char_array[i]);
     }
     // On avance de 1 position pour la prochaine boucle.
     index++;
   }
}