Daly Smart BMS: Schreib-Befehle für Balance-Schwellwerte (0x1F), Current Wave/DfilterCur (0x13) und Engineering Unlock entschlüsselt

  • Daly Smart BMS: Schreib-Befehle für Balance-Schwellwerte (0x1F), Current Wave/DfilterCur (0x13) und Engineering Unlock entschlüsselt

    ⚠️ Haftungsausschluss

    Alle Informationen in diesem Beitrag werden ohne Gewähr und ausschließlich zu Informations- und Forschungszwecken bereitgestellt. Ich übernehme keinerlei Haftung für Schäden, Datenverlust oder jegliche Beeinträchtigung an BMS, Akkupack oder angeschlossenen Geräten, die aus der Verwendung dieser Befehle resultieren. Das Schreiben falscher Werte in BMS-Konfigurationsregister kann zu gefährlichen Zuständen führen, einschließlich Überladung, Tiefentladung, thermisches Durchgehen oder Brand. Wer diese Informationen nutzt, tut dies vollständig auf eigenes Risiko. Beim Arbeiten an Lithium-Batteriesystemen immer geeignete Sicherheitsmaßnahmen treffen (Sicherungen, Überwachung, brandsichere Umgebung).

    Zusammenfassung

    Aufbauend auf der Vorarbeit der Community (insbesondere tanoshimis Teensy-MITM-Sniffing auf diysolarforum.com und den Software-Beiträgen von thsc01 und Rockfan hier im Forum) konnte ich zwei bisher undokumentierte Schreib-Befehle und eine Engineering-Unlock-Sequenz des Daly Smart BMS verifizieren.

    Der wichtigste Fund ist der Schreib-Befehl für Current Wave (DfilterCur) — der Parameter, der bei tausenden Daly BMS weltweit das Balancieren verhindert. Außerdem erstmals bestätigt: der Schreib-Befehl für Balance-Schwellwerte (0x1F), den tanoshimi aus dem Muster Read−0x40=Write vorhergesagt, aber nie unabhängig bestätigt hatte.

    Getestetes BMS

    • Daly Smart BMS "Home Energy Storage" 16S 48V 100A 1A Active Balance
    • Hardware: BMS-103 / VE-309, Firmware 41_2308 / 29_000B
    • Gekauft September 2023 über Alibaba (Sharon Liu / Daly)
    • PC-Software: DalyBmsMonitor V2.2.1 (Admin-Modus) — Danke an thsc01 für Upload und Passwort hier im Forum!

    Sniffing-Aufbau

    Code
    [Daly BMS] --UART--> [USB-Serial CH341] --USB--> [Raspberry Pi] | TCP:2217 (Python-Proxy) | [Windows-PC] HW VSP3 (virtueller COM-Port) | [DalyBmsMonitor V2.2.1]

    Ein Python-Proxy auf dem Pi leitet alle Bytes transparent weiter und loggt jeden Frame in beide Richtungen als JSONL mit Zeitstempel, Command-ID und Daten. HW VSP3 (kostenlos, hw-group.com) erstellt auf dem Windows-PC einen virtuellen COM-Port, der auf den TCP-Socket des Pi zeigt. DalyBmsMonitor merkt nichts vom Sniffer.

    Wichtige Erkenntnis: Die V1.14.x-Software (für K/M/S-Serie) spricht NICHT das A5-Protokoll, sondern ein proprietäres 32-Byte-Bulk-Format. Nur die V2.x-Software nutzt A5. Wenn euer BMS mit V2.x funktioniert aber nicht mit V1.14.x, habt ihr ein A5-BMS — auch wenn es als "Home Energy Storage" (K/M/S) vermarktet wurde.

    Fund 1: Engineering Unlock Sequenz (0xE0–0xE3)

    Die PC-Software sendet beim Verbinden eine Unlock-Sequenz, bevor sie erweiterte Befehle (über 0x90–0x98 hinaus) abfragt:

    Code
    TX: A5 40 E0 08 A5 5A 00 00 00 00 00 00 [Checksumme] → Engineering Mode Unlock
    TX: A5 40 E1 08 A5 5A 00 00 00 00 00 00 [Checksumme] → Engineering Enable 1
    TX: A5 40 E2 08 A5 5A 00 00 00 00 00 00 [Checksumme] → Engineering Enable 2
    TX: A5 40 E3 08 [JJ MM TT HH MM SS 00 00] [Checksumme] → RTC Sync

    Die Magic-Bytes A5 5A im Datenbereich dienen als Unlock-Token. Das ist der Grund, warum Befehle wie 0x5F, 0x53, 0x59–0x60 nicht antworten, wenn man sie "kalt" sendet — das BMS verlangt zuerst diesen Handshake. Wer ein eigenes Tool baut und Konfigurations-Register lesen will, muss vorher 0xE0–0xE2 senden.

    Fund 2: Balance-Schwellwerte schreiben — Befehl 0x1F ✅ Bestätigt

    Lesen (0x5F):

    Code
    TX: A5 40 5F 08 00 00 00 00 00 00 00 00 [Checksumme]
    RX: A5 01 5F 08 [start_hi][start_lo][diff_hi][diff_lo] 00 00 00 00 [Checksumme]

    Schreiben (0x1F):

    Code
    TX: A5 40 1F 08 [start_hi][start_lo][diff_hi][diff_lo] 00 00 00 00 [Checksumme]
    RX: A5 01 1F 08 [Bestätigung] [Checksumme]
    Bytes Beispiel
    0–1 0x0C80 = 3200 mV
    2–3 0x0014 = 20 mV
    4–7 0x00000000

    Getestet: Balance-Start von 3400 → 3200 mV und Balance-Diff von 30 → 20 mV geändert. Rücklesen über 0x5F bestätigte die neuen Werte. BMS hat innerhalb weniger Minuten mit dem Balancieren begonnen.

    Fund 3: Current Wave / DfilterCur + Sleep-Timer — Befehl 0x13 ✅ Bestätigt

    Das ist der wichtigste Fund. Der "Current Wave"-Parameter (intern: DfilterCur) steuert den Mindest-Stromerkennungsschwellwert. Jeder Strom unterhalb dieses Wertes wird vom BMS als 0A gemeldet. Werkseinstellung ist typischerweise 1,0–2,0A.

    Warum das wichtig ist: Active Balancing zieht ~30 mA. Steht Current Wave auf 1A, sieht das BMS 0A beim Balancieren und:

    1. Erkennt die Balance-Aktivität nicht als "Strom fließt"
    2. Löst irgendwann den Sleep-Modus aus
    3. Verhindert effektiv das Balancieren im Leerlauf/Float-Zustand

    Lesen (0x53):

    Code
    TX: A5 40 53 08 00 00 00 00 00 00 00 00 [Checksumme]
    RX: A5 01 53 08 [b0][b1][b2][b3][b4][sleep_hi][sleep_lo][current_wave] [Checksumme]

    Schreiben (0x13):

    Code
    TX: A5 40 13 08 [b0][b1][flags_hi][flags_lo][enable][sleep_hi][sleep_lo][current_wave] [Checksumme]
    RX: A5 01 13 08 [Bestätigung] [Checksumme]
    Byte(s) Beispiel
    0–1 Vom Read übernehmen
    2–3 Vom Read übernehmen
    4 0x01 = aktiviert, 0x00 = deaktiviert (nicht getestet)
    5–6 0xF230 = 62000 s
    Current Wave 7 0,1A 0x02 = 0,2A ← kleinster sinnvoller Wert

    Getestet: Current Wave von 0x0A (1,0A) auf 0x02 (0,2A) und Sleep-Timer von 3600 auf 62000 geändert. Nach dem Setzen von Current Wave auf 0,2A und einer Nullpunkt-Kalibrierung in der PC-Software zeigt das BMS im Leerlauf ~0,1–0,3A statt 0A an, und Active Balancing greift jetzt zuverlässig.

    Empfehlung: Nach dem Setzen von Current Wave auf 0,2A eine Strom-Nullpunktkalibrierung durchführen (ohne Last/Ladegerät). Damit verschiebt sich der Nullpunkt des BMS leicht, sodass es im Leerlauf immer einen kleinen positiven Strom sieht — was es wach hält und das Balancieren ermöglicht.

    Weitere entdeckte Lese-Befehle

    Kapazität (mAh), Nennspannung
    ASCII-String
    Zellenanzahl, Flags
    Zusätzliche Statusdaten
    Balance-Strom, Flags
    Active Balance Enable, Flags

    Beschreibung
    Batterie-Kenndaten
    Alternative FW-Version
    Erweiterter Status
    Erweiterter Status 2
    Balance-Status (Equilibrium)
    Balance-Konfiguration

    Alle benötigen den Engineering Unlock (0xE0–0xE2) um zu antworten.

    Wichtige Hinweise

    1. Engineering Unlock (0xE0–0xE2) vor jedem erweiterten Read/Write senden. Ohne Unlock ignoriert das BMS Befehle außerhalb von 0x90–0x98 stillschweigend.

    2. Das Schreib-Adressbyte ist 0x40 (gleich wie Lesen), NICHT 0x20 wie manche Quellen behaupten.

    3. Immer zuerst die aktuellen Werte lesen (0x53, 0x5F), bevor ihr schreibt. Alle Bytes die ihr nicht versteht unverändert zurückkopieren. Nur die spezifischen Felder ändern die ihr ändern wollt.

    4. V1.14.x ≠ A5-Protokoll. Wenn euer BMS mit der V2.x DalyBmsMonitor-Software funktioniert, spricht es A5. Wenn es nur mit V1.14.x BMSTool geht, nutzt es ein anderes proprietäres Bulk-Protokoll und diese Befehle gelten möglicherweise nicht.

    5. Hardware-Sicherheit: Der UART-Ground am Daly BMS ist mit B− (Batterie-Minus) verbunden, das bei abgeschalteten MOSFETs −50V gegenüber P− haben kann. Immer einen galvanisch getrennten USB-zu-Seriell-Adapter verwenden.

    Python-Beispiel: Current Wave auf 0,2A setzen

    NUTZUNG AUF EIGENE GEFAHR. Falsche Werte in BMS-Konfigurationsregistern können gefährliche Zustände verursachen. Immer nach dem Schreiben rücklesen und verifizieren.

    Gesnifft am 04.04.2026 an einem Daly BMS-103/VE-309 (16S 48V 100A, Active Balance 1A, FW 41_2308) mit DalyBmsMonitor V2.2.1 über TCP-Proxy auf Raspberry Pi.


    Research und Dokumentation mit KI-Unterstützung (Claude/Anthropic).

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!