mercredi 11 septembre 2019

Écran OLED SH1106 I2C et ESP32 ou ESP8266


Aujourd'hui, explorons comment écrire et dessiner sur un petit écran OLED monochrome branché à une carte ESP32 ou ESP8266.

L'écran en question a une taille de 1,3 pouce (environ 3,5 cm X 1,8 cm) et une résolution de 128 X 64 pixels. Il est basé sur le contrôleur SH1106 et utilise le protocole I2C. L'image produite est blanche sur fond noir.

Cet billet pourrait possiblement vous être utile même si vous utilisez un écran différent de celui que j'ai utilisé, puisque la bibliothèque u8g2 est compatible avec un très grand nombre de modèles d'écrans monochromes.

Connexions de l'afficheur à l'ESP32

  • Broche GND de l'afficheur - Broche GND de l'ESP32
  • Broche VCC de l'afficheur - Broche 3V3 de l'ESP32
  • Broche SCL de l'afficheur - Broche GPIO 22 de l'ESP32
  • Broche SDA de l'afficheur - Broche GPIO 21 de l'ESP32

Connexions de l'afficheur à l'ESP8266

  • Broche GND de l'afficheur - Broche GND de l'ESP8266
  • Broche VCC de l'afficheur - Broche 3V3 de l'ESP8266
  • Broche SCL de l'afficheur - Broche GPIO 5 de l'ESP8266
  • Broche SDA de l'afficheur - Broche GPIO 4 de l'ESP8266

Installation de la bibliothèque u8g2

Nous utiliserons la bibliothèque u8g2, qui peut facilement être installée depuis le gestionnaire de bibliothèques de l'IDE Arduino.

Essai des exemples fournis avec la bibliothèque


Évidemment, plusieurs exemples sont fournis avec la bibliothèque. Cependant, puisque la bibliothèque supporte plusieurs modèles d'écrans différents, chaque fichier d'exemple débute par une longue liste de constructeurs: il faut décommenter la ligne qui correspond au modèle d'écran que vous utilisez (dans mon cas: SH1106 128X64  I2C).


Écriture de texte à l'écran

Plusieurs dizaines de polices de caractères peuvent être utilisées pour écrire du texte à l'écran (voir la liste complète). Si vous désirez utiliser des caractères accentués, il est important de choisir une police dont le nom se termine par "f", ce qui indique que la police inclut tous les caractères nécessaires. De plus, la fonction "enableUTF8Print()" doit être appelée au démarrage du programme.


  • enableUTF8Print: pour permettre l'utilisation de caractères accentués
  • setFont: pour choisir une police de caractère
  • setCursor: pour choisir l'endroit sur l'écran où on désire écrire du texte
  • print: écriture du texte à la position du curseur

Dans un premier temps, le texte est écrit en mémoire (buffer). Il faut ensuite utiliser sendBuffer() pour transférer l'image à l'écran.



Dessiner des formes géométriques


Plusieurs fonctions facilitent le traçage de formes géométriques à l'écran:
  • drawPixel: pour dessiner un point
  • drawLine: pour dessiner une ligne droite
  • drawFrame: pour dessiner un contour de rectangle (vide)
  • drawBox: pour dessiner un rectangle plein
  • drawCircle: pour dessiner un contour circulaire (vide)
  • drawDisc: pour dessiner un cercle plein
  • drawTriangle: pour dessiner un triangle


Afficher un bitmap XBM



La fonction drawXBMP permet de tracer à l'écran une image bitmap de type XBM. J'ai obtenu de bons résultat en sauvegardant un petit dessin en format .xbm avec le logiciel Gimp, puis en ouvrant le fichier obtenu avec un éditeur de texte: j'en ai tiré le contenu de la variable "logoBitmap" dans le sketch de démonstration ci-dessous.


Un sketch

Pour finir, voici mon sketch complet,  qui fait apparaître des dessins et du texte à l'écran.


/*******************************************************
Utilisation d'un écran OLED avec ESP32, ESP8266 ou STM32
(bibliothèque u8g2)
Plus d'infos:
https://electroniqueamateur.blogspot.com/2019/09/ecran-oled-sh1106-i2c-et-esp32-ou.html
https://electroniqueamateur.blogspot.com/2019/11/ecran-oled-sh1106-i2c-et-stm32.html
********************************************************/
#include <U8g2lib.h>
#include <Wire.h>
U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);
// U8G2_R0 ou U8G2_R2: mode paysage, U8G2_R1 ou U8G2_R3: mode portrait
/* Définition d'une image bitmap: logo du blog Électronique en Amateur
sauvegardé dans un fichier XBM, puis ouvert avec un éditeur de texte: */
static const unsigned char logoBitmap[] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0x06, 0xf0, 0xff, 0x03, 0x3f, 0x04,
0x00, 0xf8, 0x03, 0x1f, 0x06, 0x00, 0x80, 0x03, 0x0f, 0x84, 0x0f, 0x85,
0x03, 0x07, 0x86, 0x9f, 0x8f, 0x03, 0x07, 0xc4, 0xdf, 0x8f, 0x03, 0x03,
0xc4, 0xff, 0x9f, 0x03, 0x03, 0xc6, 0xff, 0x9f, 0x03, 0x03, 0xc4, 0xf9,
0x9f, 0x03, 0x03, 0xc4, 0x70, 0x8e, 0x03, 0x03, 0xc4, 0x30, 0x8c, 0x03,
0x03, 0x84, 0x39, 0x84, 0x03, 0x03, 0x04, 0x6f, 0x86, 0x03, 0x03, 0x04,
0xc4, 0x81, 0x03, 0x03, 0x84, 0x01, 0x80, 0x03, 0x03, 0x84, 0x01, 0x98,
0x03, 0x03, 0x04, 0x03, 0x98, 0x03, 0x03, 0x04, 0x0e, 0x8e, 0x03, 0x03,
0x0c, 0xf8, 0x83, 0x03, 0x03, 0xff, 0x17, 0x80, 0x03, 0x83, 0x00, 0xfc,
0x97, 0x03, 0x63, 0x00, 0x00, 0xfc, 0x03, 0x23, 0x00, 0x00, 0x80, 0x03,
0x13, 0x00, 0x00, 0x80, 0x03, 0x0b, 0x00, 0x00, 0x80, 0x03, 0x8f, 0x07,
0x00, 0x80, 0x03, 0x07, 0x06, 0x06, 0x80, 0x03, 0x03, 0x07, 0x07, 0x86,
0x03, 0x03, 0x06, 0x86, 0x86, 0x03, 0x03, 0x06, 0x06, 0x86, 0x03, 0x03,
0x06, 0x06, 0xc6, 0x03, 0x07, 0x07, 0x06, 0xe6, 0x03, 0x0f, 0x06, 0x06,
0xf6, 0x03, 0x1f, 0x06, 0x06, 0xf6, 0x03, 0xff, 0x06, 0x06, 0xf6, 0x03,
0xff, 0x06, 0x76, 0xf6, 0x03, 0xff, 0x76, 0x76, 0xf6, 0x03, 0xff, 0x76,
0x76, 0xf6, 0x03, 0xff, 0x76, 0x76, 0xf6, 0x03, 0xff, 0x76, 0x76, 0xf6,
0x03, 0xff, 0x76, 0x76, 0xf6, 0x03, 0xff, 0x76, 0x76, 0xf6, 0x03, 0xff,
0x76, 0x76, 0xf6, 0x03, 0xff, 0x76, 0x76, 0xf6, 0x03, 0xff, 0x70, 0x74,
0xf6, 0x03, 0xff, 0x7f, 0x7c, 0xf0, 0x03, 0xff, 0xff, 0xff, 0xf8, 0x03
};
void setup(void) {
u8g2.begin();
u8g2.enableUTF8Print(); //nécessaire pour écrire des caractères accentués
}
void loop(void) {
/********* On dessine le logo (bitmap défini plus haut) ***************/
u8g2.clearBuffer(); // on efface ce qui se trouve déjà dans le buffer
u8g2.drawXBMP( 2, 8, 34, 48, logoBitmap); // position, largeur, hauteur
/************** On écrit "Électronique en amateur" *********************/
u8g2.setFont(u8g2_font_7x13B_tf); // choix d'une police de caractère
u8g2.setCursor(40, 25); // position du début du texte
u8g2.print("Électronique"); // écriture de texte
u8g2.setCursor(70, 35);
u8g2.print("en");
u8g2.setCursor(55, 45);
u8g2.print("amateur");
u8g2.sendBuffer(); // l'image qu'on vient de construire est affichée à l'écran
delay(2000);
/******************** Dessiner une ligne ******************************************/
u8g2.clearBuffer(); // on efface tout
// ligne horizontale au centre de l'écran
u8g2.drawLine(0, 32, 128 , 32); // point de départ, point d'arrivée
// ligne verticale au centre de l'écran
u8g2.drawLine(64, 0, 64, 64);
/********************* Dessiner des contours de formes géométriques ******************/
u8g2.drawFrame(15, 5, 30, 15); // coin supérieur gauche, coin inférieur droit
u8g2.drawCircle(95, 15, 8); // centre et rayon
u8g2.drawRFrame(15, 40, 30, 16, 5); // coin supérieur gauche, coin inférieur droit, rayon du coin
//il n'y a pas de fonction pour tracer un triangle vide
u8g2.drawLine(95, 40, 80, 55);
u8g2.drawLine(80, 55, 110, 55);
u8g2.drawLine(110, 55, 95, 40);
u8g2.sendBuffer();
delay(2000);
/******************* Dessiner des formes géométriqeus pleines *************************/
u8g2.drawBox(15, 5, 30, 15); // coin supérieur gauche, coin inférieur droit
u8g2.drawDisc(95, 15, 8); // centre et rayon
u8g2.drawRBox(15, 40, 30, 16, 5); // coin supérieur gauche, coin inférieur droit, rayon du coin
u8g2.drawTriangle(95, 40, 80, 55, 110, 55); // les 3 coins
u8g2.sendBuffer();
delay(2000);
/***************** dessiner pixel par pixel ***********************/
u8g2.clearBuffer();
// on trace une fonction sinusoidale, point par point
for (int x = 1; x < 128; x++) {
int y = 32 + round(16.0 * sin(x / 5.0));
u8g2.drawPixel(x, y);
}
u8g2.sendBuffer();
delay(2000);
/******************* Écrire du texte *******************************/
u8g2.setFont(u8g2_font_ncenB10_tf); // choix de la police
u8g2.clearBuffer();
u8g2.setCursor(5, 20); // position du début du texte
u8g2.print("Caractères"); // on écrit le texte
u8g2.setCursor(5, 35);
u8g2.print("accentués:");
u8g2.setCursor(5, 55);
u8g2.print("ÀàÂâÉéÈèÊêÇç");
u8g2.sendBuffer();
delay(2000);
}
view raw ESP_OLED.ino hosted with ❤ by GitHub


Articles similaires:

J'ai aussi utilisé le même écran OLED avec un Raspberry Pi , avec un Arduino et avec une carte STM32.

Avec l'ESP32 et l'ESP8266, j'ai aussi utilisé ces afficheurs:  écran couleur SPI ST7735afficheur LCD 16 X 2afficheur 7 segments TM1638.

Vous pouvez également consulter la liste de tous mes articles concernant l'ESP8266 et l'ESP32.

Yves Pelletier   (TwitterFacebook)

1 commentaire:

  1. Merci, j'ai pu utiliser mon p'tit écran oled grace à ton code super bien commenté.

    RépondreSupprimer