Accueil / Arduino / Utiliser un écran OLED I2C 128×64 0.96″ SSD1306 (Arduino)

Utiliser un écran OLED I2C 128×64 0.96″ SSD1306 (Arduino)

Dans ce tutoriel, nous allons apprendre comment utiliser un mini écran OLED monochrome de 0.96 pouces affichant de 128 x 64 pixels piloté par un micro-contrôleur SSD1306 à la norme I2C. Vous pouvez trouver cet écran chez Adafruit ou Sparkfun pour ne situer que ces deux fabricants mais également de nombreux clones Asiatiques si vous n’êtes pas pressé par le délai de livraison. Vous pouvez trouver sur les sites Asiatiques des écrans OLED à base de SSD1306 pour moins de 6€.

Câblage de l’écran OLED I2C SSD1306 128×64 0.96″

L’utilisation de l’interface I2C permet de réduire très fortement le câblage de cet écran OLED. Cet écran n’étant pas disponible dans la librairie d’Adafruit, je l’ai remplacé par son cousin plus petit, 128 x 32 pixels. L’écran est alimenté en 3.3V, il utilise le même micro-contrôleur SSD1306.

Si vous disposez d’un Arduino Uno, relié le Pin A4 sur le Pin SDA (Serial DAta) de l’écran et le port A5 sur le Pin SCL (Serial CLock). Certaines cartes disposent directement des Pins dédiés SDA/SCL. Sinon, voici un petit tableau qui récapitule les connecteurs SDA et SCL pour différentes cartes Arduino courantes (d’après cet article).

CarteSDASCL
arduino uno r3Arduino UnoA4A5
arduino-mega-2560-sainsmartArduino Mega20

Marqué SDA

21

Marqué SCL

Arduino LeonardoD2D3

 

ecran oled i2c ssd1306 arduino

Matériel nécessaire pour ce projet

Pour réaliser le montage de ce projet vous aurez besoin du matériel suivant (liens commerciaux) :

arduino uno r3Arduino Uno R3x1caddy
ssd1331 color oled displayEcran OLED I2C 0.96 » monochrome (SSD1306)x1caddy
jumper dupontJumper Dupont x4caddy

Trouver le port I2C sur lequel sur trouve le SSD1306

Avant de pouvoir utiliser l’écran OLED SSD1306, il va falloir configurer le port sur lequel celui-ci ce trouve. Pour cela, Nick Gammon’s a développé un petit programme Arduino pour trouver le port I2C sur lequel est branché l’écran OLED. Le programme scrute en boucle et recherche les appareils I2C connectés au port série toutes les 5 secondes mais on peut ajuster le délai de rafraichissement en ajustant le délai en fin de boucle.

Avant de commencer : comment installer une librairie

Pour ceux qui découvrent l’IDE Arduino, vous aurez besoin d’ajouter de nouvelles librairies pour faire fonctionner votre écran OLED. Télécharger la librairie mais ne compressé pas le Zip. Allez dans Croquis -> Inclure une librairie -> Ajouter la bibliothèque .ZIP et choisissez le zip contenant la librairie à importer.

ide arduino importer librairie

Vous pouvez maintenant aller dans Fichier -> Exemples pour découvrir les exemples proposés dans la librairie.

ide arduino exemple librairie

Pour utiliser une librairie dans vos projets, déclarez la en début de projet, par exemple #include <Adafruit_GFX.h>

Librairies disponibles pour piloter un écran OLED SSD1306

Pour gérer l’affichage sur votre écran OLED, il y a plusieurs librairies Open Source à notre disposition. Pour cet article, je vais vous présenter les deux principales. La librairie développée par Adafruit et celle de Sparkfun.

Librairies Adafruit_GFX et Adafruit_SSD1306

Adafruit a développé une librairie très puissante qui va nous permettre de gérer l’affichage de notre mini écran mais aussi de tracer plein de chose très facilement grâce à la librairie dédiée, GFX Library. Vous pouvez récupérer la librairie Adafruit SSD1306 sur le github https://github.com/adafruit/Adafruit_SSD1306 et la librairie GFX ici https://github.com/adafruit/Adafruit-GFX-Library/archive/master.zip.

Attention. Il est nécessaire d’inclure les 2 librairies dans votre projet. Pour gagner quelques précieux octets, vous pouvez utiliser la librairie Micro_OLED de Sparkfun décrite dans le prochain paragraphe.

Liste des fonctions de la librairie disponibles

Fonctions de la librairie Adafruit_SSD1306
Adafruit_SSD1306 display(OLED_RESET)initialise l’objet display(Pin pour le reset)
display()Actualise l’affichage
clearDisplay()Efface l’écran et le buffer
invertDisplay(bool)inverse l’affichage (true ou false)
Fonctions Adafruit_GFX
drawPixel(uint16_t x, uint16_t y, uint16_t color)Dessine un pixel en X,Y de la couleur color
drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)Dessine une ligne de X1,Y1 à x2,Y2 de la couleur color
drawFastVLine(uint16_t x0, uint16_t y0, uint16_t length, uint16_t color)

drawFastHLine(uin86_t x0, uin86_t y0, uint8_t length, uint16_t color);

Tracé optimisé de lignes horizontales et verticales
drawRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color)

fillRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t color)

Dessine un rectangle depuis X,Y de largeur w et hauteur h

idem mais plein

drawCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color)

fillCircle(uint16_t x0, uint16_t y0, uint16_t r, uint16_t color)

Dessine un cercle de centre X,Y et de rayon r

idem mais le cercle est plein

drawRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color)

fillRoundRect(uint16_t x0, uint16_t y0, uint16_t w, uint16_t h, uint16_t radius, uint16_t color)

 Idem rectangle mais avec un arrondi de rayon raduis aux angles
drawTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)

fillTriangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)

Dessine un triangle en spécifiant les coordonnées de chaque sommets (x0,y1), (x2,y2), (x3,y3)
drawChar(uint16_t x, uint16_t y, char c, uint16_t color, uint16_t bg, uint8_t size)Dessine un caractère en x,y
drawBitmap(int16_t x, int16_t y, uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) Affiche un bitmap en x,y de largeur w et hauteur t
fillScreen(uint16_t color); Colorie entièrement l’écran dans la couleur spécifiée
setRotation(uint8_t rotation) Rotation de l’affichage : 0 -> 0°, 1 -> 90°, 2 -> 180°, 3 -> 270°

Le paramètre color permettant de définir la couleur d’affichage uniquement sur les écrans couleur est disponible dans toutes les fonctions graphiques de la librairie GFX. Pour plus d’informations, vous pouvez consulter ce document de formation en anglais.

La librairie Adafruit_GFX est utilisée par d’autres librairies dédiées à chaque (microcontroleur) écran.

Afficher du texte

L’affichage d’un texte demande un peu plus de travail. Il est nécessaire de modifier les paramètres d’affichage paramètre par paramètre. Voici un petit exemple pour afficher Hello Word en 0,0:

display.setTextSize(1);                    // setTextSize applique est facteur d’échelle qui permet d’agrandir ou réduire la font

display.setTextColor(WHITE);    // La couleur du texte

display.setCursor(0,0);                  // On va écrire en x=0, y=0

display.println(« Hello, world! »); // un println comme pour écrire sur le port série

display.setTextColor(BLACK, WHITE); // On inverse les couleurs, le fond devient noir

display.println(« Hello, world! »);

// Vous pouvez changer à la volée de Font (pour cela vous devez la déclarer comme une librairie en début de projet, par exemple #include <Fonts/FreeMono9pt7b.h>)

display.setFont(&FreeMono9pt7b);

display.setTextColor(WHITE);

display.println(« Hello, world! »);

display.setFont();                          // Pour revenir à la Font par défaut

Par contre, vous pouvez oublier les accents, ils ne sont pas gérés dans les Fonts disponibles.

Librairie Micro_OLED de Sparkfun (compatible SSD1306)

La seconde librairie à notre disposition est celle développée par Sparkfun. Elle est disponible sur le github de Sparkfun. Elle est plus compacte que celle d’Adafruit mais en contrepartie elle offre (un peu) moins de fonctions de tracé. Cette librairie peut fonctionner aussi bien sur I2C qu’en SPI avec votre SSD1306.  Vous pouvez tester l’un ou l’autre directement en ajustant vos paramètres dans le code d’essai ci-dessous. La librairie Sparkfun est livrée avec 4 exemples :

  • Hello
  • Clock : affiche une montre qui actualise la petite aiguille à chaque seconde
  • Cube : dessine un cube 3D en rotation
  • Demo : une démo qui passe en revue toutes les possibilités de la librairie
  • DrawBitmap : Affiche un bitmap

Comment préparer vos Bitmaps

Vous voudrez très certainement afficher plus qu’un simple texte sur votre petit écran. Voici deux solutions pour convertir vos Bitmaps en chaine Hexa.

Après avoir passé beaucoup de temps à chercher les bons réglages, je vous conseil de prendre une taille d’image dans un multiple de 2 (du moins avec la librairie Adafruit_GFX).

LCD Assistant

LCD Assistant est un petit utilitaire bien pratique qui va vous permettre de convertir d’importe quel image au format Bitmap en un tableau de caractères pouvant être affiché sur votre mini écran OLED. LCD Assistant est recommandé par Sparkfun mais vous en trouverez d’autres sur internet avec les mots clés « convert bitmap to graphic lcd ».

Pour commencer vous devez disposer d’une image au format Bitmap. Après quelques tests, je vous conseil de redimensionner votre image pour quelle soit compatible avec l’écran cible. LCD Assistant est un programme bien pratique mais déjà ancien, il ne faut pas trop lui en demander et corriger à la main les petits défauts. J’ai pris pour cet exemple le logo de Projets DIY que j’ai redimensionné en 64 x 64 pixels (le logo est carré). Exportez l’image au format BMP monochrome. Si votre image dépasse la résolution demandée, elle sera tronquée et seule la partie en haut à gauche de l’image importée sera générée. J’ai obtenu le meilleur résultat en prenant la taille inférieure de 48×48 pixels.

LCD assistant convert bmp to lcd display

Ouvrez l’image dans LCD Assistant en laissant 8 pixels/byte, orientation verticale pour Byte Orientation. Exportez le tableau via File -> Save Output. Donnez d’importe quel nom avec une extension .txt par exemple pour pouvoir ouvrir facilement le fichier avec un petit éditeur de texte. Vous obtiendrez une variable contenant votre image convertie. La conversion n’est pas toujours parfaite, bien souvent (toujours !!) vous devrez supprimer la première ligne du tableau [0x40, 0x00, 0x40, 0x00,] (attention de ne pas oublier la virgule).

//——————————————————————————
// File generated by LCD Assistant
// http://en.radzio.dxp.pl/bitmap_converter/
//——————————————————————————

const unsigned char icone [] = {
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x60,
0x60, 0x60, 0x60, 0x60, 0xFF, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xE0, 0xFF, 0x60, 0x60, 0x60, 0x60,
0x60, 0x60, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x10,
0x10, 0x10, 0x10, 0x10, 0xFF, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0xFF, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x08,
0x08, 0x08, 0x08, 0x08, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xF8, 0xFF, 0xF8, 0xF8, 0xF8, 0xF8,
0xF8, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x04,
0x04, 0x04, 0x04, 0x04, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC,
0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

Affichage d’un bitmap à l’aide de la librairie Sparkfun

On commence par nettoyer l’écran

oled.clear(ALL);

En imaginant que votre écran OLED soit déclaré avec l’objet oled, il suffit d’appeler la fonction drawBitmap en lui passant en paramètre la variable contenant l’image à afficher.

oled.drawBitmap(bender);

Maintenant on actualise l’écran. C’est tout

oled.display();

Affichage d’un bitmap avec la librairie Adafruit_GFX

La librairie Adafruit_GFX utilise une variable PROGMEM pour stocker l’image. La variable suivante a été générée à l’aide d’image2cpp présenté au prochain paragraphe

const unsigned char myBitmap [] PROGMEM = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xf8, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xf8, 0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x10, 0x08, 0x07, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xe0, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,};

Les commandes sont très similaires à celles de Sparkfun. On commence par nettoyer l’écran

display.clearDisplay()

La commande drawBitmap nécessite les paramètres suivants : position x, position y, variable contenant le bitmap, largeur, hauteur, couleur. Pour mes tests, j’ai un écran de 128×32 pixels. Pour obtenir un logo carré, j’ai étendu l’image en doublant le nombre de pixels de x (64×32).

display.drawBitmap(32,0,myBitmap,64,32,WHITE);

On actualise l’affichage

display.display();

mini oled affiche display bitmap sparkfun library

 

Convertir votre bitmap en ligne avec Image2CPP

image2cpp est un outil de conversion de bitmap en chaine hexa pour afficheur LCD disponible en ligne à cette adresse http://javl.github.io/image2cpp/. image2cpp est beaucoup plus récent que LCD Assistant. image2cpp est aussi beaucoup plus puissant. Il vous permettra :

  • De choisir une taille de génération différente du fichier image
  • De choisir le mode de mise à l’échelle
  • D’ajuster le niveau de gris de seuillage (Brightness threshold) entre le noir et le blanc si vos choisissez une image en couleur ou en niveau de gris.
  • De re-centrer l’image verticalement et/ou horizontalement.
  • D’inverser les couleurs
  • D’ajouter du code Arduino qui définit la variable qu’il ne restera plus qu’à renommer après l’avoir collé dans votre code.

Un autre fonction très pratique et la possibilité de visualiser l’image qui sera produite par l’écran OLED en collant la chaine Hexa dans la zone « Paste byte array ». Par contre pour que cela fonctionne correctement, rechargez la page si vous aviez fait une conversion d’image avant.

image2cpp convert image to lcd oled display adafruit_gfx