Une Battery Management Unit qui met en parallèle jusqu'à 16 packs 24–30 V en toute
sécurité : chaque batterie est mesurée individuellement, et déconnectable par MOSFET dès qu'elle sort des clous.
Dossier techniqueGPLv32026
16packs supervisés (32 en dual-bus)
24–30 Vclasse 24 V (7s Li-ion / 8s LFP) · variante 48 V (13s) dessinée
4×44 cartes × 4 voies, chaînées RJ45
2 mΩshunt de mesure par voie
8MOSFETs par voie, back-to-back
26tests automatisés, sans matériel
La carte BMU v2 assemblée — 4 voies batterie, sous-cartes MOSFET verticales, module « I2C Amplifier and Isolator » en tête.BMU.jpeg — rendu FreeCAD
24–30 V ✶ 16 PACKS ✶ SHUNT 2 mΩ ✶ COUPURE MOSFET EN µS ✶ ISOLATION GALVANIQUE ✶ BLOCAGE BIDIRECTIONNEL ✶ MODE MANUAL ON ✶ MESURE JUSQU’À 85 V ✶ 5 ÉTATS · 5 CRITÈRES ✶ 26 TESTS ✶ 24–30 V ✶ 16 PACKS ✶ SHUNT 2 mΩ ✶ COUPURE MOSFET EN µS ✶ ISOLATION GALVANIQUE ✶ BLOCAGE BIDIRECTIONNEL ✶ MODE MANUAL ON ✶ MESURE JUSQU’À 85 V ✶ 5 ÉTATS · 5 CRITÈRES ✶ 26 TESTS ✶
01 · Contexte
Pourquoi mettre des batteries en parallèle ?
Quand une installation doit vivre plusieurs heures sans réseau électrique — LED, son,
projection, contrôle — un seul pack 24–30 V ne suffit pas. La mise en parallèle est la réponse
naturelle : elle additionne les capacités sans changer la tension du bus.
Autonomie
Les ampères-heures s'additionnent : 4 packs de 100 Ah = 400 Ah sous la même tension. La durée de l'installation se dimensionne en ajoutant des packs.
Puissance crête
Le courant se répartit entre les branches : chaque pack ne fournit qu'une fraction de la pointe, et reste dans sa zone de confort thermique.
Redondance
Un pack défaillant ne doit pas éteindre le système — à condition de pouvoir l'isoler proprement pendant que les autres continuent.
Parc hétérogène
Sur le terrain, les packs n'ont ni le même âge ni le même état de charge. Il faut pouvoir les combiner sans rituel de pré-équilibrage manuel.
« La mise en parallèle naïve de batteries à des états de charge différents génère des courants
d'équilibrage dangereux. »Spécification du projet — gate S0, 2026-03-25
C'est tout l'objet de la BMU : offrir les bénéfices du parallèle sans ses dangers. Un boîtier
ESP32-S3-BOX-3 à écran tactile pilote une électronique de puissance dédiée, avec
supervision BLE, app iOS et télémétrie cloud.
02 · Le problème physique
Paralléliser des batteries, c'est risqué
Deux packs connectés en parallèle s'imposent mutuellement leur tension. Toute différence
d'état de charge se traduit par un courant de circulation que rien ne limite, sinon les résistances internes.
Icirculation = ΔV / (Rint·A + Rint·B + Rcâblage)
Ordre de grandeur : ΔV = 1 V et ΣR ≈ 70 mΩ donnent ≈ 14 A — au-delà du seuil de
coupure de la BMU (10 A) et très au-delà du déséquilibre admis par le cahier des charges (1 A).
Courant d'inrush à la connexion
Brancher un pack chargé sur un bus plus bas : l'appel de courant n'est limité que par quelques dizaines de milliohms. Arcs, connecteurs abîmés, fusibles.
Décharge croisée
Un pack faible ou vieilli devient une charge pour les autres : les packs sains le rechargent en continu, l'énergie stockée part en chaleur.
Vieillissement asymétrique
Les résistances internes divergent avec l'âge. Le pack le plus « raide » travaille moins, le plus faible encaisse tout — et vieillit encore plus vite.
Recharge incontrôlée par body diode
Un simple MOSFET de coupure laisse passer le courant dans un sens via sa diode de corps : la voie « coupée » peut quand même se faire recharger. Il faut un blocage bidirectionnel.
Défaut alimenté par toute la flotte
Une cellule en court-circuit dans un pack est alimentée par tous les autres packs en parallèle : l'énergie cumulée aggrave l'emballement thermique.
BMS internes aveugles
Chaque pack a son BMS, mais aucun ne voit le système global : personne n'arbitre le déséquilibre entre packs. C'est le rôle de la BMU.
03 · Le cahier des charges
Surveiller chaque pack, couper vite, reconnecter prudemment
Formalisé en gates Kill_LIFE (S0 intake → S3 validation terrain). Les fonctions MUST
du gate S1 (specs/01_spec.md) :
ID
Fonction
Réponse du système
F01–F02
Mesure tension + courant par batterie
INA237 sur I2C, 5 lectures/s
F03–F04
Coupure sur sur-tension / sous-tension
> 30 V ou < 24 V → MOSFET OFF
F05
Coupure sur sur-courant (bidirectionnel)
|I| > seuil → OFF, défaut dur à 1,4× le seuil
F06
Coupure sur déséquilibre de tension
> 1 V sous le max de la flotte → OFF
F07
Reconnexion automatique
délai 10 s après disparition du défaut
F08
Verrouillage permanent
> 5 coupures → LOCKED jusqu'au reboot
F11
Jusqu'à 16 packs
4 cartes × 4 voies chaînées (32 en dual-bus firmware)
Seuil
Défaut
Configurable
Tension minimale
24 000 mV
Kconfig + NVS (écran, BLE) — plage 20–30 V
Tension maximale
30 000 mV
Kconfig + NVS — plage 25–35 V
Courant maximal
10 000 mA
Kconfig + NVS — plage 1–50 A (spec initiale : 1 A)
Déséquilibre vs max flotte
1 000 mV
Kconfig + NVS — plage 0,1–5 V
Délai de reconnexion
10 000 ms
Kconfig
Coupures avant verrouillage
5
Kconfig
☛
Règle safety du projet : les seuils ne peuvent
jamais être affaiblis à distance — les écritures BLE sont bornées aux plages ci-dessus, chiffrement de lien
obligatoire, et la machine de protection garde le droit de veto sur toute commande.
04 · Architecture système
4 cartes × 4 voies, un bus I2C en RJ45
Découverte clé de l'analyse des schémas : la carte mère ne porte pas 16 voies mais
4. Le système complet est modulaire — quatre cartes identiques chaînées par câble RJ45,
chacune flottant au potentiel de ses batteries.
Cartographie I2C
Carte
TCA9535
INA237
Batteries
#1
0x20
0x40–0x43
1–4
#2
0x21
0x44–0x47
5–8
#3
0x22
0x48–0x4B
9–12
#4
0x23
0x4C–0x4F
13–16
L'invariant topologique
Nb_TCA × 4 == Nb_INA
Vérifié au boot, à chaque cycle de protection et à chaque re-scan hotplug (10 s). Toute
incohérence — carte débranchée, capteur muet — déclenche le fail-safe : toutes les voies OFF,
et le système reste vivant pour re-détecter une topologie valide.
05 · La carte mère BMU v2
170 × 100 mm, 4 couches, la puissance partout
Face avant — RJ45 de bus et bandeau logique en haut (TCA9535, adressage, buck Manual ON), 4 voies de puissance à cuivre nu avec leur shunt 2 mΩ et leur INA237.rendu kicad-cli · BMU v2.kicad_pcb
Face arrière — les embases 2×5 où s'enfichent les sous-cartes MOSFET (deux par voie : entrée batterie / bus), les connecteurs de commande 3 points, et les tables d'adressage A0/A1/A2 sérigraphiées à côté de chaque groupe de jumpers.rendu kicad-cli · face B
Stackup 4 couches
1,6 mm FR4, cuivre 35 µm (1 oz) sur les 4 couches. Les nets de puissance (+BATT, +BAT_IN ×4, sorties shunt ×4, GND) sont des zones remplies simultanément sur F/In1/In2/B : 4 × 35 µm de section.
140 empreintes · 92 nets
103 vias (0,8/0,4 mm), pistes signal 0,2–0,5 mm. Layout des 4 voies répliqué par plugin (replicate layout). BOM ~107 références, flux JLCPCB outillé (kicad-jlcpcb-tools, 20 réf. LCSC dans les schémas).
Connectique de puissance
Par voie : pastilles M5 à cosse (+BAT_IN, GND). Bus de sortie : 2 bornes à vis traversantes (J11 +BATT, J12 GND). Sous-cartes : embases 2×5 — 10 contacts en parallèle par côté.
Adressage 100 % passif
19 solder jumpers 3 pads (JP2–JP20). L'INA237 accepte 4 niveaux (GND/VS/SDA/SCL) sur A0/A1 : 16 adresses avec 2 pins. Table de correspondance dans adresse TCA_INA.xlsx.
La v1 (193,5 × 105 mm, fabriquée) commutait le moins avec des IRFZ44N traversants ;
la v2 passe en high-side, sous-cartes enfichables par l'arrière — comparatif complet en section 12.
06 · Chaîne de mesure
Un INA237 et un shunt 2 mΩ par batterie
Le TI INA237 est un moniteur de puissance à ADC delta-sigma 16 bits : il mesure
la chute sur le shunt (±163,84 mV ou ±40,96 mV pleine échelle), la tension bus avec un mode commun
jusqu'à +85 V, la température (±1 °C) — et calcule courant et puissance en interne.
Feuille « batteries1 » (répliquée ×4) : shunt Kelvin + INA237, jumpers d'adressage A0/A1, diode-OR de commande (BATT_SW / MANUAL_SW), LED bleue témoin, connecteur vers la sous-carte MOSFET.batteries.kicad_sch · cliquer pour zoomer
Mesure côté haut, en 4 fils
Shunt HOVB4026 : 2 mΩ · 5 W · 1 % · 4 terminaux — les pads de puissance portent le courant, les pads sense partent vers IN+/IN− en Kelvin, filtrés par 0,1 µF différentiel.
À 2 mΩ, la pleine échelle ±163,84 mV équivaut à ≈ ±82 A de dynamique théorique ; à 10 A le shunt ne dissipe que 0,2 W sur 5 admissibles.
VBUS lit la tension pack en amont du shunt ; l'ADC tourne en continu — conversion 540 µs, 64 moyennes matérielles.
Calibration firmware : LSB courant ≈ 305 µA/bit (I max 10 A), SHUNT_CAL ≈ 500 ; VBUS à 3,125 mV/bit.
L'alerte câblée en dur
Les seuils BOVL = 30 V / BUVL = 24 V sont programmés dans l'INA237 à l'init : le comparateur matériel du chip surveille même si le firmware est occupé.
La broche ALERT (pull-up 10 k) remonte vers le TCA9535 (P0.4–P0.7) — lue en polling, l'INT du TCA n'étant pas routé vers le maître.
Lecture V+I atomique sous un seul verrou I2C ; sorties initialisées à NAN — un échec de lecture ne laisse jamais une donnée fantôme.
Anti-aberration : rejet des sauts > ±30 % (glitchs I2C observés type V/2, V×1,4) et des valeurs impossibles (> 35 V, > 50 A).
07 · Commutation
8 MOSFETs tête-bêche sur une sous-carte enfichable
Le point safety central du parallélisme : un seul MOSFET « coupé » conduit quand même dans
un sens, par sa diode de corps. La BMU monte donc deux groupes de 4 IRF4905 back-to-back,
drains communs — diodes de corps opposées, blocage bidirectionnel réel.
La sous-carte (38 × 85,5 mm, 2 couches) : 8× IRF4905 en D2PAK, deux groupes de 4 tête-bêche sur cuivre nu — dissipation et section de courant ; drivers SOT-23 en bas à droite.rendu kicad-cli
Q2–Q5 ‖ amont, Q7–Q10 ‖ aval, drains réunis ; commande par BJT, grilles tirées vers GND pour fermer.BMU_switch_mosfet.kicad_sch
IRF4905 — P-channel 55 V / 74 A
4 en parallèle par direction : RDS(on) divisée par 4, marge thermique confortable pour 10 A nominal par voie.
Commande high-side simple
Un BC337 par groupe : CMD haut → grilles tirées à GND → VGS ≈ −Vbat → ON. Pull-up 10 k grille-source pour l'état OFF. Coupure en microsecondes.
Enfichable = remplaçable
2 embases IDC 2×5, les 10 contacts en parallèle sur chaque net de puissance. Une voie en panne ? On change la sous-carte, pas la carte mère.
Évolutif en tension — variante 48 V dessinée
La chaîne de mesure INA237 accepte +85 V de mode commun : c'est la sous-carte qui fixe le plafond. La déclinaison 48 V (packs 13s, 54,6 V max) est à l'étude : IRF5210 (100 V, même boîtier D2PAK — drop-in), clamp zener VGS 12 V + R série, BJT de commande 300 V, buck Manual ON à passer en 100 V. Schéma ci-dessous, note de design dans le repo.
⚠ Point de vigilance relevé
VGS atteint −24/−30 V, au-delà du ±20 V absolu max de l'IRF4905, sans zener de clamp ni résistances de grille individuelles. Fonctionne en statique, mais fragilise les MOSFETs — candidat d'amélioration v3.
La variante 48 V (rev 0.2-draft, ERC au niveau du baseline) : 8× IRF5210 100 V, R série 15 k + zener BZT52C12 qui clament VGS à −12 V sur toute la plage 39–54,6 V, commande MMBTA42 300 V.BMU_switch_mosfet_48v.kicad_sch
Le PCB routé : R6/R7 insérées en série dans les lignes de grille, D1/D2 au plus court des rails — DRC au niveau du baseline, connectivité 100 %.rendu kicad-cli · BMU_switch_mosfet_48v.kicad_pcb
Côté carte mère, la cellule « Manual ON » redessinée : LM5164 (100 V, synchrone, 5,0 V / 202 kHz) remplace le MCP16331 (50 V max) — la roue libre et la diode de bootstrap disparaissent, entrée en 2×2,2 µF/100 V, réseau ripple type 3.power_48v.kicad_sch · intégrée au projet BMU-v2-48v
Et son layout sur la carte mère v2.1 : U9 en HSOP-8 dans le corridor libéré, R48 (RON), C22 de bootstrap, self 10×10, COUT 1210 et rangée feedback re-routés — DRC au niveau du baseline de production, 0 pad non connecté.BMU_v2_48v.kicad_pcb · coin haut-droit
Le pack 13s sous la loupe
Le pack cible : Ninebot 13s — 46,8 V, 24,5 Ah, 1 147 Wh — récupéré de trottinettes en fin de service.
Ports distincts au connecteur : 2 broches de puissance + signaux. Charge, décharge et communication séparées — le comportement en parallèle reste à caractériser.
Le BMS interne, noyé dans le silicone (et toujours vivant — LED bleue). C'est lui qui décidera si le backfeed passe : risque n°1 du scénario 48 V.
08 · Bus I2C isolé
Chaque carte flotte au potentiel de son pack
Relier 16 batteries à un même bus de données, c'est créer 16 boucles de masse potentielles.
La BMU isole galvaniquement chaque carte : le bus RJ45 vit dans son propre domaine électrique.
La feuille I2C : RJ45 + buffer TCA9517 (domaine bus VCC/GND1) → isolateur ISO1540 → domaine local +3,3 V. Le TCA9535 pilote 4 commandes, lit 4 alertes INA, allume 8 LEDs.I2C.kicad_sch · cliquer pour zoomer
TCA9517 — le muscle
Buffer/répéteur I2C en entrée de chaque carte : retend les fronts sur le câblage long. Bus ralenti à 50 kHz (« fiable sur câblage long » — commentaire du firmware).
ISO1540 — la barrière
Isolateur I2C galvanique entre le domaine bus (VCC/GND1, véhiculé par le RJ45) et le domaine local (+3,3 V flottant, référencé au − du pack local).
Alim isolée à transfo
Driver push-pull VPS8505 + transformateur VPT85BB-01A + redressement Schottky : le 3,3 V local est fabriqué à travers l'isolation. Aucun retour de masse entre packs.
Tête de bus « I2C repeater »
Petite carte dédiée (62,5 × 31 mm) côté ESP32-S3-BOX-3 : mêmes ISO1540 + TCA9517 + alim isolée, 2 RJ45 pour partir en chaîne ou en étoile.
La tête de bus « I2C Amplifier and Isolator » : 2 RJ45 blindés (chaîne/étoile), transformateur d'isolation et son driver, ISO1540, réservoir de filtrage.rendu kicad-cli · I2C_repeter.kicad_pcb
09 · Mode dégradé
« Manual ON » : l'installation survit à son électronique
Sur une installation en exploitation, une BMU en panne ne doit pas couper l'alimentation. Un simple header
deux points (J3 — Switch Manual ON) force toutes les voies fermées, sans MCU, sans bus,
sans firmware.
Comment ça marche
Un buck dédié MCP16331 (entrée jusqu'à 50 V) tire ≈ 5 V directement du bus +BATT 24–30 V.
Ce rail /MANUAL_SW attaque chaque commande de voie par une diode-OR (1N4148W) avec la sortie du TCA9535.
Fermer J3 = toutes les commandes à l'état haut = tous les MOSFETs ON. La protection disparaît, l'alimentation reste.
En v1 c'était un solder jumper (fer à souder requis) ; en v2, un header actionnable sur le terrain, à la main.
La paire rouge/verte est pilotée par le TCA9535 (état logiciel) ; la LED bleue est branchée
directement sur la ligne de commande — elle dit la vérité matérielle, y compris en Manual ON.
Les jacks RJ45 ont leurs propres LEDs d'activité bus.
10 · Protection firmware
Une machine à 5 états, évaluée 5 fois par seconde
Le composant bmu_protection (ESP-IDF 5.4) tourne en tâche FreeRTOS priorité 8,
période 200 ms, nourrie au watchdog. Chaque cycle : lecture V/I des 16 voies, décision, commutation.
Ordre d'évaluation (par voie)
0. Topologie invalide → fail-safe all OFF (jamais rallumé tant que Nb_TCA×4 ≠ Nb_INA)
2. Défaut dur : V > 30 V ou |I| > 14 A (1,4×) → ERROR, OFF immédiat + double-off
3. V < 1 V → pack absent → DISCONNECTED
4. nb_switch > 5 → LOCKED permanent
5. V ∉ [24 ; 30] V ou |I| > 10 A → OFF réversible
6. Déséquilibre > 1 V vs max flotte, confirmé 3 cycles → OFF
7. Tout est bon → reconnexion possible après 10 s
Et autour de la machine
Soft-balancing : pack > 200 mV au-dessus de la moyenne pendant 3 cycles → duty-cycling ~60 % (3 ON / 2 OFF), minimum 3 packs connectés. La protection a veto sur chaque demande.
R_int opportuniste : chaque coupure sous charge mesure gratuitement Rohmique = ΔV/I à +100 ms et Rtotale à +1 s. Alerte au-delà de 50/100 mΩ.
SOH embarqué : réseau FPNN quantifié INT8 (11,7 Ko, TFLite Micro) — état de santé par pack toutes les 10 s, sur l'ESP32.
I2C robuste : mutex global à héritage de priorité, 5 échecs consécutifs → reset du bus, score de santé par capteur (critique < 30 → voie forcée OFF).
⚠
Écart doc/code assumé : le README annonce un
backoff exponentiel de reconnexion — le code (IDF et legacy) implémente en réalité un délai fixe de 10 s
+ compteur + verrouillage au 6ᵉ essai. Même transparence pour le timestamp InfluxDB direct (non branché sur SNTP,
horodatage délégué à Telegraf) et l'override NVS du broker MQTT (écrit mais non consommé par le client).
11 · Supervision
De l'écran tactile au cloud
Écran LVGL sur la BOX-3
5 onglets (Batt, SOH, Sys, Alert, Config) à 2 Hz : grille des 16 voies, V min/moy/max du pack, graphes 5 min, seuils réglables aux steppers, mode nuit à 30 s.
BLE chiffré + app iOS
4 services GATT (batteries, système, contrôle, Victron) — toute écriture exige un lien chiffré et repasse par la machine de protection. App SwiftUI 3 rôles (admin / technicien / viewer), PIN + Face ID, cache offline.
Écosystème Victron
La BMU se fait passer pour un SmartShunt : advertising « Instant Readout » chiffré AES-CTR + GATT compatible VictronConnect. Elle scanne aussi les vrais équipements Victron (MPPT solaire en VE.Direct).
Télémétrie résiliente
MQTT → Telegraf → InfluxDB → Grafana (docker sur serveur dédié). WiFi coupé ? Les mesures s'accumulent en flash FAT (2 × 512 Ko en rotation) et sont rejouées à la reconnexion.
12 · Validation & état du projet
Testé sans matériel, audité deux fois
… et maintenant sur le banc — gate S3 en cours
La carte v2.0 sous tension sur des packs Li-ion 7s 18 Ah (Anderson, coupe-batterie + porte-fusible en amont, alim de labo en source) — les LEDs bleues « commande ON » confirment les voies actives.photo banc
Le détail qui explique le cuivre nu : zones rechargées à l'étain (tresse noyée) et cosses boulonnées sur les pastilles — la section des 4 couches est doublée par l'apport de soudure.photo banc
Audit 2026-06-13 : 3 points de concurrence hotplug (H3/H4/H13) documentés, refactor en attente de banc
Hardware v3 candidat : clamp VGS des IRF4905, résistances de grille, exploitation de l'INT du TCA9535, variante 48 V : sous-carte dessinée et routée (IRF5210) + carte mère v2.1 complète — schéma intégré et coin buck LM5164 re-routé (DRC au baseline) ; reste le banc
v1 → v2, ce qui a changé
BMU v1 (fabriquée)
BMU v2 (prête prod)
Coupure
low-side (le −), IRFZ44N N-ch TO-220 sur carte mère
high-side (le +), 8× IRF4905 back-to-back sur sous-carte
Blocage
unidirectionnel
bidirectionnel
Maintenance
dessouder
déficher la sous-carte
Manual ON
solder jumper
header terrain J3
Dimensions
193,5 × 105 mm
170 × 100 mm
Isolation I2C
identique — ISO1540 + alim transfo déjà en v1
Un GND commuté (v1) casse la référence de masse de la voie isolée ; passer le
commutateur côté + avec un GND commun (v2) est plus sain — et le back-to-back règle la body diode.