From 117d3082b010ff4b9b743eef242dcec459d99e48 Mon Sep 17 00:00:00 2001 From: Sebastian Nieto Date: Wed, 9 Sep 2026 22:55:13 -0300 Subject: [PATCH] Flash digital value reading synchronously with arc alarm in red zone --- sketch/obd2_gauge/meter.h | 185 ++++++++++++++++++++++++++++---------- 1 file changed, 136 insertions(+), 49 deletions(-) diff --git a/sketch/obd2_gauge/meter.h b/sketch/obd2_gauge/meter.h index 5003c59..8c67f20 100644 --- a/sketch/obd2_gauge/meter.h +++ b/sketch/obd2_gauge/meter.h @@ -800,9 +800,17 @@ void plotNumeric4(uint8_t cell, float data, int warn, bool digit, String unit) { uint8_t pidIdx = pidInCell[cell]; uint16_t col = getMeterColor(pidIdx, data, warn); + if (col == TFT_RED) { + wasInRedAlarm[cell] = true; + } else { + wasInRedAlarm[cell] = false; + } + + uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col; + String numStr = String(data, digit); tft.loadFont(DSEG7_Modern_BoldItalic_44); - tft.setTextColor(col, TFT_BLACK); + tft.setTextColor(txtCol, TFT_BLACK); tft.setTextPadding(w - 12); tft.drawRightString(numStr.c_str(), x + w - 10, y + 46, 1); tft.setTextPadding(0); @@ -910,8 +918,10 @@ void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit, } } + uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col; + tft.loadFont(DSEG7_Modern_BoldItalic_34); - tft.setTextColor(col, TFT_BLACK); + tft.setTextColor(txtCol, TFT_BLACK); tft.setTextPadding(114); tft.drawRightString(numStr.c_str(), x + 152, y + 74, 1); tft.setTextPadding(0); @@ -1068,17 +1078,26 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max, } } + uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col; + // Value bottom-right using DSEG7 Modern smooth font tft.loadFont(DSEG7_Modern_BoldItalic_80); - tft.setTextColor(col, TFT_BLACK); + tft.setTextColor(txtCol, TFT_BLACK); tft.setTextPadding(240); tft.drawRightString(numStr.c_str(), 312, 148, 1); tft.setTextPadding(0); tft.unloadFont(); } else { // Digital numeric mode full screen with DSEG7 Smooth Font (Anti-Aliased) + if (col == TFT_RED) { + wasInRedAlarm[cell] = true; + } else { + wasInRedAlarm[cell] = false; + } + uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col; + tft.loadFont(DSEG7_Modern_BoldItalic_80); - tft.setTextColor(col, TFT_BLACK); + tft.setTextColor(txtCol, TFT_BLACK); tft.setTextPadding(295); tft.drawRightString(numStr.c_str(), 295, 98, 1); tft.setTextPadding(0); @@ -1288,7 +1307,7 @@ void updateMeter(uint8_t pidNo, String response) { // update parameter on screen } /*-------------------------------*/ -// Non-blocking handler to blink/flash arcs on alarm (when in TFT_RED) +// Non-blocking handler to blink/flash arcs and numerical values on alarm (when in TFT_RED) void handleArcAlarmFlash() { uint32_t now = millis(); bool toggleTick = false; @@ -1300,43 +1319,76 @@ void handleArcAlarmFlash() { if (fullScreenCell >= 0 && fullScreenCell < 4) { uint8_t cell = fullScreenCell; - if (!cellIsNumeric[cell] && last_valid_data[cell] != -999) { + if (last_valid_data[cell] != -999) { uint8_t pidIdx = pidInCell[cell]; int warn = warningValue[pidIdx].toInt(); float data = last_valid_data[cell]; uint16_t col = getMeterColor(pidIdx, data, warn); bool inRed = (col == TFT_RED); + bool digit = pidConfig[pidIdx][7].toInt(); + String numStr = String(data, digit); if (wasInRedAlarm[cell] && !inRed) { - // Exited red alarm: restore steady arc + // Exited red alarm: restore steady arc and text wasInRedAlarm[cell] = false; - int min = pidConfig[pidIdx][4].toInt(); - int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = calcMeterBlocks(data, min, max); - for (uint8_t i = 0; i < newBlocks; i++) { - drawBarBlock(i, col); - } - for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { - drawBarBlock(i, TFT_DARKGREY); + if (!cellIsNumeric[cell]) { + int min = pidConfig[pidIdx][4].toInt(); + int max = pidConfig[pidIdx][5].toInt(); + int newBlocks = calcMeterBlocks(data, min, max); + for (uint8_t i = 0; i < newBlocks; i++) { + drawBarBlock(i, col); + } + for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { + drawBarBlock(i, TFT_DARKGREY); + } + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(col, TFT_BLACK); + tft.setTextPadding(240); + tft.drawRightString(numStr.c_str(), 312, 148, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } else { + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(col, TFT_BLACK); + tft.setTextPadding(295); + tft.drawRightString(numStr.c_str(), 295, 98, 1); + tft.setTextPadding(0); + tft.unloadFont(); } } else if (inRed) { wasInRedAlarm[cell] = true; if (toggleTick) { - int min = pidConfig[pidIdx][4].toInt(); - int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = calcMeterBlocks(data, min, max); + uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK; + if (!cellIsNumeric[cell]) { + int min = pidConfig[pidIdx][4].toInt(); + int max = pidConfig[pidIdx][5].toInt(); + int newBlocks = calcMeterBlocks(data, min, max); - if (arcFlashVisible) { - for (uint8_t i = 0; i < newBlocks; i++) { - drawBarBlock(i, TFT_RED); - } - for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { - drawBarBlock(i, TFT_DARKGREY); + if (arcFlashVisible) { + for (uint8_t i = 0; i < newBlocks; i++) { + drawBarBlock(i, TFT_RED); + } + for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { + drawBarBlock(i, TFT_DARKGREY); + } + } else { + for (uint8_t i = 0; i < NUM_BAR_BLOCKS; i++) { + drawBarBlock(i, TFT_BLACK); + } } + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(txtCol, TFT_BLACK); + tft.setTextPadding(240); + tft.drawRightString(numStr.c_str(), 312, 148, 1); + tft.setTextPadding(0); + tft.unloadFont(); } else { - for (uint8_t i = 0; i < NUM_BAR_BLOCKS; i++) { - drawBarBlock(i, TFT_BLACK); - } + tft.loadFont(DSEG7_Modern_BoldItalic_80); + tft.setTextColor(txtCol, TFT_BLACK); + tft.setTextPadding(295); + tft.drawRightString(numStr.c_str(), 295, 98, 1); + tft.setTextPadding(0); + tft.unloadFont(); } } } @@ -1344,43 +1396,78 @@ void handleArcAlarmFlash() { } else { // 4 quadrants mode for (uint8_t cell = 0; cell < 4; cell++) { - if (!cellIsNumeric[cell] && last_valid_data[cell] != -999) { + if (last_valid_data[cell] != -999) { uint8_t pidIdx = pidInCell[cell]; int warn = warningValue[pidIdx].toInt(); float data = last_valid_data[cell]; uint16_t col = getMeterColor(pidIdx, data, warn); bool inRed = (col == TFT_RED); + bool digit = pidConfig[pidIdx][7].toInt(); + String numStr = String(data, digit); + int x = cell4_x[cell]; + int y = cell4_y[cell]; if (wasInRedAlarm[cell] && !inRed) { - // Exited red alarm: restore steady arc + // Exited red alarm: restore steady arc and text wasInRedAlarm[cell] = false; - int min = pidConfig[pidIdx][4].toInt(); - int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = calcMeterBlocks(data, min, max); - for (uint8_t i = 0; i < newBlocks; i++) { - drawQuadBarBlock(cell, i, col); - } - for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { - drawQuadBarBlock(cell, i, TFT_DARKGREY); + if (!cellIsNumeric[cell]) { + int min = pidConfig[pidIdx][4].toInt(); + int max = pidConfig[pidIdx][5].toInt(); + int newBlocks = calcMeterBlocks(data, min, max); + for (uint8_t i = 0; i < newBlocks; i++) { + drawQuadBarBlock(cell, i, col); + } + for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { + drawQuadBarBlock(cell, i, TFT_DARKGREY); + } + tft.loadFont(DSEG7_Modern_BoldItalic_34); + tft.setTextColor(col, TFT_BLACK); + tft.setTextPadding(114); + tft.drawRightString(numStr.c_str(), x + 152, y + 74, 1); + tft.setTextPadding(0); + tft.unloadFont(); + } else { + tft.loadFont(DSEG7_Modern_BoldItalic_44); + tft.setTextColor(col, TFT_BLACK); + tft.setTextPadding(160 - 12); + tft.drawRightString(numStr.c_str(), x + 160 - 10, y + 46, 1); + tft.setTextPadding(0); + tft.unloadFont(); } } else if (inRed) { wasInRedAlarm[cell] = true; if (toggleTick) { - int min = pidConfig[pidIdx][4].toInt(); - int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = calcMeterBlocks(data, min, max); + uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK; + if (!cellIsNumeric[cell]) { + int min = pidConfig[pidIdx][4].toInt(); + int max = pidConfig[pidIdx][5].toInt(); + int newBlocks = calcMeterBlocks(data, min, max); - if (arcFlashVisible) { - for (uint8_t i = 0; i < newBlocks; i++) { - drawQuadBarBlock(cell, i, TFT_RED); - } - for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { - drawQuadBarBlock(cell, i, TFT_DARKGREY); + if (arcFlashVisible) { + for (uint8_t i = 0; i < newBlocks; i++) { + drawQuadBarBlock(cell, i, TFT_RED); + } + for (uint8_t i = newBlocks; i < NUM_BAR_BLOCKS; i++) { + drawQuadBarBlock(cell, i, TFT_DARKGREY); + } + } else { + for (uint8_t i = 0; i < NUM_BAR_BLOCKS; i++) { + drawQuadBarBlock(cell, i, TFT_BLACK); + } } + tft.loadFont(DSEG7_Modern_BoldItalic_34); + tft.setTextColor(txtCol, TFT_BLACK); + tft.setTextPadding(114); + tft.drawRightString(numStr.c_str(), x + 152, y + 74, 1); + tft.setTextPadding(0); + tft.unloadFont(); } else { - for (uint8_t i = 0; i < NUM_BAR_BLOCKS; i++) { - drawQuadBarBlock(cell, i, TFT_BLACK); - } + tft.loadFont(DSEG7_Modern_BoldItalic_44); + tft.setTextColor(txtCol, TFT_BLACK); + tft.setTextPadding(160 - 12); + tft.drawRightString(numStr.c_str(), x + 160 - 10, y + 46, 1); + tft.setTextPadding(0); + tft.unloadFont(); } } }