diff --git a/sketch/obd2_gauge/meter.h b/sketch/obd2_gauge/meter.h index bacfd01..ca7145a 100644 --- a/sketch/obd2_gauge/meter.h +++ b/sketch/obd2_gauge/meter.h @@ -35,6 +35,7 @@ uint8_t pidCurrentSkip[maxpidIndex] = {}; // current skip counter uint8_t engine_off_count = 0; // counter to indicate engine is off then sleep float old_data[maxpidIndex] = {}; // keep old data for each gauge to improve speed for pidIndex 0-6 +float last_valid_data[maxpidIndex] = {-999, -999, -999, -999}; // keep last valid reading across view toggles // backlight variable average counter uint8_t low_count = 0; @@ -371,6 +372,13 @@ int get7SegWidth(const char *str, uint8_t dW, uint8_t t) { return total; } +// Forward declarations +void plotNumeric4(uint8_t cell, float data, int warn, bool digit, String unit); +void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit, + String unit); +void plotFullScreen(uint8_t cell, float data, int warn, int min, int max, + bool digit, String unit); + // 4-quadrant Numeric Meter (160x120 px) void numericMeter4(uint8_t cell, uint8_t pid, bool redrawHeader = true) { int w = 160; @@ -392,13 +400,21 @@ void numericMeter4(uint8_t cell, uint8_t pid, bool redrawHeader = true) { // Clear only the body below the header to avoid any header flickering tft.fillRect(x + 1, y + 25, w - 2, h - 26, TFT_BLACK); - // Initial placeholder: right-aligned DSEG7 44pt number - tft.loadFont(DSEG7_Modern_BoldItalic_44); - tft.setTextColor(TFT_GREEN, TFT_BLACK); - tft.setTextPadding(w - 12); - tft.drawRightString("---", x + w - 10, y + 46, 1); - tft.setTextPadding(0); - tft.unloadFont(); + int warn = warningValue[pid].toInt(); + bool digit = pidConfig[pid][7].toInt(); + + if (last_valid_data[cell] != -999) { + old_data[cell] = -999; + plotNumeric4(cell, last_valid_data[cell], warn, digit, unit); + } else { + // Initial placeholder: right-aligned DSEG7 44pt number + tft.loadFont(DSEG7_Modern_BoldItalic_44); + tft.setTextColor(TFT_GREEN, TFT_BLACK); + tft.setTextPadding(w - 12); + tft.drawRightString("---", x + w - 10, y + 46, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } } void plotNumeric4(uint8_t cell, float data, int warn, bool digit, String unit) { @@ -442,18 +458,28 @@ void arcMeter4(uint8_t cell, uint8_t pid, bool redrawHeader = true) { // Clear only the body below the header to avoid any header flickering tft.fillRect(x + 1, y + 25, w - 2, h - 26, TFT_BLACK); + int min = pidConfig[pid][4].toInt(); + int max = pidConfig[pid][5].toInt(); + bool digit = pidConfig[pid][7].toInt(); + int warn = warningValue[pid].toInt(); + // Lowered smooth arc track (Center Y = y + 96, R = 66, IR = 54, thickness // 13px, sweep 130 deg: 115 to 245) tft.drawSmoothArc(x + 80, y + 96, 66, 54, 115, 245, TFT_DARKGREY, TFT_BLACK, false); - // Value placeholder using DSEG7 Modern 24pt smooth font - tft.loadFont(DSEG7_Modern_BoldItalic_24); - tft.setTextColor(TFT_GREEN, TFT_BLACK); - tft.setTextPadding(86); - tft.drawRightString("---", x + 116, y + 86, 1); - tft.setTextPadding(0); - tft.unloadFont(); + if (last_valid_data[cell] != -999) { + old_data[cell] = -999; + plotArc4(cell, last_valid_data[cell], warn, min, max, digit, unit); + } else { + // Value placeholder using DSEG7 Modern 24pt smooth font + tft.loadFont(DSEG7_Modern_BoldItalic_24); + tft.setTextColor(TFT_GREEN, TFT_BLACK); + tft.setTextPadding(86); + tft.drawRightString("---", x + 116, y + 86, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } } void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit, @@ -508,27 +534,37 @@ void fullScreenMeter(uint8_t cell, uint8_t pid, bool redrawHeader = true) { // Clear only below header tft.fillRect(0, 38, 320, 202, TFT_BLACK); - if (!cellIsNumeric[cell]) { - // Arc mode full screen - // Large full screen arc (Center: 160, 195, R: 130, IR: 108, thickness 23px, - // sweep 130 deg: 115 to 245) - tft.drawSmoothArc(160, 195, 130, 108, 115, 245, TFT_DARKGREY, TFT_BLACK, - false); + int min = pidConfig[pid][4].toInt(); + int max = pidConfig[pid][5].toInt(); + bool digit = pidConfig[pid][7].toInt(); + int warn = warningValue[pid].toInt(); - tft.loadFont(DSEG7_Modern_BoldItalic_80); - tft.setTextColor(TFT_GREEN, TFT_BLACK); - tft.setTextPadding(265); - tft.drawRightString("---", 260, 155, 1); - tft.setTextPadding(0); - tft.unloadFont(); + if (last_valid_data[cell] != -999) { + old_data[cell] = -999; + plotFullScreen(cell, last_valid_data[cell], warn, min, max, digit, unit); } else { - // Digital numeric mode full screen with DSEG7 Smooth Font (Anti-Aliased) - tft.loadFont(DSEG7_Modern_BoldItalic_80); - tft.setTextColor(TFT_GREEN, TFT_BLACK); - tft.setTextPadding(300); - tft.drawRightString("---", 305, 98, 1); - tft.setTextPadding(0); - tft.unloadFont(); + if (!cellIsNumeric[cell]) { + // Arc mode full screen + // Large full screen arc (Center: 160, 195, R: 130, IR: 108, thickness 23px, + // sweep 130 deg: 115 to 245) + tft.drawSmoothArc(160, 195, 130, 108, 115, 245, TFT_DARKGREY, TFT_BLACK, + false); + + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(TFT_GREEN, TFT_BLACK); + tft.setTextPadding(265); + tft.drawRightString("---", 260, 155, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } else { + // Digital numeric mode full screen with DSEG7 Smooth Font (Anti-Aliased) + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(TFT_GREEN, TFT_BLACK); + tft.setTextPadding(300); + tft.drawRightString("---", 305, 98, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } } } @@ -736,6 +772,8 @@ void updateMeter(uint8_t pidNo, String response) { // update parameter on screen } } + last_valid_data[pidNo] = data; + // Engine off check if PCM volt or ATRV if (pidConfig[pidIdx][2] == "0142" || pidConfig[pidIdx][2] == "ATRV") { engine_onoff(data, pidNo); diff --git a/sketch/obd2_gauge/obd2_gauge.ino b/sketch/obd2_gauge/obd2_gauge.ino index f27bda2..b67fc28 100644 --- a/sketch/obd2_gauge/obd2_gauge.ino +++ b/sketch/obd2_gauge/obd2_gauge.ino @@ -498,7 +498,6 @@ void loop() { // In full screen: single click toggles between arc and number mode without header flicker cellIsNumeric[fullScreenCell] = !cellIsNumeric[fullScreenCell]; fullScreenMeter(fullScreenCell, pidInCell[fullScreenCell], false); - old_data[fullScreenCell] = -999; } else if (clickQuadrant >= 0 && clickQuadrant < 4) { // In 4 quadrants: single click toggles between arc and number for this quadrant without header flicker cellIsNumeric[clickQuadrant] = !cellIsNumeric[clickQuadrant]; @@ -508,7 +507,6 @@ void loop() { } else { arcMeter4(clickQuadrant, pid, false); } - old_data[clickQuadrant] = -999; } } //----------------------