Fehler rechnung bei ADC Messung

OP #2689587
Lesenswert?

ich schreibe momentan eine Arbeit über eine Schaltung mit 
Mikrocontroller und bin bei der Fehlerberechnung angekommen. mein 
Problem:

ich messe mit dem 10Bit ADC des Controller eine Offset behaftete 
Spannung.
Ureff ist 5 volt Offset ist 2,5 Volt. Dann berechne ich einen Messwert 
mit der formel:
U = (int)((int64_t)ADC *5000/1023 -2500);
ich erhalte also einen Messwert im Bereich von +-2500 mVolt.
Ich brauche für die Dokumentation jetzt den relativen Messfehler. weiß 
jemand wie ich den berechne.

LSB bei 5volt Ureff ist 4,88mV aber weiter weiß ich nicht.

wehre schön wenn mir einer helfen könnte.

Mikrocontroller ATMega32
#2689590
Lesenswert?

joachim j. schrieb:

> Ich brauche für die Dokumentation jetzt den relativen Messfehler. weiß
> jemand wie ich den berechne.

Prozentrechnung.

Wenn in einer Kiste 100 Äpfel sein sollten, da aber 101 drinnen sind, 
dann hast du wieviel relativen Fehler? 1%


Wenn dein ADC mit dem letzten Bit klappert, wie weit (prozentual 
gerechnet) weicht dann der errechnete Wert vom tatsächlichen Wert ab?
#2689674
Lesenswert?

joachim j. schrieb:

> beim teilen durch 1023 wird auch gerundet wie ist der Fehler da?

Da wird überhaupt nix gerundet. Ausserdem ist dividieren durch 1023 
falsch.

Setz deine ADC Werte ein und rechne es durch! Du kannst auch die 
komplette Kette machen: Nimm eine Spannung an, rechne dir aus, was der 
ADC für diese Spannung liefern wird und rechne über deine Formel wieder 
auf die Spannung zurück. Dann vergleichst du Ausgangswert der Kette mit 
dem Endwert nach deiner Integer-Berechnung.
Tip: Mit einer Excel-Tabelle kann man das für viele unterschiedlichen 
Spannung in kurzer Zeit durchspielen und sich dann auch ein schönes 
Diagramm erzeugen lassen, wie der Fehler (absolut und relativ) von der 
zu messenden Spannung abhängt.
OP #2689696
Lesenswert?

Karl Heinz Buchegger schrieb:
> Da wird überhaupt nix gerundet. Ausserdem ist dividieren durch 1023
> falsch.


ich messe die Spannung mit dem ADC. der hat eine Auflösung von 10Bit. 
Das heist 0-1023. Das LSB ist Ureff/Auflösung und das bedeutet wenn der 
ADC eine 1 liefert ist die Spannung 5000/1023 mV (4,8875mV)

wenn ich also den ADC wert mit 5000 multipliziere und dann mit 1023 
dividiere erhalte ich den Messwert in mV. da ich aber mit integer rechne 
wird auf ganze Bits gerundet oder besser gesagt alles kleine einem Bit 
fehlt weg.
#2689710
Lesenswert?

Karl Heinz Buchegger schrieb:
> joachim j. schrieb:
>> Karl Heinz Buchegger schrieb:
>>> Da wird überhaupt nix gerundet. Ausserdem ist dividieren durch 1023
>>> falsch.
>>
>>
>> ich messe die Spannung mit dem ADC. der hat eine Auflösung von 10Bit.
>> Das heist 0-1023.
>
> Und das sind 1024 verschiedene Werte.

Spiels mit weniger Bits durch. Du hast einen 2 Bit ADC und 4Volt
Referenzspannung

    Spannung      ADC Wert
               +
     0.0 - 1.0 |    0
               +
     1.0 - 2.0 |    1
               +
     2.0 - 3.0 |    2
               +
     3.0 - 4.0 |    3
               +


Bei einem 2 Bit ADC gibt es 4 mögliche Werte. Der
Referenzspannungsbereich von 4V wird daher in 4 Teile geteilt. Jeder
Bereich ist 4/4 gleich 1Volt groß.

Dein Fehler: Du gehst davon aus, dass ein bestimmter ADC Wert EINER ganz
bestimmten Spannung entspricht. Stimmt aber nicht. Ein bestimmter ADC
Wert sagt dir nur, in welchem Bereich sich eine Spannung befindet. Hier
im Beispiel: ein ADC Wert von 3 sagt NICHT aus, dass die Spannung 4 Volt
groß war. Sie kann auch 3.8 Volt gewesen sein, der ADC liefert trotzdem
eine 3. Genausowenig sagt ein ADC Wert von 0, dass du 0V gemessen hast.
Die Spannung hätte auch 0.9V gewesen sein können, der ADC hätte das
trotzdem als 0 klassifiziert.

Klar soweit? (tm Captain Jack Sparrow)
#2689740
Lesenswert?

joachim j. schrieb:

> aber zurück zum eigentlichen Thema
>
> Fehlerrechnung

Ist das nicht schon ausreichend beantwortet?
Was ist denn ein 'Fehler'?
Aus der Messung geht ein Wert hervor. Wie gross ist dieser Wert und wie 
groß sollte er eigentlich sein. Das ist der Messfehler.
Der hängt jetzt natürlich von der Diskretisierung des ADC ab, vom 
Rauschen des ADC (wie stark die letzten Bits klappern) und durch die 
Integer-Rechnung holt man sich ebenfalls einen Fehler ins Boot.

http://de.wikipedia.org/wiki/Messabweichung
Gast #2689797
Lesenswert?

Nehmen wir mal einfach deine Rechnung und schauen uns an, welchen Fehler 
du produzierst nur durch das Rechnen:
Angenommen dein ADC-Wert ist 256.

0d5000 = 0x1388 = 0b0001 0011 1000 1000
0d5000/1024 = 0x1388>>10 = 0b0000 0000 0000 0100 = 0x0004

Multiplizieren mit ADC-Wert:
0x0004*256 = 0x0004 << 8 = 0x0400 = 1024

Offset abziehen:
1024-2500 = -1476
Also rechnest Du einen Wert von -1476mV aus.

Der reale Wert ohne Fehler wären aber 4,88mV*256 -2500mV = -1250,72mV

Damit wird der relative Fehler vom errechneten zum tatsächlichen Wert:

f_r = ((-1476/-1250,72)-1)*100% = 18%.

D.h. bei dieser Berechnungsmethode spielen die Fehler des ADC und der 
restlichen Schaltung überhaupt keine Rolle mehr.
OP #2689848
Lesenswert?

das Wusts ich vorher schon. ich will den jetzt ausrechnen und zwar nich 
absolut sonder als Relativen Fehler.

wenn der absolute Fehler des des ADC LSB/2 ist wie groß ist dann der 
Relativen Fehler.

rfADC = +- x %

wenn ich dann die Formel nehme adc(+-x%)*5000/1023 - Offest(+-0.1%)
spielt der Rundungsfehler und die Fehlerfortpflanzung eine rolle.

rf(f(x,y))=|df(x,y)/dx * rf(x)| + |df(x,y)/dy * rf(y)|

x=ADCwert rf(x)=rfADC

sagt meine Formalisierung wo ich da aber den Rundungsfehler unterbringen 
soll weiß ich nicht.

kann ich überhaupt den relativer Fehler angeben?
#2689879
Lesenswert?

Natürlich kannst du.

Dein nächster Denkfehler scheint zu sein, dass du denkst der Fehler ist 
immer und bei allen ADC Werten gleich. Ist er nämlich nicht. Der Fehler 
variiert mit dem ADC Wert. Ist auch logisch. Werden die Nachkommastellen 
von 5678.2 einfach abgeschnitten, dann spielt das prozentuell zur Zahl 
5678 gerechnet nur eine untergeordnete Rolle. Schneide ich aber von 1.5 
die Nachkommastellen einfach weg, dann ist das ein erheblicher Fehler.

Fazit: entweder du machst die Mathe oder du benutzt die 'faule' Methode 
(die ich auch bevorzugen würde, wenn mein Projektabhnehmer das 
akzeptiert): Mach dir ein Excel Sheet. In die erste Spalte kommen alle 
Spannungswerte im Messbereich in 1/100V Abstufungen. Dann rechne ich mir 
mit Gleitkommaarithmetik aus, welchen Wert der ADC dafür liefern wird, 
stelle in weiteren Spalten die im µC durchgeführte Arithmetik dar 
(dasselbe auch für einen ADC Wert +-1) und rechne mir aus, welcher Wert 
bei der Rechnerei auf dem µC rauskommen wird. Diess Ergebnis setzt ich 
dann in Beziehung zum Originalwert in dieser Zeile und hab so für diesen 
Wert den relativen Fehler bestimmt. Und zwar so, wie er sich auch 
tatsächlich in meiner Berechnung präsentieren wird.

Wenn ich was formelmässig nicht berechnen kann, dann simuliere ich es, 
indem ich den Prozess nachstelle :-)
#2689919
Lesenswert?

Hallo,

es sei noch erwähnt, dass der ADC einen Offset und Linearisierungsfehler 
hat.

Siehe:

AVR120: Characterization and Calibration of the ADC on an AVR
http://www.atmel.com/Images/doc2559.pdf

AVR121: Enhancing ADC resolution by oversampling
http://www.atmel.com/Images/doc8003.pdf

Erst wenn ich diese Fehler per Abgleich - mit einer kleinen (<0,1* VRef) 
und großen (0,8* Vref) Spannung - heraus rechnen kann, kann ich eine 
relative Fehlerbetrachtung machen !

Ich verwende nun nur noch ADC Routine mit 128 Messungen, 4-fach (2^2) 
Oversample (12Bit ADC Auflösung) und Mittelwertbildung über 32 Werte.
1
ISR(ADC_vect)            // Interrupt ADC Conversion Complete
2
{
3
  static uint8_t adc_count = 0;
4
  static uint32_t adc_avg = 0;
5

6
  if ( adc_state == ADC_SAMPLE ) {
7
    uint32_t tmp_adc_avg =  adc_avg;
8

9
    tmp_adc_avg += (uint32_t)ADCW;      // einen neuen Messerte zum Mittelwertregister addieren
10

11
    ++adc_count;
12
    if (adc_count == ADC_AVG_COUNT-1) {      // letzte Messung
13
      ADCSRA &= (uint8_t)~( _BV(ADATE) );    // ADC AutoTrigger disable
14

15
    } else
16
    if (adc_count == ADC_AVG_COUNT) {
17
      adc_count = 0;
18

19
      ADCSRA &= (uint8_t)~( _BV(ADIE) | _BV(ADATE) );  // Interrupt und AutoTrigger abschalten
20
      adc_state = ADC_STOP;
21

22
      adc_result = tmp_adc_avg / (ADC_AVG_COUNT / 4);  // berechne Oversample 2^n, mit n Anzahl weiterer Bits
23
      tmp_adc_avg = 0;          // den alten Mittelwert löschen
24

25
      // Signal an Hauptprogramm
26
      evt_adc_new_result = 1;
27

28
    } // if -then -else
29

30
    adc_avg = tmp_adc_avg;
31
  } // if -then
32
}

Die Korrekturwerte stehen in den Werten DEFAULT_ADC_FACTOR und 
DEFAULT_ADC_OFFSET.
1
  uint16_t u_mess = ( ( (uint32_t)adc_result * DEFAULT_ADC_FACTOR ) + DEFAULT_ADC_OFFSET) >> 16;  // 100µV


_
Gast #2689938
Lesenswert?

Udo Schmitt schrieb:
> joachim j. schrieb:
>
>> Das heist 0-1023.
> Und wieviele Werte sind das?
> 1023 oder 1024?
> Karl Heinz war wieder schneller :-)

schneller ja, aber leider auch falsch, denn der Wandlerwert 1024 kann ja 
nicht erreicht werden, so mit ist das Maximum nach Spec 1023. Wenn 
dieses Wert der Ref entspricht, erhält man Ref/1023 als Steigung!
#2689949
Lesenswert?

Bodo schrieb:
> Udo Schmitt schrieb:
>> joachim j. schrieb:
>>
>>> Das heist 0-1023.
>> Und wieviele Werte sind das?
>> 1023 oder 1024?
>> Karl Heinz war wieder schneller :-)
>
> schneller ja, aber leider auch falsch, denn der Wandlerwert 1024 kann ja
> nicht erreicht werden,

Schau dir doch bitte den Beitrag noch einmal an, überlege was du vom 2 
Bit Fall lernen kannst und dann behaupte noch mal ich hätte irgendwo 
gesagt, dass der Wandler den Wert 1024 auswerfen würde. 0 (inklusive) 
bis 1023 (inklusive) sind nun mal 1024 Werte. Und diese Zahl ist die 
wichtige: wieviele mögliche Ergebnisse kann der ADC liefern. Das ist um 
1 mehr als die numerisch höchste gelieferte Zahl.
Gast #2689993
Lesenswert?

> dann behaupte noch mal ich hätte irgendwogesagt, dass der Wandler den
> Wert 1024 auswerfen würde.

> Das ist um 1 mehr als die numerisch höchste gelieferte Zahl.

ich habe nicht geschrieben, du hättest solchiges behauptet.(?)

Ich habe nur die Interpretation der 1024 korrigiert. Dass es 1024 Werte 
sind bedeutet nicht, dass man /1024 teilen muss.

Nehmen wir doch mal den Fall, dass man nur den halben Bereich nutzt: 
Dann kann der Wandler die 512 ausgeben. Wenn ich diesen Entwert nehme, 
dann wäre das exakt der halbe Bereich. Nach Deiner Rechung wäre aber bei 
511 genau die Hälfte, was nicht stimmt.

Du rechnest durch 511/1023 eine Linearitätverzerrung rein.
#2690026
Lesenswert?

Im Atmel Datenblatt seht es doch richtig drin, Karl-Heinz hatte es mal 
sehr schön als ADC-Wandler-Bereiche erläutert.

Es geht nicht um den Messwertwert 1023 sondern dass ist das Intervall 
mit der Nummer 1023!. Das ist ein Unterschied.

Bei 2 Bit ADC-Auflösung und Vref = 5V, ergibt sich
1
_Ergebnis__: Spannungsbereiche
2
-----------:-------------------------
3
Intervall 3: 3,75V - 5,00V -epsilon
4
Intervall 2: 2,50V - 3,75V -epsilon
5
Intervall 1: 1,25V - 2,50V -epsilon
6
Intervall 0: 0,00V - 1,25V -epsilon
7

8
Mit epsilon klein

Das sind also 4 Intervalle mit einer Schrittweite pro Intervall von Vref 
/ 4.

_
Gast #2690029
Lesenswert?

Hi

>Nehmen wir doch mal den Fall, dass man nur den halben Bereich nutzt:
>Dann kann der Wandler die 512 ausgeben. Wenn ich diesen Entwert nehme,
>dann wäre das exakt der halbe Bereich. Nach Deiner Rechung wäre aber bei
>511 genau die Hälfte, was nicht stimmt.

Wieso stimmt 511 nicht? Sind 512 Werte, also genau die Hälfte von 1024.

MfG Spess
#2690033
Lesenswert?

Bodo schrieb:
>> dann behaupte noch mal ich hätte irgendwogesagt, dass der Wandler den
>> Wert 1024 auswerfen würde.
>
>> Das ist um 1 mehr als die numerisch höchste gelieferte Zahl.
>
> ich habe nicht geschrieben, du hättest solchiges behauptet.(?)
>
> Ich habe nur die Interpretation der 1024 korrigiert. Dass es 1024 Werte
> sind bedeutet nicht, dass man /1024 teilen muss.

Wie du meinst.
(ich wiederhol mich nur ungern. Sieh dir die Argumentation an, zeige wo 
der Fehler ist und dann sehen wir weiter). Ihr macht alle den gleichen 
Fehler: Der höchste mögliche ADC Wert wird NICHT erst bei Erreichen der 
Referenzspannung erhalten sondern bereits früher.

Ein ADC, der nur 1 Bit hat, unterteilt seinen Messbereich so

            +
            |  0
            +
            |  1
            +

Der höchst mögliche Wert vom ADC wird bereits bei der Hälfte der 
Referenzspannung erreicht und nicht erst dann, wenn die Eingangsspannung 
die gleiche Höhe wie die Referenzspannung hat.
Der höchste mögliche Wert vom ADC ist 1. Und das bedeutet, dass der ADC 
die Eingangsspannung in 2 Hälften teilt. 2(!) Hälften. Die Trennlinie 
zwishcen den Spannungsbereichen verläuft also bei Referenzspannung / 2 
und nicht bei Referenzspannung / 1.


Im übrigen ist ja auch Atmel selber meiner Ansicht. Und die werden ja 
wohl wissen, wie ihr ADC funktioniert.
#2690037
Lesenswert?

Bodo schrieb:

> Nehmen wir doch mal den Fall, dass man nur den halben Bereich nutzt:
> Dann kann der Wandler die 512 ausgeben. Wenn ich diesen Entwert nehme,
> dann wäre das exakt der halbe Bereich. Nach Deiner Rechung wäre aber bei
> 511 genau die Hälfte, was nicht stimmt.

Schau dir die Argumentation noch einmal an.

Und JA!
Wenn der ADC seinen höchst möglichen Wert ausgibt, bedeutet das NICHT, 
dass die Eingangsspannung die gleiche Höhe wie die Referenzspannung hat.

Wenn die Referenzspannung 5V ist und der ADC 1023 auswirft, dann ist das 
korrekte Ergebnis eben NICHT 5V! sondern 4.9951
Wenn man ganz korrekt ist muss man nämlich sagen: Die Spannung lag 
ZWISCHEN 4.9951V und 5V. Und genauer kann man das nicht sagen, als das 
die Spannung irgendwo in diesem Bereich war.

Genau davon rede ich die ganze Zeit und genau das ist das Um und Auf: 
Das dir der ADC eben NICHT erlaubt eine Aussage über die tatsächliche 
Spannung zu geben, sondern er dir nur eine obere und eine untere 
Schranke definiert, zwischen denen die Spannung liegt. Und beim höchst 
möglichen Wert ist diese untere Schranke eben nicht identisch mit der 
Referenzspannung, sondern die Referenzspannung definiert die obere 
Schranke.

Ich weiß schon, das sich schönere Zahlenwerte ergeben, wenn man durch 
1023 dividiert. Nur musst du dir auch bewusst sein, dass du dadurch aus 
jedem Messbereich einen jeweils anderen Wert als 'den für diesen Bereich 
repräsentativen Wert' hernimmst.

Um beim 2 Bit Wandler zu bleiben, ergebn sich dann diese Ausgaben

    Spannung      ADC Wert       zurückgerechneter
                                 Spannungswert (/3)
               +
     0.0 - 1.0 |    0            0
               +
     1.0 - 2.0 |    1            1.33
               +
     2.0 - 3.0 |    2            2.66
               +
     3.0 - 4.0 |    3            4
               +

aber mit welcher Begründung sind die jetzt besser als 0V, 1V, 2V und 3V. 
Bei letzterem kann ich immerhin noch sagen: 3V (+1V 
Diskretisierungsfehler). Bei deinen Zahlen kann ich ohne genau Kentnis 
des ADC Wertes noch nicht einmal sagen, wie hoch die Fehlerschranken in 
positiver sowie in negativer Richtung bei jedem einzelnen Wert ist. Denn 
die hängt bei dir vom konkreten Wert selber ab. 1.33 hat eine 
Fehlerschranke von -0.33/+0.67 während 2.66 eine Fehlerschranke von 
-0.67/+0.33 hat. 0 wiederrum hat eine Fehlerschranke von -0/+1, während 
die 4V als Messergebnis mit dem Fehlerintervall -1.0/+0.0 gemeldet 
werden.

Man kanns auch so ausdrücken:
Wieso soll in einem Balkendiagramm bei einem Balken mal die linke 
Balkengrenze, dann wieder die rechte Balkengrenze bzw. irgendein Wert 
dazwischen als der repräsentative Wert dieses Balkens gelten?
1
 |
2
 |              +----+
3
 |    +----+    |    |
4
 |    |    |    |    +----+
5
 |    |    +----+    |    |
6
 |    |    |    |    |    |
7
 |    |    |    |    |    |
8
 +----+----+----+----+----+----
9
      0    1    2    3    4
Gast #2690186
Lesenswert?

spess53 schrieb:
> Wieso stimmt 511 nicht? Sind 512 Werte, also genau die Hälfte von 1024.

JAAA, AAAAaber:  die 511/1011 sind nicht 50%!

Das Beispiel vom 4 Bitwandler zeigt doch, was ich meine.

Uwe S. schrieb:
> Bei 2 Bit ADC-Auflösung und Vref = 5V, ergibt sich_Ergebnis__: Spannungsbereiche
>
> -----------:-------------------------
>
> Intervall 3: 3,75V - 5,00V -epsilon
>
> Intervall 2: 2,50V - 3,75V -epsilon
>
> Intervall 1: 1,25V - 2,50V -epsilon
>
> Intervall 0: 0,00V - 1,25V -epsilon
>
>
>
> Mit epsilon klein
>
Die Zahl der Intervalle wären schon 1024 aber die Bezugnahme auf den 
Endwert stimmt nicht. Das ist was anderes.


> Das sind also 4 Intervalle mit einer Schrittweite pro Intervall von Vref
eben nicht, es sind Vref minus epsilon und genau dieses epsilon macht 
den
unterschied von 1023 / 1024.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren