From f058056827f4be260ec82cbd3dbf5c4e247e1766 Mon Sep 17 00:00:00 2001 From: Sebastian Nieto Date: Wed, 9 Sep 2026 23:17:50 -0300 Subject: [PATCH] Add volume adjustment and per-instrument alarm threshold and ON/OFF settings --- sketch/obd2_gauge/config.h | 400 +++++++++++++++++++++---------- sketch/obd2_gauge/meter.h | 29 ++- sketch/obd2_gauge/obd2_gauge.ino | 12 +- 3 files changed, 306 insertions(+), 135 deletions(-) diff --git a/sketch/obd2_gauge/config.h b/sketch/obd2_gauge/config.h index e48ae60..583c9b9 100644 --- a/sketch/obd2_gauge/config.h +++ b/sketch/obd2_gauge/config.h @@ -1,5 +1,5 @@ /* "config.h" -Configuration menu for OBD2 Gauge +Configuration menu for OBD2 Gauge with volume and per-instrument alarm controls */ #include #include @@ -9,11 +9,10 @@ Configuration menu for OBD2 Gauge #define FORMAT_SPIFFS_IF_FAILED true /*------------ SOUND EFFECTS ----------*/ -// Buzzer volume control: duty cycle out of 1023 (512 = 100% max loud, 40 = soft, gentle chirp) -const uint16_t CASIO_BEEP_DUTY = 40; - // Classic Casio Watch Beep (F-91W / G-Shock Module 593: 32768 / 16 = 2048 Hz, exact C7 note) -inline void casioBeep(uint16_t freq = 2048, uint8_t duration_ms = 20, uint16_t duty = CASIO_BEEP_DUTY) { +inline void casioBeep(uint16_t freq = 2048, uint8_t duration_ms = 20) { + uint16_t duty = VOL_DUTY_TABLE[buzzerVolumeLevel > 5 ? 2 : buzzerVolumeLevel]; + if (duty == 0) return; // Mute mode ledcSetup(buzzerChannel, freq, 10); ledcWrite(buzzerChannel, duty); delay(duration_ms); @@ -34,56 +33,260 @@ void clickSound() { casioBeep(2048, 20); } -// Configuration menu list -const String menuList[3] = { - "Warning setting", // 0 - "Load my pic 320x240 px", // 1 - "Exit" // 2 +// Configuration menu list (4 options) +const String menuList[4] = { + "Ajuste de Alarmas", // 0 + "Volumen de Bip", // 1 + "Cargar imagen de fondo", // 2 + "Salir" // 3 }; -const uint8_t maxMenu = 3; +const uint8_t maxMenu = 4; // Menu list for warning setting (4 vehicle gauges) const String parameterList[4][2] = { - {"- Temperatura (ECT)", " `c "}, - {"- RPM", " rpm "}, - {"- Voltaje Bateria", " V "}, - {"- Velocidad (SPEED)", " km/h"} + {"Temperatura", " `C"}, + {"RPM", " rpm"}, + {"Voltaje", " V"}, + {"Velocidad", " km/h"} }; -// Increments/decrements for each PID warning setting -const int pidWarnStep[4] = {1, 100, 1, 5}; +// Increments/limits for each PID warning setting +const float pidWarnStepFloat[4] = { 1.0f, 100.0f, 0.1f, 5.0f }; +const float pidWarnMin[4] = { 60.0f, 1500.0f, 12.0f, 40.0f }; +const float pidWarnMax[4] = { 125.0f, 6000.0f, 16.0f, 160.0f }; -// Highlight and change warning for each gauge -void setWarning(int8_t index, int8_t change) { - for (uint8_t i = 0; i < 4; i++) { - tft.setTextColor(TFT_WHITE, TFT_BLACK); - tft.drawString(parameterList[i][0], 10, 60 + (i * 30), 4); - tft.drawRightString(parameterList[i][1], 310, 60 + (i * 30), 4); - String result = warningValue[i]; - tft.drawRightString(result.c_str(), 230, 60 + (i * 30), 4); - } +// ------------------------------------------------------------- +// Sub-screen 0: Ajuste de Alarmas (Umbrales y Activacion ON/OFF) +// ------------------------------------------------------------- +void warningMenu() { + clickSound(); + tft.fillScreen(TFT_BLACK); + tft.fillRectVGradient(0, 0, 320, 26, TFT_ORANGE, 0xfc00); + tft.setTextColor(TFT_BLACK); + tft.drawCentreString("[--- Ajuste de Alarmas ---]", 159, 0, 4); - if (index >= 0 && index < 4) { - int min = pidConfig[index][4].toInt(); - int max = pidConfig[index][5].toInt(); - int val = warningValue[index].toInt(); - if (change == -1) { - val -= pidWarnStep[index]; - if (val < min) val = min; - } else if (change == 1) { - val += pidWarnStep[index]; - if (val > max) val = max; + int8_t selIndex = 0; + + auto drawAllRows = [&](int8_t sel) { + for (uint8_t i = 0; i < 4; i++) { + int y = 32 + i * 40; + uint16_t bg = (i == sel) ? 0x0011 : TFT_BLACK; + tft.fillRect(0, y, 320, 38, bg); + if (i == sel) { + tft.drawRect(1, y, 318, 38, TFT_CYAN); + } + + tft.setTextColor(i == sel ? TFT_YELLOW : TFT_WHITE, bg); + tft.drawString(parameterList[i][0], 8, y + 7, 4); + + // ON / OFF toggle badge + uint16_t badgeCol = alarmEnabled[i] ? TFT_GREEN : 0x8000; + tft.fillRoundRect(145, y + 5, 52, 28, 4, badgeCol); + tft.setTextColor(TFT_WHITE, badgeCol); + tft.drawCentreString(alarmEnabled[i] ? "ON" : "OFF", 171, y + 11, 2); + + // Value & Unit + tft.setTextColor(alarmEnabled[i] ? (i == sel ? TFT_WHITE : TFT_CYAN) : 0x632C, bg); + String valStr = warningValue[i] + parameterList[i][1]; + tft.drawRightString(valStr.c_str(), 312, y + 7, 4); } - warningValue[index] = String(val); + }; - tft.setTextColor(TFT_BLACK, TFT_YELLOW); // highlight selected item - tft.drawString(parameterList[index][0], 10, 60 + (index * 30), 4); - tft.drawRightString(parameterList[index][1], 310, 60 + (index * 30), 4); - tft.drawRightString(warningValue[index].c_str(), 230, 60 + (index * 30), 4); + auto drawBottomButtons = []() { + tft.fillRoundRect(4, 196, 54, 38, 4, TFT_NAVY); + tft.fillRoundRect(62, 196, 54, 38, 4, TFT_NAVY); + tft.fillRoundRect(120, 196, 64, 38, 4, 0x03E0); // Greenish + tft.fillRoundRect(188, 196, 58, 38, 4, TFT_NAVY); + tft.fillRoundRect(250, 196, 66, 38, 4, TFT_NAVY); + + tft.setTextColor(TFT_WHITE); + tft.drawCentreString("^", 31, 204, 4); + tft.drawCentreString("v", 89, 204, 4); + tft.drawCentreString("ON/OFF", 152, 208, 2); + tft.drawCentreString("-", 217, 198, 6); + tft.drawCentreString("+", 283, 198, 6); + }; + + drawAllRows(selIndex); + drawBottomButtons(); + delay(200); + + while (true) { + autoDim(); + uint16_t tx = 0, ty = 0; + if (getTouch(&tx, &ty)) { + // Direct touch on rows + if (ty >= 32 && ty < 192) { + int8_t row = (ty - 32) / 40; + if (row >= 0 && row < 4) { + if (tx >= 140 && tx <= 205) { + // Tapped ON/OFF badge directly + alarmEnabled[row] = !alarmEnabled[row]; + selIndex = row; + drawAllRows(selIndex); + clickSound(); + } else { + // Selected row + selIndex = row; + drawAllRows(selIndex); + clickSound(); + } + } + while (isScreenPressed()) { delay(10); yield(); } + delay(60); + } + // Bottom buttons + else if (ty >= 194 && ty <= 238) { + if (tx < 60) { // PREV + selIndex = (selIndex <= 0) ? 3 : (selIndex - 1); + drawAllRows(selIndex); + clickSound(); + } else if (tx >= 60 && tx < 118) { // NEXT + selIndex = (selIndex >= 3) ? 0 : (selIndex + 1); + drawAllRows(selIndex); + clickSound(); + } else if (tx >= 118 && tx < 186) { // ON/OFF TOGGLE + alarmEnabled[selIndex] = !alarmEnabled[selIndex]; + drawAllRows(selIndex); + clickSound(); + } else if (tx >= 186 && tx < 248) { // DECREASE (-) + float val = warningValue[selIndex].toFloat() - pidWarnStepFloat[selIndex]; + if (val < pidWarnMin[selIndex]) val = pidWarnMin[selIndex]; + warningValue[selIndex] = (selIndex == 2) ? String(val, 1) : String((int)(val + 0.5f)); + drawAllRows(selIndex); + clickSound(); + } else if (tx >= 248) { // INCREASE (+) + float val = warningValue[selIndex].toFloat() + pidWarnStepFloat[selIndex]; + if (val > pidWarnMax[selIndex]) val = pidWarnMax[selIndex]; + warningValue[selIndex] = (selIndex == 2) ? String(val, 1) : String((int)(val + 0.5f)); + drawAllRows(selIndex); + clickSound(); + } + while (isScreenPressed()) { delay(10); yield(); } + delay(60); + } + // Top bar touch -> SAVE & EXIT + else if (ty < 30) { + clickSound(); + break; + } + } else if (digitalRead(SELECTOR_PIN) == LOW) { + delay(200); + break; + } + yield(); } - delay(150); + + // Save changes to Preferences + tft.fillRect(0, 80, 320, 80, TFT_NAVY); + tft.drawRect(0, 80, 320, 80, TFT_WHITE); + tft.setTextColor(TFT_WHITE, TFT_NAVY); + tft.drawCentreString("Alarmas Guardadas.", 160, 105, 4); + casioBeep(4096, 30); + pref.begin("setting", false); + for (uint8_t i = 0; i < 4; i++) { + pref.putString(pidConfig[i][0].c_str(), warningValue[i]); + String almKey = "alm_" + String(i); + pref.putBool(almKey.c_str(), alarmEnabled[i]); + } + pref.end(); + delay(500); } +// ------------------------------------------------------------- +// Sub-screen 1: Volumen de Bip (Ajuste Tactil con Prueba en Vivo) +// ------------------------------------------------------------- +void volumeMenu() { + clickSound(); + tft.fillScreen(TFT_BLACK); + tft.fillRectVGradient(0, 0, 320, 26, TFT_ORANGE, 0xfc00); + tft.setTextColor(TFT_BLACK); + tft.drawCentreString("[--- Volumen de Bip ---]", 159, 0, 4); + + auto drawVolUI = []() { + tft.fillRect(0, 34, 320, 96, TFT_BLACK); + + // Level number and title + tft.setTextColor(TFT_WHITE, TFT_BLACK); + String lvlStr = "Nivel " + String(buzzerVolumeLevel) + " / 5"; + tft.drawCentreString(lvlStr.c_str(), 160, 38, 4); + + tft.setTextColor(buzzerVolumeLevel == 0 ? TFT_RED : TFT_CYAN, TFT_BLACK); + tft.drawCentreString(VOL_NAME_TABLE[buzzerVolumeLevel], 160, 66, 4); + + // Visual volume meter bar (5 discrete blocks) + for (uint8_t b = 1; b <= 5; b++) { + uint16_t bCol = (b <= buzzerVolumeLevel) ? (b >= 4 ? TFT_ORANGE : TFT_GREEN) : METER_INACTIVE_COLOR; + tft.fillRect(36 + (b - 1) * 50, 102, 44, 20, bCol); + } + }; + + drawVolUI(); + + // Draw interactive buttons + // [ - BAJAR ] + tft.fillRoundRect(20, 136, 85, 42, 6, TFT_NAVY); + tft.setTextColor(TFT_WHITE); + tft.drawCentreString("- BAJAR", 62, 148, 2); + + // [ PROBAR ] + tft.fillRoundRect(115, 136, 90, 42, 6, 0x03E0); // Dark Green + tft.setTextColor(TFT_WHITE); + tft.drawCentreString("PROBAR", 160, 148, 2); + + // [ + SUBIR ] + tft.fillRoundRect(215, 136, 85, 42, 6, TFT_NAVY); + tft.setTextColor(TFT_WHITE); + tft.drawCentreString("+ SUBIR", 257, 148, 2); + + // [ GUARDAR Y VOLVER ] + tft.fillRoundRect(40, 192, 240, 38, 6, TFT_BLUE); + tft.setTextColor(TFT_WHITE); + tft.drawCentreString("GUARDAR Y VOLVER", 160, 202, 2); + + delay(200); + + while (true) { + autoDim(); + uint16_t tx = 0, ty = 0; + if (getTouch(&tx, &ty)) { + if (ty >= 136 && ty < 178) { + if (tx >= 20 && tx < 105) { // BAJAR + if (buzzerVolumeLevel > 0) { + buzzerVolumeLevel--; + drawVolUI(); + casioBeep(2048, 20); + } + } else if (tx >= 115 && tx < 205) { // PROBAR + casioBeep(2048, 20); + } else if (tx >= 215 && tx < 300) { // SUBIR + if (buzzerVolumeLevel < 5) { + buzzerVolumeLevel++; + drawVolUI(); + casioBeep(2048, 20); + } + } + while (isScreenPressed()) { delay(10); yield(); } + delay(60); + } else if ((ty >= 190 && ty <= 236 && tx >= 30 && tx <= 290) || ty < 30) { // GUARDAR Y VOLVER + casioBeep(4096, 25); + pref.begin("setting", false); + pref.putUChar("b_vol", buzzerVolumeLevel); + pref.end(); + while (isScreenPressed()) { delay(10); yield(); } + break; + } + } else if (digitalRead(SELECTOR_PIN) == LOW) { + delay(200); + break; + } + yield(); + } +} + +// ------------------------------------------------------------- +// Sub-screen 2: Cargar imagen de fondo desde SD +// ------------------------------------------------------------- void loadMyPic() { if (!SD.begin()) { tft.pushImage(129, 44, 60, 60, sdcard); @@ -126,25 +329,29 @@ void loadMyPic() { } SD.end(); SPIFFS.end(); - beep(); + casioBeep(4096, 30); } +// ------------------------------------------------------------- +// Menu Principal +// ------------------------------------------------------------- void listMenu(uint8_t choice) { tft.fillRect(0, 30, 320, 180, TFT_BLACK); - tft.pushImage(15, 45, 25, 25, warning); // Warning setting icon - tft.pushImage(15, 95, 25, 25, image); // Load my pic icon - tft.pushImage(15, 145, 25, 25, quit); // Exit icon for (uint8_t i = 0; i < maxMenu; i++) { + int y = 36 + i * 42; if (choice == i) { + tft.fillRoundRect(10, y, 300, 38, 5, TFT_BLUE); + tft.drawRoundRect(10, y, 300, 38, 5, TFT_CYAN); tft.setTextColor(TFT_WHITE, TFT_BLUE); } else { - tft.setTextColor(TFT_WHITE, TFT_BLACK); + tft.fillRoundRect(10, y, 300, 38, 5, 0x18E3); // subtle dark card + tft.setTextColor(TFT_WHITE, 0x18E3); } - tft.drawString(menuList[i], 50, 45 + 50 * i, 4); + tft.drawString(menuList[i], 25, y + 7, 4); } tft.setTextColor(TFT_YELLOW, TFT_BLACK); - tft.drawCentreString("Tap option to select or use Button", 160, 215, 2); + tft.drawCentreString("Toque una opcion para configurar", 160, 215, 2); } void configMenu() { @@ -157,7 +364,7 @@ void configMenu() { tft.setTextColor(TFT_BLACK); tft.drawCentreString("[--- Configuration Menu ---]", 159, 0, 4); listMenu(select); - delay(400); + delay(300); while (true) { autoDim(); @@ -167,9 +374,10 @@ void configMenu() { if (getTouch(&tx, &ty)) { int8_t touchedOpt = -1; - if (ty >= 35 && ty < 85) touchedOpt = 0; - else if (ty >= 85 && ty < 135) touchedOpt = 1; - else if (ty >= 135 && ty < 195) touchedOpt = 2; + if (ty >= 34 && ty < 76) touchedOpt = 0; + else if (ty >= 76 && ty < 118) touchedOpt = 1; + else if (ty >= 118 && ty < 160) touchedOpt = 2; + else if (ty >= 160 && ty < 205) touchedOpt = 3; if (touchedOpt >= 0) { select = touchedOpt; @@ -179,7 +387,7 @@ void configMenu() { delay(10); yield(); } - delay(100); + delay(80); executeSelect = select; } } else if (digitalRead(SELECTOR_PIN) == LOW) { @@ -206,81 +414,26 @@ void configMenu() { if (executeSelect >= 0) { select = executeSelect; - // Option 0: Warning setting + // Option 0: Warning setting (Thresholds & ON/OFF) if (select == 0) { - clickSound(); - tft.fillRect(0, 30, 320, 210, TFT_BLACK); - int8_t warningMenuIndex = 0; - int8_t inc_dec = 0; - tft.setTextColor(TFT_WHITE, TFT_BLACK); - tft.drawCentreString("Warning Setting", 159, 32, 4); - - for (uint8_t i = 0; i < 5; i++) { - tft.fillRoundRect(i * 64, 211, 60, 30, 5, TFT_NAVY); - } - tft.setTextColor(TFT_WHITE); - tft.drawCentreString("DEFAULT", 31, 217, 2); - tft.drawCentreString("^ PREV", 95, 217, 2); - tft.drawCentreString("NEXT v", 159, 217, 2); - tft.drawCentreString("-", 223, 206, 6); - tft.fillRect(286, 219, 3, 16, TFT_WHITE); - tft.fillRect(280, 225, 16, 3, TFT_WHITE); - - setWarning(warningMenuIndex, inc_dec); - delay(400); - - while (digitalRead(SELECTOR_PIN) == HIGH) { - autoDim(); - uint16_t t_x = 0, t_y = 0; - bool touched = getTouch(&t_x, &t_y); - if (touched && (t_y < 50 || (t_y >= 180 && t_y < 210))) break; - if (touched && (t_y >= 55 && t_y < 180)) { - int8_t row = (t_y - 60) / 30; - if (row >= 0 && row < 4) { - warningMenuIndex = row; - setWarning(warningMenuIndex, 0); - clickSound(); - delay(150); - } - } - if (touched && (t_y > 211)) { - clickSound(); - if (t_x < 64) { // DEFAULT - for (uint8_t i = 0; i < 4; i++) { - warningValue[i] = pidConfig[i][8]; - } - } - if ((t_x >= 64) && (t_x < 128)) warningMenuIndex--; - if ((t_x >= 128) && (t_x < 192)) warningMenuIndex++; - if ((t_x >= 192) && (t_x < 256)) inc_dec = -1; - if ((t_x >= 256) && (t_x < 320)) inc_dec = 1; - if (warningMenuIndex >= 4) warningMenuIndex = 0; - if (warningMenuIndex < 0) warningMenuIndex = 3; - - setWarning(warningMenuIndex, inc_dec); - inc_dec = 0; - } - yield(); - } - while (isScreenPressed()) { delay(10); yield(); } - - // Save warning values - for (uint8_t i = 0; i < 4; i++) { - pref.putString(pidConfig[i][0].c_str(), warningValue[i]); - } - tft.setTextColor(TFT_BLACK, TFT_GREEN); - tft.drawCentreString("Parameters Saved.", 159, 120, 4); - beep(); - delay(1000); + warningMenu(); tft.fillScreen(TFT_BLACK); tft.fillRectVGradient(0, 0, 320, 26, TFT_ORANGE, 0xfc00); tft.setTextColor(TFT_BLACK); tft.drawCentreString("[--- Configuration Menu ---]", 159, 0, 4); listMenu(select); } - - // Option 1: Load my pic + // Option 1: Volume setting (Buzzer level & live test) else if (select == 1) { + volumeMenu(); + tft.fillScreen(TFT_BLACK); + tft.fillRectVGradient(0, 0, 320, 26, TFT_ORANGE, 0xfc00); + tft.setTextColor(TFT_BLACK); + tft.drawCentreString("[--- Configuration Menu ---]", 159, 0, 4); + listMenu(select); + } + // Option 2: Load pic + else if (select == 2) { clickSound(); tft.fillRect(0, 30, 320, 239, TFT_BLACK); loadMyPic(); @@ -299,9 +452,8 @@ void configMenu() { tft.drawCentreString("[--- Configuration Menu ---]", 159, 0, 4); listMenu(select); } - - // Option 2: Exit - else if (select == 2) { + // Option 3: Exit + else if (select == 3) { clickSound(); break; } diff --git a/sketch/obd2_gauge/meter.h b/sketch/obd2_gauge/meter.h index dde6b82..04cda58 100644 --- a/sketch/obd2_gauge/meter.h +++ b/sketch/obd2_gauge/meter.h @@ -711,28 +711,37 @@ inline void drawQuadrantDividers() { // 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) { +inline uint16_t getMeterColor(uint8_t pidIdx, float data, int warn = -1) { + if (pidIdx >= 4) return TFT_GREEN; + + float warnVal = (warn > 0) ? (float)warn : warningValue[pidIdx].toFloat(); + bool isEnabled = alarmEnabled[pidIdx]; + if (pidIdx == 0) { // 0 = Temperatura ECT (PID 0105) - if (data >= 106.0f) return TFT_RED; - if (data >= 98.0f) return TFT_YELLOW; + if (warnVal <= 0) warnVal = 106.0f; + if (isEnabled && data >= warnVal) return TFT_RED; + if (data >= (warnVal - 8.0f)) return TFT_YELLOW; return TFT_GREEN; } if (pidIdx == 1) { // 1 = RPM (PID 010C) - if (data >= 5000.0f) return TFT_RED; - if (data >= 3500.0f) return TFT_YELLOW; + if (warnVal <= 0) warnVal = 5000.0f; + if (isEnabled && data >= warnVal) return TFT_RED; + if (data >= (warnVal - 1500.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; + if (warnVal <= 0) warnVal = 15.0f; + if (isEnabled && (data < 12.0f || data >= warnVal)) return TFT_RED; + if (data < 13.3f || data >= (warnVal - 0.5f)) 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; + if (warnVal <= 0) warnVal = 130.0f; + if (isEnabled && data >= warnVal) return TFT_RED; + if (data >= (warnVal - 20.0f)) return TFT_YELLOW; return TFT_GREEN; } - if (warn > 0 && data >= (float)warn) return TFT_RED; + if (isEnabled && warnVal > 0 && data >= warnVal) return TFT_RED; return TFT_GREEN; } diff --git a/sketch/obd2_gauge/obd2_gauge.ino b/sketch/obd2_gauge/obd2_gauge.ino index 395445e..703b8e5 100644 --- a/sketch/obd2_gauge/obd2_gauge.ino +++ b/sketch/obd2_gauge/obd2_gauge.ino @@ -90,7 +90,13 @@ const String pidConfig[4][9] = { }; //hold warning value -String warningValue[4] = { "106", "5000", "15", "130" }; +String warningValue[4] = { "106", "5000", "15.0", "130" }; +bool alarmEnabled[4] = { true, true, true, true }; + +// Buzzer volume control table (0: Silencio, 1: Muy Bajo, 2: Bajo/Casio, 3: Medio, 4: Alto, 5: Max) +const uint16_t VOL_DUTY_TABLE[6] = { 0, 20, 50, 120, 250, 512 }; +const char* const VOL_NAME_TABLE[6] = { "SILENCIO (MUTE)", "MUY BAJO", "BAJO (CASIO)", "MEDIO", "ALTO", "MAXIMO" }; +uint8_t buzzerVolumeLevel = 2; // Default 2: Bajo (Casio suave) /* 0 - Refrigerante @@ -277,7 +283,11 @@ recent_client_addr : {0x00,0x00,0x00,0x00,0x00,0x00} array of bytes[6] pref.putUShort("layout", 0); for (uint8_t i = 0; i < maxpidIndex; i++) { //read warning value from pid name if not found load from default warningValue[i] = pref.getString(pidConfig[i][0].c_str(), pidConfig[i][8]); + String almKey = "alm_" + String(i); + alarmEnabled[i] = pref.getBool(almKey.c_str(), true); } + buzzerVolumeLevel = pref.getUChar("b_vol", 2); + if (buzzerVolumeLevel > 5) buzzerVolumeLevel = 2; pref.getBytes("recent_client", recent_client_addr, pref.getBytesLength("recent_client")); //read last bt address