« ESP32C3 avec écran spotear » : différence entre les versions

De knowledge
Aller à la navigation Aller à la recherche
 
(4 versions intermédiaires par le même utilisateur non affichées)
Ligne 43 : Ligne 43 :
J'ai trouvé :
J'ai trouvé :


https://www.elektroda.com/news/news4091334.html  où un certain p.kaczmarek2 détaille tout le process d'utilisation.
https://www.elektroda.com/news/news4091334.html  où un certain p.kaczmarek2 détaille tout le processus d'utilisation.
 
Dedans j'ai trouvé le schéma électronique.
 
[[Fichier:SCHEMA ELEC SPOTEAR.png|sans_cadre|836x836px]]


https://spotpear.com/wiki/ESP32-C3-desktop-trinket-Mini-TV-Portable-Pendant-LVGL-1.44inch-LCD-ST7735.html le site du fabricant.
https://spotpear.com/wiki/ESP32-C3-desktop-trinket-Mini-TV-Portable-Pendant-LVGL-1.44inch-LCD-ST7735.html le site du fabricant.
Ligne 75 : Ligne 79 :


=== Utiliser l'écran ===
=== Utiliser l'écran ===
J'ai eu pas mal de problèmes pour utiliser l'écran. Beaucoup de tutos (et aussi copilot) conseillent d'utiliser la librairie '''TFT_eSPI''' mais je ne suis pas arrivé à l'utiliser correctement.
D'autre part le branchement de l'écran n'est pas standard.
==== Brochage ====
Dans le schéma de principe donné sur le site de p.kaczmarek2 on voit plusieurs choses.
[[Fichier:ST7735 PINOUT.png|sans_cadre|429x429px]]
Le pinout n'est pas standard le 'backlight" n'est pas réglable. Les LEDs de rétroéclairage sont alimentées en permanence à travers R11.
En plus sur ce schéma les broches sont nommées SDA, SCL... alors que c'est du SPI et pas ce I<sub>2</sub>C.
Donc le fichier de définition est :<syntaxhighlight lang="c">
// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3
</syntaxhighlight>Mon fichier User_Setup.h complet est:<syntaxhighlight lang="c">
#define USER_SETUP_ID 44
#define ST7735_DRIVER
#define TFT_WIDTH 128
#define TFT_HEIGHT 128
// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3
#define LED_PIN  11  // GPIO11 sur ESP32-C3
#define SWITCH_0  8  // GPIO08 sur ESP32-C3
#define SWITCH_1  10  // GPIO10 sur ESP32-C3
#define TFT_RGB_ORDER TFT_BGR
#define TFT_INVERSION_ON
#define TFT_ROTATION 1
#define SPI_FREQUENCY  27000000
</syntaxhighlight>
==== Librairie Adafruit ====
Donc la librairies '''TFT_eSPI''' ne marche pas avec cet écran (ou je ne suis pas arrivé à la faire marcher) j'ai utilisé '''Adafruit_ST7735''' qui fonctionne très bien ([https://www.adafruit.com/ merci Lady Ada]).
Associée à la librairies GFX du même Adafruit on a un joli environnement pour faire des dessins sur l'écran.
On déclare la librairie dans platformio.ini :<syntaxhighlight lang="ini">
[env:adafruit_qtpy_esp32c3]
platform = espressif32
board = adafruit_qtpy_esp32c3
framework = arduino
lib_deps =
    adafruit/Adafruit ST7735 and ST7789 Library
    adafruit/Adafruit GFX Library
build_flags =
    -DUSER_SETUP_LOADED=1
    -include src/User_Setup.h
monitor_speed = 115200
upload_speed = 921600
</syntaxhighlight>On remarque l'inclusion du User_Setup.h montré ci dessus.
Et dans le code source on ajoute:<syntaxhighlight lang="c">
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
</syntaxhighlight>On déclare un objet Adafruit_ST7735 avec les broches données ci dessus.<syntaxhighlight lang="c">
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, MOSI_PIN, SCK_PIN, TFT_RST);
</syntaxhighlight>et on l'initialise dans <code>setup()</code> :<syntaxhighlight lang="c">tft.initR(INITR_144GREENTAB);
    tft.setRotation(3);
    tft.fillScreen(ST77XX_BLACK);  // Fill the screen with black color
    delay(100);
    tft.setRotation(2);</syntaxhighlight>Ici y'a deux remarques:
* La constante INITR_144GREENTAB est à utiliser car le standard INITR_BLACKTAB est en mode RGB alors que notre écran est BGR (pourquoi ... pour faire genre je suppose).
* Ensuite, lors du premier démarrage le tft.fillScreen(ST77XX_BLACK);   "oublie" quelques lignes de pixels a droite et, pour éviter ce probléme je remplis deux fois en tournant virtuellement l'écran. Il y a peut-etre une conf qui m'échappe...
===== La "default font" =====
Lorsque l'on choisit la fonte par défaut (on qu'on ne choisit rien) :<syntaxhighlight lang="c++">
tft.setFont(); // Si une fonte avait été selectionnée avant. On reviens à la 7x5 par défaut
</syntaxhighlight>C'est une police de base 5x7 mais elle va plus loin que l'ASCII standard.
* On a des caractères valides avant 32
* On a des caractères étendus après 127
Le fichier qui le décrit s'appelle <code>glcdfont.c</code> et, dans un projet Visual Studio Code est situé : <code>.pio/libdeps/adafruit_qtpy_esp32c3/Adafruit GFX Library/glcdfont.c</code>
La structure est simple chaque caractère est codé 5 octset représentant les 5 colonnes de bits.
Apres un programme en C++ pour comprendre et un programme en python pour représenter je suis arrivé à :
[[Fichier:AdafruitGFX 5x7 font.png|sans_cadre|645x645px]]
Bon le 5x7 c'est moche mais sur un écran 128x128 ca permet d'afficher 16 lignes de 21 caractères (un peu moins que le 176 × 184 du vic 20)
==== Exemple complet ====
Un programe démo complet est donné ici.
C'est un "LED Blink" amélioré.
Il fait clignoter la LED sur GPIO11 au rythme de une fois par seconde (1000 ms) ajustable.
L'écran affichera:
[[Fichier:Luxury blink.png|sans_cadre]]
On a en vert le période de "blink" et en blanc sur fond bleu le temps depuis le boot du device HH:MM:SS.
Un petit bandeau bleu a gauche indique que les boutons "+" et "-" permettent d'ajouter ou de retirer 10 ms à la période.
RST est également affiché a côté du bouton reset.
Le projet est constitué de 3 fichiers :
===== platformio.ini =====
<syntaxhighlight lang="ini">[env:adafruit_qtpy_esp32c3]
platform = espressif32
board = adafruit_qtpy_esp32c3
framework = arduino
lib_deps =
    adafruit/Adafruit ST7735 and ST7789 Library
    adafruit/Adafruit GFX Library
build_flags =
    -DUSER_SETUP_LOADED=1
    -include src/User_Setup.h
monitor_speed = 115200
upload_speed = 921600</syntaxhighlight>
===== User_Setup.h =====
<syntaxhighlight lang="c">
#define USER_SETUP_ID 44
#define ST7735_DRIVER
#define TFT_WIDTH 128
#define TFT_HEIGHT 128
// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3
#define LED_PIN  11  // GPIO11 sur ESP32-C3
#define SWITCH_0  8  // GPIO08 sur ESP32-C3
#define SWITCH_1  10  // GPIO10 sur ESP32-C3
#define TFT_RGB_ORDER TFT_BGR
#define TFT_INVERSION_ON
#define TFT_ROTATION 1
#define SPI_FREQUENCY  27000000
</syntaxhighlight>
===== main.cpp =====
<syntaxhighlight lang="c++">
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>
Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, MOSI_PIN, SCK_PIN, TFT_RST);
int periode = 1000;
void display(){
  tft.fillScreen(tft.color565(128, 128, 128));  // Fill the screen with black color
  tft.setCursor(20, 15);            // Set cursor at the top-left corner
  tft.setTextColor(ST77XX_WHITE); // Set text color to white
  tft.setFont();
  tft.print("Blink test...");      // Print the message
  tft.fillRect(0,0,15,TFT_HEIGHT,tft.color565(0, 0, 128));
  tft.drawRect(0,0,15,TFT_HEIGHT,ST77XX_BLACK);
  tft.setCursor(5, 10); tft.print("+"); 
  tft.setCursor(5, 110); tft.print("-"); 
  tft.setCursor(100, 110); tft.print("RST"); 
 
}
void update(){
  int16_t margin=5;
  int16_t x=25;
  int16_t y=50;
  int16_t x1, y1;
  uint16_t w, h;
  String displayStr=" "+String(millis())+" ms ";
  tft.setFont(&FreeSans9pt7b);
  tft.setTextSize(1); 
  tft.getTextBounds(displayStr, x, y, &x1, &y1, &w, &h);
  uint16_t real_w = TFT_WIDTH-x1-margin;
  tft.fillRect(x1-margin, y1-margin, real_w, h+margin*2, ST77XX_BLACK); // efface la zone
  tft.setCursor(x, y);            // Set cursor at the top-left corner
  tft.setTextColor(ST77XX_GREEN); // Set text color to green
  tft.print(String(periode)+" ms");      // Print the message   
}
void update_time(){
  int16_t margin=5;
  int16_t x=25;
  int16_t y=90;
  int16_t x1, y1;
  uint16_t w, h;
  uint32_t ti=millis();
  uint16_t ss=ti/1000;
  uint16_t mm=ss/60;
  ss=ss-(mm*60);
  uint16_t hh=mm/60;
  mm=mm-(hh*60);
  String displayStr=(hh < 10 ? String("0") : String(""))+String(hh)+":"+\
                    (mm < 10 ? String("0") : String(""))+String(mm)+":"+\
                    (ss < 10 ? String("0") : String(""))+String(ss);
  tft.setFont(&FreeSans12pt7b);
  tft.setTextSize(1); 
  tft.getTextBounds(displayStr, x, y, &x1, &y1, &w, &h);
  uint16_t real_w = TFT_WIDTH-x1-margin;
  tft.fillRect(x1-margin, y1-margin, real_w, h+margin*2, tft.color565(0, 0, 128)); // efface la zone
  tft.drawRect(x1-margin, y1-margin, real_w, h+margin*2,ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);     
  tft.setCursor(x, y);
  tft.print(displayStr);
}
void setup() {
  Serial.begin(115200);
  delay(1000);
  Serial.println("Démarrage ESP32-C3...");
  Serial.println(periode);
  pinMode(LED_PIN, OUTPUT);
  pinMode(SWITCH_0, INPUT_PULLUP);
  pinMode(SWITCH_1, INPUT_PULLUP);
  Serial.println("Init écran ST7735...");
  tft.initR(INITR_144GREENTAB);
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);  // Fill the screen with black color
  delay(100);
  tft.setRotation(2);
  tft.setTextSize(1); 
  display();
  update();
}
void loop() {
  if (digitalRead(SWITCH_0)==LOW){
    periode-=10;
    if (periode<100)
      periode=100;
    Serial.println(periode);
    update();
    delay(10);
    while (digitalRead(SWITCH_0)==LOW)
      delay(10);
  }
  if (digitalRead(SWITCH_1)==LOW){
    periode+=10;
    if (periode>2000)
      periode=2000;
    Serial.println(periode);
    update();
    delay(10);
    while (digitalRead(SWITCH_1)==LOW)
      delay(10);
  }
  if ((millis() % periode)< (periode/2))
    digitalWrite(LED_PIN, HIGH);
  else
    digitalWrite(LED_PIN, LOW);
 
  if ((millis() % 1000)==0)
    update_time();
}
</syntaxhighlight>

Dernière version du 13 mai 2026 à 20:05

Appelé en français "Mini ornement de Bureau" voici le module ESP32 C3 équipé de son écran. Personnellement c'est mon premier C3 donc mes débuts en RISC-V. Bon tant que je fais du C avec l'IDE Arduino ca devrait pas trop se voir.

Premier contact

Apres avoir joué au petit mécano pour monter le bidule. On le branche sur une alim USB (micro USB le design ne date pas d'hier).

On le branche et il affiche un message (assez moche en vérité) indiquant de configurer son "mobile WLAN" avec les paramètres :

SSID : spotpear (c'est le fabricant)

WIFI Key : 12345678

On peut pas plus sûr comme mot de passe !

Le message du dessous me parait me parait assez ésotérique. Ca sent la traduction du chinois fait pas une IA poussive.

Je configure un routeur avec ces paramètres et je rebranche le bigonx.

Une belle barre de progression s'affiche et ensuite un superbe écran!

Que c'est beau!

A première vue:

  • L'écran est très correct. Lumineux et lisible.
  • Pour le mini firmware:
  • L'heure locale est juste. Il sait se mètre à l'heure et détecte correctement le fuseau horaire et l'heure été/hiver
  • La date est bonne
  • La localisation à Clichy est fausse (on est a Paris aujourd'hui)
  • La température semble correcte le service météo est juste en revanche le fait d'afficher en °F alors qu'on est a Clichy...Bof bof.
  • La météo est correcte (il pleut, il pleut en ce mois de mars 2026)


Le barre de progression du wifi étant verte et le symbole "Temp" en bleu je suppose que cet écran est RGB. (Chercher le rouge)

Recherche de documentation

Le bidule acheté 9€ sur Aliexpress est livré avec.... 8 entretoises 8 vis une façade trouée pour l'écran et un bout de plastique noir pour le fond. Mais .... Aucune doc.

Pas grave y'a Google et Gemini.

J'ai trouvé :

https://www.elektroda.com/news/news4091334.html où un certain p.kaczmarek2 détaille tout le processus d'utilisation.

Dedans j'ai trouvé le schéma électronique.

https://spotpear.com/wiki/ESP32-C3-desktop-trinket-Mini-TV-Portable-Pendant-LVGL-1.44inch-LCD-ST7735.html le site du fabricant.

Niveau Hardware

La carte est assez simple on y trouve :

  • Le joli écran de 1,44'' de 128x128 pixel (on est loin du 300 ppp) utilisé en SPI (peut être possible en I2C). Pour les personnes normales utilisant le système métrique (le monde entier sauf les USA, le Libéria et la Birmanie je crois) 1.44'' ca fait 36,6 mm. La taille doit venir de ces unités exotiques où un pouce est divisé en 144 points. Je sais pas j'ai pas l'habitude... Doit y avoir une logique.
  • Une prise pour une batterie et un circuit de charge PL4054
  • Un régulateur linéaire pour faire du 3.3 V CAT 6219 qui m'a pas l'aire d'être tout jeune
  • Un quartz 40 MHz
  • Une petite mémoire flash de 128 Mbits (16b Mo) W25q128
  • 4 boutons poussoirs
    • RESET (ou plutôt CHIP_EN) avec son petit circuit de reset automatique
    • Un bouton BOOT cablé sur IO09
    • Deux boutons (actifs bas) sur IO8 et I010
  • Une led sur IO11
  • Une LED qui, si je comprends le schéma électronique s'allume quand le batterie se charge
  • Le port USB est relié au ESP32C3 qui doit savoir le gérer en natif (pas de FTDI ou autre)
  • 5 GPIO accessibles sur 6 broches
    • GPIO1
    • GPIO6
    • GPIO7
    • GPIO20
    • GPIO21
  • Une broches de masse (coté GPIO)
  • Une broche +5V et une +3.3V autour du port µUSB

Niveau developpement

Il faut installer un environnement correct. C'est détaillé ici. Avec un premier "hello world" qui fait clignoter une LED.

Utiliser l'écran

J'ai eu pas mal de problèmes pour utiliser l'écran. Beaucoup de tutos (et aussi copilot) conseillent d'utiliser la librairie TFT_eSPI mais je ne suis pas arrivé à l'utiliser correctement.

D'autre part le branchement de l'écran n'est pas standard.

Brochage

Dans le schéma de principe donné sur le site de p.kaczmarek2 on voit plusieurs choses.

Le pinout n'est pas standard le 'backlight" n'est pas réglable. Les LEDs de rétroéclairage sont alimentées en permanence à travers R11.

En plus sur ce schéma les broches sont nommées SDA, SCL... alors que c'est du SPI et pas ce I2C.

Donc le fichier de définition est :

// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3

Mon fichier User_Setup.h complet est:

#define USER_SETUP_ID 44

#define ST7735_DRIVER
#define TFT_WIDTH 128
#define TFT_HEIGHT 128

// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3

#define LED_PIN   11  // GPIO11 sur ESP32-C3
#define SWITCH_0  8   // GPIO08 sur ESP32-C3
#define SWITCH_1  10  // GPIO10 sur ESP32-C3

#define TFT_RGB_ORDER TFT_BGR
#define TFT_INVERSION_ON
#define TFT_ROTATION 1

#define SPI_FREQUENCY  27000000

Librairie Adafruit

Donc la librairies TFT_eSPI ne marche pas avec cet écran (ou je ne suis pas arrivé à la faire marcher) j'ai utilisé Adafruit_ST7735 qui fonctionne très bien (merci Lady Ada).

Associée à la librairies GFX du même Adafruit on a un joli environnement pour faire des dessins sur l'écran.

On déclare la librairie dans platformio.ini :

[env:adafruit_qtpy_esp32c3]
platform = espressif32
board = adafruit_qtpy_esp32c3
framework = arduino

lib_deps =
    adafruit/Adafruit ST7735 and ST7789 Library
    adafruit/Adafruit GFX Library

build_flags =
    -DUSER_SETUP_LOADED=1
    -include src/User_Setup.h

monitor_speed = 115200
upload_speed = 921600

On remarque l'inclusion du User_Setup.h montré ci dessus. Et dans le code source on ajoute:

#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>

On déclare un objet Adafruit_ST7735 avec les broches données ci dessus.

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, MOSI_PIN, SCK_PIN, TFT_RST);

et on l'initialise dans setup() :

tft.initR(INITR_144GREENTAB); 
    tft.setRotation(3);
    tft.fillScreen(ST77XX_BLACK);   // Fill the screen with black color
    delay(100);
    tft.setRotation(2);

Ici y'a deux remarques:

  • La constante INITR_144GREENTAB est à utiliser car le standard INITR_BLACKTAB est en mode RGB alors que notre écran est BGR (pourquoi ... pour faire genre je suppose).
  • Ensuite, lors du premier démarrage le tft.fillScreen(ST77XX_BLACK);   "oublie" quelques lignes de pixels a droite et, pour éviter ce probléme je remplis deux fois en tournant virtuellement l'écran. Il y a peut-etre une conf qui m'échappe...
La "default font"

Lorsque l'on choisit la fonte par défaut (on qu'on ne choisit rien) :

tft.setFont(); // Si une fonte avait été selectionnée avant. On reviens à la 7x5 par défaut

C'est une police de base 5x7 mais elle va plus loin que l'ASCII standard.

  • On a des caractères valides avant 32
  • On a des caractères étendus après 127

Le fichier qui le décrit s'appelle glcdfont.c et, dans un projet Visual Studio Code est situé : .pio/libdeps/adafruit_qtpy_esp32c3/Adafruit GFX Library/glcdfont.c

La structure est simple chaque caractère est codé 5 octset représentant les 5 colonnes de bits.

Apres un programme en C++ pour comprendre et un programme en python pour représenter je suis arrivé à :

Bon le 5x7 c'est moche mais sur un écran 128x128 ca permet d'afficher 16 lignes de 21 caractères (un peu moins que le 176 × 184 du vic 20)

Exemple complet

Un programe démo complet est donné ici.

C'est un "LED Blink" amélioré.

Il fait clignoter la LED sur GPIO11 au rythme de une fois par seconde (1000 ms) ajustable.

L'écran affichera:

On a en vert le période de "blink" et en blanc sur fond bleu le temps depuis le boot du device HH:MM:SS.

Un petit bandeau bleu a gauche indique que les boutons "+" et "-" permettent d'ajouter ou de retirer 10 ms à la période.

RST est également affiché a côté du bouton reset.

Le projet est constitué de 3 fichiers :

platformio.ini
[env:adafruit_qtpy_esp32c3]
platform = espressif32
board = adafruit_qtpy_esp32c3
framework = arduino

lib_deps =
    adafruit/Adafruit ST7735 and ST7789 Library
    adafruit/Adafruit GFX Library

build_flags =
    -DUSER_SETUP_LOADED=1
    -include src/User_Setup.h

monitor_speed = 115200
upload_speed = 921600
User_Setup.h
#define USER_SETUP_ID 44

#define ST7735_DRIVER
#define TFT_WIDTH 128
#define TFT_HEIGHT 128

// Pinout du module Mini-TV ESP32-C3
#define SD_CS 5
#define TFT_CS 2
#define TFT_DC 0
#define TFT_RST 5
#define MOSI_PIN 4
#define SCK_PIN 3

#define LED_PIN   11  // GPIO11 sur ESP32-C3
#define SWITCH_0  8   // GPIO08 sur ESP32-C3
#define SWITCH_1  10  // GPIO10 sur ESP32-C3

#define TFT_RGB_ORDER TFT_BGR
#define TFT_INVERSION_ON
#define TFT_ROTATION 1

#define SPI_FREQUENCY  27000000
main.cpp
#include <Arduino.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <Fonts/FreeSans9pt7b.h>
#include <Fonts/FreeSans12pt7b.h>



Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, MOSI_PIN, SCK_PIN, TFT_RST);

int periode = 1000;

void display(){
  tft.fillScreen(tft.color565(128, 128, 128));   // Fill the screen with black color
  tft.setCursor(20, 15);            // Set cursor at the top-left corner
  tft.setTextColor(ST77XX_WHITE); // Set text color to white
  tft.setFont();
  tft.print("Blink test...");       // Print the message
  tft.fillRect(0,0,15,TFT_HEIGHT,tft.color565(0, 0, 128));
  tft.drawRect(0,0,15,TFT_HEIGHT,ST77XX_BLACK);

  tft.setCursor(5, 10); tft.print("+");  
  tft.setCursor(5, 110); tft.print("-");  
  tft.setCursor(100, 110); tft.print("RST");  
  
}

void update(){
  int16_t margin=5;
  int16_t x=25;
  int16_t y=50;
  int16_t x1, y1;
  uint16_t w, h;
  String displayStr=" "+String(millis())+" ms ";
  tft.setFont(&FreeSans9pt7b);
  tft.setTextSize(1);  
  tft.getTextBounds(displayStr, x, y, &x1, &y1, &w, &h);
  uint16_t real_w = TFT_WIDTH-x1-margin;
  tft.fillRect(x1-margin, y1-margin, real_w, h+margin*2, ST77XX_BLACK); // efface la zone
  tft.setCursor(x, y);            // Set cursor at the top-left corner
  tft.setTextColor(ST77XX_GREEN); // Set text color to green
  tft.print(String(periode)+" ms");       // Print the message    
}

void update_time(){
  int16_t margin=5;
  int16_t x=25;
  int16_t y=90;
  int16_t x1, y1;
  uint16_t w, h;
  uint32_t ti=millis();
  uint16_t ss=ti/1000;
  uint16_t mm=ss/60;
  ss=ss-(mm*60);
  uint16_t hh=mm/60;
  mm=mm-(hh*60);
  String displayStr=(hh < 10 ? String("0") : String(""))+String(hh)+":"+\
                    (mm < 10 ? String("0") : String(""))+String(mm)+":"+\
                    (ss < 10 ? String("0") : String(""))+String(ss);
  tft.setFont(&FreeSans12pt7b);
  tft.setTextSize(1);  
  tft.getTextBounds(displayStr, x, y, &x1, &y1, &w, &h);
  uint16_t real_w = TFT_WIDTH-x1-margin;
  tft.fillRect(x1-margin, y1-margin, real_w, h+margin*2, tft.color565(0, 0, 128)); // efface la zone
  tft.drawRect(x1-margin, y1-margin, real_w, h+margin*2,ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);       
  tft.setCursor(x, y);
  tft.print(displayStr);
}

void setup() {
  Serial.begin(115200);
  delay(1000);

  Serial.println("Démarrage ESP32-C3...");
  Serial.println(periode);
  pinMode(LED_PIN, OUTPUT);
  pinMode(SWITCH_0, INPUT_PULLUP);
  pinMode(SWITCH_1, INPUT_PULLUP);
  Serial.println("Init écran ST7735...");
  tft.initR(INITR_144GREENTAB); 
  tft.setRotation(3);
  tft.fillScreen(ST77XX_BLACK);   // Fill the screen with black color
  delay(100);
  tft.setRotation(2);
  tft.setTextSize(1);  
  display();
  update();
}

void loop() {
  if (digitalRead(SWITCH_0)==LOW){
    periode-=10;
    if (periode<100)
      periode=100;
    Serial.println(periode);
    update();
    delay(10);
    while (digitalRead(SWITCH_0)==LOW)
      delay(10);
  }

  if (digitalRead(SWITCH_1)==LOW){
    periode+=10;
    if (periode>2000)
      periode=2000;
    Serial.println(periode);
    update();
    delay(10);
    while (digitalRead(SWITCH_1)==LOW)
      delay(10);
  }


  if ((millis() % periode)< (periode/2))
    digitalWrite(LED_PIN, HIGH);
  else
    digitalWrite(LED_PIN, LOW);
  
  if ((millis() % 1000)==0)
    update_time();

}