Ich hatte mich bisher immer drauf verlassen, dass die Spannung gegen die Referenzspannung von 3,3 V gemacht wird. Bei meinen LFP-Develboards war mir daher (zugegeben) selbst nicht klar, wie das Ganze im reinen Akkubetrieb funktionieren kann, wenn gar keine 3,3 V vorhanden sind. Ein bisschen Recherche brachte dann hervor, dass als Referenz die interne Spannung von 1,1 V verwendet wird.
Bisher hatte ich den Spannungsteiler bei den Develboards mit 300k / 300k dimensioniert und Wemos mit seinem Lolin D32 pro mit 100k / 100k. Bedeutet also, dass bei meinen LFP-Develboards bis zu 1,8 V gemessen werden und bei den Wemos-Boards bis zu 2,1 V (jeweils die Hälfte der max. Ladespannung).
Insgesamt hat das recht ok funktioniert, jedoch musste das Offset teilweise ziemlich nachjustiert werden. Wie ich gelesen habe ist es am besten, wenn man mit der Spannung bei etwa 1,1 V rauskommt, da dort auch die Referenzspannung liegt. Ich habe daher bei der neuen Complete den Spannungsteiler auf 300k / 100k gesetzt, was zu einer max. Spannung von 0,9 V führt.
Benutzt man analogRead() ohne weitere Parametrierung, so ist per Default eine interne Dämpfung von 11 dB aktiv.
Mit der aktuellen ESPuino-Implementierung hat mein neuer Spannungsteiler dazu geführt, dass ich das Offset auf satte 0,45 V korrigieren musste. Insofern ist das vielleicht doch der falsche Weg, wie wir das aktuell machen.
Ich habe daher den aktuellen Code eingekürzt und die Dämpfung zur Messung mit meiner Complete testweise auf 0 dB gesetzt. Das Offset konnte ich nun auf 0,1 V zurücksetzen, um einen sehr exakten Wert zu kriegen. Setze ich jedoch absichtlich 11dB, so kommt ein komplett falscher Wert raus. Der Code sieht wie folgt aus:
float Battery_GetVoltage(void) {
analogSetPinAttenuation(VOLTAGE_READ_PIN, ADC_0db);
// analogSetAttenuation(ADC_11db);
float averagedAnalogValue = 0;
uint8_t i;
for (i = 0; i <= 19; i++) {
averagedAnalogValue += (float) analogRead(VOLTAGE_READ_PIN);
}
averagedAnalogValue /= 20000.0f;
return averagedAnalogValue + offsetVoltage;
}
Zur Referenz: Der bisherige Code sieht so aus:
float Battery_GetVoltage(void) {
float factor = 1 / ((float) rdiv2 / (rdiv2 + rdiv1));
float averagedAnalogValue = 0;
uint8_t i;
for (i = 0; i <= 19; i++) {
averagedAnalogValue += (float) analogRead(VOLTAGE_READ_PIN);
}
averagedAnalogValue /= 20.0f;
return (averagedAnalogValue / maxAnalogValue) * referenceVoltage * factor + offsetVoltage;
}
Als Dämpfungsstufen gibt es:
- ADC_0db,
- ADC_2_5db,
- ADC_6db,
- ADC_11db,
- ADC_ATTENDB_MAX
Anmerkungen:
- Ich denke es würde generell Sinn machen, das Ganze mal zu überarbeiten. Der Programmieraufwand ist ziemlich überschaubar, jedoch ist das Testen halt aufwändig.
- Der Code lässt sich etwas verschlanken: Also die Berechnung wird einfacher und die Größe des Spannungsteilers kann man rausnehmen. Was man weiterhin brauchen wird (nehme ich an), ist der Offset.
- Bei der Complete wird’s für LFP und LiPo getrennte Boards geben. Insofern werde ich dafür Sorge tragen, dass der Spannungsteiler bei der LiPo-Variante etwas größer ist (vielleicht 400k zu 100k).
- Bei der mini4L wird man weiterhin bei 11dB bleiben müssen, da wir hier nicht zwischen LFP und LiPo unterscheiden und halt mit max. 2,1 V gerechnet werden muss.
- Mich verwundert es ehrlich gesagt, dass mein Code direkt eine Spannung und nicht den RAW-Wert liefert, den man umrechnen muss.
- Noch mehr verwundert mich: Wenn ich analogReadMilliVolts() in meinem angepassten Code verwende, dann messe 2,9 V, wenn die Spannung tatsächlich 3,5 V ist und 2,7 V, wenn die Spannung 3,2 V ist?!?
Habt ihr dazu Anmerkungen?
Hat vielleicht jmd. dazu schon Tests gemacht?
Mag mich jmd. unterstützen? ![]()
Infos:
[1] ESP32 ADC – Read Analog Input in Arduino IDE – DeepBlue
[2] ADC - - — Arduino ESP32 latest documentation

