#include <lvgl.h>
#include <TFT_eSPI.h>
#include <DHT.h>
// Configuration DHT22
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Configuration TFT
TFT_eSPI tft = TFT_eSPI();
// LVGL buffers
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[320 * 10];
// Variables globales
float temperature = 0;
float humidity = 0;
unsigned long previousMillis = 0;
const long interval = 2000;
// Labels LVGL
lv_obj_t *labelTemp;
lv_obj_t *labelHum;
lv_obj_t *labelTime;
// Callback pour le flush display LVGL
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
tft.startWrite();
tft.setAddrWindow(area->x1, area->y1, w, h);
tft.pushColors((uint16_t *)&color_p->full, w * h, true);
tft.endWrite();
lv_disp_flush_ready(disp);
}
// Fonction pour créer une carte
lv_obj_t* createCard(int x, int y, int w, int h) {
lv_obj_t *card = lv_obj_create(lv_scr_act());
lv_obj_set_size(card, w, h);
lv_obj_set_pos(card, x, y);
lv_obj_set_style_bg_color(card, lv_color_hex(0x1A3A5C), 0);
lv_obj_set_style_radius(card, 12, 0);
lv_obj_set_style_border_width(card, 0, 0);
lv_obj_set_style_shadow_width(card, 8, 0);
lv_obj_set_style_shadow_opa(card, LV_OPA_30, 0);
return card;
}
// Création du dashboard simplifié
void createDashboard() {
lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex(0x0A1E3D), 0);
// === EN-TÊTE ===
lv_obj_t *header = lv_label_create(lv_scr_act());
lv_label_set_text(header, LV_SYMBOL_HOME " Aquabouns");
lv_obj_set_style_text_color(header, lv_color_hex(0x5BC0DE), 0);
lv_obj_set_style_text_font(header, &lv_font_montserrat_16, 0);
lv_obj_set_pos(header, 10, 5);
labelTime = lv_label_create(lv_scr_act());
lv_label_set_text(labelTime, "10h31");
lv_obj_set_style_text_color(labelTime, lv_color_white(), 0);
lv_obj_align(labelTime, LV_ALIGN_TOP_RIGHT, -10, 5);
// === CARTE TEMPÉRATURE ET HUMIDITÉ (centrée et agrandie) ===
lv_obj_t *cardTemp = createCard(10, 40, 300, 160);
// Titre
lv_obj_t *titleTemp = lv_label_create(cardTemp);
lv_label_set_text(titleTemp, "Climat Aquarium");
lv_obj_set_style_text_color(titleTemp, lv_color_hex(0x5BC0DE), 0);
lv_obj_set_style_text_font(titleTemp, &lv_font_montserrat_16, 0);
lv_obj_align(titleTemp, LV_ALIGN_TOP_MID, 0, 10);
// Icône thermomètre
lv_obj_t *iconTemp = lv_label_create(cardTemp);
lv_label_set_text(iconTemp, LV_SYMBOL_WARNING);
lv_obj_set_style_text_color(iconTemp, lv_color_hex(0xFF6B6B), 0);
lv_obj_set_style_text_font(iconTemp, &lv_font_montserrat_20, 0);
lv_obj_set_pos(iconTemp, 20, 45);
// Label température
lv_obj_t *labelTempTitle = lv_label_create(cardTemp);
lv_label_set_text(labelTempTitle, "Temperature");
lv_obj_set_style_text_color(labelTempTitle, lv_color_white(), 0);
lv_obj_set_pos(labelTempTitle, 55, 45);
labelTemp = lv_label_create(cardTemp);
lv_label_set_text(labelTemp, "--.-°C");
lv_obj_set_style_text_color(labelTemp, lv_color_hex(0xFF6B6B), 0);
lv_obj_set_style_text_font(labelTemp, &lv_font_montserrat_20, 0);
lv_obj_set_pos(labelTemp, 200, 45);
// Ligne de séparation
lv_obj_t *line = lv_obj_create(cardTemp);
lv_obj_set_size(line, 260, 2);
lv_obj_set_pos(line, 20, 80);
lv_obj_set_style_bg_color(line, lv_color_hex(0x2A4A6C), 0);
lv_obj_set_style_border_width(line, 0, 0);
// Icône goutte d'eau
lv_obj_t *iconHum = lv_label_create(cardTemp);
lv_label_set_text(iconHum, LV_SYMBOL_LOOP);
lv_obj_set_style_text_color(iconHum, lv_color_hex(0x4ECDC4), 0);
lv_obj_set_style_text_font(iconHum, &lv_font_montserrat_20, 0);
lv_obj_set_pos(iconHum, 20, 100);
// Label humidité
lv_obj_t *labelHumTitle = lv_label_create(cardTemp);
lv_label_set_text(labelHumTitle, "Humidite");
lv_obj_set_style_text_color(labelHumTitle, lv_color_white(), 0);
lv_obj_set_pos(labelHumTitle, 55, 100);
labelHum = lv_label_create(cardTemp);
lv_label_set_text(labelHum, "--%");
lv_obj_set_style_text_color(labelHum, lv_color_hex(0x4ECDC4), 0);
lv_obj_set_style_text_font(labelHum, &lv_font_montserrat_20, 0);
lv_obj_set_pos(labelHum, 220, 100);
}
void setup() {
Serial.begin(115200);
Serial.println("Demarrage Aquabouns...");
// Initialiser DHT22
dht.begin();
// Initialiser TFT en PREMIER (avant LVGL)
tft.begin();
tft.setRotation(1); // Mode paysage (320x240)
tft.fillScreen(TFT_BLACK);
Serial.println("TFT initialise");
// Initialiser LVGL APRES TFT
lv_init();
// Configurer le buffer LVGL
lv_disp_draw_buf_init(&draw_buf, buf, NULL, 320 * 10);
// Configurer le driver d'affichage
static lv_disp_drv_t disp_drv;
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = 320;
disp_drv.ver_res = 240;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
Serial.println("LVGL initialise");
// Créer le dashboard
createDashboard();
Serial.println("Dashboard cree");
// Première lecture immédiate du DHT22
delay(500);
float h = dht.readHumidity();
float t = dht.readTemperature();
if (!isnan(h) && !isnan(t)) {
temperature = t;
humidity = h;
// Créer les chaînes de caractères
char tempStr[16];
char humStr[16];
snprintf(tempStr, sizeof(tempStr), "%.1f°C", t);
snprintf(humStr, sizeof(humStr), "%.0f%%", h);
lv_label_set_text(labelTemp, tempStr);
lv_label_set_text(labelHum, humStr);
Serial.printf("Lecture initiale - Temp: %.1f°C, Humidite: %.1f%%\n", t, h);
}
}
void loop() {
lv_timer_handler();
delay(5);
// Mise à jour des capteurs toutes les 2 secondes
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
float h = dht.readHumidity();
float t = dht.readTemperature();
if (!isnan(h) && !isnan(t)) {
temperature = t;
humidity = h;
// Créer les chaînes de caractères
char tempStr[16];
char humStr[16];
snprintf(tempStr, sizeof(tempStr), "%.1f°C", t);
snprintf(humStr, sizeof(humStr), "%.0f%%", h);
lv_label_set_text(labelTemp, tempStr);
lv_label_set_text(labelHum, humStr);
Serial.printf("Temp: %.1f°C, Humidite: %.1f%%\n", t, h);
} else {
Serial.println("Erreur lecture DHT22");
}
// Mise à jour de l'heure (simulation)
int hours = (millis() / 3600000) % 24 + 10;
int mins = (millis() / 60000) % 60;
char timeStr[16];
snprintf(timeStr, sizeof(timeStr), "%02dh%02d", hours, mins);
lv_label_set_text(labelTime, timeStr);
}
}Loading
ili9341-cap-touch
ili9341-cap-touch