132 lines
3.9 KiB
Plaintext
132 lines
3.9 KiB
Plaintext
#include <Arduino.h>
|
|
#include <GxEPD2_BW.h>
|
|
#include <Fonts/FreeSansBold9pt7b.h> // Pour les labels
|
|
#include <Fonts/FreeSansBold12pt7b.h> // Pour les unités
|
|
#include <Fonts/FreeSansBold24pt7b.h> // 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<GxEPD2_420, GxEPD2_420::HEIGHT> 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();
|
|
} |