espd

ESP32_EMU_BT_V.3.02 - TRY

May 20th, 2025 (edited)
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.55 KB | None | 0 0
  1. #include <Arduino.h>
  2. #define LV_COLOR_16_SWAP 0
  3. #include <lvgl.h>
  4. #include <TFT_eSPI.h>
  5.  
  6. TFT_eSPI tft = TFT_eSPI();
  7. static lv_disp_draw_buf_t draw_buf;
  8. static lv_color_t buf[LV_HOR_RES_MAX * 10];
  9.  
  10. #define NUM_TABS 3
  11. #define NUM_GAUGES 6
  12.  
  13. LV_FONT_DECLARE(lv_font_montserrat_14);
  14. LV_FONT_DECLARE(lv_font_montserrat_28);
  15.  
  16. void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  17.   uint16_t w = area->x2 - area->x1 + 1;
  18.   uint16_t h = area->y2 - area->y1 + 1;
  19.   tft.startWrite();
  20.   tft.setAddrWindow(area->x1, area->y1, w, h);
  21.   tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  22.   tft.endWrite();
  23.   lv_disp_flush_ready(disp);
  24. }
  25.  
  26. typedef struct {
  27.   lv_obj_t *label;
  28.   lv_obj_t *widget;
  29. } gauge_t;
  30.  
  31. gauge_t gauges[NUM_TABS][NUM_GAUGES];
  32.  
  33. const char *gauge_titles[NUM_TABS][NUM_GAUGES] = {
  34.   {"RPM", "Speed", "AFR", "CLT", "TPS", "Battery"},
  35.   {"Oil Temp", "Oil Press", "Boost", "IAT", "Load", "MAP"},
  36.   {"Gear", "Lambda", "Ign Adv", "Fuel Trim", "Duty", "Knock"}
  37. };
  38.  
  39. typedef enum {
  40.   GAUGE_ARC,
  41.   GAUGE_BAR,
  42.   GAUGE_LABEL
  43. } gauge_type_t;
  44.  
  45. gauge_type_t gauge_types[NUM_TABS][NUM_GAUGES] = {
  46.   {GAUGE_ARC, GAUGE_ARC, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR},
  47.   {GAUGE_BAR, GAUGE_BAR, GAUGE_ARC, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR},
  48.   {GAUGE_LABEL, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR, GAUGE_BAR}
  49. };
  50.  
  51. lv_obj_t *create_gauge(lv_obj_t *parent, const char *title, gauge_type_t type, gauge_t *g);
  52.  
  53. lv_obj_t *create_gauge(lv_obj_t *parent, const char *title, gauge_type_t type, gauge_t *g) {
  54.   lv_obj_t *cont = lv_obj_create(parent);
  55.   lv_obj_set_style_bg_color(cont, lv_color_black(), 0);
  56.   lv_obj_set_style_radius(cont, 8, 0);
  57.   lv_obj_set_style_pad_all(cont, 6, 0);
  58.   lv_obj_set_style_border_width(cont, 0, 0);
  59.  
  60.   lv_obj_set_size(cont, lv_pct(45), lv_pct(30));  // 2x3 layout
  61.  
  62.   lv_obj_t *label = lv_label_create(cont);
  63.   lv_label_set_text(label, title);
  64.   lv_obj_set_style_text_color(label, lv_color_white(), 0);
  65.   lv_obj_align(label, LV_ALIGN_TOP_MID, 0, 0);
  66.  
  67.   lv_obj_t *widget = NULL;
  68.  
  69.   switch (type) {
  70.     case GAUGE_ARC:
  71.       widget = lv_arc_create(cont);
  72.       lv_arc_set_range(widget, 0, 8000); // e.g., RPM
  73.       lv_arc_set_value(widget, 0);
  74.       lv_obj_set_size(widget, 60, 60);
  75.       lv_obj_align(widget, LV_ALIGN_CENTER, 0, 10);
  76.       lv_arc_set_bg_angles(widget, 135, 45);
  77.       lv_arc_set_rotation(widget, 270);
  78.       break;
  79.  
  80.     case GAUGE_BAR:
  81.       widget = lv_bar_create(cont);
  82.       lv_bar_set_range(widget, 0, 100);
  83.       lv_bar_set_value(widget, 0, LV_ANIM_OFF);
  84.       lv_obj_set_size(widget, lv_pct(80), 10);
  85.       lv_obj_align(widget, LV_ALIGN_CENTER, 0, 10);
  86.       break;
  87.  
  88.     case GAUGE_LABEL:
  89.       widget = lv_label_create(cont);
  90.       lv_label_set_text(widget, "--");
  91.       lv_obj_set_style_text_color(widget, lv_color_white(), 0);
  92.       lv_obj_align(widget, LV_ALIGN_CENTER, 0, 10);
  93.       break;
  94.   }
  95.  
  96.   g->label = label;
  97.   g->widget = widget;
  98.  
  99.   return cont;
  100. }
  101.  
  102. void create_ui() {
  103.   lv_obj_t *tabview = lv_tabview_create(lv_scr_act(), LV_DIR_TOP, 30);
  104.   lv_obj_set_style_bg_color(tabview, lv_color_black(), 0);
  105.  
  106.   for (int t = 0; t < NUM_TABS; t++) {
  107.     lv_obj_t *tab = lv_tabview_add_tab(tabview, ("Tab " + String(t + 1)).c_str());
  108.     lv_obj_set_style_bg_color(tab, lv_color_black(), 0);
  109.  
  110.     lv_obj_t *grid = lv_obj_create(tab);
  111.     lv_obj_set_size(grid, lv_pct(100), lv_pct(100));
  112.     lv_obj_center(grid);
  113.     lv_obj_set_layout(grid, LV_LAYOUT_FLEX);
  114.     lv_obj_set_flex_flow(grid, LV_FLEX_FLOW_ROW_WRAP);
  115.     lv_obj_set_style_pad_row(grid, 6, 0);
  116.     lv_obj_set_style_pad_column(grid, 6, 0);
  117.     lv_obj_set_scrollbar_mode(grid, LV_SCROLLBAR_MODE_OFF);
  118.     lv_obj_set_style_bg_color(grid, lv_color_black(), 0);
  119.     lv_obj_set_style_border_width(grid, 0, 0);
  120.  
  121.     for (int g = 0; g < NUM_GAUGES; g++) {
  122.       create_gauge(grid, gauge_titles[t][g], gauge_types[t][g], &gauges[t][g]);
  123.     }
  124.   }
  125. }
  126.  
  127. void update_gauges() {
  128.   static int rpm = 0;
  129.   rpm = (rpm + 200) % 8000;
  130.  
  131.   char buf[16];
  132.  
  133.   // Tab 0, RPM
  134.   lv_arc_set_value(gauges[0][0].widget, rpm);
  135.   snprintf(buf, sizeof(buf), "%d", rpm);
  136.   lv_label_set_text(gauges[0][0].label, buf);
  137.  
  138.   // Tab 0, Speed
  139.   int speed = (rpm / 30) % 240;
  140.   lv_arc_set_value(gauges[0][1].widget, speed);
  141.   snprintf(buf, sizeof(buf), "%d", speed);
  142.   lv_label_set_text(gauges[0][1].label, buf);
  143.  
  144.   // Tab 0, AFR
  145.   float afr = 14.0 + (rpm % 30) / 10.0;
  146.   lv_bar_set_value(gauges[0][2].widget, afr, LV_ANIM_OFF);
  147.   snprintf(buf, sizeof(buf), "%.1f", afr);
  148.   lv_label_set_text(gauges[0][2].label, buf);
  149.  
  150.   // Tab 2, Gear
  151.   int gear = 1 + ((rpm / 1000) % 6);
  152.   snprintf(buf, sizeof(buf), "G%d", gear);
  153.   lv_label_set_text(gauges[2][0].widget, buf);
  154. }
  155.  
  156. unsigned long last_update = 0;
  157.  
  158. void setup() {
  159.   tft.init();
  160.   uint16_t darkGray = ((30 & 0xF8) << 8) | ((30 & 0xFC) << 3) | (30 >> 3);
  161.   tft.fillScreen(darkGray);
  162.   tft.setRotation(1);
  163.   Serial.begin(1000000);
  164.  
  165.   // Initialize LVGL
  166.   lv_init();
  167.   lv_refr_now(NULL);
  168.   lv_disp_draw_buf_init(&draw_buf, buf, NULL, LV_HOR_RES_MAX * 10);
  169.  
  170.   // Setup LVGL Display Driver
  171.   static lv_disp_drv_t disp_drv;
  172.   lv_disp_drv_init(&disp_drv);
  173.   disp_drv.hor_res = 320;
  174.   disp_drv.ver_res = 240;
  175.   disp_drv.flush_cb = my_disp_flush;
  176.   disp_drv.draw_buf = &draw_buf;
  177.   lv_disp_drv_register(&disp_drv);
  178.  
  179.   create_ui();
  180. }
  181.  
  182. void loop() {
  183.   lv_timer_handler();  // Must call often
  184.   delay(5);            // Avoid watchdog
  185.  
  186.   unsigned long now = millis();
  187.   if (now - last_update > 200) {  // update every 200 ms
  188.     last_update = now;
  189.     update_gauges();
  190.   }
  191. }
  192.  
Advertisement
Add Comment
Please, Sign In to add comment