espd

esp32 final Black Background 2025-04-10

Apr 10th, 2025 (edited)
26
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.40 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.   #include "BluetoothSerial.h"
  6.   #include <string>
  7.   #include <stdexcept>
  8.   using namespace std;
  9.  
  10.   //#define USE_NAME           // Comment this to use MAC address instead of a slaveName
  11.   const char *pin = "1234";
  12.  
  13.   #if !defined(CONFIG_BT_SPP_ENABLED)
  14.   #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
  15.   #endif
  16.  
  17.   BluetoothSerial SerialBT;
  18.  
  19.   #ifdef USE_NAME
  20.   String slaveName = "EMUCANBT_SPP";
  21.   #else
  22.   String MACadd = "98:DA:20:02:BE:A4";                          // This only for printing
  23.   uint8_t address[6] = { 0x98, 0xDA, 0x20, 0x02, 0xBE, 0xA4 };  // Change this to reflect real MAC address of your slave BT device
  24.   #endif
  25.  
  26.   String myName = "ESP32-BT-Master";
  27.  
  28.   const int buzzerPin = 22;
  29.  
  30.  LV_FONT_DECLARE(lv_font_montserrat_14);
  31.  
  32.   // Display & LVGL setup
  33.   TFT_eSPI tft = TFT_eSPI();
  34.   static lv_disp_draw_buf_t draw_buf;
  35.   static lv_color_t buf[LV_HOR_RES_MAX * 10];
  36.   lv_obj_t *table;
  37.  
  38.   // LVGL Display Flush Callback
  39.   void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  40.     uint16_t w = area->x2 - area->x1 + 1;
  41.     uint16_t h = area->y2 - area->y1 + 1;
  42.     tft.startWrite();
  43.     tft.setAddrWindow(area->x1, area->y1, w, h);
  44.     tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  45.     tft.endWrite();
  46.     lv_disp_flush_ready(disp);
  47.   }
  48.  
  49.   // Initialize LVGL Table
  50.   void create_table() {
  51.     table = lv_table_create(lv_scr_act());
  52.     lv_obj_align(table, LV_ALIGN_CENTER, -1, 0);
  53.  
  54.     lv_obj_set_style_text_opa(table, LV_OPA_COVER, 0);
  55.  
  56.     lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
  57.  
  58.     lv_obj_set_style_bg_color(lv_scr_act(), lv_color_make(64, 64, 64), LV_PART_MAIN);
  59.  
  60.     lv_obj_set_style_text_color(table, lv_color_white(), LV_PART_ITEMS);
  61.  
  62.     lv_obj_set_style_bg_color(table, lv_color_make(64, 64, 64), LV_PART_MAIN);
  63.  
  64.     lv_obj_set_style_text_font(table, &lv_font_montserrat_14, LV_PART_ITEMS);
  65.  
  66.     // Set table properties
  67.     lv_table_set_col_cnt(table, 4);
  68.     lv_table_set_row_cnt(table, 6);
  69.  
  70.     lv_obj_set_style_border_width(table, 1, LV_PART_ITEMS);
  71.     lv_obj_set_style_border_color(table, lv_color_white(), LV_PART_ITEMS);
  72.     lv_obj_set_style_border_side(table, LV_BORDER_SIDE_FULL, LV_PART_ITEMS);
  73.  
  74.     lv_table_set_col_width(table, 0, 60);
  75.     lv_table_set_col_width(table, 1, 100);
  76.     lv_table_set_col_width(table, 2, 60);
  77.     lv_table_set_col_width(table, 3, 100);
  78.  
  79.     lv_table_add_cell_ctrl(table, 5, 1, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
  80.     lv_table_add_cell_ctrl(table, 5, 2, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
  81.     lv_table_add_cell_ctrl(table, 5, 3, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
  82.  
  83.     lv_table_set_cell_value(table, 0, 0, "RPM");
  84.     lv_table_set_cell_value(table, 0, 2, "SPD");
  85.     lv_table_set_cell_value(table, 1, 0, "AFR");
  86.     lv_table_set_cell_value(table, 1, 2, "CLT");
  87.     lv_table_set_cell_value(table, 2, 0, "TPS");
  88.     lv_table_set_cell_value(table, 2, 2, "BAT");
  89.     lv_table_set_cell_value(table, 3, 0, "MAP");
  90.     lv_table_set_cell_value(table, 3, 2, "BST");
  91.     lv_table_set_cell_value(table, 4, 0, "INJ");
  92.     lv_table_set_cell_value(table, 4, 2, "IGN");
  93.     lv_table_set_cell_value(table, 5, 0, "CEL");
  94.  
  95.     lv_obj_add_event_cb(table, my_table_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
  96.  
  97.     lv_obj_add_event_cb(table, table_event_cb_bg, LV_EVENT_DRAW_PART_BEGIN, NULL);
  98.  
  99.     lv_timer_handler();
  100.   }
  101.  
  102.   void setup() {
  103.     Serial.begin(1000000);
  104.  
  105.     pinMode(buzzerPin, OUTPUT);
  106.  
  107.     tft.begin();
  108.     tft.setRotation(1);
  109.  
  110.     // Initialize LVGL
  111.     lv_init();
  112.     lv_refr_now(NULL);
  113.     lv_disp_draw_buf_init(&draw_buf, buf, NULL, LV_HOR_RES_MAX * 10);
  114.  
  115.     // Setup LVGL Display Driver
  116.     static lv_disp_drv_t disp_drv;
  117.     lv_disp_drv_init(&disp_drv);
  118.     disp_drv.hor_res = 320;
  119.     disp_drv.ver_res = 240;
  120.     disp_drv.flush_cb = my_disp_flush;
  121.     disp_drv.draw_buf = &draw_buf;
  122.     lv_disp_drv_register(&disp_drv);
  123.  
  124.     create_table();
  125.     connectToBt();
  126.   }
  127.  
  128.   void connectToBt() {
  129.     bool connected;
  130.     SerialBT.begin(myName, true);
  131.  
  132.   #ifndef USE_NAME
  133.     SerialBT.setPin(pin);
  134.   #endif
  135.  
  136.   #ifdef USE_NAME
  137.     connected = SerialBT.connect(slaveName);
  138.   #else
  139.     connected = SerialBT.connect(address);
  140.   #endif
  141.  
  142.     if (connected) {
  143.       Serial.println("Connected Successfully!");
  144.     } else {
  145.       Serial.println("Initial connect failed. Will retry in loop...");
  146.     }
  147.   }
  148.  
  149.   int rpm;
  150.   int spd;
  151.   float afr;
  152.   float mapR;
  153.   float boost;
  154.   int tps;
  155.   int clt;
  156.   int ign;
  157.   int inj;
  158.   float bat;
  159.   int cel;
  160.  
  161.   unsigned long lastReconnectAttempt = 0;
  162.   const unsigned long reconnectInterval = 5000;  // 5 seconds
  163.  
  164.   void loop() {
  165.     uint8_t frame[5];
  166.     uint8_t channel;
  167.     uint16_t value;
  168.     int chData;
  169.  
  170.     if (!SerialBT.connected()) {
  171.       // Attempt reconnection every few seconds
  172.       if (millis() - lastReconnectAttempt > reconnectInterval) {
  173.         lastReconnectAttempt = millis();
  174.         connectToBt();
  175.       }
  176.     }
  177.  
  178.     // Wait until at least 5 bytes are available
  179.     while (SerialBT.available() >= 5) {
  180.       SerialBT.readBytes(frame, 5);  // Read exactly 5 bytes
  181.  
  182.       // Extract values
  183.       channel = frame[0];
  184.       value = (frame[2] << 8) | frame[3];  // Combine High and Low byte
  185.  
  186.       chData = static_cast<int>(channel);
  187.       if (chData == 1) {
  188.         rpm = static_cast<int>(value);
  189.         // Serial.println("RPM: " + String(rpm));
  190.         lv_table_set_cell_value(table, 0, 1, String(rpm).c_str());
  191.       } else if (chData == 28) {
  192.         spd = (static_cast<int>(value) / 2.8);
  193.         //Serial.println("SPD: " + String(spd) + " KM/H");
  194.         lv_table_set_cell_value(table, 0, 3, (String(spd) + " KM/H").c_str());
  195.       } else if (chData == 12) {
  196.         afr = (static_cast<float>(value) / 10);
  197.         //Serial.println("AFR: " + String(afr));
  198.         lv_table_set_cell_value(table, 1, 1, String(afr).c_str());
  199.       } else if (chData == 2) {
  200.         mapR = (static_cast<float>(value) / 100);
  201.         boost = (mapR - 1.0132f);
  202.         //Serial.println("MAP: " + String(mapR) + " BAR");
  203.         // Serial.println("BST: " + String(boost) + " BAR");
  204.         lv_table_set_cell_value(table, 3, 1, (String(mapR) + " BAR").c_str());
  205.         lv_table_set_cell_value(table, 3, 3, (String(boost) + " BAR").c_str());
  206.       } else if (chData == 3) {
  207.         tps = static_cast<int>(value);
  208.         //Serial.println("TPS: " + String(tps) + " %");
  209.         lv_table_set_cell_value(table, 2, 1, (String(tps) + " %").c_str());
  210.       } else if (chData == 24) {
  211.         clt = static_cast<int>(value);
  212.         //Serial.println("CLT: " + String(clt) + " °C");
  213.         lv_table_set_cell_value(table, 1, 3, (String(clt) + " °C").c_str());
  214.       } else if (chData == 6) {
  215.         ign = static_cast<int>(value);
  216.         //Serial.println("IGN: " + String(ign) + " °");
  217.         lv_table_set_cell_value(table, 4, 3, (String(ign) + " °").c_str());
  218.       } else if (chData == 19) {
  219.         inj =  static_cast<int>(value);
  220.         //Serial.println("INJ: " + String(inj) + " %");
  221.         lv_table_set_cell_value(table, 4, 1, (String(inj) + " %").c_str());
  222.       } else if (chData == 5) {
  223.         bat = (static_cast<float>(value) / 37);
  224.         //Serial.println("BAT: " + String(bat) + " V");
  225.         lv_table_set_cell_value(table, 2, 3, (String(bat) + " V").c_str());
  226.       } else if (chData == 255) {
  227.         cel = decodeCheckEngine(value);
  228.         //Serial.println("CEL: " + String(cel));
  229.       }
  230.     }
  231.  
  232.     if (cel > 0 || clt > 105 || rpm > 7200 || boost > 1.10 || (bat < 12.00 && bat > 1.00)) {
  233.       digitalWrite(buzzerPin, HIGH);  // Buzzer ON
  234.     } else {
  235.       digitalWrite(buzzerPin, LOW);   // Buzzer OFF
  236.     }
  237.  
  238.     lv_obj_invalidate(table);
  239.     lv_timer_handler();
  240.     // Run LVGL
  241.     //delay(10);
  242.   }
  243.  
  244.   int decodeCheckEngine(uint16_t value) {
  245.     int cel_codes = 0; string cel_names = "";
  246.     if (value == 0) {
  247.       return 0;
  248.     }
  249.     else {
  250.       //Serial.print("CEL Codes: ");
  251.       if (value & (1 << 0)) {
  252.         cel_codes++;  // Bit 0
  253.         //Serial.print("CLT ");
  254.         cel_names = "CLT ";
  255.       }
  256.       if (value & (1 << 1)) {
  257.         //  cel_codes++;  // Bit 1
  258.         //  Serial.print("IAT ");
  259.         //   cel_names += "IAT ";
  260.       }
  261.       if (value & (1 << 2)) {
  262.         cel_codes++;  // Bit 2
  263.         //Serial.print("MAP ");
  264.         cel_names += "MAP ";
  265.       }
  266.       if (value & (1 << 3)) {
  267.         cel_codes++;  // Bit 3
  268.         //Serial.print("WBO ");
  269.         cel_names += "WBO ";
  270.       }
  271.       if (value & (1 << 8)) {
  272.         cel_codes++;  // Bit 8
  273.         //Serial.print("FF SENSOR ");
  274.         cel_names += "FF SENSOR ";
  275.       }
  276.       if (value & (1 << 9)) {
  277.         cel_codes++;  // Bit 9
  278.         //Serial.print("DBW ");
  279.         cel_names += "DBW ";
  280.       }
  281.       if (value & (1 << 10)) {
  282.         cel_codes++;  // Bit 10
  283.         //Serial.print("FPR ");
  284.         cel_names += "FPR ";
  285.       }
  286.       //Serial.print("Total CEL Codes: " + cel_codes);
  287.       //Serial.println();
  288.  
  289.       lv_table_set_cell_value(table, 5, 1, cel_names.c_str());
  290.       return cel_codes;
  291.     }
  292.   }
  293.  
  294.   // Custom draw callback for right-aligned text in specific cells
  295.   void my_table_event_cb(lv_event_t * e) {
  296.     lv_obj_t * table = lv_event_get_target(e);
  297.     lv_obj_draw_part_dsc_t * dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_param(e);
  298.  
  299.     if (dsc->part == LV_PART_ITEMS) {
  300.       uint16_t row = dsc->id / lv_table_get_col_cnt(table);
  301.       uint16_t col = dsc->id % lv_table_get_col_cnt(table);
  302.  
  303.       // Default Left Align
  304.       dsc->label_dsc->align = LV_TEXT_ALIGN_LEFT;
  305.  
  306.       // Right-align specific cells
  307.       if ((row == 0 && col == 1) || (row == 0 && col == 3) || (row == 1 && col == 1) || (row == 1 && col == 3) || (row == 2 && col == 1) || (row == 2 && col == 3) || (row == 3 && col == 1) || (row == 3 && col == 3) ||
  308.           (row == 4 && col == 1) || (row == 4 && col == 3)) {
  309.         dsc->label_dsc->align = LV_TEXT_ALIGN_RIGHT;
  310.       }
  311.       if (row == 5 && col == 1) {
  312.         dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER;
  313.       }
  314.     }
  315.   }
  316.  
  317.   static void table_event_cb_bg(lv_event_t *e) {
  318.     lv_obj_t *table = lv_event_get_target(e);
  319.     lv_obj_draw_part_dsc_t *dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_param(e);
  320.  
  321.     // Ensure dsc and rect_dsc are valid
  322.     if (!dsc || !dsc->rect_dsc) return;
  323.  
  324.     // Only modify table cell backgrounds
  325.     if (dsc->part == LV_PART_ITEMS) {
  326.       uint16_t row = dsc->id / lv_table_get_col_cnt(table);
  327.       uint16_t col = dsc->id % lv_table_get_col_cnt(table);
  328.  
  329.       const char *value_str = lv_table_get_cell_value(table, row, col);
  330.  
  331.       // Check if value_str is null or empty before conversion
  332.       float value = 0.0f;  // Default value
  333.       if (value_str != nullptr && value_str[0] != '\0') {
  334.         try {
  335.           value = std::stof(value_str);  // Convert string to float safely
  336.         } catch (...) {
  337.           value = 0.0f;  // Handle invalid conversions
  338.         }
  339.       }
  340.  
  341.       // Default cell color
  342.       lv_color_t bg_color = lv_color_make(64, 64, 64);
  343.       lv_color_t text_color = lv_color_white();
  344.  
  345.       if (row == 0 && col == 1 && value > 7200.00) {
  346.         bg_color = lv_color_make(0, 255, 0);
  347.         text_color = lv_color_white();
  348.       }
  349.       if (row == 1 && col == 3 && value > 100.00) {
  350.         bg_color = lv_color_make(0, 255, 0);
  351.         text_color = lv_color_white();
  352.       }
  353.       if (row == 1 && col == 3 && value < 55.00 && value > 01.00) {
  354.         bg_color = lv_color_make(0, 255, 255);
  355.         text_color = lv_color_black();
  356.       }
  357.       if (row == 2 && col == 3 && value < 12.00 && value > 01.00) {
  358.         bg_color = lv_color_make(0, 255, 0);
  359.         text_color = lv_color_white();
  360.       }
  361.       if (row == 3 && col == 3 && value > 1.10) {
  362.         bg_color = lv_color_make(0, 255, 0);
  363.         text_color = lv_color_white();
  364.       }
  365.       if (row == 5 && col == 1 && value_str != nullptr && value_str[0] != '\0') {
  366.         bg_color = lv_color_make(0, 255, 0);
  367.         text_color = lv_color_white();
  368.       }
  369.  
  370.       // Apply background color to the cell
  371.       dsc->rect_dsc->bg_color = bg_color;
  372.       dsc->rect_dsc->bg_opa = LV_OPA_COVER; // Ensure background is visible
  373.       dsc->label_dsc->color = text_color;
  374.     }
  375.   }
Advertisement
Add Comment
Please, Sign In to add comment