From 429944b8348b15a7fc9d74b09f412b8b52b2e217 Mon Sep 17 00:00:00 2001 From: Sebastian Nieto Date: Wed, 9 Sep 2026 22:44:20 -0300 Subject: [PATCH] gauge: implement full calibrations for speed (0-160km/h) and volt (10-16V) with floating precision --- emulator/obd2_emulator.py | 12 +++--- sketch/obd2_gauge/meter.h | 64 +++++++++++++++----------------- sketch/obd2_gauge/obd2_gauge.ino | 4 +- 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/emulator/obd2_emulator.py b/emulator/obd2_emulator.py index 33868d6..c090054 100755 --- a/emulator/obd2_emulator.py +++ b/emulator/obd2_emulator.py @@ -47,26 +47,26 @@ class VehicleState: if phase < 8.0: p = phase / 8.0 self.rpm = 800.0 + p * (6000.0 - 800.0) - self.speed = p * 180.0 + self.speed = p * 160.0 self.coolant_temp = 85.0 + p * (120.0 - 85.0) - self.pcm_volt = 13.2 + p * (16.0 - 13.2) + self.pcm_volt = 11.5 + p * (16.0 - 11.5) elif phase < 12.0: # MAX SCALE ON ALL INSTRUMENTS self.rpm = 6000.0 - self.speed = 180.0 + self.speed = 160.0 self.coolant_temp = 120.0 self.pcm_volt = 16.0 elif phase < 20.0: p = (phase - 12.0) / 8.0 self.rpm = 6000.0 - p * (6000.0 - 800.0) - self.speed = 180.0 - p * 180.0 + self.speed = 160.0 - p * 160.0 self.coolant_temp = 120.0 - p * (120.0 - 85.0) - self.pcm_volt = 16.0 - p * (16.0 - 13.2) + self.pcm_volt = 16.0 - p * (16.0 - 11.5) else: self.rpm = 800.0 self.speed = 0.0 self.coolant_temp = 88.0 - self.pcm_volt = 13.8 + self.pcm_volt = 14.2 # Correlated auxiliary telemetry self.map_psi = 10.0 + 16.0 * ((self.rpm - 800.0) / 5200.0) diff --git a/sketch/obd2_gauge/meter.h b/sketch/obd2_gauge/meter.h index dc3ab99..4008aab 100644 --- a/sketch/obd2_gauge/meter.h +++ b/sketch/obd2_gauge/meter.h @@ -697,6 +697,8 @@ inline void drawQuadrantDividers() { // Determine display color for meter: // ECT (PID 0): VERDE (< 98), AMARILLO (98-105), ROJO (>= 106) // RPM (PID 1): VERDE (< 3500), AMARILLO (3500-5000), ROJO (5000-6000) +// Voltaje (PID 2): ROJO (< 12.0 o >= 15.3), AMARILLO (12.0-13.2 o 14.8-15.2), VERDE (13.3-14.7) +// Velocidad (PID 3): VERDE (< 110), AMARILLO (110-130), ROJO (>= 130) // Otros instrumentos: VERDE / ROJO (segĂșn umbral de advertencia) inline uint16_t getMeterColor(uint8_t pidIdx, float data, int warn) { if (pidIdx == 0) { // 0 = Temperatura ECT (PID 0105) @@ -709,10 +711,30 @@ inline uint16_t getMeterColor(uint8_t pidIdx, float data, int warn) { if (data >= 3500.0f) return TFT_YELLOW; return TFT_GREEN; } + if (pidIdx == 2) { // 2 = Voltaje (PID 0142) + if (data < 12.0f || data >= 15.3f) return TFT_RED; + if (data < 13.3f || data >= 14.8f) return TFT_YELLOW; + return TFT_GREEN; + } + if (pidIdx == 3) { // 3 = Velocidad (PID 010D) + if (data >= 130.0f) return TFT_RED; + if (data >= 110.0f) return TFT_YELLOW; + return TFT_GREEN; + } if (warn > 0 && data >= (float)warn) return TFT_RED; return TFT_GREEN; } +// Compute block count (0..NUM_BAR_BLOCKS) with sub-integer floating point precision +inline int calcMeterBlocks(float val, int min, int max) { + float range = (float)(max - min); + if (range <= 0.0f) return 0; + int b = (int)(((val - (float)min) / range) * (float)NUM_BAR_BLOCKS + 0.5f); + if (b < 0) b = 0; + if (b > NUM_BAR_BLOCKS) b = NUM_BAR_BLOCKS; + return b; +} + // 4-quadrant Numeric Meter (160x120 px) void numericMeter4(uint8_t cell, uint8_t pid, bool redrawHeader = true) { int w = 160; @@ -816,17 +838,8 @@ void plotArc4(uint8_t cell, float data, int warn, int min, int max, bool digit, String numStr = String(data, digit); - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) - newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) - newBlocks = NUM_BAR_BLOCKS; - - int oldBlocks = (old_data[cell] < min) ? 0 : map(old_data[cell], min, max, 0, NUM_BAR_BLOCKS); - if (oldBlocks < 0) - oldBlocks = 0; - if (oldBlocks > NUM_BAR_BLOCKS) - oldBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); + int oldBlocks = (old_data[cell] < min) ? 0 : calcMeterBlocks(old_data[cell], min, max); bool colorChanged = (col != oldCol); if (col == TFT_RED) { @@ -983,17 +996,8 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max, String numStr = String(data, digit); if (!cellIsNumeric[cell]) { - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) - newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) - newBlocks = NUM_BAR_BLOCKS; - - int oldBlocks = (old_data[cell] < min) ? 0 : map(old_data[cell], min, max, 0, NUM_BAR_BLOCKS); - if (oldBlocks < 0) - oldBlocks = 0; - if (oldBlocks > NUM_BAR_BLOCKS) - oldBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); + int oldBlocks = (old_data[cell] < min) ? 0 : calcMeterBlocks(old_data[cell], min, max); bool colorChanged = (col != oldCol); if (col == TFT_RED) { @@ -1282,9 +1286,7 @@ void handleArcAlarmFlash() { wasInRedAlarm[cell] = false; int min = pidConfig[pidIdx][4].toInt(); int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) newBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); for (uint8_t i = 0; i < newBlocks; i++) { drawBarBlock(i, col); } @@ -1296,9 +1298,7 @@ void handleArcAlarmFlash() { if (toggleTick) { int min = pidConfig[pidIdx][4].toInt(); int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) newBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); if (arcFlashVisible) { for (uint8_t i = 0; i < newBlocks; i++) { @@ -1330,9 +1330,7 @@ void handleArcAlarmFlash() { wasInRedAlarm[cell] = false; int min = pidConfig[pidIdx][4].toInt(); int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) newBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); for (uint8_t i = 0; i < newBlocks; i++) { drawQuadBarBlock(cell, i, col); } @@ -1344,9 +1342,7 @@ void handleArcAlarmFlash() { if (toggleTick) { int min = pidConfig[pidIdx][4].toInt(); int max = pidConfig[pidIdx][5].toInt(); - int newBlocks = map(data, min, max, 0, NUM_BAR_BLOCKS); - if (newBlocks < 0) newBlocks = 0; - if (newBlocks > NUM_BAR_BLOCKS) newBlocks = NUM_BAR_BLOCKS; + int newBlocks = calcMeterBlocks(data, min, max); if (arcFlashVisible) { for (uint8_t i = 0; i < newBlocks; i++) { diff --git a/sketch/obd2_gauge/obd2_gauge.ino b/sketch/obd2_gauge/obd2_gauge.ino index db0ab14..f454abd 100644 --- a/sketch/obd2_gauge/obd2_gauge.ino +++ b/sketch/obd2_gauge/obd2_gauge.ino @@ -85,8 +85,8 @@ const String pidConfig[4][9] = { //[pid][data] { "Temperatura", "`C", "0105", "1", "0", "120", "2", "0", "106" }, //0 = Temperatura (0105) { "RPM", "rpm", "010C", "3", "0", "6000", "0", "0", "5000" }, //1 = RPM (010C) - { "Voltaje", "V", "0142", "4", "0", "16", "1", "1", "15" }, //2 = Voltaje (0142) - { "Velocidad", "km/h", "010D", "7", "0", "180", "0", "0", "130" } //3 = Velocidad (010D) + { "Voltaje", "V", "0142", "4", "10", "16", "1", "1", "15" }, //2 = Voltaje (0142) + { "Velocidad", "km/h", "010D", "7", "0", "160", "0", "0", "130" } //3 = Velocidad (010D) }; //hold warning value