#include #include #include // Pour les labels #include // Pour les unités #include // Pour les gros chiffres // --- Configuration des Pins (ESP32-S3-Zero) --- #define EPD_CS 7 #define EPD_DC 6 #define EPD_RST 5 #define EPD_BUSY 4 // Driver pour Waveshare 4.2" B&W GxEPD2_BW display(GxEPD2_420(EPD_CS, EPD_DC, EPD_RST, EPD_BUSY)); // --- Variables de simulation --- float vitesse = 7.42; int perf = 102; float vmg = 5.15; float cible = 7.20; int loopCount = 0; // --- Helper pour dessiner une "Tuile" d'instrument --- void dessinerTuile(int x, int y, int w, int h, const char* label) { // 1. Cadre arrondi extérieur display.drawRoundRect(x, y, w, h, 8, GxEPD_BLACK); // 2. Bandeau noir pour le titre (label) display.fillRoundRect(x, y, w, 30, 8, GxEPD_BLACK); display.fillRect(x, y+20, w, 10, GxEPD_BLACK); // Carré pour éviter l'arrondi en bas du bandeau // 3. Texte du Label display.setFont(&FreeSansBold9pt7b); display.setTextColor(GxEPD_WHITE); display.setCursor(x + 10, y + 20); display.print(label); } // --- Dessiner tout le layout fixe --- void dessinerLayoutFixe() { display.fillScreen(GxEPD_WHITE); // On divise l'écran (400x300) en 4 zones de ~190x140 pixels dessinerTuile(5, 5, 190, 140, "STW"); dessinerTuile(205, 5, 190, 140, "POLAR"); dessinerTuile(5, 155, 190, 140, "VMG"); dessinerTuile(205, 155, 190, 140, "TARGET"); } void afficherValeur(int x, int y, int width, int height, const char* tvalue, const char* tunit) { int16_t x1, y1; uint16_t textW, textH; display.getTextBounds(tvalue, 0, 0, &x1, &y1, &textW, &textH); display.fillRect(x, y, width, height, GxEPD_WHITE); display.setFont(&FreeSansBold24pt7b); display.setCursor(x + (width - textW) / 2 - x1, y+55); display.print(tvalue); display.setFont(&FreeSansBold12pt7b); display.setCursor(x, y+5); display.print(tunit); } // --- Mettre à jour les chiffres uniquement --- void mettreAJourValeurs() { display.fillScreen(GxEPD_WHITE); // dessinerLayoutFixe(); dessinerTuile(5, 5, 190, 140, "STW"); dessinerTuile(205, 5, 190, 140, "POLAR"); dessinerTuile(5, 155, 190, 140, "VMG"); dessinerTuile(205, 155, 190, 140, "TARGET"); display.setTextColor(GxEPD_BLACK); // --- 1. VITESSE --- afficherValeur(15, 60, 130, 70, String(vitesse, 1).c_str(), " kt"); // --- 2. PERFORMANCE --- afficherValeur(215, 60, 130, 70, String(perf).c_str(), " %"); // --- 3. VMG --- afficherValeur(15, 210, 130, 70, String(vmg, 1).c_str(), " kt"); // --- 4. CIBLE --- afficherValeur(215, 210, 130, 70, String(cible, 1).c_str(), " kt"); } void setup() { Serial.begin(115200); display.init(115200, true, 2, false); display.setRotation(0); // Mode paysage Serial.println("Initialisation du Layout..."); display.setFullWindow(); display.firstPage(); do { // dessinerLayoutFixe(); mettreAJourValeurs(); } while (display.nextPage()); } void loop() { delay(3000); // 3 secondes // Simulation de variation vitesse += (random(-5, 6) / 100.0); perf = random(95, 105); vmg = vitesse * 0.8; loopCount++; if (loopCount >= 20) { // Full refresh toutes les minute pour nettoyer display.setFullWindow(); display.firstPage(); do { // dessinerLayoutFixe(); mettreAJourValeurs(); } while (display.nextPage()); loopCount = 0; } else { // Rafraîchissement Partiel display.setPartialWindow(0, 0, 400, 300); display.firstPage(); do { // dessinerLayoutFixe(); mettreAJourValeurs(); } while (display.nextPage()); } display.powerOff(); }