S'équiper

Vous voulez participer au financement du blog. C’est simple, suivez les liens commerciaux pour faire vos achats. Quelques pourcents qui font toute la différence. Merci à vous !

IoT sans programmation
PlatformIO
T-Watch
Capteurs
Actionneurs
Sans-fil

T-Watch. Débuter avec la librairie ESP32 TFT_eSPI. Afficher texte, formes, détection tactile

Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

La librairie LilyGoWatch intègre une version pré-configurée de la librairie TFT_eSPI de Badmer qui permet d’afficher du texte, des formes géométriques de base (rectangle, cercle, ellipse, triangle, ligne, point…), des images et plein d’autre choses.

Les exemples données dans ce tutoriel sont adaptés aux écrans TFT des montres ESP32 TTGO T-Watch. Il sont compatibles avec d’autres écrans et cartes de développement Arduino, ESP32 ou ESP8266.
A LIRE AUSSI :
TTGO T-Watch ESP32. Quel modèle choisir ? Cartes d'extension disponibles

 

Dans cet article nous allons uniquement utiliser l’écran TFT couleur tactile présent dans la T-Watch Touch et la T-Watch 2020. Cependant, vous ne devriez rencontrer aucune difficulté à l’utiliser sur les modèles équipés d’un écran eInk (T-Block et T-Bot).

Si vous débutez le développement d’application pour les boitiers et montres ESP32 TTGO T-Watch du fabricant LilyGo, vous pouvez commencer par lire cet article d’introduction.

A LIRE AUSSI :
T-Watch. Créer votre 1er projet ESP32 avec la librairie LilyGoWatch (IDE Arduino ou PlatformIO)

Comment utiliser la librairie TFT_eSPI dans un projet Arduino T-Watch ?

La librairie LilyGoWatch intègre une version pré-configurée (code source) de la librairie TFT_eSPI de Bodmer. Celle-ci est est chargée au démarrage avec les paramètres qui correspondent à l’écran embarqué par le T-Watch utilisée.

La libraire TFT_eSPI prend en charge les écrans eInk et TFT des différents modèles de T-Watch.

Vous n’avez donc rien à faire ! Tout marche out of the box 🙂

Palette de couleur

On dispose d’une palette de couleur pré-définie accessible à l’aide des constantes suivantes

▉ TFT_BLACK
▉ TFT_NAVY (#000080)
▉ TFT_DARKGREEN (#008000)
▉ TFT_DARKCYAN (#008080)
▉ TFT_MAROON (#80000)
▉ TFT_PURPLE #800080)
▉ TFT_OLIVE (#808000)
▉ TFT_LIGHTGREY (#D3D3D3)
▉ TFT_DARKGREY (#808080)
▉ TFT_BLUE (#0000FF)
▉ TFT_GREEN (#00FF00)
▉ TFT_CYAN (#00FFFF)
▉ TFT_RED (#FF0000)
▉ TFT_MAGENTA (#FF00FF)
▉ TFT_YELLOW (#FFFF00)
▢ TFT_WHITE (#FFFFFF)
▉ TFT_ORANGE (#FFB400)
▉ TFT_GREENYELLOW (#B4FF00)
▉ TFT_PINK (#FFC0CB)
▉ TFT_BROWN (#964B00)
▉ TFT_GOLD (#FFD700)
▉ TFT_SILVER (#C0C0C0)
▉ TFT_SKYBLUE (#87CEEB)
▉ TFT_VIOLET (#B42EE2)

Fonctions de la librairie TFT_eSPI (API)

Voici une liste des fonctions les plus courantes proposées par la librairie TFT_eSPI. En l’absence de documentation officielle, les fonctions ont été extraites directement du code source de la librairie LilyGoWatch sur GitHub.

Les fonctions dépréciées sont barrées.

Liste des variables utilisées

  • m entier
  • color au format hexadécimal
  • x0, y0, x1, y1 coordonnées (en pixel)
  • r, rx, ty rayon (en pixel)
  • w (width) largeur en pixel
  • h (height) hauteur en pixel

Ecran et curseur

  • width() largeur de l’écran en pixels
  • height() hauteur de l’écran en pixels
  • setRotation(uint8_t m) tourne le contenu de l’écran. L’orientation est un nombre compris entre 0 et 3 et 4 à 7 pour un bitmap
    • getRotation() renvoie l’orientation de l’écran
  • invertDisplay(bool i) inverser les couleurs d’affichage i = 1 inverser, i = 0 normal
  • fillScreen(uint32_t color) met en couleur le fond de l’écran. En fait la fonction dessine un rectangle plein prenant toute la surface de l’écran
  • setCursor(int16_t x, int16_t y) positionne le curseur.
    • getCursorX renvoie la coordonnée X du curseur
    • getCursorY renvoie la coordonnée Y du curseur
  • setPivot(int16_t x, int16_t y) point pivot de l’écran
    • getPivotX() coordonnée X du point pivot
    • getPivotY() coordonnée X du point pivot
  • readPixel(int32_t x, int32_t y) Lit la couleur d’un pixel au format 565

Primitives géométriques

  • drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) dessine le contour d’un cercle
  • fillCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color) dessine un cercle plein
  • drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color) dessine le contour d’une ellipse
  • fillEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color) dessine une ellipse pleine
  • drawRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) dessine le contour d’un rectangle
  • fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color) dessine un rectangle plein
  • drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color) contour d’un rectangle au bord arrondi. Tous les angles ont le même rayon
  • fillRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color) idem mais plein
  • drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color) contour d’un triangle. Il faut passer les coordonnées des trois sommets
  • fillTriangle ( int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color) idem mais avec un triangle plein.
  • drawPixel(int32_t x, int32_t y, uint32_t color) dessine un pixel de colour
  • drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color) dessine une ligne entre deux points arbitraires
  • drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color) ligne verticale de longueur
  • drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color) ligne horizontale de longueur l

Images

  • drawBitmap(int16_t x, int16_t y, const uint8_t *bitmap, int16_t w, int16_t h, uint16_t color) affiche une image stockée dans un tableau
  • drawXBitmap(int16_t x, int16_t y, const uint8_t bitmap[], int16_tw, int16_th, uint16_tcolor) dessine une image monochrome stockée dans un tableau. On peut par exemple convertir une image JPG ou PNG à l’aide de GIMP au format XBM et récupérer le tableau de point.
A LIRE AUSSI :
T-Watch. Afficher des images XBM (TFT_eSPI) et C++ (LVGL). Compatible ESP32, Arduino
  • setBitmapColor(uint16_t c, uint16_t b) attribue la couleur de fond d’une image bitmap

Polices

  • fontsLoaded() renvoie une valeur codée de 16 bits indiquant les polices chargées
  • fontHeight(int16_t font) hauteur de la police
  • setFreeFont(const GFXfont *f) Définit la police GFX à utiliser

Texte, caractère, chaîne

  • setTextSize(uint8_t s) attribue la taille du texte. Elle doit être comprise entre 1 et 7 (max.)
  • setTextColor(uint16_t c) attribue la couleur de texte. Couleur en hexadécimal
  • setTextColor(uint16_t c, uint16_t b) idem mais définit également la couleur du fond. A privilégier pour du texte qui change souvent (horloge, coordonnées, position…), cela évite de redessiner la totalité de l’écran à chaque actualisation
  • setTextWrap(bool wrapX, bool wrapY) ne fonctionne pas…
  • textWidth(const String &string, uint8_t font) renvoie la largeur en pixels d’une chaîne dans une police donnée
  • drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size) affiche (dessine) un caractère à la position indiquée.

Affichage de chaine justifiée (Datum)

Positions disponibles

  • TL_DATUM 0 // En haut à gauche (par défaut)
  • TC_DATUM 1 // Centre supérieur
  • TR_DATUM 2 // En haut à droite
  • ML_DATUM 3 // Milieu gauche
  • CL_DATUM 3 // Centre gauche, comme ci-dessus
  • MC_DATUM 4 // Centre central
  • CC_DATUM 4 // Centre au centre, comme ci-dessus
  • MR_DATUM 5 // Milieu droit
  • CR_DATUM 5 // Centre droit, comme ci-dessus
  • BL_DATUM 6 // En bas à gauche
  • BC_DATUM 7 // En bas au centre
  • BR_DATUM 8 // En bas à droite
  • L_BASELINE 9 // Ligne de base du caractère gauche (ligne sur laquelle le caractère ‘A’ serait assis)
  • C_BASELINE 10 // Ligne de base du caractère central
  • R_BASELINE 11 // Ligne de base du caractère droit

Méthodes

  • setTextDatum(uint8_t d) référence du texte. Utiliser l’une des constantes ci-dessus
  • setTextPadding(uint16_t x_width) marge interne (équivalent au style CSS)
    • getTextPadding() renvoie le padding actuel
  • drawString(const String &string, int32_t poX, int32_t poY) dessine une chaîne (type String)
  • drawCentreString(const String &string, int32_t dX, int32_t poY, uint8_t font) dessine une chaîne (type String) centrée sur la position X
  • drawRightString(const String &string, int32_t dX, int32_t poY, uint8_t font)

Conversions

Quelques méthodes de conversion utiles

  • Couleurs
    • color8to16(uint8_t color) convertir une couleur 8 bits en une valeur de couleur 16 bits 565
    • color16to24(uint16_t color565) convertir une couleur 16 bits en une valeur de couleur 24 bits 888
    • color24to16(uint32_t color888) convertir une couleur 24 bits en une valeur de couleur 16 bits 565
  • Chaînes
    • decodeUTF8(uint8_t c) Convertit un caractère ASCII au format UTF-8
    • decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining) Décode un buffer de caractères au format ASCII étendu en UTF-8

La librairie n’est pas encore documentée, il faut directement chercher directement dans le code source.

Comment accéder aux fonctions de la librairie TFT_eSPI ?

En therme informatique, la Librairie LilyGoWatch est un wrapper, c’est à dire qu’elle unifie l’accès à un ensemble de librairies.

Les méthodes proposées par les différentes librairies sont accessibles depuis l’objet C++ TTGOClass.

Pour accéder à un périphérique puis aux fonctions (méthodes C++), on utilise l’opérateur flèche ->. C’est l’équivalent du point . en Javascript par exemple.

Voici un exemple de programme minimal qui allume l’écran et colorie le fond en rouge

#include <LilyGoWatch.h>

TTGOClass *ttgo;

void setup() {
    ttgo = TTGOClass::getWatch();
    ttgo->begin();     
    ttgo->openBL();
        
    ttgo->tft->fillScreen(TFT_RED);
}

void loop(){}

On doit commencer par initialiser l’objet watch en appelant la méthode getWatch(). Cet objet contiendra toutes les méthodes pour accéder aux périphériques de la montre (accéléromètre, GPS, horloge RTC, écran TFT ou eInk…).

watch = TTGOClass::getWatch();

Ensuite on doit allumer l’écran TFT de la montre en appelant la méthode begin(), puis le rétro-éclairage à l’aide de la méthode openBL().

watch->begin();  // Initialise l'écran couleur TFT
watch->openBL(); // Allume le rétro-éclairage de l'écran

Maintenant on accède aux fonctions comme ceci

objetmontre->driver->fonction()

Ce qui donne pour mettre le fond de l’écran en rouge

ttgo->tft->fillScreen(TFT_RED);

Créer un objet TFT_eSPI contenant le driver de l’écran

Il est également possible de créer un objet de type TTGOClass qui contiendra le drivers de l’écran pour réduire le code

TFT_eSPI * tft = ttgo->tft;
tft->fillScreen(TFT_RED);

Connaitre la résolution de l’écran

Il est souvent nécessaire de connaitre la résolution de l’écran pour positionner les éléments. Pour cela, on dispose des méthodes width() et height() pour connaitre respectivement la largeur et la hauteur de l’écran en pixels.

  w = ttgo->tft->width();
  h = ttgo->tft->height();
  Serial.printf("Screen size %u * %u", w, h);

Comment positionner le curseur sur l’écran ?

La librairie TFT_eSPI utilise un curseur pour positionner les éléments à l’écran. Les coordonnées X et Y du curseur sont déterminée à partir du coin supérieur gauche de l’écran. L’origine change en fonction de l’orientation de l’écran.

Pour changer manuellement l’orientation de l’écran, rendez-vous à ce paragraphe pour apprendre comment faire.

ttgo t-watch lilygo tft_espi screen oriantation reference pos2

Le curseur permet d’afficher du texte à l’aide des fonctions standards print, println ou printf par exemple.

Les fonctions getCursorX et getCursorY permettent de connaître la position du curseur et setCursor pour positionner ce dernier au pixel prêt.

Par contre, les autres méthodes de dessin (y compris pour dessiner du texte) utilisent simplement les coordonnées.

Détecter lorsque l’utilisateur touche l’écran et récupérer la position

La méthode getTouch(x, y) permet de détecter lorsque l’utilisateur touche l’écran. La méthode retourne un booléen et affecte les coordonnées X et Y du point touché sur l’écran.

La méthode getTouch() est directement accessible depuis la classe ttgo de la librarie LiLyGoWatch

A LIRE AUSSI :
T-Watch. Créer votre 1er projet ESP32 avec la librairie LilyGoWatch (IDE Arduino ou PlatformIO)

La librairie est livrée avec l’exemple Touch Pad dans le dossier BasicUnit

TTGOClass *ttgo;

char buf[128];

void setup()
{
    ttgo = TTGOClass::getWatch();
    ttgo->begin();
    ttgo->openBL();
    ttgo->tft->fillScreen(TFT_BLACK);
    ttgo->tft->setTextFont(2);
    ttgo->tft->setTextColor(TFT_WHITE, TFT_BLACK);
    ttgo->tft->drawString("T-Watch Touch Test", 62, 90);
}

void loop()
{
    int16_t x, y;
    if (ttgo->getTouch(x, y)) {
        sprintf(buf, "x:%03d  y:%03d", x, y);
        ttgo->tft->drawString(buf, 80, 118);
    }
    delay(5);
}

Comment la librairie TFT_eSPI construit l’écran ?

Avant d’aller plus loin, il est important de comprendre comment la librairie construit l’écran. Il faut considérer l’écran comme un tableau de points. Lorsqu’on dessine une forme (ou du texte ou une image), on ne fait “qu’allumer” des points du tableau avec une certaine couleur.

C’est à dire que l’ordre d’execution des fonctions va avoir un impact direct sur la construction de l’affichage. Ici par exemple le cercle bleu masque une partie du texte blanc posé lui même sur le rectangle vert.

t-watch tft_espi library order draw elements

Même si la librairie TFT_eSPI est très puissante, elle ne gère pas les éléments graphiques.

Lorsqu’on actualise l’affichage, on a deux solutions

Reconstruire la totalité de l’écran à chaque modification Ne reconstruire que le strict nécessaire.

Par exemple effacer (donner la couleur du fond) de l’aiguille d’une horloge puis dessiner la nouvelle position.

Avantage Facile Plus complexe
Inconvénient Risque élevé de clignotement.

Le clignotement augmente avec le nombre d’éléments à afficher et la fréquence de rafraîchissement.

Performant, peu de clignotement

Afficher du texte avec les fonctions C++ print(), println() ou printf()

Pour afficher du texte, on peut utiliser les mêmes méthodes C++ qui permettent d’écrire sur le port série print(), println() ou printf().

A LIRE AUSSI :
Fonctions C++ print•println•printf•sprintf pour Arduino ESP32 ESP8266. Combiner•formater → port série

La macro F() qui permet de placer la chaîne dans la mémoire Flash est supportée mais cela n’a toutefois aucun intérêt.

Le texte est affiché à la position du curseur. Ici par exemple, on fait varier la taille de la police entre 1 et 7 (il n’est pas possible d’aller au delà).

  TFT_eSPI * tft = ttgo->tft;
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE);
    for (size_t i = 1; i <= 7; i++){  // La taille doit être comprise entre 1 et 7
      tft->setTextFont(1);     // Uniquement 1
      tft->setTextSize(i);     // change la taille        
      tft->setCursor(0, 0);
      txt = "Text with size "; txt += i;
      Serial.print("Display"); Serial.println(txt);
      tft->println(txt);
      delay(1000);
      tft->fillScreen(TFT_BLACK);
    }

Afficher une liste défilante

Dans l’exemple précédent le curseur reste à l’origine (0,0) et l’écran est effacé (repeint en noir) à chaque itération de la boucle for. La méthode println() permet de déplacer le curseur à la ligne suivante. Toutefois, la librairie TFT_eSPI ne gère pas le scrolling vertical de la fonction print.

Pour afficher une liste qui dépasse la hauteur de l’écran, l’astuce consiste à tester la position du curseur et renvoyer ce dernier en haut de l’écran dès que la position courante dépasse la hauteur de l’écran.

On a vu précédemment comment récupérer la résolution de l’écran.

Voici un exemple de code qui affiche une liste de 20 éléments à l’écran

  TFT_eSPI * tft = ttgo->tft;
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE, TFT_BLACK);
  tft->setTextSize(2);
  tft->setCursor(0,0);
  
  for (size_t i = 0; i <= 20; i++) {
    // Renvoi le curseur en haut de l'écran 
    if ( tft->getCursorY() >= h ) {
      tft->fillScreen(TFT_BLACK);
      tft->setCursor(0,0);
    }
    tft->printf("This is the line %u \n", i);
    delay(200);
  }
  tft->setTextSize(1);
  tft->println(" \n *** End of the list ***");

Les méthodes avancées pour justifier la position du texte

Ls méthodes standards ne permettent pas de gérer la justification du texte. C’est à dire que le texte est obligatoirement positionné à gauche.

Pour justifier le texte à afficher, il suffit de définir la position souhaitée à l’aide de la méthode setTextDatum(DATUM_TYPE). On affiche (dessine) le texte ensuite à l’aide de la fonction drawString().

Voici un exemple de texte centré au centre de l’écran

ttgo->tft->fillScreen(TFT_BLACK);
ttgo->tft->setTextColor(TFT_WHITE);
ttgo->tft->setTextDatum(MC_DATUM);
ttgo->tft->drawString("Text in center", w / 2, h / 2, 2);

Dessiner des formes géométriques, rectangle, cercle, ellipse, ligne, point…

Passons maintenant à la création de formes géométriques simples. La librairie permet de dessiner le contour ou de remplir les formes simples suivantes rectangle, triangle, cercle, ellipse.

Le contour a la même couleur que le fond.

On peut aussi dessiner des lignes arbitraires entre deux points, horizontales ou verticales.

Voici une exemple qui trace une ligne horizontale à 10 pixels du bord de l’écran

  tft->drawFastHLine(0, 10, 240, TFT_DARKGREY);

Rendez vous à la fin de l’article pour trouver un exemple complet.

ttgo t-watch tft_espi dra line rectangle circle triangle point ellipse

Changer l’orientation de l’écran

Par défaut, la librairie LilyGoWatch oriente l’écran dans le sens du bracelet pour chaque type de T-Watch. Rien ne vous empêche de changer l’orientation de l’écran pour votre application. La rotation s’effectue dans le sens horaire comme ceci.

Position 0 Position 1 Position 2 (par défaut) Position 3
ttgo t-watch lilygo tft_espi screen oriantation reference pos0 ttgo t-watch lilygo tft_espi screen oriantation reference pos1 ttgo t-watch lilygo tft_espi screen oriantation reference pos2 ttgo t-watch lilygo tft_espi screen oriantation reference pos3

Voici le code source avec lequel les images ont été créés. Il met en pratique la plupart des notions abordées précédemment :

  • Récupération de la résolution de l’écran à l’aide des fonctions width (largeur de l’écran) et height (hauteur de l’écran)
  • Le repère est tracé à l’aide des fonctions drawFastHLine et drawFastVLine
  • Les flèches sont dessinées à l’aide d’un triangle plein à l’aide de la méthode fillTriangle
  • Le point d’origine à l’aide d’un cercle plein fillCircle
  • Chaque fois que l’utilisateur touche l’écran, on change l’orientation de l’affichage à l’aide de la fonction setRotation puis on re-dessine l’écran
#include <LilyGoWatch.h>

TTGOClass *ttgo;
TFT_eSPI *tft;

int w, h, orientation;
int p = 5 ;  // marge

// Prototype
void drawReference();

void setup() {
  Serial.begin(115200);
  // Récupère l'objet et allume l'écran
  ttgo = TTGOClass::getWatch();
  ttgo->begin();     
  ttgo->openBL();

  // Accès facile aux fonctions de la librairie TFT 
  tft = ttgo->tft;
  
  // Récupère le résolution de l'écran
  w = tft->width();     // largeur
  h = tft->height();    // hauteur

  // Orientation initiale de l'écran
  orientation = tft->getRotation();
  drawReference();
}

void loop() {
  int16_t x, y;
  if (ttgo->getTouch(x, y)) {
    if ( orientation == 3 ) {
      orientation = 0;
    } else {
      orientation += 1;
    }
    tft->setRotation(orientation);
    Serial.printf("Change screen orientation %u \n", orientation);
    drawReference();
    delay(100);
  }
}

void drawReference(){
  // Efface l'écran
  tft->fillScreen(TFT_BLACK);  // Colorie le fond de l'écran en noir
  tft->setTextFont(1);
  tft->setTextSize(2);
  tft->setTextColor(TFT_WHITE, TFT_BLACK);
  tft->setCursor(0, 0);

  // Dessine le référentiel X/Y
  tft->drawFastHLine(p,p, w - 2*p, TFT_WHITE);
  tft->drawFastVLine(p,p, h - 2*p, TFT_WHITE);

  // Affiche les lettres X et Y (en utilisant le code ascii)
  // Use http://www.asciitable.com/ (for example) to find ascii char code
  // drawChar(int16_t x, int16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
  tft->drawChar(w - 3*p, 3*p, 88, TFT_WHITE, TFT_BLACK, 2); // X
  tft->fillTriangle(w, p, w - 2*p, 0, w - 2*p, 2*p, TFT_RED ); // Triangle pour la flèche X
  tft->drawChar(3*p, w - 3*p, 89, TFT_WHITE, TFT_BLACK, 2);  // Y
  tft->fillTriangle(p, h, 0, h - 2*p, 2*p, h - 2*p, TFT_RED ); // Triangle pour la flèche Y
  tft->fillCircle(p,p,p,TFT_RED); // Point d'origine

  // Message au centre de l'écran 
  tft->setTextDatum(MC_DATUM); 
  tft->drawString("Touch Screen", w / 2, h / 2 - 10, 1);
  tft->drawString("to rotate", w / 2, h / 2 + 10, 1);
}

Code complet des exemples

Voici le code complet de tous les exemples présentés précédemment.

Vous pouvez également récupérer directement sur le dépôt GitHub le code source

Débuter avec la librairie TFT_eSPI et la T-Watch

logo github

Orientation de l’écran

logo github

Le code est compatible avec l’IDE Arduino ou PlatfomIO.

/* Arduino IDE - uncomment your watch */
//#define LILYGO_WATCH_2019_WITH_TOUCH
//#define  LILYGO_WATCH_2019_NO_TOUCH
//#define LILYGO_WATCH_BLOCK=1
//#define LILYGO_WATCH_2020_V1

/* PlatformIO -> Select your watch in platformio.ini file */
#include <Arduino.h>
#include <LilyGoWatch.h>

// Objet C++ qui permettra d'accéder aux fonctions du boitier
TTGOClass *ttgo;
// Objet C++ TFT_eSPI permettant un accès rapide aux fonctions
TFT_eSPI *tft;

String txt; 
int w = 240;    // Largeur de l'écran
int h = 240;    // Hauteur de l'écran
int16_t x, y;
char buf[128];

/* Prototypes */
void fillScreenBackground();
void displayFontSize();
void drawBasic();
void drawStringDemo();
void screenOrientationDemo();
void printAListToScreen();

void setup() {
    Serial.begin(115200);
    // Récupère l'objet Watch et allume l'écran
    ttgo = TTGOClass::getWatch();
    ttgo->begin();     
    ttgo->openBL();
    tft = ttgo->tft;
    // Dé-commenter les fonctions que vous voulez tester
    //fillScreenBackground();
    //displayFontSize();
    drawBasic();
    //drawStringDemo();
    //screenOrientationDemo();
    //printAListToScreen();
    
    // Efface l'écran 
    tft->fillScreen(TFT_BLACK);
    tft->setTextColor(TFT_WHITE, TFT_BLACK);
    tft->setTextDatum(MC_DATUM);
}

void loop(){
  // Affiche les coordonnées du curseur chaque fois que l'écran est touché
  if (ttgo->getTouch(x, y)) {
    sprintf(buf, "  x:%u  y:%u   ", x, y);
    tft->drawString(buf, w / 2, h / 2);
    Serial.println(buf);
  }
}

// Constantes des couleurs disponibles
/* 
 * TFT_BLACK         0,   0,   0 
 * TFT_NAVY          0,   0, 128 
 * TFT_DARKGREEN     0, 128,   0 
 * TFT_DARKCYAN      0, 128, 128 
 * TFT_MAROON      128,   0,   0 
 * TFT_PURPLE      128,   0, 128 
 * TFT_OLIVE       128, 128,   0 
 * TFT_LIGHTGREY   211, 211, 211 
 * TFT_DARKGREY    128, 128, 128 
 * TFT_BLUE          0,   0, 255 
 * TFT_GREEN         0, 255,   0 
 * TFT_CYAN          0, 255, 255 
 * TFT_RED         255,   0,   0 
 * TFT_MAGENTA     255,   0, 255 
 * TFT_YELLOW      255, 255,   0 
 * TFT_WHITE       255, 255, 255 
 * TFT_ORANGE      255, 180,   0 
 * TFT_GREENYELLOW 180, 255,   0 
 * TFT_PINK        255, 192, 203     
 * TFT_BROWN       150,  75,   0 
 * TFT_GOLD        255, 215,   0 
 * TFT_SILVER      192, 192, 192 
 * TFT_SKYBLUE     135, 206, 235 
 * TFT_VIOLET      180,  46, 226 
*/
void fillScreenBackground(){
    Serial.println("Red");
    tft->fillScreen(TFT_RED);
    delay(1000);
    Serial.println("Green");
    tft->fillScreen(TFT_GREEN);
    delay(1000);
    Serial.println("Black");
    tft->fillScreen(TFT_BLACK);
    delay(1000);
}

void getScreenSize(){
  w = tft->width();
  h = tft->height();
  Serial.printf("Screen size %u * %u", w, h);
}

// Dessine les primitives geometriques
void drawBasic(){
  int margin = 20;
  int _delay = 500;
  getScreenSize();
  
  Serial.println("Draw a rectangle");
  tft->fillScreen(TFT_BLACK);
  tft->drawRect(margin,margin, w - ( 2* margin ), h - ( 2 * margin),TFT_RED);
  delay(_delay);

  Serial.println("Draw a filled rectangle");
  // fillRect(int32_t x, int32_t y, int32_t w, int32_t h, uint32_t color)
  tft->fillRect(2 * margin, 2 * margin, w - ( 4 * margin), h - (4 * margin), TFT_VIOLET);
  delay(_delay);

  Serial.println("Draw a rounded corner rectangle outline");
  //drawRoundRect(int32_t x, int32_t y, int32_t w, int32_t h, int32_t r, uint32_t color)
  tft->drawRoundRect(3 * margin, 3 * margin, w - ( 6 * margin), h - (6 * margin), 8, TFT_YELLOW);
  delay(_delay);

  Serial.println("Draw a line");
  // drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, uint32_t color)
  tft->drawLine(0, 0, w, h, TFT_DARKGREY);
  delay(_delay);  

  Serial.println("Draw a triangle outline using 3 arbitrary points");
  // drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint32_t color)
  tft->drawTriangle(w,h - 1, w - 40 , h, w - 20, h - 30, TFT_PURPLE);
  delay(_delay); 

  Serial.println("Draw a circle outline");
  //drawCircle(int32_t x0, int32_t y0, int32_t r, uint32_t color)
  tft->drawCircle(w / 2, h / 2, 80, TFT_SKYBLUE);
  delay(_delay);

  Serial.println("Draw a ellipse outline");
  //drawEllipse(int16_t x0, int16_t y0, int32_t rx, int32_t ry, uint16_t color)
  tft->drawEllipse(w, h, 80, 60, TFT_SKYBLUE);
  delay(_delay);

  Serial.println("Draw horizontal line");
  // drawFastHLine(int32_t x, int32_t y, int32_t w, uint32_t color)
  tft->drawFastHLine(0, 0, w, TFT_DARKGREY);
  delay(_delay);  
  
  Serial.println("Draw Vertical line");
  // drawFastVLine(int32_t x, int32_t y, int32_t h, uint32_t color)
  tft->drawFastVLine(0, 0, h, TFT_DARKGREY);
  delay(_delay);
  
  Serial.println("Draw A char (ascii 65)");
  //drawChar(int32_t x, int32_t y, uint16_t c, uint32_t color, uint32_t bg, uint8_t size)
  // Use this to find char code http://www.asciitable.com/
  tft->drawChar(margin, margin, 65, TFT_BLUE, TFT_WHITE, 2);
  delay(_delay);

  Serial.println("Draw a string");
  //drawString(const char *string, int32_t poX, int32_t poY)
  tft->drawString("T-Watch",margin, margin * 2);
  delay(_delay);

  Serial.println("Draw a pixel");
  //drawPixel(int32_t x, int32_t y, uint32_t color)
  tft->drawPixel(w / 2 , h / 2, TFT_RED);
  delay(_delay);
  /* Other usefull functions 
      invertDisplay(bool i)
      decodeUTF8(uint8_t *buf, uint16_t *index, uint16_t remaining)
  */
}

// Affiche une police en augmentant la taille progressivement de 1 à 7 (max)
void displayFontSize(){
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE);
    for (size_t i = 1; i <= 7; i++){  // Size from 1 to 7 (includes) | La taille doit être comprise entre 1 et 7
      tft->setTextFont(1);     // Only font 1 is available | Uniquement 1
      tft->setTextSize(i);     // Change size | change la taille        
      tft->setCursor(0, 0);
      txt = "Text with size "; txt += i;
      Serial.print("Display"); Serial.println(txt);
      tft->println(txt);
      delay(1000);
      tft->fillScreen(TFT_BLACK);
    }
}

void drawStringDemo(){
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE);
  tft->setTextSize(2); 
  for (size_t i = 0; i < 12; i++)
  {
    tft->setTextDatum(i);
    Serial.printf("Display string with justification %u \n", tft->getTextDatum());
    tft->drawString("TFT_eSPI Demo", w / 2, h / 2, 2);
    delay(1000);
    tft->fillScreen(TFT_BLACK);
  }
}

void screenOrientationDemo(){
  Serial.printf("Current screen orientation %u \n", tft->getRotation());
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE);
  tft->setTextDatum(MC_DATUM);
  tft->setTextSize(2); 
  tft->drawString("Rotate Screen", w / 2, h / 2, 2);
  for (size_t i = 1; i < 4; i++)
  {
    // rotate the screen orientation m = 0-3 or 4-7 for BMP drawing
    //setRotation(uint8_t m)
    Serial.printf("Rotate the screen to %u \n", i);
    tft->setRotation(i);
    tft->fillScreen(TFT_BLACK);
    tft->drawString("Rotate Screen", w / 2, h / 2, 2);
    delay(1000);
  }
  
  tft->setRotation(2);
  tft->fillScreen(TFT_BLACK);
  tft->drawString("Rotate Screen", w / 2, h / 2, 2);
}

// Use printf or println to display a list to screen | utilise la fonction println or printf pour afficher une liste à l'écran
void printAListToScreen(){
  //TFT_eSPI * tft = tft;
  tft->fillScreen(TFT_BLACK);
  tft->setTextColor(TFT_WHITE, TFT_BLACK);
  tft->setTextSize(2);
  tft->setCursor(0,0);
  
  for (size_t i = 0; i <= 20; i++) {
    // Return cursor on the top of the screen | Renvoi le curseur en haut de l'écran 
    if ( tft->getCursorY() >= h ) {
      tft->fillScreen(TFT_BLACK);
      tft->setCursor(0,0);
    }
    tft->printf("This is the line %u \n", i);
    delay(200);
  }
  tft->setTextSize(1);

  tft->println(" \n *** End of the list ***");
  delay(2000);
}

Le fichier de configuration platformio.ini

env:ttgo-t-watch]
platform = espressif32
board = ttgo-t-watch
framework = arduino
build_flags =
    ;-D LILYGO_WATCH_2019_WITH_TOUCH=1
    ;-D LILYGO_WATCH_2019_NO_TOUCH=1
    ;-D LILYGO_WATCH_BLOCK=1
    -D LILYGO_WATCH_2020_V1=1
lib_deps =
    TTGO TWatch Library
upload_speed = 2000000
monitor_speed = 115200

Et la petite vidéo de démo qui va bien

Mises à jour

25/11/2020 Ajout de la fonction drawXBitmap()

16/11/2020 Publication de l’article

English Version

Avez-vous aimé cet article ?
[Total: 0 Moyenne: 0]

Vous rencontrez un problème avec ce sujet ?

Peut-être que quelqu’un a déjà trouvé la solution, visitez le forum avant de poser votre question

Vous avez aimé ce projet ? Ne manquez plus aucun projet en vous abonnant à notre lettre d’information hebdomadaire!

Nous serions ravis de connaître votre avis

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Sondage

Vous avez la parole. Quels sont les thèmes qui vous intéressent en 2021.

Résultats du sondage début janvier.

Merci pour votre confiance. Prenez soin de vous et passez de bonnes fêtes !

Jusqu’à 8 réponses possibles. Vous pouvez faire d’autres propositions.

Les thèmes qui vous intéressent en 2021
  • Proposer une autre réponse
Publicité
Partager
Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur email
Partager sur telegram

Table des matières

S'équiper
À Lire aussi
Publicité
Domotique et objets connectés à faire soi-même
Vous avez aimé ce tutoriel

Ne manquez plus les prochains projets

Recevez chaque semaine le récapitulatif des tutoriels et projets.

Vous pouvez vous désabonner à tout moment.