www.safezone-fpv.com

GUI Core - ESP32-3248S035LCD + GT911

Configuration unique de Station S avec l'ecran tout-en-un Sparkle ESP32-3248S035LCD : LVGL + LovyanGFX, GT911 sur I2C partage et microSD dediee. Base de code avant les captures publiees dans gui-dashboard/gui-dashboard.php.

ESP32-3248S035LCD front
Avant 3.5" (320x480, ST7796, GT911).
ESP32-3248S035LCD back
Dos : module Sparkle XH-32S, microSD, connecteurs JST.

Resume materiel

MCUESP32 classique (Xtensa dual-core, Wi-Fi/BT) sur module Sparkle XH-32S avec antenne U.FL.
Affichage3.5" 480x320 (ST7796/ILI9488). Pilote LovyanGFX.
TouchCapacitif GT911 (I2C IO22/IO21) + IRQ.
MemoireFlash 16 MB + PSRAM 8 MB pour LVGL.
AudioSortie HP 2 pins (PWM/LEDC, bips <= 2 kHz).
StockagemicroSD SPI soudee (GeoMail offline, logs, assets).
AlimentationUSB-C (CP210x) ou VIN 5 V, LDO 3.3 V, entree LiPo JST.
I/OHeaders I2C, UART, ADC IO35, SPI expander, pads GPIO.

Connectique prioritaire

  1. I2C (3.3 V / IO22 / IO21 / GND) : GT911 + futurs capteurs/expanders.
  2. Header ADC (GND / IO35 / IO22 / IO21) : IO35 = ADC1 input-only pour l'axe X du joystick.
  3. Audio 2 pins : driver HP natif pour bips LVGL.
  4. UART header : VIN, TX, RX, GND (3.3 V) pour modem/GPS/debug.
  5. microSD SPI : stockage offline, ne pas partager les broches.
  6. U.FL 2.4 GHz : antenne Wi-Fi dediee (pas d'antenne 900 MHz/5.8 GHz).

Les anciens montages ESP32 + ecran SPI + XPT2046 sont retires : Station S tourne uniquement sur ce module (swipe GT911 + joystick IO35 en secours).

Stack firmware

Initialisation type

#include <LovyanGFX.hpp>
#include <lvgl.h>
#include "obb_touch_gt911.h"

static LGFX lcd;
static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf1[480 * 40];
static lv_color_t buf2[480 * 40];

void gui_core_init() {
  lcd.init();
  lcd.setBrightness(200);

  lv_init();
  lv_disp_draw_buf_init(&draw_buf, buf1, buf2, LV_HOR_RES_MAX * 40);

  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = 480;
  disp_drv.ver_res = 320;
  disp_drv.flush_cb = [](lv_disp_drv_t *drv, const lv_area_t *area, lv_color_t *color_p) {
    const uint32_t w = area->x2 - area->x1 + 1;
    const uint32_t h = area->y2 - area->y1 + 1;
    lcd.startWrite();
    lcd.setAddrWindow(area->x1, area->y1, w, h);
    lcd.pushPixels((lgfx::rgb565_t *)color_p, w * h);
    lcd.endWrite();
    lv_disp_flush_ready(drv);
  };
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  obb_touch_gt911_init();
  obb_touch_gt911_attach_lvgl();
}

Le joystick IO35 sera ajoute ensuite via un driver LVGL de type encoder.

Guides

Code Arduino/C++ stock© dans assets/station_s/... pour refl©ter lâarborescence firmware. Fichiers cr©©s :

assets/station_s/include/app/core/gui_core.h
assets/station_s/src/app/core/gui_core.cpp
assets/station_s/include/app/input/obb_touch_gt911.h
assets/station_s/src/app/input/obb_touch_gt911.cpp
assets/station_s/include/app/ui/obb_tiles_dashboard.h
assets/station_s/src/app/ui/tiles/obb_tiles_dashboard.cpp

Prototype 3x3 (dashboard)

On code en premier le carrousel central (tile Dashboard) avec swipes GT911 + marqueurs verts/rouges. Le detail visuel partira dans gui-dashboard/gui-dashboard.php.

  1. Grille logique : 9 tuiles (indices 0..8), centre = 4.
  2. Swipes : deplace l'index si la tuile existe sinon flash rouge.
  3. Liseres : bandes fines dessinees sur le bord actif.
  4. Joystick : fallback prevu (IO35 + SW) branche sur LVGL encoder.
static const char *kTileNames[9] = {
  "Discover","GeoMail","Tools",
  "Settings","Dashboard","Alerts",
  "Logs","Station K","Services"
};
static int8_t currentTile = 4;

static bool tile_exists(int8_t from, int8_t to, lv_dir_t dir) {
  if (to < 0 || to > 8) return false;
  if ((dir == LV_DIR_LEFT && from % 3 == 0) ||
      (dir == LV_DIR_RIGHT && from % 3 == 2)) return false;
  return true;
}

static void pulse_edge(lv_dir_t dir, lv_color_t color);
static void draw_tiles(lv_obj_t *screen);

void on_swipe(lv_dir_t dir) {
  const int8_t delta = (dir == LV_DIR_RIGHT) ? 1 :
                       (dir == LV_DIR_LEFT)  ? -1 :
                       (dir == LV_DIR_TOP)   ? -3 :
                       (dir == LV_DIR_BOTTOM)? 3  : 0;
  const int8_t next = currentTile + delta;
  if (tile_exists(currentTile, next, dir)) {
    currentTile = next;
    draw_tiles(lv_scr_act());
    pulse_edge(dir, lv_palette_main(LV_PALETTE_GREEN));
  } else {
    pulse_edge(dir, lv_palette_main(LV_PALETTE_RED));
  }
}

void obb_tile_init() {
  lv_obj_t *screen = lv_scr_act();
  lv_obj_set_style_bg_color(screen, lv_color_hex(0x0D1117), 0);
  draw_tiles(screen);
  obb_touch_set_swipe_cb(on_swipe);
}

Les helpers draw_tiles et pulse_edge sont postes dans app/ui/tiles/obb_tiles_dashboard.cpp et refleches dans la page dashboard.