Service d'affichage

Utilisez le service d'affichage thread-safe pour un écran OLED SSD1306 128 × 64 avec U8G2 afin d'y dessiner

Aperçu

Le service d'affichage est un wrapper global et thread-safe autour du pilote U8G2 pour un OLED SSD1306 128 × 64. Vous l'utilisez pour restituer le texte et les graphiques de n'importe quelle tâche sans scintillement ni déchirure. Un mutex FreeRTOS garantit un accès exclusif pendant que vous dessinez ; les fonctions d'assistance gèrent l'effacement des régions, l'actualisation partielle, le découpage et la mise en cache du texte.

Cette page documente l'API de développement au niveau du micrologiciel utilisée sur nos appareils. Pour connaître le comportement de l'affichage destiné à l'utilisateur (par exemple, masquer les écrans de temps restant ou d'état de l'appareil), consultez les pages associées à la fin.

Conditions préalables

  • ESP32 avec interface I2C matérielle disponible
  • Bibliothèque U8G2 intégrée à la compilation de votre micrologiciel
  • FreeRTOS (pour le mutex d'affichage)
  • Broches configurées pour SDA/SCL dans le Pins.h de votre carte

Configuration matérielle

PropriétéValeur
AffichageSSD1306 OLED
Résolution128×64 pixels
InterfaceI2C (matériel)
RotationU8G2_R0 (0°)
Adresse I2C0x3C
Contraste255 (maximum)

Certains constructeurs U8G2 attendent l'adresse I2C 8 bits. Si tel est le cas, transmettez 0x3C << 1. Vérifiez que cela correspond à la signature de votre constructeur.

Modèle de mise en page

L'écran est traité comme une grille de cellules de 8 × 8 pixels :

  • Grille : 8 lignes × 16 colonnes
  • Origine : (0,0) en haut à gauche
  • Taille de cellule : 8 × 8 pixels

Régions

Les API de texte U8G2 utilisent la ligne de base pour y. Pour les polices de 8 pixels de hauteur, commencez la première ligne de texte à y = 8, puis ajoutez la hauteur d’ascendante/hauteur de ligne de la police pour les lignes suivantes.

Sécurité des threads

Le service d'affichage fournit un mutex FreeRTOS. Verrouillez-le toujours avant de dessiner et déverrouillez-le lorsque vous avez terminé.

#pragma once
#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>

extern SemaphoreHandle_t displayMutex;

Si vous ne parvenez pas à libérer le mutex, toutes les autres tâches nécessitant l'affichage seront bloquées. Associez toujours un xSemaphoreTake réussi avec un xSemaphoreGive dans un chemin de style finally.

Modèle d'utilisation de base

// Acquire, draw, refresh affected region(s), release
if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  // ... drawing commands, e.g.:
  display.drawStr(x, y, "HELLO WORLD");

  // Call an appropriate refresh helper (see below)
  refreshPage();

  xSemaphoreGive(displayMutex);
}

Initialisation

Appelez initDisplay() une fois au démarrage.

#pragma once
void initDisplay();

Créer des ressources et configurer le panneau

initDisplay() crée le mutex d'affichage, initialise l'instance d'affichage U8G2, définit l'adressage/rotation/contraste et efface le tampon.

Après l'initialisation, l'écran doit être vide et rétroéclairé, et displayMutex doit être non nul.

Vérifier le dessin

Affichez une seule ligne de texte dans la zone de la page.

if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  clearPage();
  display.setFont(u8g2_font_spleen5x8_mu);
  display.drawStr(0, 16, "SANITY PASS");
  refreshPage();
  xSemaphoreGive(displayMutex);
}

Aides à l'effacement

Effacez efficacement uniquement ce que vous envisagez de redessiner. Toutes les fonctions d'aide utilisent updateDisplayArea() en interne pour effectuer une actualisation partielle de la région affectée.

FonctionDescriptionRégion effacée
clearHeader()Efface uniquement le texte de l'en-têteLigne 0, cellules 0 à 12
clearIcons()Efface uniquement la zone d'icôneLigne 0, cellules 13 à 15
clearFooter()Efface uniquement le texte du pied de pageLigne 7, cellules 0 à 14
clearTimeout()Efface l'indicateur de délai d'attenteLigne 7, cellule 15
clearPage(includeFooter=false, includeHeader=false)Efface la zone de la page ; en-tête/pied de page en optionLignes 1 à 6 (plus en-tête/pied de page sur demande)
void clearHeader();
void clearIcons();
void clearFooter();
void clearTimeout();
void clearPage(bool includeFooter = false, bool includeHeader = false);

clearPage() définit une fenêtre de découpage pour empêcher le contenu de se répandre dans l'en-tête ou le pied de page.

Aides à l'actualisation

Appelez une fonction d’actualisation après avoir modifié une région. Elle effectue une mise à jour minimale de l’affichage.

FonctionDescriptionRégion mise à jour
refreshHeader()Envoie le texte d'en-têteLigne 0, cellules 0 à 12
refreshIcons()Envoie la zone d'icônesLigne 0, cellules 13 à 15
refreshFooter()Envoie le texte du pied de pageLigne 7, cellules 0 à 14
refreshTimeout()Met à jour l'indicateur de délai d'attenteLigne 7, cellule 15
refreshPage(includeFooter=false, includeHeader=false)Envoie le contenu principal ; en-tête/pied de page en optionLignes 1 à 6 (plus en-tête/pied de page sur demande)
void refreshHeader();
void refreshIcons();
void refreshFooter();
void refreshTimeout();
void refreshPage(bool includeFooter = false, bool includeHeader = false);

Fonctions d'aide au contenu

setHeader()

Définit le texte de l'en-tête. Le service convertit la dernière valeur en majuscules et la met en cache pour éviter les redessins redondants.

void setHeader(String &text);

Si vous appelez setHeader() avec la même valeur, le service ignore le dessin et l'actualisation.

setFooter()

Définit le texte du pied de page aligné à gauche et à droite. Les deux sont en majuscules et mis en cache.

void setFooter(String &left, String &right);
  • La chaîne gauche s'aligne sur le bord gauche de la région du pied de page
  • La chaîne droite s'aligne sur le bord droit de la région du pied de page

drawWrappedText()

Dessinez du texte avec retour à la ligne automatique et alignement central en option.

int drawWrappedText(int x, int y, const String &text, bool center = false);

intrequired

Coordonnée x de départ en pixels.

intrequired

Coordonnée de départ de la ligne de base y en pixels.

Stringrequired

Texte à restituer. Prend en charge le littéral \n pour les sauts de ligne.

bool

Centrez chaque ligne renvoyée à la ligne dans la zone de page lorsque center vaut true.

returnintrequired

Nombre de lignes dessinées.

Modèles courants

Dessiner un écran complet

if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  clearPage();
  display.setFont(u8g2_font_spleen5x8_mu);
  display.drawStr(0, 16, "MAIN CONTENT");
  refreshPage();
  xSemaphoreGive(displayMutex);
}

Ce modèle efface uniquement la zone de la page, dessine du nouveau contenu et effectue une actualisation partielle pour plus de rapidité.

Mettre à jour l'en-tête uniquement

if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  String headerText = "NEW HEADER"; // case‑insensitive; will be uppercased
  setHeader(headerText);
  // setHeader internally decides whether a refresh is required
  xSemaphoreGive(displayMutex);
}

Dessiner du texte centré avec retour automatique à la ligne

if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  clearPage();
  int lines = drawWrappedText(0, 16, "Long text that will wrap", /*center=*/true);
  (void)lines; // optionally use the line count
  refreshPage();
  xSemaphoreGive(displayMutex);
}

Directives de dessin

Verrouillez le mutex pour chaque séquence de dessin

Regroupez les opérations de dessin et d’actualisation dans une section critique protégée par displayMutex.

if (xSemaphoreTake(displayMutex, portMAX_DELAY) == pdTRUE) {
  // Drawing
  xSemaphoreGive(displayMutex);
}

Préférez les aides régionales aux effacements complets

Minimisez le trafic de bus et le scintillement en utilisant les assistants clear*() et refresh*().

clearPage();
display.drawStr(0, 16, "Content");
refreshPage();
// Full‑buffer clears cost time and cause visible flicker
// display.clearBuffer();

Respectez les limites

Conservez le contenu dans :

  • En-tête : ligne 0, cellules 0 à 12
  • Icônes : ligne 0, cellules 13 à 15
  • Page : lignes 1 à 6
  • Pied de page : ligne 7, cellules 0 à 14 ; indicateur de délai d’attente dans la cellule 15

Utilisez clearPage() pour empêcher le contenu de la page d’empiéter sur l’en-tête ou le pied de page.

Choisissez des polices lisibles

ZonePolice recommandée
En-tête/pied de pageu8g2_font_spleen5x8_mu
Contenu des pagesChoisissez une police lisible ; ajustez l'espacement des lignes selon les métriques de la police

Tenez compte de la hauteur d’ascendante de la police et de la hauteur totale des lignes lors du calcul des décalages y entre les lignes.

Considérations sur les performances

  • Les mises à jour partielles ne redessinent que les régions que vous avez modifiées
  • La mise en cache du texte évite les cycles de dessin/actualisation inutiles
  • Le découpage maintient le dessin dans la région prévue et réduit le surdessin
  • Les séquences protégées par mutex empêchent le déchirement d'image entre les tâches

Dépannage

Dépendances

DépendanceBut
U8G2Rendu SSD1306 et gestion des polices
FreeRTOSMutex pour la sécurité des threads
ESP32 HALInterface matérielle I2C
Pins.hDéfinitions des broches de la carte pour SDA/SCL

Pages connexes

Sur cette page