Quoi de mieux qu’un afficheur graphique OLED, pour rendre son Arduino bien plus interactif ? Car ainsi, on peut afficher tout plein d’informations, aussi bien sous forme de texte, que d’images ou éléments graphiques. Et tout ceci, le plus tout simplement du monde, si vous prenez un modèle i2c ! Car dans ce cas, il suffit seulement de brancher 2 fils, pour prendre le contrôle de son écran OLED. Et ce n’est pas là son seul avantage, car on pourrait également parler de son prix, qui est dérisoire comparé à bon nombre d’autres afficheurs graphiques ! C’est pourquoi j’ai tenu à vous faire ce tuto aujourd’hui 😉
Pour ma part, j’utilise très souvent des écrans oled dans mes montages à arduino, et plus particulièrement le modèle faisant 0,96 pouces de diagonale, avec une résolution de 128 x 64 pixels (reposant sur le contrôleur SSD1306, et piloté via bus I2C). C’est d’ailleurs cet écran qui va me servir de support tout au long de cet article. À ce sujet, nous verrons ensemble ses principales caractéristiques techniques et électriques, et comment le raccorder à un Arduino (Uno, Nano, Mega, …). Enfin, je vous mettrai des exemples de programmes pour faire vos premiers pas avec, en commençant par l’affichage d’un simple pixel, en passant par l’utilisation de différentes polices de caractères, pour finir avec l’affichage d’image à l’écran. En bref, tout ce qu’il est intéressant de découvrir à ses débuts, dès lors qu’on souhaite utiliser des afficheurs OLED !
À noter que cet article n’est qu’une intro aux écrans OLED, et qu’il y aurait énormément à dire sur le sujet. Et vous verrez que rien que cette intro est déjà très volumineuse ! Ici, je me cantonne donc essentiellement à parler des écrans oled I2C basés sur le chipset SSD1306 (affichage monochrome, avec 128×32 ou 128×64 pixels). Mais il faut savoir que certains afficheurs OLED peuvent être pilotés en SPI, ou être multicolores (mais attention au prix dans ce dernier cas, car le prix s’envole !). Du reste, j’ai préféré rester ici sur des choses simples, et à portée de tout bon débutant en électronique ! Alors en avant !
Caractéristiques d’un écran OLED i2C (monochrome, chipset SSD1306)
Les écrans OLED sont des écrans graphiques, monochromes ou multi-couleurs, permettant d’afficher du texte, des images, et des figures graphiques. Ces écrans intègrent généralement un contrôleur, permettant de faire l’interface entre l’écran oled en lui même, et la partie « commande » (l’arduino, par exemple). Pour ma part, j’utilise un afficheur OLED doté d’un contrôleur SSD1306 (un « classique », dès lors qu’il s’agit d’afficheur OLED 0,96 pouces monochrome, faisant 128×64 pixels). C’est d’ailleurs cet écran qui va me servir de support, tout au long de cet article.
S’agissant de la manière de communiquer avec un écran OLED, on trouve principalement 2 protocoles de communication courants :
- Le bus I2C (utilisant que 2 fils : SDA et SCL)
- Le bus SPI (utilisant 4 fils : SCK, MOSI, MISO, et SS, aussi noté D0, D1, DC, et CS)
Pour ma part, afin de rester sur des choses les plus simples possibles, je vais vous parler ici de la version I2C. Parce que c’est selon moi le type d’afficheur le plus facile à mettre en œuvre, et qui ne nécessite que de très peu de fils pour fonctionner.
Au niveau de l’alimentation électrique de ces modules OLED, ils s’alimentent généralement de 3,3 à 5V. Bien sûr, il peut y avoir des exceptions. Cela sera donc toujours à vérifier auprès de votre fournisseur de composants électroniques ou du fabricant, afin de ne pas commettre d’impairs !
Au niveau des couleurs, on trouve un peu de tout. Et d’ailleurs, attention à ne pas vous méprendre, quand je vous parle d’afficheur monochrome. Car ce n’est pas parce qu’un afficheur oled est qualifié de monochrome, qu’il serait pour autant limité à un affichage en « noir et blanc » ! En effet, les pixels allumés peuvent tous uniformément être d’une autre couleur, telle que le bleu, le jaune, ou un mix des deux, comme vous pourrez le constater ci-dessous (avec les « classiques » écrans OLED 0,96″, sur chipset SSD1306) :
Écran oled BLANC | Écran oled BLEU | Écran oled JAUNE | Écran oled JAUNE/BLEU |
---|---|---|---|
128×64 pixels blancs | 128×64 pixels bleus | 128×64 pixels jaunes | 128×64 pixels jaunes+bleus (1) |
(1) JAUNE en haut, soit 128×16 pixels (16 lignes, numérotées de 0 à 15), et BLEU en milieu/bas, soit 128×48 pixels (48 lignes, numérotées de 16 à 63). Donc, au total, l’affichage est bien de 128×64 pixels.
Nota : le modèle JAUNE/BLEU, à droite ci-dessus, est celui que j’ai utilisé de mon côté, pour faire ce tuto. Il est bel est bien monochrome, mais divisé en 2 parties colorées de deux manières différentes. En fait, il est JAUNE sur la partie haute de l’afficheur, et BLEU sur toute la partie médiane et basse. Dans tous les cas, on ne décide pas ici de faire afficher un pixel de couleur jaune ou bleue, selon son bon vouloir !
Sinon, côté avantages, il faut savoir que la technologie OLED offre une excellente lisibilité des choses affichées à l’écran, en ce sens où on peut facilement lire tout ce qui est écrit dessus, même en le regardant de côté. Qui plus est, il n’y a nullement besoin de rétroéclairage ici, tellement c’est lumineux !
Cependant, il faut également savoir que ce type d’afficheur à tout de même plusieurs inconvénients. En effet, parmi eux, on retrouve le fait que :
- Ils sont souvent de (trop) petites tailles, à l’image de celui que j’ai utilisé comme support à ce tuto, faisant 0,96″ de diagonale (c’est vraiment « mini » !). Et si on n’a pas de bons yeux, ça peut vite devenir pénible à lire !
- Ils ne sont pas forcément faciles à intégrer dans un boitier, malgré la présence de trous de fixation (même s’il existe des moyens de contourner cela, comme je vous montrerai dans un prochain article)
- Ils sont la plupart du temps monochromes, si l’on souhaite rester sur des prix raisonnables (au passage, ne vous méprenez pas en voyant l’écran jaune/bleu ci-dessus, car ce dernier est en fait constitué de deux « sous-écrans » : un jaune en haut, et un bleu en dessous ! Donc deux écrans monochromes, l’un au-dessus de l’autre, mais avec chacun une couleur qui lui est propre !)
Maintenant que nous avons survolé toutes les généralités concernant les écrans OLED, voyons à présent comment les raccorder à un Arduino !
Comment raccorder un écran OLED à l’Arduino ? (via le bus I2C)
Comme voir allez le voir juste après, raccorder un écran OLED à un Arduino via le bus I2C est on ne peut plus simple ! Car il suffit au final de brancher 4 fils :
- SDA et SCL, pour la liaison i2c
- Et VCC / GND, pour l’alimentation (qui, pour rappel, se fait généralement entre 3,3V et 5V)
Voici d’ailleurs un exemple de câblage, avec un Arduino Uno :
Bien sûr, rien ne vous empêche de brancher votre afficheur OLED sur un autre type d’arduino, ou dispositif électronique muni d’une liaison i2c. Car, au final, on en revient toujours à brancher 4 fils, dont deux pour l’alim et deux pour la liaison I2C. Pour info, voici les broches classiquement utilisées pour le bus i2c, sur les arduino les plus courants :
Type d’arduino | Broche SDA | Broche SCL |
---|---|---|
Arduino Uno | Pin A4 | Pin A5 |
Arduino Nano | Pin A4 | Pin A5 |
Arduino Mega | Pin 20 | Pin 21 |
Arduino Pro Mini | Pin A4 | Pin A5 |
Cela étant dit, nous allons à présent voir quelles peuvent être les adresses I2c d’un écran OLED, c’est à dire à quelle adresse écouter ou écrire, afin de pouvoir les piloter depuis son programme arduino ! Alors en avant 😉
Quelle adresse i2c a mon écran OLED ? 0x3C, 0x3D, 0x78, ou 0x7A ?
Je vais vous parler ici d’une chose particulière à connaitre, au sujet des petits écrans OLED I2C, couramment utilisés en électronique. Car ceci est source de grande confusion, et évitera que vous soyez perdu, avant même de commencer !
En fait, si vous êtes attentif, vous verrez que l’adresse i2c figurant au dos d’un afficheur OLED ne sera absolument pas l’adresse à utiliser dans votre programme Arduino ! Et aussi bizarre que cela puisse paraître, il y a une bonne explication à cela. Mais encore faut-il la connaître, pour éviter de se méprendre. Mais avant de vous donner l’explication technique, je vais vous illustrer le « problème » en image. Car voici les informations « gravées » sur le PCB de l’écran OLED :
On note 2 adresses i2c possibles : 0x78 ou 0x7A (c’est écrit en petit, sur la photo ci-dessus, là où j’ai entouré en rouge). Pourtant :
- si vous utilisez l’adresse 0x78 ou 0x7A dans votre code de programmation arduino, vous verrez que rien ne fonctionnera
- mais si vous utilisez l’adresse i2C 0x3C ou 0x3D (dont je vous parlerai ensuite), alors l’écran OLED répondra à vos commandes sur l’une ou l’autre de ces adresses
Bizarre, non ?
Maintenant, si je vous disais que 0x78 = 0x3C, et que 0x7A = 0x3D. Vous penseriez certainement que j’ai bu un peu trop, et pas que de l’eau ! Pourtant, ces valeurs sont bien « égales », … si l’on se place dans un référentiel bien particulier. En fait, tout est histoire de contexte, car dans un cas on parle d’un mot sur une base à 8 bits, tandis que dans l’autre, on parle d’un mot sur une base à 7 bits.
Il suffit donc juste de savoir cela, afin de pouvoir piloter son écran OLED, sans soucis de communication !
Maintenant, pour ceux qui souhaitent découvrir la justification technique de tout cela, voici ce que je peux vous dire :
- En « langage » i2c, on travaille sur 7 bits et non 8 bits, au niveau des adresses. Cela donne donc des nombres entiers pouvant aller de 0 à 127 (soit de 0x00 à 0x7F en hexadécimal, ou de 000 0000 à 111 1111 en binaire)
- Or, en binaire, une adresse 8 bits valant « 0x78 » donne le nombre suivant : 01111000. Et si on « transforme » ce nombre 8 bits en nombre 7 bits, pour être « conforme » à l’adressage i2c à 7 bits, en ne gardant que la partie « de poids fort » (MSB), alors on « perd » le dernier chiffre. Ce qui donne le nombre binaire suivant : 0111100 sur 7 bits. Et cette valeur binaire donne bien 0x3C en hexadécimal ! Donc l’adresse matérielle « 0x78 » sur 8 bits correspond bien à l’adresse logicielle « 0x3C » sur 7 bits !
- De même : une adresse 8 bits valant « 0x7A » donne le nombre 01111010 en binaire. Mais si on transforme ce mot 8 bits en mot sur 7 bits MSB, alors on « perd » là encore le dernier chiffre. Ce qui nous donne le nombre de 0111101, lorsqu’écrit sur 7 chiffres, en gardant uniquement les bits de poids forts. Et cette valeur binaire nous donne bien du 0x3D en hexadécimal ! Ainsi, l’adresse physique « 0x7A » sur 8 bits équivaut bien à l’adresse logicielle « 0x3D » sur 7 bits !
La synthèse en image, pour ceux qui n’aiment pas lire trois tonnes de texte !
Tout cela vous parait compliqué ? Ne vous inquiétez pas ! Car il suffit de retenir ce qui suit, si vous utilisez un petit écran OLED 0,96″ I2C comme moi :
- Si votre écran OLED a l’adresse 0x78, alors il faudra utiliser l’adresse 0x3C dans votre programme arduino, pour communiquer avec lui
- Si votre écran OLED a l’adresse 0x7A, alors il faudra utiliser l’adresse 0x3D dans votre programme arduino, pour communiquer avec lui
Nota : pour connaitre l’adresse « exacte » de votre écran I2C, vous pouvez :
– soit vous rapporter à la documentation constructeur (si celle-ci précise les correspondances physiques <-> logicielles)
– soit utiliser un scanner i2c (comme vous verrez dans l’exemple n°1, présenté un peu plus bas, dans cet article)
– soit simplement convertir la ou les valeurs inscrites sur le PCB de votre écran OLED
À noter que, dans mon cas, une petite résistance CMS, soudée « à cheval » sur le PCB visible ci-dessus, fixe l’adresse i2c à une valeur, plutôt qu’à l’autre. Ici, c’est l’adresse 0x78 qui sera utilisée pour communiquer avec l’afficheur OLED, car la résistance est soudée du côté de cette inscription. Si j’avais souhaité utiliser l’adresse 0x7A, il aurait alors fallu que je dessoude cette petite résistance SMD, et que je la soude du côté de l’inscription « 0x7A ». Mais si vous débutez, je vous recommande de laisser cette résistance où elle est, à moins d’être bien équipé pour faire la manip !
Librairie SSD1306 et GFX (de Adafruit) pour Arduino
Pour piloter un écran OLED avec un Arduino, il existe plusieurs librairies très utiles. Les plus « populaires », au moment où je rédige ce tuto, sont :
- la librairie « U8G2 » de Olikraus (https://www.arduino.cc/reference/en/libraries/u8g2/), très complète, mais pas forcément la plus facile à manipuler, lorsqu’on débute
- et la librairie « SSD1306 » de Adafruit (https://github.com/adafruit/Adafruit_SSD1306), spécialisée pour les écrans OLED dotés du contrôleur SSD1306, tel que celui présenté dans cet article ; cette bibliothèque est clairement plus facile à manipuler lorsqu’on fait ses premiers pas avec les afficheurs OLED, selon moi
Pour cet article, et afin de rendre les chose les plus simples et compréhensibles possibles, j’ai choisi de partir sur la librairie de chez Adafruit. Car sa mise en œuvre est plus facile et parlante, d’après moi, que la librairie U8G2. Bien sûr, libre à vous d’utiliser la librairie qui vous plaira, par la suite 😉
À noter que la librairie SSD1306 d’Adafruit impose souvent l’installation d’une librairie « complémentaire » (dépendance), appelée « librairie GFX ». Il faudra bien évidemment l’installer, si vous souhaitez avoir accès à toutes les fonctions avancées, proposées par Adafruit (https://github.com/adafruit/Adafruit-GFX-Library). Mais rassurez-vous, car comme nous allons le voir, cette installation se fait « dans la foulée », en quasi automatique !
L’installation des librairies SSD1306 et GFX de Adafruit, dans l’IDE Arduino
Pour installer les librairies « Adafruit_SSD1306.h » et « Adafruit_GFX.h » de chez Adafruit, il suffit simplement d’ouvrir son IDE Arduino, et de cliquer sur : Outils > Gérer les Bibliothèques ; puis il faudra renseigner le mot « ssd1306 » dans le champ de recherche, et appuyer sur la touche ENTRÉE. Ainsi, vous devriez voir s’afficher à l’écran une liste, semblable à celle-ci :
Il vous suffira alors de cliquer sur le bouton « Installer », présent lorsque vous survolerez le « pavé » correspondant à la bibliothèque « Adafruit SSD1306 ». Une fois fait, vous devriez voir une seconde fenêtre apparaître par-dessus, vous demandant si vous souhaitez également installer les dépendances de cette librairie. Ici, il suffit alors juste de cliquer sur « Install all », pour que tous les modules nécessaires au bon fonctionnement de l’ensemble soient bien installés sur votre ordi. Au passage, voici l’aperçu de cette fenêtre « intermédiaire » :
Une fois que vous aurez cliqué sur « Install all », vous retombez sur la fenêtre de recherche initiale. Mais cette fois-ci, vous verrez la mention « INSTALLED » annotée à côté du nom de la librairie « Adafruit SSD1306 », comme visible ci-dessous :
Maintenant, vous êtes fin prêt, pour vous servir de cette librairie pleinement !
Initialisation de la bibliothèque SSD1306, en tête de programme arduino
Ici encore, vous allez voir, c’est super simple ! Car pour inclure la librairie nécessaire, il suffit simplement d’insérer la ligne suivante dans le haut de votre programme arduino :
#include <Adafruit_SSD1306.h>
Et d’instancier en suivant la classe « Adafruit_SSD1306 », pour pouvoir vous en servir par la suite. Cela se fait d’ailleurs d’une seule ligne :
Adafruit_SSD1306 ecranOLED(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED);
Avec :
- « nombreDePixelsEnLargeur », à remplacer par la valeur correspondant au nombre de pixels en largeur de votre écran OLED (normalement 128 pixels)
- « nombreDePixelsEnHauteur » à remplacer par la valeur correspondant au nombre de pixels en hauteur de votre écran OLED (possiblement 32 ou 64 pixels)
- « &Wire » à ne pas toucher, car cela permet d’inclure la librairie « Wire » dans l’instanciation de cette classe, lui indiquant au passage que nous travaillons sur un écran OLED de type « I2C »)
- Et « brocheResetOLED » à remplacer par la valeur correspondant à la broche RESET de votre écran OLED (si comme moi votre afficheur OLED ne dispose d’aucune broche RESET, il suffira alors de mettre la valeur « -1 » ici)
Si tout cela vous parait quelque peu compliqué, ne vous inquiétez pas ! Car au final, cette ligne de code se résume souvent à écrire : Adafruit_SSD1306 ecranOLED(128, 64, &Wire, -1);
Une fois cela fait, il ne vous restera plus qu’à insérer une dernière ligne de code, dans la partie « setup » de votre programme arduino, cette fois-ci :
ecranOLED.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED);
Avec :
- « SSD1306_SWITCHCAPVCC » à ne pas toucher, si vous avez un écran comme le mien
- Et « adresseI2CecranOLED » à remplacer par la valeur correspondant à l’adresse de votre afficheur OLED (classiquement 0x3C ou 0x3D, suivant si votre écran est physiquement configuré sur l’adresse 0x78 ou 0x7A, comme vu plus haut)
Au final, cette dernière ligne s’écrit couramment de la manière suivante : ecranOLED.begin(SSD1306_SWITCHCAPVCC, 0x3C); (dans le cas où l’écran OLED aurait bien l’adresse « par défaut » 0x3C, bien entendu !).
L’origine du repère (cordonnées X et Y)
Autre chose à connaître, avant de manipuler toutes les fonctions disponibles dans la bibliothèque Adafruit : l’origine du repère permettant de définir l’axe X et Y des écrans OLED, pour cette librairie arduino. Ici, le « point zéro » sera situé en haut à gauche de l’écran. Ainsi, plus nous irons sur la droite, et plus la valeur « X » augmentera. Et plus nous irons vers le bas, et plus la valeur « Y » augmentera. Visuellement, cela peut se représenter de la manière suivante :
Gardez bien cela en mémoire, sinon vous risquez fort de ne plus savoir quelles coordonnées mettre, pour le positionnement de vos objets graphiques 😉
Modification / rafraîchissement de ce qui est affiché à l’écran
Une chose importante à savoir, au sujet de cette librairie pour écrans OLED, c’est que l’affichage ne sera pas mis à jour à chaque fois que vous ajouterez tel ou tel texte, ou élément graphique. En fait, vous ne ferez que mettre à jour la mémoire tampon, et il sera nécessaire d’envoyer toute cette mémoire tampon à l’écran, une fois que vous aurez envoyé toutes vos commandes d’affichage.
Ainsi, vous devrez utiliser la fonction « display() », une fois que vous souhaiterez que tous vos éléments « préparés en mémoire » soient envoyés à l’écran (comme vous le verrez dans les exemples ci-dessous, un peu plus loin dans cet article). Sinon, aucune modification n’apparaîtra !
Nota : pour ma part, et comme vous le verrez dans les exemples que vous ai mis un peu plus bas, j’effectue toujours un « ClearDisplay » en premier, pour vider la mémoire tampon. Ensuite, j’exécute les commandes permettant l’ajout de texte ou éléments graphiques dans cette mémoire. Et à la fin seulement, j’exécute la commande display. Cela permet d’avoir une totale maîtrise de ce qui est affiché à l’écran. Par contre, l’inconvénient pourrait être l’apparition d’un scintillement à l’écran, si jamais la fréquence de rafraîchissement de votre afficheur venait à être trop importante.
La gestion des couleurs (écrans monochromes)
Comme évoqué plus haut, les écrans OLED munis du chipset SSD1306 sont monochromes. Pour autant, ils n’affichent pas les choses en « noir et blanc », comme on pourrait le croire. En fait, ils permettent plutôt d’afficher une couleur donnée, sur fond noir.
Du coup, on peut être surpris lorsqu’on fait appel à des couleurs « blanc » ou « noir » avec cette librairie arduino, alors que l’afficheur ne pourra en lui-même qu’afficher des choses soit tout en blanc, soit tout en jaune, soit tout en bleu, ou soit d’une toute autre couleur encore, par exemple.
En fait, pour bien comprendre cette librairie Adafruit, il faut simplement retenir la chose suivante :
- La couleur « WHITE » dans le code arduino permet d’allumer un pixel de couleur « unique », selon votre type d’écran OLED
- La couleur « BLACK » dans le code arduino permet « d’éteindre » un pixel (et là, pour le coup, il sera bien noir !)
- À noter la présence d’une couleur « INVERSE », qui, dans votre programme, permettra d’inverser la couleur des pixels (c’est-à-dire d’écrire en noir sur fond coloré, par exemple)
Mais dans tous les cas, un écran monochrome reste monochrome, et en faisant appel à la couleur « blanche » dans vos programmes arduino, vos pixels s’allumeront de la couleur native de votre écran (s’il est JAUNE, alors les pixels s’allumeront en jaune, et non en blanc).
Au passage, voici le nom de ces 3 couleurs possibles, telles que déclarées dans la bibliothèque « Adafruit_SSD1306.h » :
#define SSD1306_BLACK 0 // Draw 'off' pixels
#define SSD1306_WHITE 1 // Draw 'on' pixels
#define SSD1306_INVERSE 2 // Invert pixels
Fonctions logicielles et graphiques très utiles (drawPixel, setCursor, setFont, drawBitmap, drawLine, drawCircle, …)
À présent, nous allons attaquer une partie bien plus intéressante, car plus visuelle et plus pratique, et donc, moins barbant ! Nous verrons d’ailleurs ici :
- comment changer l’état d’un pixel à l’écran (avec drawPixel)
- comment afficher du texte, ou des caractères spéciaux (avec print et println)
- comment déplacer le pointeur de l’écran (avec setCursor)
- comment grossir du texte avant affichage (avec setTextSize)
- comment changer la couleur du texte et du fond d’écran (avec setTextColor)
- comment modifier la police de caractère à utiliser (avec setFont)
- comment afficher une image (avec drawBitmap)
- comment utiliser toutes les fonctions étendues de dessin (telles que : drawLine, drawRect, fillRect, drawRoundRect, fillRoundRect, drawCircle, fillCircle, drawTriangle, et fillTriangle)
- comment inverser les couleurs de l’écran (avec invertDisplay)
- et comment remplir la totalité de l’écran avec la couleur souhaitée (avec fillScreen)
En bref, que des trucs sympas quoi 😉
Remarque : toutes les fonctions détailles ci-après nécessitent l’appel de la fonction « display » juste après elles, pour valider le transfert de la mémoire tampon vers l’écran ! Ne l’oubliez jamais ! Sinon, vous ne verrez aucun changement sur votre afficheur !
Changer l’état d’un pixel à l’écran (fonction « drawPixel »)
Chaque pixel d’un écran OLED peut être changé d’état, à la demande. Pour cela, il suffit d’utiliser la fonction « drawPixel », en spécifiant :
- la position du pixel visé, sur l’axe horizontal (X), et sur l’axe vertical (Y)
- et la couleur qu’on souhaite (SSD1306_WHITE, SSD1306_BLACK, ou SSD1306_INVERSE, pour respectivement ALLUMER, ÉTEINDRE, ou INVERSER L’ÉTAT d’un pixel)
Au niveau du code, voici un exemple de ce qu’il est possible de faire (pour rappel : la position 0, des axes X et Y, se situe en haut à gauche d’un afficheur OLED, avec cette librairie) :
int16_t posX = 40;
int16_t posY = 20;
int16_t couleur = SSD1306_WHITE;
ecranOLED.drawPixel(posX, posY, couleur); // Pour allumer un pixel, à la position X=40 et Y=20
Facile, non ?
Afficher du texte à l’écran, ou des caractères spéciaux (avec print et println)
Pour afficher du texte à l’écran, il n’y a rien de plus simple, en fait ! Car il suffit d’utiliser la fonction :
- print, pour afficher des caractères à l’écran
- println, pour faire de même, AVEC un saut de ligne à la fin
Côté code, voici un exemple d’affichage de texte à l’écran :
int valeurTemperature = 25; // Température, exprimée en degrés Celsius
ecranOLED.print("Temperature = ");
ecranOLED.print(valeurTemperature);
ecranOLED.print((char)247);
ecranOLED.println("C");
Ce qui permettra d’afficher : « Temperature = 25°C », à l’endroit où était positionné le curseur (pointeur) à l’écran.
Deux remarques, au passage :
- vous noterez l’emploi du caractère spécial « 247 » qui correspond au symbole « ° » dans la police de caractère utilisée ici ; en effet, la fonction print/println peut parfois avoir du mal à afficher certain caractères « spéciaux », qui ne correspondent pas forcément à une table ascii étendue ou ANSI. Du coup, se servir du code ascii d’un caractère permet de l’afficher, même s’il correspond « en temps normal » à un autre caractère 😉
- à noter également que lorsque les caractères dépassent le côté droit de l’écran oled, ceux-ci seront imprimés sur la ligne suivante, après un retour à la ligne. Et si jamais vous dépassez le bas de l’écran, alors, dans ce cas… ils ne s’afficheront simplement jamais (pas de retour en haut de l’écran une fois arrivé en bas, en fait !).
Déplacer le curseur / pointeur « invisible » sur l’écran (avec setCursor)
Quand on veut écrire du texte ou placer un élément graphique à un endroit précis de l’écran, il est quasi indispensable de préalablement se servir de la fonction « setCursor ». Car celle-ci permet de positionner le « curseur » exactement où l’on veut, afin que le texte ou l’objet graphique s’écrive ou se dessine à partir de ce point là.
Mais avant tout, rappelez-vous bien que :
- le point « 0 » se situe en haut / à gauche de l’écran OLED
- l’axe X correspond à l’axe horizontal
- l’axe Y correspond à l’axe vertical
Ainsi, si je veux écrire du texte à partir du 15ème pixel en partant de la gauche (axe X), et du 9ème pixel en partant du haut (axe Y), alors il faudra que je positionne le curseur (pointeur) aux coordonnées (15,9). Ainsi, tout ce qui suit sera positionné sur la 15ème colonne de l’axe X (horizontal), et la 9ème ligne de l’axe Y (vertical).
En codant tout cela, ça donne les lignes suivantes :
int16_t positionX = 15; // Coordonnées X en pixels (sur le plan horizontal)
int16_t positionY = 9; // Coordonnées Y en pixels (sur le plan vertical)
ecranOLED.setCursor(positionX, positionY);
Définir le facteur de grossissement d’un texte avant affichage (avec setTextSize)
Pouvoir afficher du texte où l’on veut, c’est bien, mais pouvoir lui changer sa taille au passage, c’est encore mieux ! Et pour cela, il suffit d’utiliser la fonction « setTextSize », mise à disposition avec les bibliothèques Adafruit.
Mais avant d’aller plus loin, il faut bien comprendre à quoi sert cette fonction, pour ne pas se méprendre sur ce qu’elle permet de faire. Car il ne s’agit pas là de définir une taille de police de caractère précise, mais plutôt de choisir un « niveau de grossissement ». Ainsi :
- si vous faites un setTextSize = 1, alors le texte sera écrit de « taille normale » à l’écran (sans grossissement aucun)
- si vous faites un setTextSize = 2, alors le texte sera simplement écrit 2 fois plus gros
- si vous faites un setTextSize = 3, alors le texte sera simplement écrit 3 fois plus gros
- et ainsi de suite !
Au final, il faut donc voir cette fonction comme un « multiplicateur » de taille de police de caractère, et non quelque chose permettant de définir une taille précise (comme 8, 10, 11, 12, 14, 16 pt, … que l’on retrouve couramment dans nos traitements de texte).
Côté code de programmation, voici un exemple d’appel de cette fonction :
uint8_t niveauDeGrossissementTexte = 2; // Multiplie la « grosseur » du texte
ecranOLED. setTextSize(niveauDeGrossissementTexte); // (nombre entier supérieur ou égal à 1, uniquement)
À noter qu’on peut zoomer de manière dissymétrique, c’est-à-dire zoomer plus en largeur qu’en hauteur (ou plus en hauteur qu’en largeur). Pour ce faire, voici un exemple de code permettant de « déformer » son texte, selon ses souhaits :
uint8_t niveauDeGrossissementLargeurTexte = 2; // Multiplie la largeur du texte, par un certain nombre
uint8_t niveauDeGrossissementHauteurTexte = 3; // Multiplie la hauteur du texte, par un certain nombre
ecranOLED.setTextSize(niveauDeGrossissementLargeurTexte, niveauDeGrossissementHauteurTexte);
Malheureusement, comme vous l’aurez compris en voyant des nombres de type « uint8_t », on ne peut pas entrer de nombre à virgule ! Mais seulement des nombres entiers (supérieurs ou égal à 1). Dommage 😉
Nota : si vous souhaitez utiliser des tailles de polices 8 pts, 10 pts, ou toute autre valeur, alors il faudra sélectionner la police de caractère « taillée » à cette valeur. Car avec cette librairie OLED, on ne peut pas faire appel à une police de caractères « entière », c’est à dire comportant plusieurs tailles, mais bien une police de caractère mono-taille (comme vous verrez dans un des exemples plus bas, où j’importe des polices de caractères à taille unique).
Changer la couleur du texte, et celle du fond d’écran (avec setTextColor)
Pour rappel, nous fonctionnons ici avec des afficheurs monochromes. Et quand bien même ceux-ci pourraient afficher des pixels de couleur blanche, jaune, ou bleue, ils ne peuvent afficher que cette unique couleur, et aucune autre. Du coup, quand on parle de couleur de texte, il faut bien comprendre qu’on est limité à la simple couleur de son écran OLED, et aucune autre (et quand vous voyez 2 couleurs, c’est en fait une partie colorée uniquement d’une façon, et une autre, indépendante, colorée d’une autre façon).
Au final :
- soit un pixel est allumé (couleur nommée « WHITE » dans le code arduino), et celui-ci s’allume de la couleur unique de l’écran (qui peut être blanc, jaune, bleu, ou je ne sais quelle autre couleur !)
- soit le pixel est éteint (couleur nommée « BLACK » dans le code arduino), et on obtient la couleur noire
J’avoue que l’histoire de la couleur « WHITE » dans le programme arduino peut quelque peu induire en erreur, alors que l’écran OLED peut très bien avoir ses pixels de couleur jaune, bleue, ou autre. Mais bon, … telle a été la manière dont a été construite cette librairie Adafruit, et on va faire avec 😉
Au niveau de votre programme arduino, voici donc un exemple pour afficher du texte en couleur (qui pour rappel, sera la couleur « unique » de votre écran monochrome) :
uint16_t couleurDeMonTexte = SSD1306_WHITE;
ecranOLED.setColor(couleurDeMonTexte);
ecranOLED.print("Mon texte");
Mais dans quel cas utiliser la valeur « BLACK », allez-vous me dire ? Eh bien… en l’utilisant « sur fond blanc », tout simplement (comme si on inversait les couleurs). Et pour se faire, il suffit de renseigner un deuxième argument à la fonction setColor, pour indiquer la couleur de fond, cette fois-ci.
Voici d’ailleurs un bout de code, permettant d’afficher du texte « noir », sur fond « blanc » (blanc étant la couleur de votre écran, vous l’aurez compris !) :
uint16_t couleurEcritureTexte = SSD1306_BLACK;
uint16_t couleurSousTexte = SSD1306_WHITE;
ecranOLED.setColor(couleurEcritureTexte, couleurSousTexte);
ecranOLED.print("Mon texte");
Ici, on affiche un texte noir sur fond coloré, comme si on avait inversé les couleurs. En espérant que tout cela soit suffisamment clair au niveau des explications… car je ne saurais vous l’expliquer plus simplement !
Modifier la police de caractère d’un texte à afficher (avec setFont)
Je suis certain que, comme moi, vous chercherez assez vite à changer la police de caractère. Car celle par défaut, bien que très utile, se révèle parfois un peu trop … ordinaire ! Du coup, rien de tel qu’importer d’autres polices de caractères, pour égayer son affichage ! Mais autant vous le dire de suite : les capacités de l’Arduino et de la librairie Adafruit vous imposeront très vite des limites. Car :
- autant il est effectivement possible d’importer des polices de caractères, autant celles-ci ne pourront l’être qu’à taille unique ; vous ne pourrez donc pas importer l’intégralité d’une police de caractère « multi-taille », mais seulement une partie, de taille unique (par exemple de « l’Arial 14 pt Gras Italique », et rien d’autre)
- et chacune des polices que vous importerez prendra une place vraiment importante en mémoire (facilement 20 à 30% de la mémoire d’un Arduino Uno, avec une taille « classique »)
Donc : OUI, vous pourrez vous faire plaisir ! Mais NON, vous ne pourrez probablement pas utiliser plus de 3 ou 4 polices de caractères différentes (suivant leur taille), dans votre programme arduino. Cela étant dit, on peut effectivement réaliser de très belles choses ici 😉
Maintenant, comment faire pour importer une police de caractère, allez-vous me demander ? En fait, c’est relativement simple, si l’on suit bien les étapes suivantes :
- Télécharger par exemple une police « libre de droit d’utilisation » (perso, je vais la chercher sur le site dafont : https://www.dafont.com/fr/)
- Dézipper ensuite cette police de caractère, afin de récupérer le fichier « .TTF » qui nous intéresse
- Ensuite, envoyer ce fichier TTF dans un convertisseur de police de caractère « TrueType vers Adafruit GFX ». Perso, je me sers du site suivant : https://rop.nl/truetype2gfx/. En pratique, il faut :
- Cliquer sur « Télécharger un fichier » pour ouvrir son fichier TTF
- Puis cliquer sur « Upload » pour l’afficher à l’écran
- Ensuite, sélectionner la taille de police voulue dans la case « Font Size » (par exemple « 12 », pour sélectionner la taille « 12 points »)
- Optionnel : saisir un texte dans le champ « Demo Text », pour voir ce que ça donnera à l’écran de votre afficheur OLED (NOTA : ne faites pas attention à la taille représentée à l’écran, car elle est souvent trop petite ; en réalité c’est bien plus grand, et donc assez trompeur !)
- Et cliquer sur « Get GFX font file », pour générer un fichier « .h », contenant votre police de caractère, à taille souhaitée
Voici d’ailleurs un extrait du fichier généré avec cet utilitaire, pour la police Tahu prise en exemple, en taille 16 points (source de la police de caractère : https://www.dafont.com/fr/tahu.font) :
const uint8_t Tahu_16pt7bBitmaps[] PROGMEM = {
0x00, 0x06, 0x1C, 0x30, 0xE1, 0xC3, 0x0E, 0x1C, 0x30, 0x61, 0x83, 0x02,
0x00, 0x00, 0x60, 0xC1, 0x80, 0x96, 0xE5, 0x40, 0x09, 0x82, 0x30, 0x4E,
0x3F, 0xEF, 0xF1, 0x4C, 0x1F, 0xE7, 0x20, 0x4C, 0x11, 0x02, 0x00, 0x00,
0x00, 0x80, 0x08, 0x00, 0x80, 0xFC, 0x1F, 0xE3, 0x12, 0x39, 0x03, 0xF8,
0x07, 0xE0, 0x2E, 0x02, 0x73, 0x23, 0x66, 0x36, 0x43, 0xC4, 0x7C, 0x47,
0xE5, 0xE7, 0xFC, 0x3F, 0x80, 0xE0, 0x08, 0x00, 0x80, 0x08, 0x00, 0x60,
0xBC, 0x6D, 0xF3, 0x6C, 0xF6, 0x19, 0x80, 0xE0, 0x30, 0x0C, 0x06, 0x01,
0x80, 0x64, 0x33, 0xCD, 0xB2, 0x7C, 0x8E, 0x40, 0x00, 0x00, 0x78, 0x00,
0x7F, 0x80, 0x3C, 0x60, 0x1C, 0x08, 0x06, 0x00, 0x03, 0x80, 0x00, 0xE0,
...
0xF0, 0x30, 0x1C, 0x06, 0x01, 0x80, 0x60, 0x38, 0x0C, 0x07, 0x0F, 0x83,
0xC0, 0x30, 0x06, 0x01, 0x80, 0x60, 0x38, 0x0C, 0x03, 0x00, 0xC0, 0x30,
0x0C, 0x03, 0x00, 0xE0, 0x18, 0x00, 0x08, 0x46, 0x31, 0x8C, 0x63, 0x39,
0xCE, 0x73, 0x98, 0xCE, 0x73, 0x9C, 0xC6, 0x31, 0x9C, 0xC6, 0x31, 0x00,
0x01, 0x00, 0x78, 0x03, 0x80, 0x18, 0x01, 0x80, 0x18, 0x03, 0x80, 0x30,
0x03, 0x00, 0x38, 0x03, 0xF0, 0x1E, 0x03, 0x80, 0x60, 0x06, 0x00, 0xE0,
0x0C, 0x00, 0xC0, 0x0C, 0x00, 0xC0, 0x1C, 0x01, 0x80, 0x38, 0x07, 0x00,
0x60, 0x00, 0x30, 0x34, 0x71, 0xE0, 0x40 };
const GFXglyph Tahu_16pt7bGlyphs[] PROGMEM = {
{ 0, 1, 1, 6, 0, 0 }, // 0x20 ' '
{ 1, 7, 18, 9, 0, -18 }, // 0x21 '!'
{ 17, 5, 4, 8, 2, -19 }, // 0x22 '"'
{ 20, 11, 11, 14, 2, -9 }, // 0x23 '#'
{ 36, 12, 23, 13, 0, -19 }, // 0x24 '$'
{ 71, 10, 17, 11, 0, -15 }, // 0x25 '%'
{ 93, 18, 20, 19, 0, -17 }, // 0x26 '&'
{ 138, 2, 4, 6, 2, -19 }, // 0x27 '''
{ 139, 10, 27, 8, 0, -22 }, // 0x28 '('
{ 173, 10, 27, 10, -1, -22 }, // 0x29 ')'
{ 207, 6, 5, 10, 2, -22 }, // 0x2A '*'
{ 211, 9, 9, 13, 1, -8 }, // 0x2B '+'
{ 222, 3, 5, 8, 3, -2 }, // 0x2C ','
{ 224, 9, 2, 13, 1, -5 }, // 0x2D '-'
...
{ 3053, 10, 11, 11, -1, -10 }, // 0x72 'r'
{ 3067, 11, 17, 9, -2, -11 }, // 0x73 's'
{ 3091, 17, 26, 8, -3, -21 }, // 0x74 't'
{ 3147, 15, 12, 12, -1, -10 }, // 0x75 'u'
{ 3170, 13, 11, 11, 0, -10 }, // 0x76 'v'
{ 3188, 15, 11, 15, 1, -10 }, // 0x77 'w'
{ 3209, 12, 12, 9, -2, -9 }, // 0x78 'x'
{ 3227, 18, 25, 11, -5, -8 }, // 0x79 'y'
{ 3284, 16, 25, 11, -3, -9 }, // 0x7A 'z'
{ 3334, 10, 25, 8, 0, -20 }, // 0x7B '{'
{ 3366, 5, 28, 10, 2, -23 }, // 0x7C '|'
{ 3384, 12, 25, 10, -2, -20 }, // 0x7D '}'
{ 3422, 9, 4, 11, 0, -6 } }; // 0x7E '~'
const GFXfont Tahu_16pt7b PROGMEM = {
(uint8_t *)Tahu_16pt7bBitmaps,
(GFXglyph *)Tahu_16pt7bGlyphs,
0x20, 0x7E, 46 };
// Approx. 4099 bytes
Enfin, une fois cette étape atteinte, il ne reste plus qu’à inclure cette nouvelle police de caractère à taille unique, dans son programme Arduino. Pour ce faire, il suffira de :
- L’inclure au début du code, avec la commande : #include « Tahu16pt7b.h »
- Et d’utiliser la fonction setFont pour s’en servir → exemple d’utilisation : ecranOLED.setFont(&Tahu16pt7b);
Et comme vous l’aurez compris : cette police de caractère est monotaille, comme les autres (ici en taille « 16 pt »).
Au passage, si tout cela ne vous semble pas très parlant, ne vous inquiétez pas ! Car je vous mettrai un peu plus loin, dans cet article, un exemple vous montrant comment importer plusieurs polices de caractères, et passer de l’une à l’autre en toute simplicité !
Nota : pour revenir à la police de caractère par défaut, il suffit d’utiliser la commande « ecranOLED.setFont(); », sans préciser le moindre argument. Il n’y a donc pas besoin de la nommer, car la librairie Adafruit comprendra alors que vous cherchez à réutiliser la font par défaut !
Afficher une image (avec drawBitmap)
Comme vous allez voir, afficher une image sur un écran OLED est vraiment quelque chose de simple à faire, au niveau du code. Mais avant d’arriver à faire cela, il va simplement falloir faire quelques manips de préparation ! En fait, il faudra :
- Sélectionner une image, de type JPG par exemple
- De transformer cette image en code Arduino, compatible avec la librairie Adafruit GFX (perso, je me sers du site suivant : https://javl.github.io/image2cpp/)
- D’importer ce code dans votre programme (à mettre au début)
- Et de la faire afficher avec la fonction « drawBitmap »
Pour vous détailler toutes ces étapes, je vais vous prendre un exemple parlant : imaginons que nous souhaitons faire afficher le logo du site « Passion Electronique » sur son écran OLED. Du coup, première étape, il nous faut un fichier image. Ici, je vous propose le logo au format 64×64 pixels, afin qu’il puisse s’afficher pleinement en hauteur, sur un afficheur OLED faisant 128×64 pixels. D’ailleurs, voici ce logo / image :
En utilisant le convertisseur image2cpp (accessible ici : https://javl.github.io/image2cpp/), on obtient un code arduino, représentant cette image :
Pour ce faire, j’ai dû sélectionner les paramètres suivants, dans cet outil en ligne :
- Préciser la couleur de fond (« Background Color » : White)
- Cocher la case permettant d’inverser les couleurs de l’image (« Invert image colors ») ; car pour rappel, ce qui s’affiche sur un écran OLED est ce qui est en « blanc » sur l’image, et vice-versa (d’où la nécessité d’avoir un fond noir au niveau de son image)
- Et sélectionner le format « Arduino code, single bitmap » dans la liste déroulante « Code output format »
Ainsi, on obtient le block de code suivant :
const unsigned char NaN [] PROGMEM = {
// 'logo_pse_nb_64x64, 64x64px
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, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x86, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x86, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x78, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x31, 0x86, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x04, 0x21, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x03, 0xc0, 0x00, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xff, 0xc0,
0x00, 0xff, 0xb0, 0x00, 0x00, 0x4d, 0xff, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0xec, 0x03, 0xc0,
0x00, 0x00, 0x30, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xcc, 0x00, 0x00,
0x03, 0xff, 0xb0, 0x7f, 0xfe, 0x0c, 0x00, 0x00, 0x03, 0xff, 0xb0, 0x40, 0x03, 0x0d, 0xff, 0xf0,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0d, 0xff, 0xf0, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x1e, 0x00,
0x1f, 0xff, 0xb0, 0xc0, 0x03, 0x0d, 0xfe, 0x00, 0x1f, 0xff, 0xb0, 0xc0, 0x03, 0x0d, 0xfe, 0x00,
0x1e, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x1c, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x1f, 0xb0, 0xc0, 0x03, 0x0d, 0xff, 0xc0, 0x00, 0x1f, 0xb0, 0x7f, 0xff, 0x0d, 0xff, 0x80,
0x00, 0x00, 0x30, 0x7f, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00,
0x00, 0xe0, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xfc, 0x00,
0x01, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xfc, 0x00, 0x00, 0xe0, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x71, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0xf9, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf9, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x71, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x80, 0x78, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x01, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x80, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 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
};
À noter qu’il faut remplacer le nom de variable « NaN » par « leNomDeMonImage », afin que ce soit plus parlant, dans votre code arduino ! Enfin, au niveau de votre codage arduino, il faudra :
- Mettre le block de code ci-dessus dans l’entête de votre programme (avant la fonction setup, par exemple)
- Et de se servir de la fonction drawBitmap pour afficher cette image, là où on le désire
Et comme vous allez le voir, seules quelques instructions permettent d’afficher cette image à l’écran :
int16_t positionImageAxeHorizontal = 20; // Position de la gauche de l’image à 20 pixels du bord gauche de l’écran
int16_t positionImageAxeVertical = 16; // Position du haut de l’image à 16 pixels du bord haut de l’écran OLED
int16_t largeurDeLimage = 64; // Largeur de l’image à afficher : 64 pixels
int16_t hauteurDeLimage = 64; // Hauteur de l’image à afficher : 64 pixels
ecranOLED.drawBitmap(positionImageAxeHorizontal, positionImageAxeVertical, leNomDeMonImage, largeurDeLimage, hauteurDeLimage, WHITE);
C’est d’ailleurs, à peu de chose près, ce que je vous montrerai dans un des exemples plus bas ! En somme, rien de bien compliqué 😉
Utiliser toutes les fonctions étendues de dessin (telles que : drawLine, drawRect, fillRect, drawRoundRect, fillRoundRect, drawCircle, fillCircle, drawTriangle, et fillTriangle)
Autres fonctions très intéressantes : les outils de dessins ! Et ils couvrent globalement tous nos besoins, en nous permettant de pouvoir :
- Tracer/remplir un rectangle
- Tracer/remplir un rectangle à coins arrondis
- Tracer/remplir un cercle
- Et tracer/remplir un triangle
En bref, il y a de quoi faire tout notre bonheur 😉
Côté codage informatique, c’est d’ailleurs assez simple à mettre en oeuvre. Voyez par vous-même !
- drawLine(x1, y1, x2, y2, couleur) : permet de tracer une ligne sur son écran OLED, allant du point (x1, y1) au point (x2, y2)
- drawRect(posX, posY, largeur, hauteur, couleur) : permet de tracer le contour d’un rectangle ayant une largeur et hauteur donnée, à partir du point de coordonnées (posX, posY)
- fillRect(posX, posY, largeur, hauteur, couleur) : permet de tracer un rectangle plein, ayant une largeur et hauteur donnée, à partir du point aux coordonnées (posX, posY)
- drawRoundRect(posX, posY, largeur, hauteur, rayon, couleur) : identique à drawRect, à ceci près qu’on a un argument en plus, spécifiant le rayon en pixels, des angles arrondis du rectangle (si par exemple vous souhaitez que votre bord arrondi soit de 3 pixels, alors il suffira de mettre la valeur 3 à la place du mot « rayon »)
- fillRoundRect(posX, posY, largeur, hauteur, rayon, couleur) : idem à fillRect, à ceci près qu’il faut également renseigner le rayon des angles (exprimé en « nombres de pixels souhaités »)
- drawCircle(posX, posY, rayon, couleur) : permet de tracer le contour d’un cercle, ayant pour centre la position (posX, posY), avec un rayon égal à la valeur spécifiée (en remplaçant le mot « rayon » par sa valeur, en pixels)
- fillCircle(posX, posY, rayon, couleur) : permet de tracer un cercle plein, en prenant pour centre la position (posX, posY), et en lui donnant une valeur de rayon spécifique
- drawTriangle(x1, y1, x2, y2, x3, y3, couleur) : permet de tracer le contour d’un triangle, ayant ses 3 sommets aux coordonnées (x1, y1), (x2, y2), et (x3, y3)
- et fillTriangle(x1, y1, x2, y2, x3, y3, couleur) : permet de tracer un triangle plein (rempli), avec 3 sommets figurant aux coordonnées (x1, y1) ; (x2, y2) ; et (x3, y3)
Dans chacune de ses fonctions, vous aurez la « couleur » comme dernier argument. Vous pourrez ici mettre la valeur « SSD1306_WHITE » pour tracer en couleur, et « SSD1306_BLACK » pour dessiner en noir.
Inverser les couleurs à l’écran (avec invertDisplay)
Autre fonction qui peut avoir son utilité, si on cherche à attirer l’attention de l’utilisateur sur l’écran : la fonction « invertDisplay ». Comme son nom l’indique, elle permet d’inverser toutes les couleurs d’un écran OLED. Et comme nous travaillons ici sur des écrans monochromes, cela se traduit par :
- l’allumage de tous les pixels éteints
- et de l’extinction de tous les pixels allumés
Au niveau de l’appel de cette fonction, il suffit de lui indiquer une valeur TRUE ou FALSE en argument, selon si vous souhaitez inverser tous les pixels allumés à l’écran, ou les rétablir dans leur état « d’origine ». Ainsi, dans le code :
- ecranOLED.invertDisplay(TRUE) permet d’inverser tous les pixels éteints/allumés
- ecranOLED.invertDisplay(FALSE) permet de désactiver l’inversion de tous les pixels éteints/allumés
Remplir la totalité de l’écran en couleur (avec fillScreen)
Enfin, une dernière fonction intéressante : la fonction fillScreen. Car elle permet, en une seule ligne :
- soit l’effaçage complet de tous les pixels de l’écran
- soit l’allumage complet de tous les pixels à l’écran
Au niveau du code arduino, cela se fait en toute simplicité, en envoyant vrai ou faux comme argument à la fonction fillScreen. Cela donne :
- pour allumer tous les pixels de l’écran : ecranOLED.invertDisplay(TRUE);
- pour éteindre tous les pixels de l’écran : ecranOLED.invertDisplay(FALSE);
Pour rappel, comme nous travaillons sur des écrans OLED monochrome (chipset SSD1306), la couleur affichée à l’écran sera celle de votre afficheur OLED, et ne pourra pas être une autre couleur de votre choix. Car celle-ci est « unique » pour chaque pixel, et par conséquent, chaque pixel ne pourra prendre qu’une couleur donnée, et aucune autre.
Nota : comme toujours, et pour toutes les fonctions énumérées ci-dessus, il faudra utiliser la fonction « display », pour « envoyer tous ces changements à l’écran ». Sinon, tout ce que vous aurez fait sera simplement enregistré en mémoire tampon, et non envoyé à l’écran !
Voilà qui conclut cette partie, qui je pense couvre la plupart des fonctionnalités de bases de cette librairie ! À présent, place aux exemples !
EXEMPLE 1 : « scanner i2c », permettant de retrouver l’adresse d’un afficheur OLED I2C
Comme premier exemple, je vous propose ce « scanner i2c ». Car dû au fait que les adresses écrites sur les PCB des écrans OLED (sur 8 bits) diffèrent des adresses à renseigner dans votre programme arduino (sur 7 bits), il peut être intéressant de faire détecter l’adresse « exacte » de son afficheur OLED, par un programme qui scanne toutes les adresses depuis l’arduino. Ainsi, si jamais vous avez le moindre doute sur l’adresse de votre afficheur I2C (en cas de dysfonctionnement par exemple), vous saurez déjà s’il répond ou non, à l’appel du scanner !
Mais avant d’entrer dans le cœur du programme en lui-même, voyons ensemble le montage que je vous propose de réaliser, afin de pouvoir tester le code en suivant :
Comme vous le voyez, le câblage est hyper simple à réaliser : 2 fils pour l’alim, et 2 fils de communication (SDA et SCL). En somme, rien de bien compliqué 😉
Côté programmation arduino, voici le programme permettant de scanner toutes les adresses i2c, afin de détecter tous les périphériques branchés sur votre arduino, et opérationnels :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier : scannerI2C.ino
Description : Scanne les 127 adresses i2c possibles, à la recherche de périphériques connectés sur l'Arduino
(affiche l'adresse des périphériques détectés)
Auteur : Jérôme TOMSKI (https://passionelectronique.fr/)
Créé le : 25.07.2021
*/
#include <Wire.h> // Appel de la bibliothèque Wire.h, afin de pouvoir envoyer des commandes sur le port i2c
byte nombreDePeripheriquesTrouves = 0; // Variable indiquant combien de périphériques ont été trouvés en scannant le port I2C
// ========================
// Initialisation programme
// ========================
void setup() {
// Initialisation de la liaison série, côté PC (pour y faire afficher des infos, via le moniteur série de l'IDE Arduino)
Serial.begin(9600);
Serial.println(F(" ~~ SCANNER I2C ~~ "));
Serial.println(F("Scanne toutes les adresses i2c, afin de repérer tous les périphériques connectés à l'arduino"));
Serial.println(F("============================================================================================"));
Serial.println();
// Initialisation de la liaison i2C
Wire.begin();
// Boucle de parcous des 127 adresses i2c possibles
for (byte adresseI2C = 0; adresseI2C < 127; adresseI2C++)
{
Wire.beginTransmission(adresseI2C); // Interrogation de l'adresse i2c ciblée
if (Wire.endTransmission () == 0) // Si cela s'est bien passé, c'est qu'il y a un périphérique répondant à cette adresse
{
Serial.print(F("Périphérique i2c trouvé à l'adresse : "));
Serial.print(adresseI2C, DEC); // On affiche son adresse au format décimal
Serial.print(F(" (0x"));
Serial.print(adresseI2C, HEX); // ... ainsi qu'au format héxadécimal (0x..)
Serial.println(F(")"));
nombreDePeripheriquesTrouves++;
delay(1); // Temporisation, avant de passer au scan de l'adresse suivante
}
}
// Affichage final, indiquant le nombre total de périphériques trouvés sur le port I2C de l'arduino
if (nombreDePeripheriquesTrouves == 0) {
Serial.println(F("Aucun périphérique I2C trouvé…"));
}
else if (nombreDePeripheriquesTrouves == 1) {
Serial.println();
Serial.println(F("1 périphérique trouvé !"));
}
else {
Serial.println();
Serial.print(nombreDePeripheriquesTrouves);
Serial.println(F("périphériques trouvés !"));
}
Serial.println(F("Scan terminé."));
}
// =================
// Boucle principale
// =================
void loop() {
// Aucun code ici, car tout se passe dans la fonction setup !
}
Pour utiliser ce programme, il s’agit d’uploader ce code dans votre Arduino (Uno ou autre), et de lancer le moniteur série de votre IDE. Ainsi, sur ce dernier, vous devriez voir des infos s’afficher. Et théoriquement, il y a 2 issues possibles, suivant si votre écran OLED a pu être trouvé, ou non.
→ Si jamais votre afficheur OLED ne répond pas, alors vous devriez alors avoir un message le signifiant clairement en retour (« aucun périphérique trouvé »). Voici ce que j’obtiens de mon côté, si je le débranche :
→ Et si votre écran OLED est bien détecté par ce programme « scanner I2C », alors l’adresse de ce dernier devrait clairement s’afficher dans votre moniteur série. Dans mon cas, l’adresse de mon afficheur OLED était 0x3C, comme vous pourrez le constater ci-dessous :
Perso, j’adore ce petit programme. Car au-delà du fait qu’il puisse retrouver une adresse i2c, ce bout de code permet également de vérifier si le périphérique I2C en question (ici un écran OLED) n’est pas « mort ». Car si jamais c’est le cas, il ne répondra pas. Ainsi, on saura de suite qu’il s’agit d’un problème matériel, et non logiciel !
Mais maintenant que nous savons que notre afficheur OLED fonctionne bien, et que nous avons vérifié son adresse i2c (0x3C dans mon cas), nous allons pouvoir passer à la suite, et (enfin !) pouvoir commencer à faire afficher des choses à l’écran 😉
EXEMPLE 2 : code arduino faisant allumer tous les pixels d’un écran OLED (pour vérifier leur état)
Maintenant est venue l’heure de faire nos premiers pas avec notre écran OLED. Et pour ce faire, je vous propose un petit bout de code, permettant d’allumer tous les pixels de votre afficheur OLED. Ainsi, vous pourrez :
- vérifier le bon fonctionnement de la communication I2C avec votre écran OLED
- et vérifier qu’aucun des pixels de son afficheur est « en défaut » (auquel cas, il restera « noir »)
Pour ce faire, je vais me servir de la fonction drawPixel, vue un peu plus haut, et permettant d’allumer un point précis de l’écran. Et en balayant toute la largeur, puis hauteur de notre afficheur, nous pourrons ainsi allumer tous les pixels. À noter qu’il existe au passage un moyen plus rapide de faire allumer tous les pixels à l’écran (avec la fonction fillScreen), mais j’ai tenu à vous montrer comment débuter, avec l’allumage de points précis sur l’afficheur (plus utile selon moi, par la suite !).
Côté montage, c’est exactement la même chose que vu dans l’exemple précédent, à savoir :
- on alimente l’écran OLED en 5 volts, via l’arduino
- et on raccorde les broches SCL et SDA de l’Arduino à l’afficheur (pour la partie communication)
Voici ce que cela donne, avec un Arduino Nano, pour varier !
Et côté programme, en voici son contenu :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier : allumeTousLesPixelsOLEDssd1306.ino
Description : Permet de vérifier visuellement le bon fonctionnement de tous les pixels d'un écran OLED 128x64 pixels,
fonctionnant sur un chipset SSD1306
Auteur : Jérôme TOMSKI (https://passionelectronique.fr/)
Créé le : 25.07.2021
*/
#include <Adafruit_SSD1306.h>
#define nombreDePixelsEnLargeur 128 // Taille de l'écran OLED, en pixel, au niveau de sa largeur
#define nombreDePixelsEnHauteur 64 // Taille de l'écran OLED, en pixel, au niveau de sa hauteur
#define brocheResetOLED -1 // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define adresseI2CecranOLED 0x3C // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)
Adafruit_SSD1306 oled(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED);
// ========================
// Initialisation programme
// ========================
void setup() {
// Initialisation de la liaison série, côté PC (pour y faire afficher des infos, via le moniteur série de l'IDE Arduino)
Serial.begin(9600);
Serial.println(F("Allumage de l'intégralité des pixels (OLED 128x64, chipset SSD1306)"));
Serial.println(F("==================================================================="));
Serial.println();
// Initialisation de l'écran OLED
if(!oled.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED)) {
Serial.println(F("Erreur de communication avec le chipset SSD1306… arrêt du programme."));
while(1); // Arrêt du programme (boucle infinie)
}
else {
Serial.println(F("Initialisation du contrôleur SSD1306 réussi."));
}
// Allumage de tous les pixels de l'écran OLED
Serial.println(F("Chargement de la mémoire tampon de l'écran OLED, avec tous les pixels à allumer…"));
oled.clearDisplay(); // Effaçage de l'intégralité du buffer
for(byte numeroLigne=0 ; numeroLigne < nombreDePixelsEnHauteur ; numeroLigne++) {
for(byte numeroColonne=0 ; numeroColonne < nombreDePixelsEnLargeur ; numeroColonne++) {
oled.drawPixel(numeroColonne, numeroLigne, WHITE); // On demande l'allumage de chaque pixel, un à un, avec la commande : drawPixel(posX,posY,couleur);
}
}
// Nota 1 : le "WHITE" ne veut pas dire "blanc" ici, mais la couleur de votre écran OLED monochrome (qui peut être blanc, bleu, jaune, bleu/jaune, …)
// Nota 2 : on aurait pu utiliser la fonction "fillScreen(couleur)" pour remplir/effacer l'écran, avec la couleur souhaitée ; mais ici, j'ai voulu vous montrer
// comment se servir de la fonction "drawPixel(posX,posY,couleur)"
Serial.println(F("Chargement terminé. Affichage !"));
oled.display(); // Transfert du buffer à l'écran
Serial.println(F("Fin."));
}
// =================
// Boucle principale
// =================
void loop() {
// Aucun code dans cette partie, car tout se passe dans la fonction setup !
}
Si tout se passe bien, vous devriez voir tous les pixels de votre afficheur OLED s’illuminer, à l’image de ce que j’ai obtenu de mon côté, avec mon Arduino Nano (désolé pour le contrejour …) :
Ici, comme vous pouvez le constater, j’utilise un écran OLED monochrome « bicolore », si je puis dire ! Vous voyez donc apparaître 2 zones bien distinctes :
- la partie haute (les 16 premiers pixels), qui sont de couleur jaune
- la partie basse (les 48 autres pixels), qui sont de couleur bleue
Mais pour rappel : en aucun cas cet écran pourrait afficher deux couleurs différentes, sur un même pixel donné. Car cet afficheur oled fonctionne avec le chipset monochrome SSD1306. Ainsi, la zone haute sera TOUJOURS jaune, et la zone milieu et basse, TOUJOURS bleue !
Du reste, j’ai inséré dans le code quelques checkpoint, pour vérifier que tout se passe bien. Si vous ouvrez le moniteur série de votre IDE arduino, vous devriez voir apparaître quelque chose comme cela :
Remarque : maintenant que nous avons vu comment allumer un point précis de l’écran OLED, libre à vous de vous essayer au traçage de lignes, rectangles, cercles, et triangles, en utilisant les fonctions drawLine, drawRect, drawCircle, et drawTriangle, vues plus haut. D’ailleurs, si vous souhaitez plus d’infos à ce sujet, n’hésitez pas à revenir au chapitre 5, nommé « Fonctions logicielles et graphiques très utiles » (un peu plus haut dans cet article !).
EXEMPLE 3 : code arduino permettant d’afficher du texte à l’écran (de différentes tailles)
À présent, nous allons voir comment afficher du texte sur un écran OLED. Pour ce faire, nous allons utiliser la police « par défaut » de la librairie SSD1306 d’Adafruit, et nous amuser à agrandir la taille des caractères au besoin.
Tout d’abord, concernant le montage à réaliser, il s’agit toujours du même que nous avons vu dans les exemples précédents. Je vous le remets ici, pour info, avec un exemple de raccordement d’afficheur OLED à un Arduino Uno, par exemple :
Côté logiciel, nous allons nous servir de la fonction « print » pour afficher du texte à l’écran, et de la fonction « setTextSize » pour en grossir la taille. Pour illustrer le tout, je vous propose ici un petit bout de programme arduino, permettant d’afficher successivement des textes, de 3 tailles différentes. Ainsi, vous verrez trois affichages se succéder :
- 1er affichage : 8 lignes de taille normale (zoom = 1), en alternant la couleur du fond à chaque ligne
- 2ème affichage : 4 lignes de taille double (zoom = 2), toujours en alternant la couleur de fond, à chaque changement de ligne
- 3ème affichage : 3 lignes de taille triple (zoom = 3), en sachant qu’on peut grossir davantage le texte encore, si on le souhaite !
L’important ici, outre le fait d’apprendre comment afficher du texte à l’écran, est de voir comment le grossir au passage, selon ses besoins (tout en gardant que la multiplication de taille ne pourra se faire que d’un multiplicateur de type « nombre entier », supérieur ou égal à 1). Du coup, on est limité à un grossissement par x1, x2, x3, ou plus, mais sans aucune possibilité de rétrécissement, ni d’usage de « valeurs intermédiaires » (telles que 1,5 ou n’importe quel autre nombre à virgule).
Voici donc le programme, permettant de faire afficher les 3 affichages détaillés ci-dessus :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier : afficherTexteSsd1306.ino
Description : Affiche du texte de test, sur un écran OLED i2c de 128x64 pixels,
fonctionnant avec un contrôleur SSD1306
Auteur : Jérôme TOMSKI (https://passionelectronique.fr/)
Créé le : 26.07.2021
*/
#include <Adafruit_SSD1306.h>
#define nombreDePixelsEnLargeur 128 // Taille de l'écran OLED, en pixel, au niveau de sa largeur
#define nombreDePixelsEnHauteur 64 // Taille de l'écran OLED, en pixel, au niveau de sa hauteur
#define brocheResetOLED -1 // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define adresseI2CecranOLED 0x3C // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)
Adafruit_SSD1306 ecranOLED(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED);
// ========================
// Initialisation programme
// ========================
void setup() {
// Initialisation de l'écran OLED
if(!ecranOLED.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED))
while(1); // Arrêt du programme (boucle infinie) si échec d'initialisation
// *************************************************************************
// Affichage de 3 écrans successifs, avec zoom sur police x1, puis x2, et x3
// *************************************************************************
for(byte tailleDeCaractere=1; tailleDeCaractere <=3; tailleDeCaractere++) {
boolean bCouleurInverse = false;
ecranOLED.clearDisplay(); // Effaçage de l'intégralité du buffer
ecranOLED.setTextSize(tailleDeCaractere); // Taille des caractères (1:1, puis 2:1, puis 3:1)
ecranOLED.setCursor(0, 0); // Déplacement du curseur en position (0,0), c'est à dire dans l'angle supérieur gauche
// ***********************************************************************
// Affichage de 8 lignes à couleurs alternées, dans chaque écran successif
// ***********************************************************************
for(byte numeroDeLigne=1; numeroDeLigne<=8; numeroDeLigne++) {
if(bCouleurInverse)
ecranOLED.setTextColor(SSD1306_BLACK, SSD1306_WHITE); // Couleur du texte, et couleur du fond
else
ecranOLED.setTextColor(SSD1306_WHITE); // Affichage du texte en "blanc" (avec la couleur principale, en fait, car l'écran monochrome peut être coloré)
ecranOLED.print("Ligne ");
ecranOLED.println(numeroDeLigne);
bCouleurInverse = !bCouleurInverse;
}
ecranOLED.display(); // Transfert le buffer à l'écran
delay(2000);
}
}
// =================
// Boucle principale
// =================
void loop() {
// Aucun code dans cette partie, car tout se passe dans la fonction setup !
}
Une fois exécuté, ce programme fera donc s’afficher 3 écrans différents, avec un grossissement de police de caractère à chaque fois. Au final, vous devriez visuellement obtenir quelque chose du type :
Nota : ne faites pas attention à la couleur des pixels jaunes et bleus, car ici, j’utilise un écran monochrome à 2 parties (1 zone haute de couleur jaune, et 1 zone médiane/basse de couleur bleue).
Du reste, comme vous l’aurez compris avec cette méthode (setTextSize), nous sommes assez limités au niveau du dimensionnement des tailles de police de caractère. Du coup, afin d’avoir quelque chose qui correspond vraiment plus à certains de nos besoins, il va falloir aller plus loin, et ne pas se limiter à la police par défaut. C’est d’ailleurs ce que je vous propose de voir à présent, dans l’exemple qui suit !
EXEMPLE 4 : code arduino montrant comment utiliser d’autres polices de caractères, sur son écran OLED
Maintenant que nous avons vu comment afficher du texte sur un écran OLED, nous allons pousser les choses un peu plus, afin d’afficher d’autres polices de caractères, plus exotiques et plus fun 😉
À noter que le montage à réaliser ici est encore le même que vu précédemment. Pour la forme, je vous remets un exemple de branchement d’écran OLED sur arduino nano, afin que vous puissiez reproduire le montage pour tester cet exemple de code :
Pour cet exemple, nous allons utiliser plusieurs polices de caractères différentes. Mais avant tout, sachez qu’il en existe de 2 types :
- Celles fournies avec la librairie Adafruit
- Et celles qu’on peut importer, directement dans notre code
Concernant les polices de caractères natives, déjà intégrées dans la bibliothèque Adafruit, on retrouve :
- La police par défaut (uni-taille)
- La police « FreeMono », déclinée en Normal/Gras/Italique, et en tailles 9 pt, 12 pt, 18 pt, et 24 pt
- La police « FreeSans », déclinée en Normal/Gras/Italique, et en tailles 9 pt, 12 pt, 18 pt, et 24 pt
- Et la police «FreeSerif », déclinée en Normal/Gras/Italique, et en tailles 9 pt, 12 pt, 18 pt, et 24 pt
Ces polices sont particulièrement faciles à intégrer, car un « #include » suffit en entête de programme. Du coup, si l’on souhaite par exemple pouvoir utiliser, dans son programme, la police « FreeSans Gras 12 pt », il suffit d’ajouter la ligne suivante, en tête de code arduino : « #include <Fonts/FreeSansBold12pt7b.h>; ».
À noter que je vous mettrai en commentaire, dans le programme exemple ci-dessous, toutes ces définitions de polices, et leur include associé. Ainsi, vous pourrez les tester par vous-même, et faire appel à elles au besoin !
Ceci étant dit, vous vous intéresserez peut-être à intégrer d’autres polices de caractères, plus « sympa », ou plus « exotiques » ! Pour cela, il vous suffira de suivre les étapes suivantes, à savoir :
- Récupérer le fichier TTF de la police de caractères que vous souhaitez intégrer à votre programme Arduino
- Transformer une partie de ce fichier, pour en extraire un petit fichier « .h », qui soit compatible avec la librairie Adafruit GFX, utilisée ici
- D’insérer ce fichier « .h » dans votre projet et faire appel à lui (avec un #include), dans votre code arduino
- Et d’appeler cette police de caractère à l’endroit voulu, avec la fonction « setFont »
IMPORTANT : on ne va pouvoir importer ici qu’une seule taille de caractères (par exemple : du 11 pt) et qu’un seul type de lettrage (par exemple : de l’italique). Si vous voulez utiliser d’autres tailles spécifiques, ou d’autres styles, il faudra alors les importer séparément, à leur tour. En bref : on ne peut importer dans son programme arduino que des polices de caractère à taille unique, et de style prédéfini. Bien sûr, on pourra importer autant de fichiers de tailles ou styles différents qu’on souhaite, mais dans la limite de l’Arduino. Et croyez moi… celle-ci est très limitée. D’ailleurs, en pratique, on pourra difficilement importer plus de 3 ou 4 fichiers de police différentes, avant d’arriver à saturation de la mémoire de son arduino ! Alors réfléchissez bien, avant tout usage !
Dans le code qui suit, je vous ai pris l’exemple d’une police gratuite trouvée sur le net, appelée « AlarmClock » (source : https://www.dafont.com/fr/alarm-clock.font). Vous pouvez d’ailleurs peut-être également trouver votre bonheur sur ce site, où figurent bon nombre de polices « libres de droits », si vous souhaitez en faire un usage commercial (chose à toujours vérifier).
Comme évoqué plus haut, j’ai exporté une taille et un type précis de cette police AlarmClock. En fait, j’ai extrait la taille « 6 points » et le style « Normal ». Pour faire cette extraction, je me suis servi d’un outil d’extraction gratuit en ligne (accessible ici : https://rop.nl/truetype2gfx/). Si jamais vous avez des difficultés à utiliser ce site, sachez que j’ai déjà abordé tout ceci un peu plus haut dans cet article, dans la partie « setFont ». Donc n’hésitez pas à vous y reporter, si jamais vous rencontrez la moindre difficulté.
Une fois cette « portion de police de caractère » extraite, on récupère un fichier « .h ». Il faudra déplacer ce fichier dans le répertoire courant de votre programme exemple arduino. Ensuite, il faudra rajouter l’include qui va bien (#include « alarm_clock6pt7b.h »), dans l’entête de votre code arduino. Une fois fait, le changement de police de caractère pourra s’effectuer en une seule ligne, en écrivant : ecranOLED.setFont(&alarm_clock6pt7b) … comme vous pourrez le constater dans le programme ci-dessous !
Nota : voici le fichier à dézipper pour faire fonctionner l’exemple qui suit ; ce fichier est à mettre directement dans le répertoire de votre programme exemple arduino. Ce fichier représente en fait la police de caractère Alarm Clock, en taille 6 points, en style « normal », et au format compatible avec la librairie Adafruit GFX (lien de téléchargement : https://passionelectronique.fr/wp-content/uploads/alarm_clock6pt7b.zip).
Et en parlant de code à exécuter, le voilà !
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier : autresPolicesDeCaracteresSsd1306.ino
Description : Affiche des texte avec des polices de caractères différentes,
sur un écran OLED i2c faisant 128x64 pixels (contrôleur SSD1306)
Auteur : Jérôme TOMSKI (https://passionelectronique.fr/)
Créé le : 26.07.2021
/// ATTENTION \\\ : LES POLICES DE CARACTÈRES PRENNENT BEAUCOUP DE PLACE EN MÉMOIRE. Utilisez les donc avec parcimonie !
Convertisseur TTF vers GFX FONTS utilisé : https://rop.nl/truetype2gfx/
*/
#include <Adafruit_SSD1306.h>
//========= Police de caractère : AlarmClock (https://www.dafont.com/fr/alarm-clock.font)
#include "alarm_clock6pt7b.h" // Normal, en 6 pts
//========= Police de caractère : FreeMono (fournie avec librairie Adafruit GFX)
#include <Fonts/FreeMono9pt7b.h> // Normal (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeMono12pt7b.h>
//#include <Fonts/FreeMono18pt7b.h>
//#include <Fonts/FreeMono24pt7b.h>
//#include <Fonts/FreeMonoBold9pt7b.h> // Gras (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeMonoBold12pt7b.h>
//#include <Fonts/FreeMonoBold18pt7b.h>
//#include <Fonts/FreeMonoBold24pt7b.h>
//#include <Fonts/FreeMonoOblique9pt7b.h> // Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeMonoOblique12pt7b.h>
//#include <Fonts/FreeMonoOblique18pt7b.h>
//#include <Fonts/FreeMonoOblique24pt7b.h>
//#include <Fonts/FreeMonoBoldOblique9pt7b.h> // Gras + Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeMonoBoldOblique12pt7b.h>
//#include <Fonts/FreeMonoBoldOblique18pt7b.h>
//#include <Fonts/FreeMonoBoldOblique24pt7b.h>
//========= Police de caractère : FreeSans (fournie avec librairie Adafruit GFX)
#include <Fonts/FreeSans9pt7b.h> // Normal (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSans12pt7b.h>
//#include <Fonts/FreeSans18pt7b.h>
//#include <Fonts/FreeSans24pt7b.h>
//#include <Fonts/FreeSansBold9pt7b.h> // Gras (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSansBold12pt7b.h>
//#include <Fonts/FreeSansBold18pt7b.h>
//#include <Fonts/FreeSansBold24pt7b.h>
//#include <Fonts/FreeSansOblique9pt7b.h> // Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSansOblique12pt7b.h>
//#include <Fonts/FreeSansOblique18pt7b.h>
//#include <Fonts/FreeSansOblique24pt7b.h>
//#include <Fonts/FreeSansBoldOblique9pt7b.h> // Gras + Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSansBoldOblique12pt7b.h>
//#include <Fonts/FreeSansBoldOblique18pt7b.h>
//#include <Fonts/FreeSansBoldOblique24pt7b.h>
//========= Police de caractère : FreeSerif (fournie avec librairie Adafruit GFX)
#include <Fonts/FreeSerif9pt7b.h> // Normal (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSerif12pt7b.h>
//#include <Fonts/FreeSerif18pt7b.h>
//#include <Fonts/FreeSerif24pt7b.h>
//#include <Fonts/FreeSerifBold9pt7b.h> // Gras (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSerifBold12pt7b.h>
//#include <Fonts/FreeSerifBold18pt7b.h>
//#include <Fonts/FreeSerifBold24pt7b.h>
//#include <Fonts/FreeSerifItalic9pt7b.h> // Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSerifItalic12pt7b.h>
//#include <Fonts/FreeSerifItalic18pt7b.h>
//#include <Fonts/FreeSerifItalic24pt7b.h>
//#include <Fonts/FreeSerifBoldItalic9pt7b.h> // Gras + Italique (en 9, 12, 18, et 24 pts)
//#include <Fonts/FreeSerifBoldItalic12pt7b.h>
//#include <Fonts/FreeSerifBoldItalic18pt7b.h>
//#include <Fonts/FreeSerifBoldItalic24pt7b.h>
#define nombreDePixelsEnLargeur 128 // Taille de l'écran OLED, en pixel, au niveau de sa largeur
#define nombreDePixelsEnHauteur 64 // Taille de l'écran OLED, en pixel, au niveau de sa hauteur
#define brocheResetOLED -1 // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define adresseI2CecranOLED 0x3C // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)
Adafruit_SSD1306 ecranOLED(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED); // Le "Wire" indique qu'on travaille en I2C
// ========================
// Initialisation programme
// ========================
void setup() {
// Initialisation de l'écran OLED
if(!ecranOLED.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED))
while(1); // Arrêt du programme (boucle infinie) si échec d'initialisation
// Affichage d'un texte "Hello World", avec une des autre polices disponibles
ecranOLED.clearDisplay(); // Vidange du buffer de l'écran OLED
ecranOLED.setTextSize(1); // Sélection de l'échelle 1:1
ecranOLED.setTextColor(WHITE); // Couleur "blanche" (ou colorée, si votre afficheur monochrome est bleu, jaune, ou bleu/jaune)
ecranOLED.setCursor(0,1); // Positionnement du curseur dans l'angle haut-gauche, avec décalage de 1 pixel vers le bas
ecranOLED.setFont(&alarm_clock6pt7b); // Sélection de la police "Alarm Clock"
ecranOLED.println("AlarmClock"); // …et affichage du nom de cette police
ecranOLED.setFont(&FreeMono9pt7b); // Sélection de la police "Free Mono"
ecranOLED.println("FreeMono"); // …et affichage du nom de cette police
ecranOLED.setFont(&FreeSans9pt7b); // Sélection de la police "Free Sans"
ecranOLED.println("FreeSans"); // …et affichage du nom de cette police
ecranOLED.setFont(&FreeSerif9pt7b); // Sélection de la police "Free Serif"
ecranOLED.println("FreeSerif"); // …et affichage du nom de cette police
ecranOLED.display();
// Nota : pour revenir à la police de caractère "d'origine", il suffit d'écrire la ligne : display.setFont();
}
// =================
// Boucle principale
// =================
void loop() {
// Boucle sans fin (code principal dans partie "setup", en fait)
}
Si tout est bien câblé, et votre programme bien uploadé, vous devriez voir à l’écran quelque chose comme ce qui suit :
Comme toujours, ne faites pas attention aux couleurs ici, car j’utilise un écran OLED « monochrome bicolore », dont les pixels sont divisés en 2 parties (jaunes en haut, et bleus en milieu/bas).
À présent, voyons un dernier exemple, permettant de faire afficher une image à l’écran. Ainsi, je pense que nous aurons fait le tour de tout ce qu’il convient de découvrir au début, lorsqu’on veut apprendre à utiliser un afficheur OLED basé sur la chipset SSD1306 (c’est à dire monochrome 128×32 ou 128×64 pixels).
EXEMPLE 5 : code arduino permettant d’afficher une image sur un afficheur OLED (après importation dans le programme)
Dernière chose que je tenais à vous montrer : l’affichage d’une image sur un écran OLED, depuis un Arduino ! Car oui, vous souhaiterez sûrement afficher des déco, symboles, ou autre logo, sur votre afficheur OLED. Et pour ce faire, rien de plus simple à mettre en œuvre, avec la fonction « drawBitmap » (abordée précédemment, dans le chapitre sur la librairie Adafruit GFX).
Ici, je vous propose simplement d’afficher le logo du site PassionElectronique, directement sur votre écran OLED. Ainsi, en copiant/collant le bout de programme que je vais vous proposer ci-dessous, vous serez à même d’afficher n’importe quelle image sur votre afficheur OLED 😉
Mais avant tout, il y a plusieurs étapes à suivre, avant de pouvoir arriver au résultat final. Dans l’ordre, il faudra :
- Redimensionner votre image à la taille de votre écran OLED (le mien faisant 128×64 pixels, j’ai choisi d’afficher une image faisant 64×64 pixels, afin qu’elle ne déborde pas)
- La transformer en tableau de données, interprétable par la bibliothèque Adafruit GFX (pour cela, il suffit de se servir du site https://javl.github.io/image2cpp/, par exemple, comme détaillé plus haut, dans le paragraphe détaillant la fonction « drawBitmap »)
- Insérer ce tableau de données, représentant l’image, dans l’entête de votre programme Arduino (en lui donnant un « nom de tableau » parlant, pour plus de commodités)
- Et de faire afficher cette image où bon vous semble, avec la fonction drawBitmap
Encore une fois, si vous avez besoin de plus de détail sur cette procédure, n’hésitez pas à relire la partie que j’avais détaillé un peu plus haut, dans cet article, au niveau du paragraphe traitant spécifiquement la fonction « drawBitmap ». Ainsi, vous aurez toutes les infos pour faire comme moi ici !
Du coup… histoire de revenir à notre exemple… il faudra, comme d’habitude, relier votre écran OLED à votre arduino. Pour ce faire, il suffit de reproduire le montage vu précédemment. Je vous le remets ici, avec un exemple câblage avec l’Arduino Uno :
Concernant l’image à afficher sur l’écran OLED, j’ai simplement pris le logo du site Passion Electronique. À ce sujet, le voici :
À noter que cette image fait 64 x 64 pixels, ce qui est idéal pour l’afficher sur un afficheur OLED faisant 128 x 64 pixels. Cette image est au format JPG, et est dessinée en noir, sur fond blanc (important de le noter, comme vous verrez un peu plus loin).
Pour obtenir un code arduino, ou plutôt un tableau de données, représentant cette image, je me suis servi de l’outil en ligne (gratuit) accessible ici : https://javl.github.io/image2cpp/. Les étapes que j’ai suivi ont été de :
- Sélectionner mon fichier JPEG (upload)
- D’ajuster le paramètres Background color, en le mettant sur « White » (car le fond de l’image est bel et bien blanc, dans mon cas)
- De cocher la case « Invert Image Color », car on veut afficher « en clair » sur l’écran OLED, tous les pixels dessinés en « en noir » sur le logo (d’où, l’inversion à faire)
- De sélectionner la valeur « Arduino Code, single bitmap » dans la liste déroulante nommée « Code Output Format »
- Et de cliquer sur « Generate Code » (pour pouvoir récupérer du code, à recopier dans l’entête de son programme arduino)
Au passage, si vous suivez toutes cette procédure à la lettre, en vous servant de mon logo en exemple, vous devez obtenir un tableau de données, représentant cette image. Il ne vous restera donc plus qu’à insérer ces données en tête de votre programme arduino. Voici d’ailleurs ce que j’ai visuellement obtenu, de mon côté, avec cette image et en suivant toutes ces étapes :
Et comme vous l’aurez compris, ce sont les données ci-dessus qu’il va falloir insérer dans votre programme arduino, afin d’intégrer cette image « en dur », pour pouvoir la faire s’afficher ensuite.
Du coup, voici le programme final, vous montrant l’insertion de ces données dans le code arduino, ainsi que l’utilisation de la fonction « drawBipmap », pour faire afficher l’image à un endroit précis de son écran OLED :
/*
______ _ _///_ _ _ _
/ _ \ (_) | ___| | | | (_)
| [_| |__ ___ ___ _ ___ _ __ | |__ | | ___ ___| |_ _ __ ___ _ __ _ ___ _ _ ___
| ___/ _ \| __|| __| |/ _ \| '_ \_____| __|| |/ _ \/ _| _| '__/ \| '_ \| |/ \| | | |/ _ \
| | | ( ) |__ ||__ | | ( ) | | | |____| |__ | | __/| (_| |_| | | (_) | | | | | (_) | |_| | __/
\__| \__,_|___||___|_|\___/|_| [_| \____/|_|\___|\____\__\_| \___/|_| |_|_|\__ |\__,_|\___|
| |
\_|
Fichier : afficherImageSsd1306.ino
Description : Affiche une image de test au centre d'un écran OLED, faisant 128x64 pixels,
avec pilotage via bus I2C (chipset SSD1306)
Auteur : Jérôme TOMSKI (https://passionelectronique.fr/)
Créé le : 27.07.2021
Transformation des images JPG au format Adafruit GFX réalisable sur le site : https://javl.github.io/image2cpp/
*/
#include <Adafruit_SSD1306.h>
// =======================
// Paramètrages écran OLED
// =======================
#define nombreDePixelsEnLargeur 128 // Taille de l'écran OLED, en pixel, au niveau de sa largeur
#define nombreDePixelsEnHauteur 64 // Taille de l'écran OLED, en pixel, au niveau de sa hauteur
#define brocheResetOLED -1 // Reset de l'OLED partagé avec l'Arduino (d'où la valeur à -1, et non un numéro de pin)
#define adresseI2CecranOLED 0x3C // Adresse de "mon" écran OLED sur le bus i2c (généralement égal à 0x3C ou 0x3D)
Adafruit_SSD1306 ecranOLED(nombreDePixelsEnLargeur, nombreDePixelsEnHauteur, &Wire, brocheResetOLED);
// ================
// Image à afficher
// ================
#define largeurDeLimage 64 // Largeur de l'image à afficher, en pixels
#define hauteurDeLimage 64 // Hauteur de l'image à afficher, en pixels
const unsigned char imageAafficher [] PROGMEM = {
// 'logo_pse_nb_64x64, 64x64px
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, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0xf8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x86, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x31, 0x86, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x78, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x31, 0x86, 0x78, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x31, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x04, 0x21, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0f, 0xff, 0xff, 0xf8, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xfc, 0x03, 0xc0, 0x00, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xff, 0xc0,
0x00, 0xff, 0xb0, 0x00, 0x00, 0x4d, 0xff, 0xc0, 0x00, 0x00, 0x30, 0x00, 0x00, 0xec, 0x03, 0xc0,
0x00, 0x00, 0x30, 0x00, 0x00, 0xec, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0xcc, 0x00, 0x00,
0x03, 0xff, 0xb0, 0x7f, 0xfe, 0x0c, 0x00, 0x00, 0x03, 0xff, 0xb0, 0x40, 0x03, 0x0d, 0xff, 0xf0,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0d, 0xff, 0xf0, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00, 0x1e, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x1e, 0x00,
0x1f, 0xff, 0xb0, 0xc0, 0x03, 0x0d, 0xfe, 0x00, 0x1f, 0xff, 0xb0, 0xc0, 0x03, 0x0d, 0xfe, 0x00,
0x1e, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x1c, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0xc0, 0x03, 0x0c, 0x00, 0x00,
0x00, 0x1f, 0xb0, 0xc0, 0x03, 0x0d, 0xff, 0xc0, 0x00, 0x1f, 0xb0, 0x7f, 0xff, 0x0d, 0xff, 0x80,
0x00, 0x00, 0x30, 0x7f, 0xfe, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00,
0x00, 0xe0, 0x30, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x01, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xfc, 0x00,
0x01, 0xff, 0xb0, 0x00, 0x00, 0x0d, 0xfc, 0x00, 0x00, 0xe0, 0x3f, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x61, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x71, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0xf9, 0x86, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xf9, 0x86, 0x30, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x71, 0x84, 0x30, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x01, 0x80, 0x78, 0x00, 0x00,
0x00, 0x00, 0x0c, 0x01, 0x80, 0x78, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x80, 0x78, 0x00, 0x00,
0x00, 0x00, 0x00, 0x01, 0x80, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x80, 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
};
// ========================
// Initialisation programme
// ========================
void setup() {
// Initialisation de l'écran OLED
if(!ecranOLED.begin(SSD1306_SWITCHCAPVCC, adresseI2CecranOLED))
while(1); // Arrêt du programme (boucle infinie) en cas d'échec de l'initialisation
// Affichage d'une image au centre de l'écran
ecranOLED.clearDisplay(); // Effaçage de la mémoire tampon de l'écran OLED
ecranOLED.drawBitmap(
(ecranOLED.width() - largeurDeLimage ) / 2, // Position de l'extrême "gauche" de l'image (pour centrage écran, ici)
(ecranOLED.height() - hauteurDeLimage) / 2, // Position de l'extrême "haute" de l'image (pour centrage écran, ici)
imageAafficher,
largeurDeLimage,
hauteurDeLimage,
WHITE); // "couleur" de l'image
ecranOLED.display(); // Transfert de la mémoire tampon à l'écran OLED, pour affichage
}
// =================
// Boucle principale
// =================
void loop() {
// Partie vide, car tout se passe dans la fonction setup()
}
Une fois le code exécuté, vous devriez voir l’image ci-dessous s’afficher à l’écran :
Maintenant, libre à vous de reprendre ce code de programmation, et de l’adapter à vos besoins, pour afficher l’image de votre choix !
Liens utiles et téléchargements
Histoire de regrouper la plupart des liens cités dans cet article, vous trouverez ci-après la liste de ceux qui sont particulièrement utiles, selon moi !
Au niveau logiciel :
- La librairie arduino « Adafruit SSD1306 » (https://github.com/adafruit/Adafruit_SSD1306) : pour pouvoir piloter des écrans OLED monochrome, tel que celui présenté dans cet article (fonctionnant sur chipset SSD1306) => à importer depuis le gestionnaire de bibliothèque de votre IDE Arduino
- La librairie arduino « Adafruit GFX » (https://github.com/adafruit/Adafruit-GFX-Library) : pour pouvoir utiliser des fonctions de dessin avancées, entre autres choses => à importer depuis le gestionnaire de bibliothèque de votre IDE Arduino
- L’extracteur de police de caractères TTF, compatible GFX (https://rop.nl/truetype2gfx/) : pour pouvoir intégrer des extraits de polices de caractères, à même son programme Arduino => utilitaire gratuit, et « en ligne »
- Le convertisseur d’image JPG, compatible GFX (https://javl.github.io/image2cpp/) : pour pouvoir intégrer ses propres images dans son code de programmation arduino => utilitaire « en ligne », et gratuit
- Un site proposant tout plein de polices de caractères à télécharger (https://www.dafont.com/fr/) : pour pouvoir trouver des polices gratuites, ou libres de droits (suivant l’usage que vous comptez en faire !)
Au niveau matériel :
- 1 x Arduino Uno ou Nano
- 1 x Afficheur OLED 0,96″ I2C 128×64 jaune/bleu (existe aussi en blanc, bleu, ou seulement jaune)
Voilà ! J’espère n’avoir rien oublié 😉
Conclusion
Nous voici au terme de ce long article sur les écrans oled, qui j’espère, aura su vous apporter toutes les infos nécessaires pour que vous puissiez faire vos premiers pas avec, sans prise de tête ! Je n’ai bien sûr pas pu tout aborder ici, tellement il y avait de choses à dire. Toutefois, je pense que vous avez là toutes les bases pour bien débuter avec un afficheur OLED à base de contrôleur SSD1306, à piloter depuis votre Arduino !
Du reste, je vous présenterai prochainement un projet de thermomètre hygromètre utilisant ce type d’écran, afin de vous en présenter un usage pratique, et sympa ! Alors à très vite 😉
Jérôme.
À découvrir aussi : comment brancher un lecteur de carte SD sur son Arduino ?
(*) Mis à jour le 17/01/2024
Merci pour ce super tutoriel qui tombe à pic pour moi.
Je dois en effet recevoir bientôt deux écrans de ce type et j’aurais surement mis pas mal de temps pour retrouver tout cela.
Merci encore.
Amicalement Daniel
Au plaisir, Daniel !
Et n’hésite surtout pas à reprendre tous les exemples que j’ai mis ici, afin de bien être guidé au début, ou si tu rencontres des difficultés 😉
Du reste, amuse toi bien !
Jérôme.
Bien que j’utilise ces écrans dans mes projets, j’en ai appris beaucoup grace à votre article, qui à votre habitude est d’une clarté, d’une précision et d’un contenu exemplaire ! Merci !
De rien ! Ça me fait plaisir de partager tout ce contenu avec vous, d’autant que cela permet à un maximum de personnes de moins ramer 😉
Et merci à toi aussi, pour ce retour !
Jérôme.
Bonjour, super TUTO, très bien fait, très utile, donc beaucoup de travail, MERCI
J’ai néanmoins un Pb que je ne sais pas résoudre : avec mon écran OLED bizone, je n’écris uniquement que dans la première zone du haut soit dans les 16 premières lignes. Rien à faire pour adresser les 48 lignes suivantes, que ce soit en allumant tous les pixels comme dans votre exemple ou autre. Je n’ai que la version AdafruitSSD1306 : 2.3.0 et n’arrive pas à implanter le 2.4.6
Avez-vous une idée ?
A l’avance merci
Bonsoir François !
Je viens de jeter un coup d’œil de mon côté, et j’ai la version 2.4.7 d’installée actuellement (IDE Arduino).
Et effectivement, si tu as une vieille version de cette bibliothèque, il n’est pas impossible que tes soucis viennent de là.
Il faut donc, en premier lieu, mettre à jour cette librairie Arduino, avant d’aller plus loin.
Pour ce faire, tu peux aller dans le gestionnaire de bibliothèque arduino, et taper « SSD1306 » dans la zone de recherche.
Ensuite, il faut que tu retrouves la ligne « Adafruit SSD1306 », et que tu cliques sur « Mettre à jour », si un bouton de ce type t’es proposé.
Sinon, si tu n’as aucune possibilité de mise à jour, regardes si tu as une liste déroulante, comme visible ci-dessous, afin de sélectionner une version plus récente que la tienne.
Enfin, si tu ne peux toujours pas charger la dernière version de cette bibliothèque, je pense qu’il faudrait que tu réinstalle ton IDE Arduino, car tout ceci n’est pas normal !
Voilà !
Sinon, je n’ai malheureusement pas d’autres idées, désolé !
Jérôme.
En fait c’est tjrs pareil avec les version 2.4.6 et de même avec la 2.4.7
Merci pour ta réponse que je n’avais pas vu avant mon commentaire, j’ai commandé deux nouveaux écrans, mono zone cette fois. J’espère que ça ira mieux.
En attendant merci encore pour ton tuto qui est d’une grande qualité, c’est du beau travail.
Ok, ça marche ! Et n’hésite pas à repasser par ici, pour nous dire ce qu’il en est !
À bientôt !
Jérôme.
Bonjour, j’ai reçu des nouveaux écrans, 128×64 mais en 0.96″ les précédents étaient aussi en 128×64 mais en 1,3″.
Avec le même programme les 0.96″ fonctionnent parfaitement mais tjrs pas les écrans 1.3″. Mystère, je ne comprend pas pourquoi car la taille de l’écran n’est pas spécifiée dans le Programme.
Il me semble avoir vu des commentaires avec des photos jointes, mais je n’ai pas trouvé le moyen de le faire.
Bonne journée
Salut François !
La taille n’est pas spécifiée dans le programme, car elle n’entre nullement en ligne de compte. En fait, quelle que soit la taille de ton écran, tu ne devrais pas rencontrer le moindre soucis avec la librairie utilisée ici, du moment où :
Du coup, à moins que ton écran OLED de 1,3″ ne soit pas véritablement équipé d’un chipset SSD1306, ou s’il souffre d’un défaut de fabrication, ou s’il possède des spécificités qui lui sont propres, je ne vois pas d’où peut venir le soucis ici. Désolé !
Jérôme.
Bonsoir
Après pas mal de résultats négatifs j’ai enfin la solution pour les premiers tests et l’explication des adr 0x78 & 0x7a. Donc je poursuis mes essais pour réaliser un compte tour digital sur un tour à métaux.
A+ et merci
Salut Sergio !
Comme quoi, il faut toujours persévérer, et ne jamais rien lâcher 😉
@+
Jérôme.
Vraiment intéressant, bien rédigé, didactique, détaillé, bref époustouflant par rapport à ce qu’on peut lire ailleurs. Bravo.
Moi qui débute j’ai tout compris.
Je vais maintenant lire en détail les bibliothèques utilisées.
Encore une fois bravo pour ce magnifique travail pédagogique.
Merci François, pour ce commentaire chaleureux ! Et bon courage à toi alors, dans ton apprentissage 😉
Merci beaucoup. Vos contenus me sont d’une grande utilité !
Excellent, très complet et très didactique, merci …
Au fait quelle est la valeur de la résistance cms qui fixe l’adresse i2c ?
Salut !
La résistance de sélection d’adresse I2C fait 4,7 k-ohms de mon côté (notée « 472 » sur le CMS, signifiant donc une valeur de 47 ohms avec 2 zéros derrière, soit 4700 ohms). C’est d’ailleurs la même valeur que les résistances de pull-up i2c, présentes pas très loin.
Et merci pour tes remerciements, au passage 😉
Bonjour,
Merci pour vos magnifiques tutoriels, avec vous cela paraît simple !
Une petite question, quand on inclut une librairie, c’est toute la librairie qui va être compilée ?
Si c’est le cas, est-il possible de n’inclure que les parties dont on a besoin ?
Encore merci pour la qualité de votre travail.
Salut Phil !
Effectivement, toute librairie appelée est compilée. Mais sauf erreur de ma part, seules les parties réellement utilisées sont conservées, si je puis dire. Ainsi, en passant au travers du compilateur C intégré à l’IDE Arduino (avr-gcc), seules les lignes de code arduino vraiment utilisées sont transformées en langage machine (assembleur), et non les autres.
Cela étant dit, on peut effectivement parfois optimiser son programme, en écrivant directement du code, sans faire appel à certaines librairies. Pour autant, l’optimisation vient ici, selon moi, de la façon de faire les choses, et de comment on gère/réserve les variables (ou constantes) en mémoire, et non des parties utilisées ou non.
Enfin… c’est mon avis là dessus, n’étant pas un expert sur ce sujet !
Jérôme.
Bonjour,
Et bien comme pas mal de commentaires, ce tuto qui décortique le programme est vraiment accessible à tous. Je débute aussi en Arduino et là, j’ai tout compris !
J’ai un projet de thermomètre avec écran et qui transmettrait la température à une centrale domotique (en Wifi). Après on peut complexifier avec un affichage sur l’écran temporaire, pourquoi pas afficher l’heure aussi. Tout ça avec 2 boutons poussoirs. Bref de l’évolution en perspective !
Philippe
Salut Philippe !
Ravi de voir que ce tuto puisse toi aussi te servir ! Et surtout que tout soit bien clairement compréhensible, car là est toujours ma crainte.
En tous cas, je vois que tu as un beau projet, et que tu es super motivé ! Alors bon courage à toi 😉
Jérôme.
Formidable tuto !
Clair, précis, bien documenté, et ce qui est plus rare, sans faute d’orthographe. Il y a 2 heures je ne connaissais rien à cet affichage. Grâce à vous, je suis maintenant capable d’afficher ce que je veux.
Merci beaucoup. Vos programmes de démo ont fonctionné du premier coup.
Merci, merci ! C’est avec plaisir !
Génial ! Merveilleux.
Monsieur Jérôme, grâce à votre tutoriel, vous me faites gagner un temps précieux. Ma réflexion se portera sur la compréhension de vos écrits et non de me casser la tête dans diverses recherches. Tantôt mes afficheurs devraient arriver afin que je puisse procéder aux tests.
Un tout grand merci pour ce magnifique partage.
Salut Etienne !
Merci pour ce message très chaleureux ! Par contre, si j’étais toi, je ne me limiterais pas uniquement à ce site. Car la force d’internet est justement d’offrir la possibilité d’avoir différents points de vue partagés, et différentes approches/méthodologies, concernant tout sujet d’ailleurs. Alors profites-en, au contraire !
Et bon courage à toi, pour tes futurs tests et essais 😉
Jérôme.
Comme tout le monde, bravo pour ces explications claires et détaillées !
Bonjour,
Merci pour cet article très complet pour moi !
J’attends mes écrans pour essayer !
Un grand merci pour la complétude de ces éléments qui me permettent d’avancer dans mon projet de contrôleur MIDI ! Sans doute à bientôt !
Un super méga grand merci.
Hâte de recevoir mes chinoiseries pour tester tout cela.
Super tuto, un grand merci !
Je débute l’arduino, et je dois avouer que pour quelque chose de « simple », cela reste relativement compliqué pour un débutant (comme moi).
J’ai lu attentivement la procédure, avec le même matériel que vous, préparé une image en 80X40 et j’ai une erreur dans le code :
ecranOLED.drawBitmap(24, 24, NaN, 80, 40, WHITE);
^~~~~~~~~
exit status 1
Compilation error: 'ecranOLED' does not name a type
Je me demande bien ce qui cloche, et après de nombreuse tentatives je n’arrive toujours pas à afficher quelque chose sur cet écran. Je vais continuer mes recherches.
Encor merci pour ce travail partagé.
Salut Marius !
Je vois que ton image s’appelle « NaN ». Pourrais-tu essayer de la renommer, pour voir si la problème ne viendrait pas de là ?
Car « NaN » signifie « Not A Number ». Du coup, c’est peut-être un mot réservé, et cela expliquerait l’erreur au moment de la compilation.
Bon courage à toi !
Jérôme.
Super bien fait !!!! Merci
Bonjour, merci pour cet article très complet !!!
J’ai une petite question.
Sur un projet arduino existant utilisant un afficheur basé sur SSD1306 (0.96″) est-il possible de monter un afficheur de même résolution en pixel basé sur SSD1309 (2.42″) juste en chargeant la librairie adéquate en début de code ?
Merci d’avance.
Salut Manu !
Je pense que c’est possible d’adapter ça, oui, mais sans reprendre quelques lignes du code, j’en doute ! Car tu auras forcément des variances, d’une librairie à une autre. Maintenant, tout ça reste à voir, dans le détail (et désolé de ne pouvoir t’en dire davantage, car je n’ai jamais utilisé d’afficheur avec SSD1309, jusqu’à présent).
Voilà ! Bon courage à toi 😉
Jérôme.
Un grand merci pour ce cours très détaillé et surtout très bien construit.
De plus il est écrit dans un français impeccable.
Je suis dans la phase (bien) montante de la progression en Arduino & Cie. Et là, BINGO ! je tombe sur un site parfaitement documenté, progressif, avec des exemples qui fonctionnent, les bons commentaires … Et là je craque : en Gaulois !
Merci pour l’excellent travail
Claude
Merci, et bon courage à toi alors !
Bonjour
Votre travail est excellentissime !!!
Merci pour votre aide
Bonjour Jérome,
Je suis en cours de test de l’écran OLED. J’ai utilisé ton programme pour les test du montage. Je n’avais pas d’affichage en respectant la liaison I2C avec la carte UNO sur les bornes A4 et A5. En connectant l’afficheur sur les les bornes SDA et SCL de l’Arduino UNO l’afficheur fonctionne.
Bravo pour la complétude de ta doc.
Cordialement
Chaf
Salut Chaf !
Normalement, sur un Arduino Uno, les bornes SDA et SCL sont respectivement reliées en interne à A4 et A5 (4ème et 5ème bit du PORT C, au niveau du microcontrôleur ATmega328P). En fait, ce ne sont pas des sorties arduino supplémentaires, quand bien même elles sont mises à part, avec des noms différents.
Donc, sauf à utiliser un Arduino Uno « customisé » (c’est à dire différent de « l’original »), il n’y a pas de raison que ça ne fonctionne pas sur A4 et A5 !
Voilou ! Bon courage à toi 😉
Jérôme.
Bonjour Jérôme,
J’ai parcouru ton site et je trouve que tu fais un très très bon travail de pédagogie.
Aujourd’hui j’aimerai faire un menu sur un afficheur OLED avec sélection via un encodeur. Il y a pléthores de sites mais soit avec des codes très compliqués soit qui ne fonctionnent pas. Aurais-tu un exemple de code pour avoir un affichage principal avec 2 sous menus ? Le premier pour un fonctionnement auto, le 2ème pour permettre de régler des valeurs via l’encodeur et de les enregistrer dans l’EEPROM.
Merci de ton aide pour me montrer un peu le chemin, surtout pour créer les menus.
Cordialement
Bonsoir Jean-Luc !
Non désolé, je n’ai malheureusement pas de code « tout prêt » sous la main, permettant de faire cela (mais c’est prévu un jour, pour compléter mes articles sur les encodeurs rotatifs et celui-ci sur les écrans OLED).
Par contre, j’ai réalisé il y a peu un Testeur de servo, qui intégrait un menu sur écran OLED, avec réglages et enregistrement en EEPROM ; même si ça fonctionne avec des boutons de navigation, et non un encodeur rotatif, ça peut peut-être t’aider.
Voilà ! Bonne soirée à toi,
Jérôme.
Bonjour,
Je souhaiterais utiliser les pins A6 et A7 de la nano ATMEGA328 pour câbler la SDA et SCL (respectivement) de mon écran OLED. Les pins A4 et 45 sont déjà utilisées pour un module d’horloge en temps réel RTC DS1307 I2C.
Comment faire ?
Merci d’avance
Cdlt
Bonsoir !
En fait : branche tout sur A4/A5, tout simplement. Car le bus I2C est prévu pour fonctionner avec 1 ou plusieurs périphériques en parallèle (en prenant soin d’éviter la multiplication de résistances pull-up, par contre).
Ainsi, tu n’auras aucun risque de conflit sur le bus, car chaque périphérique a une adresse i²c qui lui est propre, « gravée dans le dur » au moment de sa fabrication (0x68 pour les RTC DS1307 et 0x78/0x7A pour les écrans OLED).
Voilà ! Bonne fin d’année à toi 😉
Jérôme.
Merci je n’arrivais vraiment pas à faire fonctionner ces écrans 😊
Bonjour,
Merci pour cet excellent tuto.
Je me pose une question : peut-on raccorder 4 écrans OLED sur le même bus I2C ? Je souhaiterai afficher la même information dans 4 endroits différents (étage de mon élévateur).
Merci d’avance pour votre éclairage
Salut !
Nativement, l’écran OLED SSD1306 n’accepte que 2 adresses I²C possibles. Du coup, sur un même bus I2C, tu ne pourras en brancher que deux.
Par contre, tu peux facilement contourner ce problème, en utilisant un multiplexeur I2C (un TCA9548 par exemple). Ainsi, tu pourrais par exemple piloter jusqu’à 8 périphériques i2c avec la même adresse, si tu le souhaitais.
Du reste, je me note de faire un tuto là dessus dès que je pourrais, pour que vous ayez un exemple pratique de mise en œuvre !
Voilà ! Bon courage à toi 🙂
Jérôme.
Merci beaucoup !!!
Tuto très pédagogique
Un grand merci à vous pour tout le temps que vous devez y passer !!
Bonjoir
J’ai une question concernant ce bus I2c.
J’utilise un écran oled 0,96 avec la librairie u8g2. Cet écran est connecté sur SDA et SCL de l’arduino. J’utilise les deux entrées analogiques A4 et A5 pour entrer d autres signaux. Mais mon écran et la maison série ne fonctionne pas du tout … En lisant un commentaire plus haut j’ai vu que A4 et A5 sont liées intérieurement à SDA et SCL. J’imagine qu’il n y a rien à faire ?
Merci
Salut Alexandre !
Alors, A4 et A5 sont effectivement reliés au SDA et SCL. Mais cela ne pose pas de problème en soi, car on peut brancher plusieurs périphériques I2C dessus (du moment que ceux-ci n’ont pas la même adresse sur le bus). Tu trouveras plus d’infos illustrées ici : https://passionelectronique.fr/liaisons-series-uart-i2c-spi/#la-liaison-serie-i2c
Du coup, selon moi, ton problème ne se situe pas à ce niveau là !
Bon courage à toi,
Jérôme.
Merci Jérôme pour cette réponse.
Je rentre sur les entrées analogiques A4 et A5 deux tensions, rien à voir avec un périphérique i2c. J’ai aussi essayé de mêler un périphérique i2c et un spi sur ce même bus, sans succès …
Ah d’accord ! C’est là que ce situe le problème alors.
En effet, il faut faire un choix au niveau des pins A4/A5 : soit tu t’en sers comme entrées analogiques, soit tu t’en sers comme lignes de bus I²C. Car tu ne pourras pas faire les 2 en même temps !
J’avoue que c’est trompeur au niveau du brochage Arduino, car on pourrait croire qu’il existe des sorties indépendantes « SDA » et « SCL ». En fait il n’en n’est rien, car ce sont tout simplement les lignes A4/A5 qui sont reportées ici (ces lignes étant « multifonction », c’est à dire pouvant être configurées au choix comme entrées, sorties, ou lignes de bus i2c).
Du reste, concernant le bus SPI, celui-ci se configure nativement sur les broches MOSI (D11), MISO (D12), SCK (D13), et /SS (D10) de l’Arduino (donc complètement à part des lignes A4 et A5).
Merci Jérôme pour ce tuto très clair (je n’ai pas encore reçu mes écrans, mais ça va bien me servir).
J’ai toutefois une question un peu hors sujet : lorsque tu écris Serial.println(F(« Fin. »)); que signifie le F(…) ? C’est la 1ère fois que je le vois.
Salut Richard !
En fait, pour faire simple, la fonction F() permet d’économiser de la RAM.
Car lorsqu’on fait un print/println(), il faut savoir que les caractères inscrits entre parenthèses sont initialement « recopiés » en mémoire RAM (comme n’importe quelle variable, en fait), avant d’être émis sur le port série. Du coup, si on veut éviter de surcharger la RAM, on englobe ces caractères à envoyer d’une fonction F(), car cette fonction permet d’utiliser la mémoire programme uniquement (mémoire FLASH) pour les stocker, sans qu’ils soient inscrits « en double » au niveau de la RAM (si je simplifie les choses).
Bien sûr, le pourcentage d’utilisation de la mémoire RAM n’est pas un problème lorsqu’on écrit un programme léger (avec peu de ligne et/ou librairies) ! Mais lorsqu’on rajoute du contenu, la mémoire RAM est vite remplie (pouvant causer dysfonctionnements/erreurs).
Voili voilou !
Excellente journée à toi,
Jérôme.
Afin de filtrer au maximum les messages de type "spam" ou "inappropriés", chaque commentaire est soumis à modération, et validé manuellement. Du coup, il se peut que certains commentaires ne soient pas publiés, ou sinon, avec un peu de retard. Par ailleurs, j'ai malheureusement plus de messages à traiter que de temps pour y répondre ; c'est pourquoi je ne pourrais pas répondre à tout le monde. Désolé …