From 80cfa134a6b4b06ea63b9b675e0818964cd53c57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=27=C3=A9lectron=20rare?= <108685187+electron-rare@users.noreply.github.com> Date: Tue, 7 Jul 2026 16:05:43 +0200 Subject: [PATCH] feat(firmware): 48V pack class for 13s packs Add a Kconfig voltage-class choice (BMU_PACK_CLASS: 24V default / 48V) plus an sdkconfig.defaults.48v overlay, implementing lot 4 of the 48V design note. 48V class defaults: min 44600 mV (3.43 V/cell, same fleet policy as 24V), max 55200 mV (charger CV 54.6 V + 600 mV margin), imbalance 2000 mV (x13/7), VRM SOC window 44600-53500 mV. Blocking fixes found while implementing: - bmu_protection: plausibility guard rejected any reading above 35 V as an I2C glitch -> class macro BMU_V_PLAUSIBLE_MAX_MV. - bmu_ina237: BOVL/BUVL hardwired 30000/24000 -> programmed from runtime thresholds (NVS/Kconfig) at init; log real values. - bmu_ble control + display steppers: hardcoded 20-30/25-35 V setting bounds rejected any 48V config -> class-derived macros BMU_VMIN/VMAX_SET_FLOOR/CEIL_MV in bmu_config.h. - bmu_ui_detail: chart autoscale seeds 35000/15000 broke above 35 V -> neutral 65535/0. - bmu_ble_victron: SOC window hardcoded 24.0/28.8 -> reads the VRM Kconfig (class fallback when VRM disabled). - legacy firmware/src/config.h: BATTERY_PACK_CLASS_48V ifdef. Validated: idf.py build green for both classes (esp32s3, isolated sdkconfig; 48V generates 44600/55200/2000), no new warnings in touched files, legacy sim-host tests 13/13 pass. NVS erase needed when reflashing a board that has 24V thresholds persisted. --- .gitignore | 2 +- .../2026-07-05-bmu-48v-13s-variant-design.md | 54 +++++++++++++------ firmware-idf/CLAUDE.md | 8 +++ .../bmu_ble/bmu_ble_control_svc.cpp | 6 +-- .../bmu_ble_victron/bmu_ble_victron.cpp | 10 +++- firmware-idf/components/bmu_config/Kconfig | 33 ++++++++++++ .../bmu_config/include/bmu_config.h | 17 ++++++ .../components/bmu_display/bmu_ui_config.cpp | 14 ++--- .../components/bmu_display/bmu_ui_detail.cpp | 2 +- .../components/bmu_ina237/CMakeLists.txt | 2 +- .../components/bmu_ina237/bmu_ina237.cpp | 32 ++++++----- .../bmu_protection/bmu_protection.cpp | 3 +- firmware-idf/components/bmu_vrm/Kconfig | 2 + firmware-idf/sdkconfig.defaults.48v | 6 +++ firmware/src/config.h | 8 +++ 15 files changed, 154 insertions(+), 45 deletions(-) create mode 100644 firmware-idf/sdkconfig.defaults.48v diff --git a/.gitignore b/.gitignore index 178aef8..16dbc3e 100644 --- a/.gitignore +++ b/.gitignore @@ -107,7 +107,7 @@ models/*.onnx .failsafe/ firmware-idf/managed_components/ -firmware-idf/build/ +firmware-idf/build*/ firmware-idf/sdkconfig firmware-idf/sdkconfig.old firmware-idf/.cache/ diff --git a/docs/superpowers/specs/2026-07-05-bmu-48v-13s-variant-design.md b/docs/superpowers/specs/2026-07-05-bmu-48v-13s-variant-design.md index e8522c3..8c5b55a 100644 --- a/docs/superpowers/specs/2026-07-05-bmu-48v-13s-variant-design.md +++ b/docs/superpowers/specs/2026-07-05-bmu-48v-13s-variant-design.md @@ -69,24 +69,46 @@ identiques : la sous-carte 48 V est interchangeable avec la 30 V. Le reste de la carte mère (INA, TCA, jumpers, RJ45, LEDs, bornes) est inchangé. -## 4. Firmware à modifier (variante Kconfig « 13S ») +## 4. Firmware à modifier (variante Kconfig « 13S ») — ✅ IMPLÉMENTÉ 2026-07-07 -Trois points durs identifiés dans le code + deux calibrations : +Implémentation : choix Kconfig **`BMU_PACK_CLASS`** (24V défaut / 48V) dans +`bmu_config/Kconfig` + overlay **`sdkconfig.defaults.48v`** +(`idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.48v"`). -1. `bmu_config/Kconfig` — defaults : `BMU_MIN_VOLTAGE_MV` 24000 → 41000, - `BMU_MAX_VOLTAGE_MV` 30000 → 54600 (proposition à affiner). -2. `bmu_ble/bmu_ble_control_svc.cpp:233-234` — bornes de validation codées en - dur (20–30 V / 25–35 V) → à dériver du Kconfig (plage 13s : 36–48 V / - 45–56 V) plutôt que de nouvelles constantes magiques. -3. `bmu_display/bmu_ui_config.cpp:188-189` — mêmes bornes dans les steppers - de l'écran → même traitement. -4. **Seuil de déséquilibre** : 1 V @7s ≈ 1,9 V @13s à iso-déséquilibre par - cellule (×13/7). Garder le paramètre en absolu mais adapter le défaut de - la variante (~2000 mV). -5. **SOC/VRM et SOH** : mapping SOC linéaire 24,0–28,8 V → profil 13s - (39,0–54,6 V) ; le modèle SOH FPNN est entraîné sur les packs 7s terrain - → recalibration nécessaire pour la chimie INR 13s (advisory only, les - protections restent autoritaires). +1. ✅ `bmu_config/Kconfig` — defaults conditionnels : `BMU_MIN_VOLTAGE_MV` + 24000 → **44600** (3,43 V/él., même politique parc que 24 V ; l'onduleur + ~40,3 V et le BMS pack restent en filets), `BMU_MAX_VOLTAGE_MV` 30000 → + **55200** (4,246 V/él., CV 54,6 V + 600 mV — la proposition initiale + 54600 déclenchait pile à la CV chargeur). +2. ✅ `bmu_ble/bmu_ble_control_svc.cpp` — bornes dérivées des macros de + classe `BMU_VMIN_SET_FLOOR/CEIL_MV`, `BMU_VMAX_SET_FLOOR/CEIL_MV` + (13s : 36–48 V / 45–56 V) définies dans `bmu_config.h`. +3. ✅ `bmu_display/bmu_ui_config.cpp` — steppers écran sur les mêmes macros ; + défauts statiques 24000/30000 remplacés par les macros Kconfig. +4. ✅ **Seuil de déséquilibre** : défaut 2000 mV en classe 48 V (×13/7). +5. ✅ **SOC/VRM** : fenêtre SOC Kconfig `BMU_VRM_SOC_V_MIN/MAX` → défauts + 13s 44600/53500 mV (×13/7 de 24,0–28,8 V) ; `bmu_ble_victron.cpp` + lit désormais le Kconfig (fallback par classe si VRM désactivé). + **SOH FPNN : recalibration chimie INR 13s toujours à faire** (advisory + only, les protections restent autoritaires). + +Corrections trouvées en implémentant (bloquantes à 48 V) : + +- `bmu_protection.cpp` : garde de plausibilité `v_mv > 35000` → toute + lecture 13s aurait été rejetée comme glitch I2C → macro de classe + `BMU_V_PLAUSIBLE_MAX_MV` (60 V en 48 V). +- `bmu_ina237.cpp` : alertes matérielles BOVL/BUVL codées en dur + 30000/24000 → programmées depuis les seuils runtime (NVS/Kconfig). + NB : reprogrammées au boot uniquement (un changement BLE des seuils ne + met à jour le chip qu'au reboot ; la protection logicielle, elle, suit + immédiatement). +- `bmu_ui_detail.cpp` : seeds d'auto-échelle du graphe (35000/15000) → + 65535/0, neutres toutes classes. +- Legacy `firmware/src/config.h` : bloc `#ifdef BATTERY_PACK_CLASS_48V` + (44600/55200), défaut 24 V inchangé — tests sim-host verts. + +⚠ Passage d'une carte 24 V → 48 V déjà configurée : effacer la NVS +(seuils persistés) — cf. `firmware-idf/CLAUDE.md` « Erase NVS ». ## 5. Points système à instruire au banc diff --git a/firmware-idf/CLAUDE.md b/firmware-idf/CLAUDE.md index de4b9ac..2ccf79f 100644 --- a/firmware-idf/CLAUDE.md +++ b/firmware-idf/CLAUDE.md @@ -9,8 +9,16 @@ source ~/esp/esp-idf/export.sh idf.py build # ~30-60s incremental idf.py -p /dev/cu.usbmodem* flash monitor # flash + serial idf.py menuconfig # configure sdkconfig + +# Variante 48V (packs 13s, hardware BMU-v2-48v) — overlay Kconfig : +idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.48v" build +# (supprimer sdkconfig existant + erase NVS si seuils 24V déjà persistés) ``` +**Classe de tension** : choix Kconfig `BMU_PACK_CLASS` (24V défaut / 48V). +Fixe les défauts des seuils (44600/55200 mV en 48V), les bornes de réglage +BLE/écran, le garde de plausibilité INA237 et la fenêtre SOC VRM. + **Erase NVS** (si config corrompue ou override sdkconfig) : ```bash python3 -m esptool --chip esp32s3 -p /dev/cu.usbmodem* erase_region 0x9000 0x6000 diff --git a/firmware-idf/components/bmu_ble/bmu_ble_control_svc.cpp b/firmware-idf/components/bmu_ble/bmu_ble_control_svc.cpp index 2356e9a..5f2d469 100644 --- a/firmware-idf/components/bmu_ble/bmu_ble_control_svc.cpp +++ b/firmware-idf/components/bmu_ble/bmu_ble_control_svc.cpp @@ -229,9 +229,9 @@ static int control_chr_access_cb(uint16_t conn_handle, uint16_t attr_handle, s_last_status.last_cmd = 2; s_last_status.battery_idx = 0xFF; - /* Validation des plages */ - if (min_mv < 20000 || min_mv > 30000 || - max_mv < 25000 || max_mv > 35000 || + /* Validation des plages — bornes selon la classe de tension */ + if (min_mv < BMU_VMIN_SET_FLOOR_MV || min_mv > BMU_VMIN_SET_CEIL_MV || + max_mv < BMU_VMAX_SET_FLOOR_MV || max_mv > BMU_VMAX_SET_CEIL_MV || max_ma < 1000 || max_ma > 50000 || diff_mv < 100 || diff_mv > 5000) { ESP_LOGW(TAG, "Config: valeurs hors plage min=%u max=%u maxI=%u diff=%u", diff --git a/firmware-idf/components/bmu_ble_victron/bmu_ble_victron.cpp b/firmware-idf/components/bmu_ble_victron/bmu_ble_victron.cpp index 313279b..04effab 100644 --- a/firmware-idf/components/bmu_ble_victron/bmu_ble_victron.cpp +++ b/firmware-idf/components/bmu_ble_victron/bmu_ble_victron.cpp @@ -89,8 +89,14 @@ static int build_battery_adv(uint8_t *buf, size_t buf_len) float avg_v = avg_mv / 1000.0f; /* SOC estimation */ - float v_min = 24.0f; /* CONFIG_BMU_VRM_SOC_V_MIN / 1000 */ - float v_max = 28.8f; /* CONFIG_BMU_VRM_SOC_V_MAX / 1000 */ +#ifdef CONFIG_BMU_VRM_SOC_V_MIN + float v_min = (float)CONFIG_BMU_VRM_SOC_V_MIN / 1000.0f; + float v_max = (float)CONFIG_BMU_VRM_SOC_V_MAX / 1000.0f; +#elif CONFIG_BMU_PACK_CLASS_48V /* VRM desactive : fenetre par classe */ + float v_min = 44.6f, v_max = 53.5f; +#else + float v_min = 24.0f, v_max = 28.8f; +#endif float soc = (avg_v - v_min) / (v_max - v_min) * 100.0f; if (soc < 0) soc = 0; if (soc > 100) soc = 100; diff --git a/firmware-idf/components/bmu_config/Kconfig b/firmware-idf/components/bmu_config/Kconfig index 16b16d1..59be5b3 100644 --- a/firmware-idf/components/bmu_config/Kconfig +++ b/firmware-idf/components/bmu_config/Kconfig @@ -1,12 +1,41 @@ menu "BMU Protection Config" + choice BMU_PACK_CLASS + prompt "Classe de tension du parc" + default BMU_PACK_CLASS_24V + help + Fixe les defauts usine des seuils tension (surchargeables via + NVS/BLE/ecran), les bornes de reglage et le garde de + plausibilite des lectures INA237. + 24V = packs 7s Li-ion / 8s LFP (fenetre 20-30V). + 48V = packs 13s Li-ion (fenetre 39.0-54.6V) — necessite le + hardware BMU-v2-48v (sous-carte IRF5210 + buck LM5164), cf. + docs/superpowers/specs/2026-07-05-bmu-48v-13s-variant-design.md + + config BMU_PACK_CLASS_24V + bool "24V — packs 7s Li-ion / 8s LFP" + + config BMU_PACK_CLASS_48V + bool "48V — packs 13s Li-ion" + endchoice + config BMU_MIN_VOLTAGE_MV int "Seuil sous-tension (mV)" + default 44600 if BMU_PACK_CLASS_48V default 24000 + help + Deconnexion du pack sous ce seuil. Defauts : 24000 = 3.43 V/el. + sur 7s ; 44600 = meme politique sur 13s (l'onduleur ~40.3 V et + le BMS pack restent en filets de securite). config BMU_MAX_VOLTAGE_MV int "Seuil sur-tension (mV)" + default 55200 if BMU_PACK_CLASS_48V default 30000 + help + Deconnexion au-dessus de ce seuil. Defauts : 30000 = marge + 600 mV sur la pleine charge 29.4 V (7s) ; 55200 = 4.246 V/el. + sur 13s, marge 600 mV sur la CV chargeur 54.6 V. config BMU_MAX_CURRENT_MA int "Seuil sur-courant (mA)" @@ -14,7 +43,11 @@ menu "BMU Protection Config" config BMU_VOLTAGE_DIFF_MV int "Tolerance desequilibre (mV)" + default 2000 if BMU_PACK_CLASS_48V default 1000 + help + 1000 mV @7s = ~143 mV/el. ; a iso-desequilibre par cellule le + 13s tolere ~2000 mV (x13/7). Cf. note de design 48V, point 4. config BMU_RECONNECT_DELAY_MS int "Delai reconnexion (ms)" diff --git a/firmware-idf/components/bmu_config/include/bmu_config.h b/firmware-idf/components/bmu_config/include/bmu_config.h index e905c9c..5fd090d 100644 --- a/firmware-idf/components/bmu_config/include/bmu_config.h +++ b/firmware-idf/components/bmu_config/include/bmu_config.h @@ -22,6 +22,23 @@ extern "C" { #define BMU_MAX_BATTERIES 32 #define BMU_MAX_TCA 8 +/* ── Classe de tension du parc (Kconfig BMU_PACK_CLASS) ──────────────── + * Bornes de reglage des seuils (BLE + ecran) et garde de plausibilite + * des lectures INA237. Les seuils actifs restent ceux de NVS/Kconfig. */ +#if CONFIG_BMU_PACK_CLASS_48V +#define BMU_VMIN_SET_FLOOR_MV 36000 /* V_min reglable 36.0-48.0 V */ +#define BMU_VMIN_SET_CEIL_MV 48000 +#define BMU_VMAX_SET_FLOOR_MV 45000 /* V_max reglable 45.0-56.0 V */ +#define BMU_VMAX_SET_CEIL_MV 56000 +#define BMU_V_PLAUSIBLE_MAX_MV 60000 /* lecture > 60 V = glitch I2C */ +#else /* 24 V (defaut) */ +#define BMU_VMIN_SET_FLOOR_MV 20000 +#define BMU_VMIN_SET_CEIL_MV 30000 +#define BMU_VMAX_SET_FLOOR_MV 25000 +#define BMU_VMAX_SET_CEIL_MV 35000 +#define BMU_V_PLAUSIBLE_MAX_MV 35000 +#endif + /* ── Limites buffers ───────────────────────────────────────────────── */ #define BMU_CONFIG_NAME_MAX 32 #define BMU_CONFIG_SSID_MAX 33 /* 802.11 max SSID = 32 + NUL */ diff --git a/firmware-idf/components/bmu_display/bmu_ui_config.cpp b/firmware-idf/components/bmu_display/bmu_ui_config.cpp index 84e4a4e..6a1ba31 100644 --- a/firmware-idf/components/bmu_display/bmu_ui_config.cpp +++ b/firmware-idf/components/bmu_display/bmu_ui_config.cpp @@ -14,11 +14,11 @@ static lv_obj_t *s_ssid_ta = NULL; static lv_obj_t *s_pass_ta = NULL; static lv_obj_t *s_mqtt_ta = NULL; -/* Valeurs seuils — modifiées par les steppers */ -static uint16_t s_v_min = 24000; -static uint16_t s_v_max = 30000; -static uint16_t s_i_max = 10000; -static uint16_t s_v_diff = 1000; +/* Valeurs seuils — modifiées par les steppers (défauts = classe de tension) */ +static uint16_t s_v_min = BMU_MIN_VOLTAGE_MV; +static uint16_t s_v_max = BMU_MAX_VOLTAGE_MV; +static uint16_t s_i_max = BMU_MAX_CURRENT_MA; +static uint16_t s_v_diff = BMU_VOLTAGE_DIFF_MV; static lv_obj_t *s_vmin_lbl = NULL; static lv_obj_t *s_vmax_lbl = NULL; @@ -185,8 +185,8 @@ void bmu_ui_config_create(lv_obj_t *parent) section_label(cont, "SEUILS PROTECTION"); bmu_config_get_thresholds(&s_v_min, &s_v_max, &s_i_max, &s_v_diff); - s_steppers[0] = {&s_v_min, 20000, 30000, 500, &s_vmin_lbl, "%u mV", true}; - s_steppers[1] = {&s_v_max, 25000, 35000, 500, &s_vmax_lbl, "%u mV", true}; + s_steppers[0] = {&s_v_min, BMU_VMIN_SET_FLOOR_MV, BMU_VMIN_SET_CEIL_MV, 500, &s_vmin_lbl, "%u mV", true}; + s_steppers[1] = {&s_v_max, BMU_VMAX_SET_FLOOR_MV, BMU_VMAX_SET_CEIL_MV, 500, &s_vmax_lbl, "%u mV", true}; s_steppers[2] = {&s_i_max, 1000, 50000, 1000, &s_imax_lbl, "%u mA", false}; s_steppers[3] = {&s_v_diff, 100, 5000, 100, &s_vdiff_lbl, "%u mV", true}; diff --git a/firmware-idf/components/bmu_display/bmu_ui_detail.cpp b/firmware-idf/components/bmu_display/bmu_ui_detail.cpp index 4ba6d68..cd1e057 100644 --- a/firmware-idf/components/bmu_display/bmu_ui_detail.cpp +++ b/firmware-idf/components/bmu_display/bmu_ui_detail.cpp @@ -77,7 +77,7 @@ static lv_color_t state_color(bmu_battery_state_t s) static void update_chart_range(bmu_chart_history_t *hist) { if (hist->count == 0) return; - float v_min = 35000, v_max = 15000; + float v_min = 65535, v_max = 0; /* seeds neutres, valables toutes classes de tension */ for (int i = 0; i < hist->count; i++) { int idx = (hist->head - hist->count + i + CONFIG_BMU_CHART_HISTORY_POINTS) % CONFIG_BMU_CHART_HISTORY_POINTS; float v = hist->voltage_mv[idx]; diff --git a/firmware-idf/components/bmu_ina237/CMakeLists.txt b/firmware-idf/components/bmu_ina237/CMakeLists.txt index 2d9b5bf..b677302 100644 --- a/firmware-idf/components/bmu_ina237/CMakeLists.txt +++ b/firmware-idf/components/bmu_ina237/CMakeLists.txt @@ -1,6 +1,6 @@ idf_component_register( SRCS "bmu_ina237.cpp" INCLUDE_DIRS "include" - REQUIRES driver bmu_i2c_bitbang + REQUIRES driver bmu_i2c_bitbang bmu_config PRIV_REQUIRES bmu_i2c ) diff --git a/firmware-idf/components/bmu_ina237/bmu_ina237.cpp b/firmware-idf/components/bmu_ina237/bmu_ina237.cpp index d8d7cb9..5c22b56 100644 --- a/firmware-idf/components/bmu_ina237/bmu_ina237.cpp +++ b/firmware-idf/components/bmu_ina237/bmu_ina237.cpp @@ -7,6 +7,7 @@ */ #include "bmu_ina237.h" +#include "bmu_config.h" #include "bmu_i2c.h" #include "esp_log.h" #include "freertos/FreeRTOS.h" @@ -241,19 +242,24 @@ esp_err_t bmu_ina237_init(i2c_master_bus_handle_t bus, uint8_t addr, goto fail_remove_device; } - /* 7. Alertes bus tension : BOVL et BUVL - * Bus voltage LSB = 3.125 mV, registre = voltage_mV / 3.125 */ - bovl = (uint16_t)(30000U * 1000U / 3125U); - buvl = (uint16_t)(24000U * 1000U / 3125U); - ret = ina237_write_reg16_retry(ctx->dev, INA237_REG_BOVL, bovl); - if (ret == ESP_OK) { - ret = ina237_write_reg16_retry(ctx->dev, INA237_REG_BUVL, buvl); - } - if (ret == ESP_OK) { - ESP_LOGI(TAG, "[0x%02X] Alertes bus: BOVL=30000 mV (reg=%u) BUVL=24000 mV (reg=%u)", - addr, bovl, buvl); - } else { - ESP_LOGW(TAG, "[0x%02X] Echec config alertes tension (non fatal)", addr); + /* 7. Alertes bus tension : BOVL et BUVL — seuils runtime (NVS/Kconfig, + * classe 24 V ou 48 V). Bus voltage LSB = 3.125 mV. */ + { + uint16_t th_min_mv = BMU_MIN_VOLTAGE_MV, th_max_mv = BMU_MAX_VOLTAGE_MV; + uint16_t th_max_ma, th_diff_mv; + bmu_config_get_thresholds(&th_min_mv, &th_max_mv, &th_max_ma, &th_diff_mv); + bovl = (uint16_t)((uint32_t)th_max_mv * 1000U / 3125U); + buvl = (uint16_t)((uint32_t)th_min_mv * 1000U / 3125U); + ret = ina237_write_reg16_retry(ctx->dev, INA237_REG_BOVL, bovl); + if (ret == ESP_OK) { + ret = ina237_write_reg16_retry(ctx->dev, INA237_REG_BUVL, buvl); + } + if (ret == ESP_OK) { + ESP_LOGI(TAG, "[0x%02X] Alertes bus: BOVL=%u mV (reg=%u) BUVL=%u mV (reg=%u)", + addr, th_max_mv, bovl, th_min_mv, buvl); + } else { + ESP_LOGW(TAG, "[0x%02X] Echec config alertes tension (non fatal)", addr); + } } bmu_i2c_unlock(); diff --git a/firmware-idf/components/bmu_protection/bmu_protection.cpp b/firmware-idf/components/bmu_protection/bmu_protection.cpp index 7876870..3490160 100644 --- a/firmware-idf/components/bmu_protection/bmu_protection.cpp +++ b/firmware-idf/components/bmu_protection/bmu_protection.cpp @@ -1,5 +1,6 @@ #include "bmu_protection.h" #include "bmu_balancer.h" +#include "bmu_config.h" #include "bmu_i2c.h" #include "bmu_rint.h" #include "esp_log.h" @@ -180,7 +181,7 @@ esp_err_t bmu_protection_check_battery_ex(bmu_protection_ctx_t *ctx, int idx, fl * Symptomes observes : V/2 (14.4V au lieu de 28.8V), V*1.4 (40V). * Filtre : si la batterie est CONNECTED/RECONNECTING et que la tension * s'ecarte de >30% de la derniere valeur connue, c'est un artefact. */ - if (v_mv > 35000 || fabs(i_a) > 50.0f) { + if (v_mv > BMU_V_PLAUSIBLE_MAX_MV || fabs(i_a) > 50.0f) { ESP_LOGW(TAG, "BAT[%d] lecture aberrante V=%.0f I=%.1f — skip", idx + 1, v_mv, i_a); return ESP_ERR_INVALID_RESPONSE; diff --git a/firmware-idf/components/bmu_vrm/Kconfig b/firmware-idf/components/bmu_vrm/Kconfig index bbb18c1..af1e37e 100644 --- a/firmware-idf/components/bmu_vrm/Kconfig +++ b/firmware-idf/components/bmu_vrm/Kconfig @@ -21,11 +21,13 @@ menu "BMU VRM (Victron Remote Monitoring)" config BMU_VRM_SOC_V_MIN int "SOC 0% voltage (mV)" + default 44600 if BMU_PACK_CLASS_48V default 24000 depends on BMU_VRM_ENABLED config BMU_VRM_SOC_V_MAX int "SOC 100% voltage (mV)" + default 53500 if BMU_PACK_CLASS_48V default 28800 depends on BMU_VRM_ENABLED endmenu diff --git a/firmware-idf/sdkconfig.defaults.48v b/firmware-idf/sdkconfig.defaults.48v new file mode 100644 index 0000000..8f9275e --- /dev/null +++ b/firmware-idf/sdkconfig.defaults.48v @@ -0,0 +1,6 @@ +# Overlay classe 48 V (packs 13s Li-ion, hardware BMU-v2-48v). +# Build : +# idf.py -DSDKCONFIG_DEFAULTS="sdkconfig.defaults;sdkconfig.defaults.48v" build +# (supprimer le sdkconfig existant ou effacer la NVS si des seuils 24 V +# y sont déjà persistés — cf. CLAUDE.md "Erase NVS") +CONFIG_BMU_PACK_CLASS_48V=y diff --git a/firmware/src/config.h b/firmware/src/config.h index c6d92f7..96eac0f 100644 --- a/firmware/src/config.h +++ b/firmware/src/config.h @@ -13,8 +13,16 @@ #define I2C_Speed 50 // Vitesse I²C en kHz (50 = fiable sur câblage long) // ── Protection tension ─────────────────────────────────────────────────────── +// Classe de tension du parc : définir BATTERY_PACK_CLASS_48V (build_flags +// PlatformIO : -DBATTERY_PACK_CLASS_48V) pour un parc 13s Li-ion +// (fenêtre 39,0–54,6 V, hardware BMU-v2-48v requis). Défaut : 24 V (7s/8s). +#ifdef BATTERY_PACK_CLASS_48V +#define alert_bat_min_voltage 44600 // Seuil sous-tension en mV (3,43 V/él. sur 13s) +#define alert_bat_max_voltage 55200 // Seuil sur-tension en mV (4,246 V/él., CV 54,6 V + 600 mV) +#else #define alert_bat_min_voltage 24000 // Seuil sous-tension en mV (24 V) #define alert_bat_max_voltage 30000 // Seuil sur-tension en mV (30 V) +#endif // ── Protection courant ─────────────────────────────────────────────────────── #define alert_bat_max_current 10 // Seuil sur-courant en A (valeur absolue)