dimanche 3 novembre 2019

Écran OLED SH1106 I2C et STM32

Le projet d'aujourd'hui consiste à afficher du texte et des images sur un petit écran OLED SH1106 i2c de 128 X 64 pixels. L'écran sera piloté par une carte STM32 (Blue Pill ou Nucleo, par exemple), programmée au moyen de l'IDE Arduino.


Afin de pouvoir programmer une carte STM32 avec l'IDE Arduino, ces cartes doivent préalablement avoir été installées dans l'IDE au moyen de son gestionnaire de cartes. Si ce n'est pas déjà fait, vous pouvez vous référer à ce précédent article.

Installation de la bibliothèque u8g2

Il faut aussi que la bibliothèque u8g2 soit installée. Cette bibliothèque est compatible avec de nombreuses cartes de développement, et avec pratiquement tous les modèles d'écrans monochromes. Le gestionnaire de bibliothèques de l'IDE constitue la façon la plus simple de l'installer.

Connexion de l'écran OLED à une carte STM32 Nucleo

Puisqu'il s'agit d'un périphérique I2C, 4 fils sont suffisants pour brancher l'écran à votre carte de développement.

Sur une carte Nucleo, les connexions sont assez évidentes:
  • GND de l'écran OLED - GND de la carte Nucleo
  • VCC de l'écran OLED - 3V3 de la carte Nucleo
  • SCL de l'écran OLED - SCL de la carte STM32
  • SDA de l'écran OLED - SDA de la carte STM32


Connexions à une Blue Pill

Si vous utilisez une Blue Pill, il faut savoir que les broches B6 et B7 sont consacrées à la communication I2C, car ce n'est pas indiqué sur la carte.
  • GND de l'écran OLED - G de la carte STM32
  • VCC de l'écran OLED - 3V3 de la carte STM32
  • SCL de l'écran OLED - broche B6 de la carte STM32
  • SDA de l'écran OLED - broche B7 de la carte STM32

N.B.: j'ai essayé sans succès de piloter l'écran OLED avec mon STM32F030 Demo Board V1.1, mais la bibliothèque u9g2 semble trop gourmande pour ses 16 kb de mémoire flash.

Sketch de démonstration

Voici un sketch qui écrit et dessine sur l'écran. Il s'agit en fait du sketch que j'avais écrit il y a quelques mois pour contrôler l'écran OLED avec un ESP32. Aucune modification n'a été nécessaire pour le faire fonctionner avec un STM32, et vous pouvez donc consulter ce précédent article pour plus d'explications.

-
/*******************************************************
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

-

À lire aussi

Vous serez peut-être intéressés par ces autres tutoriels qui montrent comment utiliser ce même écran OLED SH1106 avec un Raspberry Pi, un Arduino, un ESP32 ou un ESP8266.

D'autres types d'écrans peuvent être pilotés par une carte STM32: écran couleur ST7735, afficheur 2 X 16, etc.

De plus, vous trouverez ici la liste de tous les projets impliquant les cartes STM32 (programmées avec l'IDE Arduino ou avec mbed).

Yves Pelletier   (TwitterFacebook)

2 commentaires:

  1. simplement merci pour ce travail et la diffusion
    F1CHF

    RépondreSupprimer
  2. MERCI Yves pour ton travail et la diffusion de celui ci et un grand bravo.

    Bernard

    RépondreSupprimer