feat: make parameter icon flash synchronously with alarm in 4-quadrant and full-screen modes

This commit is contained in:
Sebastián Nieto 2026-09-09 23:21:54 -03:00
parent f058056827
commit 5f8b3a04d8

View file

@ -67,6 +67,21 @@ void drawPidIcon(int x, int y, const String &pidStr) {
} }
} }
// Clear parameter icon for 4-quadrant view
void clearPidIcon(int x, int y, const String &pidStr) {
if (pidStr == "0105") {
tft.fillRect(x, y, 38, 37, TFT_BLACK);
} else if (pidStr == "010D") {
tft.fillRect(x, y, 42, 43, TFT_BLACK);
} else if (pidStr == "010C") {
tft.fillRect(x, y, 42, 43, TFT_BLACK);
} else if (pidStr == "0142" || pidStr == "ATRV") {
tft.fillRect(x, y, 46, 35, TFT_BLACK);
} else {
tft.fillRect(x, y, 42, 42, TFT_BLACK);
}
}
// Draw header icon (42x42 px, ~30% larger) for full screen mode // Draw header icon (42x42 px, ~30% larger) for full screen mode
void drawPidIconHeader(int x, int y, const String &pidStr) { void drawPidIconHeader(int x, int y, const String &pidStr) {
tft.setSwapBytes(true); tft.setSwapBytes(true);
@ -81,6 +96,36 @@ void drawPidIconHeader(int x, int y, const String &pidStr) {
} }
} }
// Restore blue header background over the 42x42 icon area during alarm blink OFF phase
void clearPidIconHeader(int x = 10, int y = 4, int w = 42, int h = 42) {
const float fade_w_left = 16.0f;
uint16_t lineBuf[64];
if (w > 64) w = 64;
tft.startWrite();
tft.setAddrWindow(x, y, w, h);
for (int16_t j = y; j < y + h; j++) {
float vy = 1.0f;
if (j >= 30) {
float t = (50.0f - (float)j) / 20.0f;
vy = t * t * (3.0f - 2.0f * t);
}
for (int16_t i = 0; i < w; i++) {
int16_t px = x + i;
float hx = 1.0f;
if (px < (int16_t)fade_w_left) {
float t = (float)px / fade_w_left;
hx = t * t * (3.0f - 2.0f * t);
}
float b = vy * hx;
uint8_t g = (uint8_t)(140.0f * b);
uint8_t bl = (uint8_t)(255.0f * b);
lineBuf[i] = tft.color565(0, g, bl);
}
tft.pushPixels(lineBuf, w);
}
tft.endWrite();
}
// Full Screen Exponential Segmented Block Bar Graph (20 blocks: 3mm width x 4mm height, 0.5mm gap, Anti-Aliased) // Full Screen Exponential Segmented Block Bar Graph (20 blocks: 3mm width x 4mm height, 0.5mm gap, Anti-Aliased)
const uint8_t NUM_BAR_BLOCKS = 20; const uint8_t NUM_BAR_BLOCKS = 20;
const int16_t blockMinX[20] PROGMEM = { 0, 5, 11, 17, 25, 34, 46, 59, 76, 95, 114, 134, 154, 174, 193, 213, 232, 251, 271, 290 }; const int16_t blockMinX[20] PROGMEM = { 0, 5, 11, 17, 25, 34, 46, 59, 76, 95, 114, 134, 154, 174, 193, 213, 232, 251, 271, 290 };
@ -795,8 +840,14 @@ void plotNumeric4(uint8_t cell, float data, int warn, bool digit, String unit) {
uint16_t col = getMeterColor(pidIdx, data, warn); uint16_t col = getMeterColor(pidIdx, data, warn);
if (col == TFT_RED) { if (col == TFT_RED) {
if (!wasInRedAlarm[cell]) {
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
} else { } else {
if (wasInRedAlarm[cell]) {
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
} }
@ -871,10 +922,14 @@ void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit,
bool colorChanged = (col != oldCol); bool colorChanged = (col != oldCol);
if (col == TFT_RED) { if (col == TFT_RED) {
if (!wasInRedAlarm[cell]) {
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
if (colorChanged) { if (colorChanged) {
arcFlashVisible = true; arcFlashVisible = true;
lastArcFlashTime = millis(); lastArcFlashTime = millis();
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
for (uint8_t i = 0; i < newBlocks; i++) { for (uint8_t i = 0; i < newBlocks; i++) {
drawQuadBarBlock(cell, i, TFT_RED); drawQuadBarBlock(cell, i, TFT_RED);
} }
@ -893,6 +948,9 @@ void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit,
} }
} }
} else { } else {
if (wasInRedAlarm[cell]) {
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
if (colorChanged || old_data[cell] < min) { if (colorChanged || old_data[cell] < min) {
for (uint8_t i = 0; i < newBlocks; i++) { for (uint8_t i = 0; i < newBlocks; i++) {
@ -1031,10 +1089,14 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max,
bool colorChanged = (col != oldCol); bool colorChanged = (col != oldCol);
if (col == TFT_RED) { if (col == TFT_RED) {
if (!wasInRedAlarm[cell]) {
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
if (colorChanged) { if (colorChanged) {
arcFlashVisible = true; arcFlashVisible = true;
lastArcFlashTime = millis(); lastArcFlashTime = millis();
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
for (uint8_t i = 0; i < newBlocks; i++) { for (uint8_t i = 0; i < newBlocks; i++) {
drawBarBlock(i, TFT_RED); drawBarBlock(i, TFT_RED);
} }
@ -1053,6 +1115,9 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max,
} }
} }
} else { } else {
if (wasInRedAlarm[cell]) {
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
if (colorChanged || old_data[cell] < min) { if (colorChanged || old_data[cell] < min) {
for (uint8_t i = 0; i < newBlocks; i++) { for (uint8_t i = 0; i < newBlocks; i++) {
@ -1084,8 +1149,14 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max,
} else { } else {
// Digital numeric mode full screen with DSEG7 Smooth Font (Anti-Aliased) // Digital numeric mode full screen with DSEG7 Smooth Font (Anti-Aliased)
if (col == TFT_RED) { if (col == TFT_RED) {
if (!wasInRedAlarm[cell]) {
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
} else { } else {
if (wasInRedAlarm[cell]) {
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
}
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
} }
uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col; uint16_t txtCol = (col == TFT_RED && !arcFlashVisible) ? TFT_BLACK : col;
@ -1316,8 +1387,9 @@ void handleArcAlarmFlash() {
String numStr = String(data, digit); String numStr = String(data, digit);
if (wasInRedAlarm[cell] && !inRed) { if (wasInRedAlarm[cell] && !inRed) {
// Exited red alarm: restore steady arc and text // Exited red alarm: restore steady arc, text, and icon
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
if (!cellIsNumeric[cell]) { if (!cellIsNumeric[cell]) {
int min = pidConfig[pidIdx][4].toInt(); int min = pidConfig[pidIdx][4].toInt();
int max = pidConfig[pidIdx][5].toInt(); int max = pidConfig[pidIdx][5].toInt();
@ -1346,6 +1418,11 @@ void handleArcAlarmFlash() {
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
if (toggleTick) { if (toggleTick) {
uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK; uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK;
if (arcFlashVisible) {
drawPidIconHeader(10, 4, pidConfig[pidIdx][2]);
} else {
clearPidIconHeader(10, 4, 42, 42);
}
if (!cellIsNumeric[cell]) { if (!cellIsNumeric[cell]) {
int min = pidConfig[pidIdx][4].toInt(); int min = pidConfig[pidIdx][4].toInt();
int max = pidConfig[pidIdx][5].toInt(); int max = pidConfig[pidIdx][5].toInt();
@ -1395,8 +1472,9 @@ void handleArcAlarmFlash() {
int y = cell4_y[cell]; int y = cell4_y[cell];
if (wasInRedAlarm[cell] && !inRed) { if (wasInRedAlarm[cell] && !inRed) {
// Exited red alarm: restore steady arc and text // Exited red alarm: restore steady arc, text, and icon
wasInRedAlarm[cell] = false; wasInRedAlarm[cell] = false;
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
if (!cellIsNumeric[cell]) { if (!cellIsNumeric[cell]) {
int min = pidConfig[pidIdx][4].toInt(); int min = pidConfig[pidIdx][4].toInt();
int max = pidConfig[pidIdx][5].toInt(); int max = pidConfig[pidIdx][5].toInt();
@ -1425,6 +1503,11 @@ void handleArcAlarmFlash() {
wasInRedAlarm[cell] = true; wasInRedAlarm[cell] = true;
if (toggleTick) { if (toggleTick) {
uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK; uint16_t txtCol = arcFlashVisible ? TFT_RED : TFT_BLACK;
if (arcFlashVisible) {
drawPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
} else {
clearPidIcon(x + 5, y + 3, pidConfig[pidIdx][2]);
}
if (!cellIsNumeric[cell]) { if (!cellIsNumeric[cell]) {
int min = pidConfig[pidIdx][4].toInt(); int min = pidConfig[pidIdx][4].toInt();
int max = pidConfig[pidIdx][5].toInt(); int max = pidConfig[pidIdx][5].toInt();