Fix full-screen arc negative sign bug, switch battery to ATRV, and add PID communication watchdog

This commit is contained in:
Sebastián Nieto 2026-09-07 21:10:05 -03:00
parent 2fecf43275
commit 3e697f360a
2 changed files with 88 additions and 45 deletions

View file

@ -524,16 +524,16 @@ void fullScreenMeter(uint8_t cell, uint8_t pid, bool redrawHeader = true) {
tft.loadFont(DSEG7_Modern_BoldItalic_80);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.setTextPadding(155);
tft.drawRightString("---", 230, 155, 1);
tft.setTextPadding(280);
tft.drawCentreString("---", 160, 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(295);
tft.drawRightString("---", 295, 98, 1);
tft.setTextPadding(300);
tft.drawRightString("---", 305, 98, 1);
tft.setTextPadding(0);
tft.unloadFont();
}
@ -565,16 +565,16 @@ void plotFullScreen(uint8_t cell, float data, int warn, int min, int max,
// Value below the arc using DSEG7 Modern smooth font
tft.loadFont(DSEG7_Modern_BoldItalic_80);
tft.setTextColor(col, TFT_BLACK);
tft.setTextPadding(155);
tft.drawRightString(numStr.c_str(), 230, 155, 1);
tft.setTextPadding(280);
tft.drawCentreString(numStr.c_str(), 160, 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(col, TFT_BLACK);
tft.setTextPadding(295);
tft.drawRightString(numStr.c_str(), 295, 98, 1);
tft.setTextPadding(300);
tft.drawRightString(numStr.c_str(), 305, 98, 1);
tft.setTextPadding(0);
tft.unloadFont();
}
@ -611,11 +611,14 @@ void initScreen() {
// get A B from response return in global A B variable
void getAB(String elm_rsp) { // 41 05 2A 3C 01>
if (elm_rsp == "NO DATA\r\r>") { // pid no data
if (pidList[pidIndex] == "ATRV") {
return;
}
if (elm_rsp.indexOf("NO DATA") != -1) { // pid no data
A = 0;
B = 0;
} else {
return;
}
// check if pid is 2 or 3 command length.
uint8_t charcnt = pidList[pidIndex].length() / 2; // 0105->2,221E1C->3
String strs[8];
@ -625,22 +628,27 @@ void getAB(String elm_rsp) { // 41 05 2A 3C 01>
if (index == -1) // No space found
{ // only data without space is now in strs {41,05,aa,bb}
strs[StringCount++] = elm_rsp; // last byte
if (StringCount > charcnt + 1) {
A = strtol(strs[charcnt].c_str(), NULL, 16); // byte 3 save to A
B = strtol(strs[charcnt + 1].c_str(), NULL, 16); // byte 4 save to B
} else if (StringCount > charcnt) {
A = strtol(strs[charcnt].c_str(), NULL, 16);
B = 0;
}
break;
} else { // found space
strs[StringCount++] =
elm_rsp.substring(0, index); // copy strings from 0 to space to strs
elm_rsp = elm_rsp.substring(index +
1); // copy the rest behind space to elm_rsp
if (StringCount >= 7) break;
}
} // while
} // else
} // getAB
/*-------------------------------*/
// check engine status if off then turn off gauge
void engine_onoff(float data, uint8_t pid) { // use pcm volt
if (pidList[pid] == "0142") { // pcm voltage
void engine_onoff(float data, uint8_t pid) { // use pcm volt or ATRV
if (pidList[pid] == "0142" || pidList[pid] == "ATRV") { // pcm voltage or ATRV
if (data > 0.5 && data < ecu_off_volt)
engine_off_count++;
else if (data >= ecu_off_volt)
@ -716,10 +724,27 @@ void updateMeter(uint8_t pidNo, String response) { // update parameter on screen
case 7:
data = A; // km/h (PID 010D Vehicle Speed)
break;
case 8: {
// Battery Voltage from ELM327 command "ATRV" (e.g. "14.2V\r\r>")
String s = response;
s.trim();
int vIdx = s.indexOf('V');
if (vIdx == -1) vIdx = s.indexOf('v');
if (vIdx != -1) s = s.substring(0, vIdx);
int lastSpace = s.lastIndexOf(' ');
if (lastSpace != -1) s = s.substring(lastSpace + 1);
int lastCr = s.lastIndexOf('\r');
if (lastCr != -1) s = s.substring(lastCr + 1);
int lastLf = s.lastIndexOf('\n');
if (lastLf != -1) s = s.substring(lastLf + 1);
s.trim();
data = s.toFloat();
break;
}
}
// Engine off check if PCM volt
if (pidConfig[pidIdx][2] == "0142") {
// Engine off check if PCM volt or ATRV
if (pidConfig[pidIdx][2] == "0142" || pidConfig[pidIdx][2] == "ATRV") {
engine_onoff(data, pidNo);
}

View file

@ -85,7 +85,7 @@ const String pidConfig[4][9] = {
//[pid][data]
{ "Refrigerante", "`C", "0105", "1", "0", "120", "2", "0", "100" }, //0 = Refrigerante (0105)
{ "Revoluciones", "rpm", "010C", "3", "0", "6000", "0", "0", "5000" }, //1 = Revoluciones (010C)
{ "Voltaje", "V", "0142", "4", "0", "16", "1", "1", "15" }, //2 = Voltaje (0142)
{ "Voltaje", "V", "ATRV", "8", "0", "16", "1", "1", "15" }, //2 = Voltaje Batería (ATRV)
{ "Velocidad", "km/h", "010D", "7", "0", "180", "0", "0", "130" } //3 = Velocidad (010D)
};
@ -380,9 +380,10 @@ recent_client_addr : {0x00,0x00,0x00,0x00,0x00,0x00} array of bytes[6]
bt_message = "";
for (uint8_t initIndex = 0; initIndex < elm327InitCount; initIndex++) { //send init ELM327 AT command
BTSerial.print(elm327Init[initIndex] + "\r");
if (initIndex == elm327InitCount - 1) delay(2000); //wait for 0100 Searching..protocal
else delay(100); //must add delay , unless will skip BTSerial.avaialble>0
while (BTSerial.available() > 0) {
uint32_t waitTimeout = (initIndex == elm327InitCount - 1) ? 5000 : 1500;
uint32_t startWait = millis();
while (millis() - startWait < waitTimeout) {
if (BTSerial.available() > 0) {
char incomingChar = BTSerial.read();
if (incomingChar == '>') { //check prompt
BTSerial.flush(); //clear buffer
@ -394,10 +395,14 @@ recent_client_addr : {0x00,0x00,0x00,0x00,0x00,0x00} array of bytes[6]
#endif
if (initIndex == 1) BTSerial.print("\r"); //ATBRD23 response
bt_message = "";
break;
} else {
bt_message.concat(incomingChar); //keep elm327 respond
}
} //while
} else {
delay(10);
}
} //while waitTimeout
} //for
initScreen();
@ -508,6 +513,18 @@ void loop() {
}
//----------------------
//BLUETOOTH read
static uint32_t lastPidSendTime = 0;
// Watchdog: If waiting for prompt for more than 1500ms, recover!
if (!prompt && (millis() - lastPidSendTime > 1500)) {
#ifdef SERIAL_DEBUG
Serial.printf("PID timeout for %s, recovering...\n", pidList[pidIndex].c_str());
#endif
BTSerial.flush();
bt_message = "";
prompt = true;
skip = true;
}
while (BTSerial.available() > 0) {
char incomingChar = BTSerial.read();
if (incomingChar == '>') { //check prompt
@ -570,6 +587,7 @@ void loop() {
pidCurrentSkip[pidIndex] = pidReadSkip[pidIndex]; //read max delay loop to current
skip = false;
BTSerial.print(pidList[pidIndex] + "\r"); //send PID request
lastPidSendTime = millis();
} else { //skip sending request
pidCurrentSkip[pidIndex] = pidCurrentSkip[pidIndex] - 1; //decrese loop count
prompt = true;