avr adc streuung ausgleichen

OP #8104258
Lesenswert?
• ▲
▼

ich möchte per m328-adc die Spannung eines 15kW-48-V-PV-Akkus messen und danach den WR an- und ausschalten. Der ADC streut um ca.1v. Wie gleiche ich das am besten aus? Wie viele Messungen, Höchstwert, Mittelwert, Unterwert? Welche genauigkeit ist erreichbar?

1
int16_t adc_read(u8 ADCchannel)
2
{
3
    // Select ADC channel (0-7) by setting the lower bits of ADMUX
4
    ADMUX = (ADMUX & 0xF8) | (ADCchannel & 0x07);
5
    
6
    // Start the conversion
7
    ADCSRA |= (1 << ADSC);
8
    
9
    // Wait for the conversion to complete
10
    while (ADCSRA & (1 << ADSC));
11
    
12
  
13
  
14
    // Return the ADC result
15
    return ADC;
16
}
17

18

19
int16_t adc_read_volt()
20
{
21

22
u32 val=adc_read(1);
23
val=val*100/106;
24
return val;
25
}
#8104271
Lesenswert?
• ▲
▼

Der AVR Mega328 hat einen 10 Bit-Wandler. Wenn der um 1V streut, machst du was grundsätzlich falsch. Erläutere deinen Aufbau sowie die Schaltung (Stromlaufplan), vielleicht kann man helfen.

Nach meiner Erfahrung mit den moderneren ATTiny mit 12 Bit-Wandler, kann man bei einmaligen Auslesen die beiden unteren Bits vergessen.

Durch starke Überabtastung / Mittlung, was ja bei einer Batteriemessung ohne weiteres geht, ist die nominale Auflösung erreichbar.

Mal ein älterer Beitrag zu dem Thema: Beitrag "[AVR] ADC oversampling, nutzbarer Wertebereich"

OP #8104276
Lesenswert?
• ▲
▼

Ki-Antwort: 2. Welche Filtermethode ist am besten? Ich würde für deinen Fall mit 32 Messungen, Verwerfen der Extremwerte und anschließendem Mittelwert anfangen. Verfahren Vorteil Nachteil Empfehlung

  • Einzelmessung Schnell Sehr störanfällig Nicht für Schaltentscheidungen

  • Mittelwert aus 8 Messungen Einfach Filtert starke Ausreißer nur begrenzt Gute erste Verbesserung

-Mittelwert aus 32 Messungen Reduziert zufälliges Rauschen Reagiert langsamer; hilft nicht gegen systematische Fehler Sehr gut

  • Minimum/Maximum Zeigt Schwankungen Einzelne Störungen verfälschen den Wert stark Zur Diagnose

  • Median aus 9 Messungen Unterdrückt einzelne Ausreißer Bei normalem Rauschen weniger effizient als Mittelwert Gut bei Störspitzen

  • 32 Messungen, Extremwerte verwerfen Gute Kombination aus Glättung und Ausreißerunterdrückung Etwas mehr Rechenaufwand

Meine Empfehlung Du musst nicht den höchsten und niedrigsten Wert jeder Messreihe speichern, um daraus die Akkuspannung zu bestimmen. Du kannst beide Werte verwerfen und die übrigen Messwerte mitteln. Minimum und Maximum kannst du zusätzlich zur Diagnose ausgeben.

1
uint16_t adc_read_filtered(uint8_t channel)
2
{
3
    uint32_t sum = 0;
4
    uint16_t min_val = 1023;
5
    uint16_t max_val = 0;
6

7
    for (uint8_t i = 0; i < 32; i++) {
8
        uint16_t v = adc_read(channel);
9

10
        sum += v;
11

12
        if (v < min_val) min_val = v;
13
        if (v > max_val) max_val = v;
14
    }
15

16
    // Je einen kleinsten und größten Wert entfernen.
17
    sum -= min_val;
18
    sum -= max_val;
19

20
    return (uint16_t)(sum / 30);
21
}
#8104295
Lesenswert?
• ▲
▼

Karl K. schrieb:

Der ADC streut um ca.1v.

Bei 1V Streuung liegt ein Fehler in der Schaltung oder bei der Messung vor. Ein Filter würde nur an den Symptomen rumdoktern und, je nach Art des Fehlers, evtl. völlig unsinnige Werte liefern.

Beseitige den Schaltungsfehler bzw. die Störungen an der Quelle.

Wie sieht deine Schaltung aus (Schaltplan, Photo)?
Wie sehen Referenzspannung und Spannung am ADC-Mux-Eingang auf dem Oszi aus?

: Bearbeitet durch User
#8104459
Lesenswert?
• ▲
▼

Ich habe vor 3 Jahren einen ausführlichen Test zur Oversampling-Messung mit einem M328 gemacht. Als Voraussetzung habe ich extra ein sauber aufgebautes Testboard erstellt, das absolut kein Rauschen (0 Bit) gezeigt hat.

Das Oversampling habe ich exakt nach AVR121 gemacht. D.h. Oversampling von 16 Werten, die 16 Werte addiert, 2 Bit-Rechtsshift und Teilen durch 4. Das sollte ein Ergebnis mit 12 Bit Auflösung, d.h 0,27mV bei Vref=1,1V ergeben. Auch das Rauschen wurde wie vorgeschlagen mit einem Timer erzeugt, das +-2Bit nicht überschritten hat. Es wurde am Eingang aufaddiert. Dieses Dreieck-Rauschen habe ich synchron mit den 16 Messungen gemacht, also immer eine volle Periode.

Ich habe den ganzen Bereich in engen Stufen durchgefahren mit Rohwerten von 10 bis 1021. Die Eingangswerte wurden mit meinem HP34401 gemessen und mit den intern kalibrierten Werten verglichen.

Ich wollte es kaum glauben: es wurde im ganzen Bereich kein einziges Mal eine Abweichung größer 0,27mV erreicht. D.h. volle 12 Bit Auflösung. Also: richtig gemacht funktioniert das Oversampling wunderbar.

: Bearbeitet durch User
Beitrag #8104475 wurde vom Autor gelöscht.
Moderator (Firma: Titel) Persönliche Seite #8104521
Lesenswert?
• ▲
▼

Hermann W. schrieb:

Also: richtig gemacht funktioniert das Oversampling wunderbar.

Wenn man zudem auch noch Glück gehabt und einen schön linearen ADC erwischt hat. Am nächsten Tag erwischt man dann aber einen, der sich das volle halbe Bit Nichtlinearität aus dem Datenblatt gönnt, und All die hübschen oversampelten Werte sind Makulatur.

Karl K. schrieb:

Der ADC streut um ca.1v.

Welche Art von "Streuung" ist das? Zeig deine Schaltung und deinen Schaltungsaufbau. Hast du einfach mal mit einem Oszi am ADC-Eingang gemessen?

Welche genauigkeit ist erreichbar?

Realistisch: knapp unter 10 Bit. Wenn du also z.B einen Messbereich von 0..60V hast, dann wären das ca. 100mV.

Wenn du deine Schaltung aber so aufbaust, dass nur der interessante Bereich von z.B 30..60V gemessen wird, dann bekommst du 1 zusätzliches Bit "geschenkt". Deine Schaltung könnte also auf 50mV auflösen.

Karl K. schrieb:

1
return (uint16_t)(sum / 30);

Ein guter Programmierer würde seine SW so auslegen, dass da "/32" steht. Denn so ein 8-Bit uC hat ein zutiefst binäres inneres Wesen.

: Bearbeitet durch Moderator
#8104526
Lesenswert?
• ▲
▼

Karl K. schrieb:

Ki-Antwort: 2. Welche Filtermethode ist am besten? Ich würde für deinen Fall mit 32 Messungen, Verwerfen der Extremwerte und anschließendem Mittelwert anfangen.

Alles klar, lösche die 'bösen' Werte und die 'wahren' Werte bleiben übrig.
Völliger Quatsch!

Der ADC läuft wohl mit 4 oder 8 MHz weshalb die Auflösung passt. Das hätte die 'KI' selber merken müssen, anstatt irgendwelchen Unsinn nachzuplappern.

#8104527
Lesenswert?
• ▲
▼

Karl K. schrieb:

ich möchte per m328-adc die Spannung eines 15kW-48-V-PV-Akkus messen

Gönn dir einen INA228 o.Ä., der misst bis zu 80V mit 20Bit-Auflösung, und lässt sich auch leicht an deinen Mega328 verbinden.

Gibt's als Breakout-Board bei den üblichen Maker-Shops.

Der Shunt auf den Boards ist natürlich nix für deinen PV-Akku.

Wenn du auch den Strom messen oder zumindest abschätzen willst, kannst du einen externen Shunt nehmen, oder das Akku-Kabel verwenden. Für einen groben Schätzwert zur Unterscheidung "Wird stark Geladen … fast nix … Wird stark entladen" reicht das auch.

#8104537
Lesenswert?
• ▲
▼

Εrnst B. schrieb:

Wenn du auch den Strom messen oder zumindest abschätzen willst, kannst du einen externen Shunt nehmen, oder das Akku-Kabel verwenden.

Wenn man genau messen möchte, tut man gut daran, auch die Temperatur des Shunts/Kabels zu erfassen, um den Temperaturkoeffizienten zu berücksichtigen. Sonst nützt einem die Genauigkeit des INA228 nicht so richtig viel. Und ein sauberer 4-Leiter-Anschluss ist natürlich Pflicht.

: Bearbeitet durch User

Antwort schreiben

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.