Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Arduino.h>
- #include <lvgl.h>
- #include <TFT_eSPI.h>
- #include "BluetoothSerial.h"
- #include <string>
- #include <stdexcept>
- using namespace std;
- //#define USE_NAME // Comment this to use MAC address instead of a slaveName
- const char *pin = "1234";
- #if !defined(CONFIG_BT_SPP_ENABLED)
- #error Serial Bluetooth not available or not enabled. It is only available for the ESP32 chip.
- #endif
- BluetoothSerial SerialBT;
- #ifdef USE_NAME
- String slaveName = "EMUCANBT_SPP";
- #else
- String MACadd = "XX:XX:XX:XX:XX:XX"; // This only for printing
- uint8_t address[6] = { 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX }; // Change this to reflect real MAC address of your slave BT device
- #endif
- String myName = "ESP32-BT-Master";
- const int buzzerPin = 22;
- // Display & LVGL setup
- TFT_eSPI tft = TFT_eSPI();
- static lv_disp_draw_buf_t draw_buf;
- static lv_color_t buf[LV_HOR_RES_MAX * 10];
- lv_obj_t *table;
- // LVGL Display Flush Callback
- void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
- uint16_t w = area->x2 - area->x1 + 1;
- uint16_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);
- }
- // Initialize LVGL Table
- void create_table() {
- table = lv_table_create(lv_scr_act());
- lv_obj_align(table, LV_ALIGN_CENTER, 0, 0);
- lv_obj_clear_flag(lv_scr_act(), LV_OBJ_FLAG_SCROLLABLE);
- lv_obj_set_style_bg_color(lv_scr_act(), lv_color_make(255, 255, 255), LV_PART_MAIN);
- lv_obj_set_style_text_color(table, lv_color_black(), LV_PART_ITEMS);
- lv_obj_set_style_bg_color(table, lv_color_white(), LV_PART_MAIN);
- // Set table properties
- lv_table_set_col_cnt(table, 4);
- lv_table_set_row_cnt(table, 6);
- lv_obj_set_style_border_width(table, 1, LV_PART_ITEMS);
- lv_obj_set_style_border_color(table, lv_color_make(64, 64, 64), LV_PART_ITEMS);
- lv_obj_set_style_border_side(table, LV_BORDER_SIDE_FULL, LV_PART_ITEMS);
- lv_table_set_col_width(table, 0, 60);
- lv_table_set_col_width(table, 1, 100);
- lv_table_set_col_width(table, 2, 60);
- lv_table_set_col_width(table, 3, 100);
- lv_table_add_cell_ctrl(table, 5, 1, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
- lv_table_add_cell_ctrl(table, 5, 2, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
- lv_table_add_cell_ctrl(table, 5, 3, LV_TABLE_CELL_CTRL_MERGE_RIGHT);
- lv_table_set_cell_value(table, 0, 0, "RPM");
- lv_table_set_cell_value(table, 0, 2, "SPD");
- lv_table_set_cell_value(table, 1, 0, "AFR");
- lv_table_set_cell_value(table, 1, 2, "CLT");
- lv_table_set_cell_value(table, 2, 0, "TPS");
- lv_table_set_cell_value(table, 2, 2, "BAT");
- lv_table_set_cell_value(table, 3, 0, "MAP");
- lv_table_set_cell_value(table, 3, 2, "BST");
- lv_table_set_cell_value(table, 4, 0, "INJ");
- lv_table_set_cell_value(table, 4, 2, "IGN");
- lv_table_set_cell_value(table, 5, 0, "CEL");
- lv_obj_add_event_cb(table, my_table_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
- lv_obj_add_event_cb(table, table_event_cb_bg, LV_EVENT_DRAW_PART_BEGIN, NULL);
- lv_timer_handler();
- }
- void setup() {
- Serial.begin(1000000);
- pinMode(buzzerPin, OUTPUT);
- tft.begin();
- tft.setRotation(1);
- // Initialize LVGL
- lv_init();
- lv_refr_now(NULL);
- lv_disp_draw_buf_init(&draw_buf, buf, NULL, LV_HOR_RES_MAX * 10);
- // Setup LVGL Display Driver
- 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);
- create_table();
- connectToBt();
- }
- void connectToBt() {
- bool connected;
- SerialBT.begin(myName, true);
- #ifndef USE_NAME
- SerialBT.setPin(pin);
- #endif
- #ifdef USE_NAME
- connected = SerialBT.connect(slaveName);
- #else
- connected = SerialBT.connect(address);
- #endif
- if (connected) {
- Serial.println("Connected Successfully!");
- } else {
- Serial.println("Initial connect failed. Will retry in loop...");
- }
- }
- int rpm;
- int spd;
- float afr;
- float mapR;
- float boost;
- int tps;
- int clt;
- int ign;
- int inj;
- float bat;
- int cel;
- unsigned long lastReconnectAttempt = 0;
- const unsigned long reconnectInterval = 5000; // 5 seconds
- void loop() {
- uint8_t frame[5];
- uint8_t channel;
- uint16_t value;
- int chData;
- if (!SerialBT.connected()) {
- // Attempt reconnection every few seconds
- if (millis() - lastReconnectAttempt > reconnectInterval) {
- lastReconnectAttempt = millis();
- connectToBt();
- }
- }
- // Wait until at least 5 bytes are available
- while (SerialBT.available() >= 5) {
- SerialBT.readBytes(frame, 5); // Read exactly 5 bytes
- // Extract values
- channel = frame[0];
- value = (frame[2] << 8) | frame[3]; // Combine High and Low byte
- chData = static_cast<int>(channel);
- if (chData == 1) {
- rpm = static_cast<int>(value);
- // Serial.println("RPM: " + String(rpm));
- lv_table_set_cell_value(table, 0, 1, String(rpm).c_str());
- } else if (chData == 28) {
- spd = (static_cast<int>(value) / 2.8);
- //Serial.println("SPD: " + String(spd) + " KM/H");
- lv_table_set_cell_value(table, 0, 3, (String(spd) + " KM/H").c_str());
- } else if (chData == 12) {
- afr = (static_cast<float>(value) / 10);
- //Serial.println("AFR: " + String(afr));
- lv_table_set_cell_value(table, 1, 1, String(afr).c_str());
- } else if (chData == 2) {
- mapR = (static_cast<float>(value) / 100);
- boost = (mapR - 1.0132f);
- //Serial.println("MAP: " + String(mapR) + " BAR");
- // Serial.println("BST: " + String(boost) + " BAR");
- lv_table_set_cell_value(table, 3, 1, (String(mapR) + " BAR").c_str());
- lv_table_set_cell_value(table, 3, 3, (String(boost) + " BAR").c_str());
- } else if (chData == 3) {
- tps = static_cast<int>(value);
- //Serial.println("TPS: " + String(tps) + " %");
- lv_table_set_cell_value(table, 2, 1, (String(tps) + " %").c_str());
- } else if (chData == 24) {
- clt = static_cast<int>(value);
- //Serial.println("CLT: " + String(clt) + " °C");
- lv_table_set_cell_value(table, 1, 3, (String(clt) + " °C").c_str());
- } else if (chData == 6) {
- ign = static_cast<int>(value);
- //Serial.println("IGN: " + String(ign) + " °");
- lv_table_set_cell_value(table, 4, 3, (String(ign) + " °").c_str());
- } else if (chData == 19) {
- inj = static_cast<int>(value);
- //Serial.println("INJ: " + String(inj) + " %");
- lv_table_set_cell_value(table, 4, 1, (String(inj) + " %").c_str());
- } else if (chData == 5) {
- bat = (static_cast<float>(value) / 37);
- //Serial.println("BAT: " + String(bat) + " V");
- lv_table_set_cell_value(table, 2, 3, (String(bat) + " V").c_str());
- } else if (chData == 255) {
- cel = decodeCheckEngine(value);
- //Serial.println("CEL: " + String(cel));
- }
- }
- if (cel > 0 || clt > 105 || rpm > 7200 || boost > 1.10 || (bat < 12.00 && bat > 1.00)) {
- digitalWrite(buzzerPin, HIGH); // Buzzer ON
- } else {
- digitalWrite(buzzerPin, LOW); // Buzzer OFF
- }
- lv_obj_invalidate(table);
- lv_timer_handler();
- // Run LVGL
- //delay(10);
- }
- int decodeCheckEngine(uint16_t value) {
- int cel_codes = 0; string cel_names = "";
- if (value == 0) {
- return 0;
- }
- else {
- //Serial.print("CEL Codes: ");
- if (value & (1 << 0)) {
- cel_codes++; // Bit 0
- //Serial.print("CLT ");
- cel_names = "CLT ";
- }
- if (value & (1 << 1)) {
- // cel_codes++; // Bit 1
- // Serial.print("IAT ");
- // cel_names += "IAT ";
- }
- if (value & (1 << 2)) {
- cel_codes++; // Bit 2
- //Serial.print("MAP ");
- cel_names += "MAP ";
- }
- if (value & (1 << 3)) {
- cel_codes++; // Bit 3
- //Serial.print("WBO ");
- cel_names += "WBO ";
- }
- if (value & (1 << 8)) {
- cel_codes++; // Bit 8
- //Serial.print("FF SENSOR ");
- cel_names += "FF SENSOR ";
- }
- if (value & (1 << 9)) {
- cel_codes++; // Bit 9
- //Serial.print("DBW ");
- cel_names += "DBW ";
- }
- if (value & (1 << 10)) {
- cel_codes++; // Bit 10
- //Serial.print("FPR ");
- cel_names += "FPR ";
- }
- //Serial.print("Total CEL Codes: " + cel_codes);
- //Serial.println();
- lv_table_set_cell_value(table, 5, 1, cel_names.c_str());
- return cel_codes;
- }
- }
- // Custom draw callback for right-aligned text in specific cells
- void my_table_event_cb(lv_event_t * e) {
- lv_obj_t * table = lv_event_get_target(e);
- lv_obj_draw_part_dsc_t * dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_param(e);
- if (dsc->part == LV_PART_ITEMS) {
- uint16_t row = dsc->id / lv_table_get_col_cnt(table);
- uint16_t col = dsc->id % lv_table_get_col_cnt(table);
- // Default Left Align
- dsc->label_dsc->align = LV_TEXT_ALIGN_LEFT;
- // Right-align specific cells
- 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) ||
- (row == 4 && col == 1) || (row == 4 && col == 3)) {
- dsc->label_dsc->align = LV_TEXT_ALIGN_RIGHT;
- }
- if (row == 5 && col == 1) {
- dsc->label_dsc->align = LV_TEXT_ALIGN_CENTER;
- }
- }
- }
- static void table_event_cb_bg(lv_event_t *e) {
- lv_obj_t *table = lv_event_get_target(e);
- lv_obj_draw_part_dsc_t *dsc = (lv_obj_draw_part_dsc_t *)lv_event_get_param(e);
- // Ensure dsc and rect_dsc are valid
- if (!dsc || !dsc->rect_dsc) return;
- // Only modify table cell backgrounds
- if (dsc->part == LV_PART_ITEMS) {
- uint16_t row = dsc->id / lv_table_get_col_cnt(table);
- uint16_t col = dsc->id % lv_table_get_col_cnt(table);
- const char *value_str = lv_table_get_cell_value(table, row, col);
- // Check if value_str is null or empty before conversion
- float value = 0.0f; // Default value
- if (value_str != nullptr && value_str[0] != '\0') {
- try {
- value = std::stof(value_str); // Convert string to float safely
- } catch (...) {
- value = 0.0f; // Handle invalid conversions
- }
- }
- // Default cell color
- lv_color_t bg_color = lv_color_white();
- lv_color_t text_color = lv_color_black();
- if (row == 0 && col == 1 && value > 7200.00) {
- bg_color = lv_color_make(0, 255, 0);
- text_color = lv_color_white();
- }
- if (row == 1 && col == 3 && value > 100.00) {
- bg_color = lv_color_make(0, 255, 0);
- text_color = lv_color_white();
- }
- if (row == 1 && col == 3 && value < 55.00 && value > 01.00) {
- bg_color = lv_color_make(0, 255, 255);
- }
- if (row == 2 && col == 3 && value < 12.00 && value > 01.00) {
- bg_color = lv_color_make(0, 255, 0);
- text_color = lv_color_white();
- }
- if (row == 3 && col == 3 && value > 1.10) {
- bg_color = lv_color_make(0, 255, 0);
- text_color = lv_color_white();
- }
- if (row == 5 && col == 1 && value_str != nullptr && value_str[0] != '\0') {
- bg_color = lv_color_make(0, 255, 0);
- text_color = lv_color_white();
- }
- // Apply background color to the cell
- dsc->rect_dsc->bg_color = bg_color;
- dsc->rect_dsc->bg_opa = LV_OPA_COVER; // Ensure background is visible
- dsc->label_dsc->color = text_color;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement