Bitte um Review: Neuer Battery Code, Ausschalten bei Akku leer und MAX17055

Hi Leute,

ich habe bei meiner Version, um sinnvoll den den Ladestand des LiFePO4 auslesen zu können, Unterstützung für einen MAX17055 eingebaut. Dafür musste ich etwas umstrukturieren und würde mich freuen wenn sich jemand bereit erklären würde, drüber zu schauen und den Code zu testen.

Neue Features:

  • Niedriger Ladezustand wird erkannt und shutdown/deepsleep ausgelöst
  • Battery.h ist jetzt generisch und es könnten andere Backends hinzugefügt werden (manuelles Coulomb-Counting z.B.)
  • MAX17055 als Batterie-Implementierung

Dass zur Zeit natürlich keiner einen MAX17055 hat ist mir klar, aber diejenigen mit Spannungsmessung könnten gerne mal testen ob noch alles klappt und ob der ESPuino den kritischen Ladezustand erkennen kann und dann auch richtig herunterfährt / aus bleibt.

Ich gehe davon aus, dass noch die eine oder andere Änderung nötig sein wird :D.

Hier kommt ihr zum Pull: Complete Battery Rewrite and MAX17055 support by SZenglein · Pull Request #123 · biologist79/ESPuino · GitHub

3 „Gefällt mir“

Hallo @SZenglein,

danke erstmal für deinen PR!
Ein paar Anmerkungen habe ich dazu, habe die Änderungen jedoch bisher nur überflogen. Also wenn ich da mit etwas falsch liege, dann korrigiere mich gerne.

  1. Die i2c-Instanzierung muss mit dem Port-Expander und mit RC522-I2C in Einklang gebracht werden. Weil die hängen auf jeden Fall alle an der gleichen Instanz.
  2. Ist die i2c-Adresse immer gleich? Weil wenn nicht, dann müsste die konfigurierbar sein.
  3. Die Umbenennung des zentralen Switches von MEASURE_BATTERY_VOLTAGE zu BATTERY_MEASURE_ENABLE möchte ich nicht so wirklich. Das ist an unendlich vielen Stellen hier im Forum referenziert. Wenn man das überhaupt macht, dann muss man das abwärtskompatibel halten. Heißt: Das muss auch mit dem alten Namen funktionieren.
  4. Ich habe kürzlich erst ENABLE_BATTERY_MEASUREMENTS im Code eingeführt. Das war dafür gut, dass es keine Compile-Fehler gibt auf GitHub. Denn es ist so, dass die Akkumessung per Default in der settings.h aktiviert ist, mindestens jedoch mit dem AZDelivery-Board gibt es eine Variante, die das nicht kann. Wenn ich jedoch anfange und im Settings-File für das AZDelivery-Board Sachen dafür auszukommentieren, dann gibt es Compilefehler. Ergo brauche ich eine Möglichkeit, um das zB auf 99 zu setzen. Und an der Stelle kommt jetzt das Flag ENABLE_BATTERY_MEASUREMENTS ins Spiel, da es die Messungen nur tatsächlich dann zulässt, wenn die IO-Angabe zwischen 0 und 39 liegt.
    Wenn ich das richtig sehe, ist das wieder „rausgekegelt“.
  1. SHUTDOWN_ON_BAT_CRITICAL als zusätzliches Kriterium finde ich gut, damit da (hoffentlich) niemand überrascht wird.
  2. Welches Board hast dir denn da besorgt? Habe mal bei Ali geschaut und da liegt der Chip bei etwa 5eur (zzgl. Versand und Steuern).
  3. Habe ich vermutlich übersehen: Wo konfiguriert man denn, welche Kapazität der Akku hat, damit man die geleistete Arbeit ins Verhältnis nur Kapazität setzen kann?
1 „Gefällt mir“

Erstmal danke dass du den Änderungen gegenüber offen bist und für dein Feedback!

  1. Stimmt, das muss noch erledigt werden. Hatte ehrlich gesagt noch nicht so ganz verstanden was an welchem Bus hängt. Also der i2cBusOne ist reserviert für HAL==1 und sonst wird immer i2cBusTwo verwendet?
  2. Ja, ist immer gleich.
  3. Ja, mit dem Forum hast du irgendwie recht. Ich habe jetzt MEASURE_BATTERY_VOLTAGE eben für die tatsächliche Spannungsmessung verwendet. Also gibt es schon noch. Man könnte natürlich darunter quasi rückwärts BATTERY_MEASURE_ENABLE setzen, aber das wird ziemlich unübersichtlich. Was würdest du denn davon halten, das einfach direkt darüber in einem Kommentar sehr deutlich zu erklären?
  4. Das habe ich berücksichtigt und die Dummy-methoden dafür in BatteryMeasureV.cpp eingefügt. Das war überall im Code verstreut und als eigentlicher „Konfigurationsfehler“ ziemlich unnötig. Da sowieso nichts besonderes gemacht wird, sondern nur Platzhalter zurückgegeben werden ist das in dem betreffenden Modul wesentlich besser gelöst.
  5. :v:
  6. Okay das ist ärgerlich. Ich glaube als ich geschaut habe gab es den auch bei AliExpress günstiger. Bei mouser kostet der IC 2€.
  7. In settings.h unter s_batteryCapacity

Ja es gibt das ESP32-A1S-Audiokit, da ist ein AC101 als DAC drauf. Der braucht i2c zur internen Steuerung. Naja und der ganze Rest, der i2c benutzt, kriegt dann die two-Instanz.

Sollte man dokumentieren, wie die ID lautet. Weil dann weiß man zur Not, nach was man suchen muss.

Also ich störe mich so ein bisschen dran, dass das überhaupt nicht mehr abwärtskompatibel ist und das letztlich ohne Not. Ja ich weiß, aus namentlichen Konsistenzgründen kann man das auch anders sehen, aber ob man das jetzt nochmal ändern muss, wenn man eh hin zu nem universal build will!? Man kann halt nicht verlangen, dass jeder User das immer so aufmerksam liest. Also wenn ich eine Software einsetze, dann finde ich das immer schlechten Stil, wenn sich eine Direktive plötzlich komplett ändert und ich dann quasi gegen die Wand fahre.

Aber da dürfen sich hier gerne noch andere Leute zu Wort melden :slight_smile:. Ich muss das nicht alleine entscheiden.

Da gebe ich dir Recht, das ist zentral besser. Der Code war vorher redundant.

Was mich nochmal interessieren würde: Nehmen wir an, du hast einen Akku mit 3000 mAh. Der ist jetzt halb leer und dann lädst du mal kurz auf, so dass wieder 2000 mAh drin sind. Wie kriegt der MAX17055 von den 500 mAh mit? Also dass er die 500 mAh sieht, daran habe ich keinen Zweifel. Aber woher weiß er, dass die 500 mAh nicht aus dem Akku kamen, sondern in den Akku gingen?

Naja, der chip hat einen eingebauten Coulomb-Counter, der den Strom in beide Richtungen (positiv und negativ) messen kann. Das funktioniert über einen 10mΩ Messwiderstand an dem gemessen wird wie viel Spannung abfällt. Der IC macht das alles intern und nimmt einem da einiges an Arbeit ab. Es soll auch einberechnet werden wie sich die Spannung verhält und wie der Akku altert. Aber keine Ahnung wie wichtig das genau ist.

Vielleicht hilft meine Log Ausgabe hier beim Verständnis:

Betrieb:

Aktuelle Batteriespannung: 3.30 V
Aktuelle Batterieladung: 70.88 %
Stromverbrauch (Batterie): -204.53 mA
Temperatur der Batterie: 25.00 °C
Gesehene Batteriezyklen: 0.13

Laden:

Aktuelle Batteriespannung: 3.37 V
Aktuelle Batterieladung: 70.73 %
Stromverbrauch (Batterie): 822.50 mA
Temperatur der Batterie: 25.12 °C
Gesehene Batteriezyklen: 0.13

Die generische Implementierung für die Batterie öffnet auch die Tür für andere Lösungen, sollte der MAX17055 sich als zu schlecht verfügbar oder anderweitig schlecht geeignet zeigen. Man könnte zum Beispiel einen reinen Coulomb-Counter wie den LTC4150 einsetzen und sich damit das Batterie-Management quasi selbst bauen. Man muss da halt einiges beachten: regelmäßig voll/leer kalibrieren, Akkuverschleiß bei der Kapazität usw… (Für mich war das auch ein kleines Experiment mit dem MAX17055. Für diesen gab es eine anfängliche library, er unterstützt LiFePO4 und war nicht übertrieben teuer. Ich bin aber überrascht wie gut es doch funktioniert.)

Ich hätte gerne auch auf eine DIY-freundlichere Lösung mit eventuellem Breakout gesetzt. Gerade im Bereich LiFePO4 gibt es da aber noch nichts. Man kann hoffen dass z.B. die SparkFun LiPo Fuel Gauge mit MAX17043 irgendwann auf den MAX17055 oder anderen IC mit LiFePO4-Unterstützung aktualisiert wird.

Ich finde gerade bei der steigenden Beliebtheit von LiFePO4 kann das schon sinnvoll sein auch andere Techniken zur Batteriemessung zu haben. Vielleicht gibt es ja auch irgendwo Power Bank Chips die man auslesen kann.

1 „Gefällt mir“

Danke für deinen erneuten Commit. Ich weiß nicht, ob ich heute Abend schon dazu komme, aber spätestens morgen. Ist ja inzwischen bisschen was aufgelaufen, was ich testen/mergen muss :joy:.

Es eilt nicht. Ich habe ja absichtlich auch noch keine Implementierung für die Web-UI, falls sich da noch was ändert.

Du wirst du eh erstmal der Einzige sein, der das laufen hat, hehe.
Ich werde testen, ob es soweit mit dem läuft, was ich erwarte. Aber generell ist das Battery-Relayout schon gut. Aber ich muss mir das erst noch genau anschauen.

Aber Du hast jetzt schon ein Board damit ?

Mhh ja ich hab den bei mir verbaut und damit ja auch den Code entwickelt, oder was meinst du?

Ich sagte dass den keiner hat weil das in der DIY-Szene nicht vertreten ist und es keine Breakout-Boards gibt. Würde mich jedenfalls sehr überraschen wenn hier im Forum jetzt einer kommt und sagt dass er den rumliegen hat.:joy:

Ja, das meinte ich :wink: Hast Du den Schaltplan veröffentlicht?
Ich habe für LiPo so etwas hier im Einsatz:

…und suche ebenfalls schon länger nach einer entsprechenden Lösung für LiFePo4.

Ah, nett. Da bin ich ja nicht ganz alleine mit meinen Ambitionen.
Der LC709203 kann denke ich auch nur Li-Ion? Es gibt noch LTC2941 dem der Akkutyp wohl recht egal ist, der aber auch nicht viel mehr als coulomb counting kann. Dann hab ich noch von TI BQ78z100 oder BQ27z561 gefunden. Alle sehr ähnlich, alle mäßig gut verfügbar (Chipkrise?) und alle mit wenig fertigen Lösungen.

Der Schaltplan ist denkbar einfach und steht im Datenblatt. Einfach 2 Kondensatoren zwischen Vcc und GND und dazu der Messwiderstand. Der muss ne gute Toleranz haben und man sollte den wohl auch mit entsprechenden Leiterbahnen anbinden, aber meine Messung ist vollkommen ausreichend. Ich habe den einfach auf Lochraster geklatscht. :man_shrugging:
Für beste Ergebnisse muss man den LiFePO4 auch zu Maxim schicken damit die ein Batteriemodell anfertigen, aber naja die Ergebnisse sind wirklich gut genug mit „Standardwerten“ für den ESPuino.

Wenn du das bereits verwendest, wie hast das in die Software eingebunden?

Ja, kann nur Li-lon. Der Bedarf scheint irgendwie noch nicht da zu sein für fertige Breakouts - schade.

War blöd formuliert von mir - in einem anderen Projekt.
Aber Du hast es jetzt ja quasi eingebunden bzw. die Grundlage gelegt :+1:

Danke für die Hinweise zur Schaltung.

1 „Gefällt mir“

Ich habe keine Ahnung von Bestückung bei JLCPCB oder Aisler etc., aber wenn du Lust hast dafür mal eine Platine zu entwerfen würde ich gerne mitwirken. Haben die z.B. den MAX17055 bzw. was kostet das? Vielleicht gibt es ja Interesse und man kann gleich einen Batzen bestellen. Bestückung ist quasi Pflicht, da die verfügbaren Chips quasi alle winzig sind.

Hier ist die DB von JLC: PCB Prototype & PCB Fabrication Manufacturer - JLCPCB.
Da kannst nachschauen, was es gibt.

Tipp: KiCad STM32 + USB + Buck Converter PCB Design and JLCPCB Assembly (Update) - YouTube
Das ganze Video ist recht cool, aber ich habe mal den Punkt markiert, wo es erst um das „Verstecken“ der Order-Nummer von JLC geht und dann kommt, was man alles so braucht, wenn man von denen einen PCB bestücken lassen möchte.

1 „Gefällt mir“

Hallo @SZenglein , Danke für Deine Arbeit!
LiFePo4 ist definitiv die Zukunft. Ich habe vor einiger Zeit durch Fahrlässigkeit einen iPhone Akku hochgejagt und kann nur sagen das ist nicht lustig, im Kinderzimmer undenkbar…
Du hast jetzt viel Aufwand betrieben mit einem zusätzlichen IC. Warum? Hat die Messung des zugegeben sehr ungenauen ADC keine Ergebnisse ergeben mit dem bestehenden System? Ist die Entladekurve zu flach?

1 „Gefällt mir“

Ladekurve ist für LiFePO4 absolut unbrauchbar. Bei meinem Akku und ersten Tests (dauert nur leider ewig den Akku zu entleeren :smiley: ) bewegt sich die Spannung von 20-85% im Bereich zwischen 3.25V und 3.30V. Also zumindest bei Zimmertemperatur könnte man mit genauer Messung sicherlich eine Untergrenze definieren um zu sehen wann der Akku bei 5-10% ist, mehr aber auch nicht.
Das wird alles komplizierter bei schwankenden Temperaturen und Laststrom, daher hat die Fuel Gauge vermutlich auch einen Temperatursensor (oder doch nur um zu warnen?).

Aber so ziemlich alle Quellen online besagen auch, dass die Spannung unbrauchbar ist um den Ladestand zu schätzen.

1 „Gefällt mir“

Hab mich da noch nicht so eingelesen, aber ein TP5000 habe ich hier auf dem Board. Soll wohl auch für LiFePo4 geignet sein. Der hat zwei Ausgänge für LEDs/Ladezustand. Wenn man die Pins jetzt an den ESPuino anschließen und den Zustand auswerten würde? Wäre es mit Deiner Code-Zwischenschicht möglich dies zu erweiterrn? Also Zustand leer/laden/voll? Ich benötige keine exakte Ladezustandsanzeige:

grafik

Bild ist jetzt für Lion, sollte aber aber auch für LiFePo4 gehen.
Du hast Dich da ja richtig mit dem Laden beschäftigt, würde mich interessieren warum Deine Wahl auf den MAX17055 gefallen ist…

@tueddy Das würde ich auf den Port-Expander auflegen, weil da wären eh noch Eingänge frei. Beim Port-Expander hat man pro Port ja acht Kanäle; da muss mich sich das passende Bit nur rausholen. Das hat mit seiner Implementierung (aus meiner Sicht zumindest) erstmal nix zu tun.

Der MAX im Gegenzug wird ja per i2c angeschlossen und darüber ausgelesen. Was halt insofern praktisch ist, wenn man i2c eh am Laufen hat wegen dem Port-Expander.

Die entladekurve hatten wir schon mal - ich glaube ein messen der Spannung bringt nicht viel. Vielleicht voll und leer.