Forum: Mikrocontroller und Digitale Elektronik atmega8 adc falsche werte


von Tino K. (blumengiesser)


Lesenswert?

folgendes:
[1]
ich habe bei einem Atmega8 den Analog/Digitalwandler laut dem Tutorial 
aktiviert. Rahmenbedingung 8Mhz und Vorteiler auf 128 gesetzt. Das 
funktioniert auch, sprich es kommen plausible Werte an. Leider stimmen 
die aber nicht mit der gemessenen Spannung richtig überein. Beispiel: Es 
liegt eine Spannung von 0,74 mV an und es wird der Wert 289 angezeigt. 
Rechnerisch sollte doch der Wert 296 ankommen. Ich habe mal geschaut, 
AREV ist nicht 2,56 sondern 2,6V. Damit umgerechnet (2,6=1023) kommt 291 
raus. Das ist aber immer noch nicht der richtige Wert und auch mehr als 
die 2bit Toleranz. Woran liegt es, was mache ich falsch?

[2]
da es werte von einem teperatursensor sind, wollte ich die messung ein 
wenig integrieren damit die anzeige nicht flackert. ich habe mir 
folgendes programm überlegt:

//
uint16_t temperaturAverage;
uint16_t adcval;

int main()
{
   ADC_Init();

   while(1)
   {
   adcval = ADC_Read_Avg(0, 5);
   temperaturAverage = (temperaturAverage * 149 + adcval) /150 ;
   }
}


Der Wert temperaturAverage landet so auf dem Wert 150. Wird mehr wenn es 
warm wird aber nicht weniger... Was läuft da falsch? Gibt es einen 
besseren Weg das Flackern zu beseitigen? I-Glied?

von Ralli (Gast)


Lesenswert?

0,74 mV sind mit einem 10-Bit-ADC und Vref = 2,56 V nicht
erfassbar. Geht wohl um 0,74 V.

Die ergeben bei

Vref min = 2,3  V: 0,74 / 2,30 * 1024 = 329
Vref nom = 2,56 V: 0,74 / 2,56 * 1024 = 296
Vref max = 2,7  V: 0,74 / 2,70 * 1024 = 280

Ergebnis ist also voll in der Spezifikation.
RTFM ;-)

Also Abgleich erforderlich, wenns um den Absolutwert
geht. :-(

Mitteln ist gut, man kanns aber auch übertreiben.
Nicht verkehrt sind z.B. 4 oder 8 Messungen
gleichverteilt über 20 ms.
Das eliminiert den Einfluss von Netzbrumm.

von Stefan B. (stefan) Benutzerseite


Lesenswert?

> liegt eine Spannung von 0,74 mV an und es wird der Wert 289 angezeigt.

Dein Signal ist bestimmt 0,74V nicht mV.
Bei 0,74 mV und AREF 2,6V sollte der ADC Wert betragen:
ADC = 1024 * 0,00074V/2,6V = 0 (genau: 0,291)

> damit gerechnet (2,6=1023)

Das ist falsch gerechnet. AREF wäre der ADC-Wert 1024

> uint16_t temperaturAverage;
> temperaturAverage = (temperaturAverage * 149 + adcval) /150 ;

Ist im ersten Durchlauf gleichbedeutend mit

uint16_t temperaturAverage = 0;
also
temperaturAverage = (0 * 149 + 291) /150 = 1

im 23. Durchlauf:      temperaturAverage = 23
im 42. Durchlauf:      temperaturAverage = 42
im 142. Durchlauf:     temperaturAverage = 142
im 143. Durchlauf:     temperaturAverage = 142
im 1000000. Durchlauf: temperaturAverage = 142 (bei adcval 289: 140)

IMHO muss die Formel für dein Messsystem anders sein.

von Tino K. (blumengiesser)


Lesenswert?

danke schon mal für die antworten.

ich muß kurz klarstellen, 10bit, sind 1023 und nicht 1024. steht im 
tutorial oder zeigt auch der windows taschenrechner an wenn man 10 1-zen 
eintippt. aber egal.

die genauigkeit ist in der spec, hatte ich mir schon fast gedacht. wie 
verhält es sich eigentlich mit der internen Referenzspannung, kann die 
sich irgendwann mal ändern? sprich wenn es kälter oder wärmer wird? wenn 
ich auf diese kalibriere bleibt das ergebniss dann so..?!

wegen dem mitteln der messwerte würde ich gerne über 3 min den wert sich 
langsamm ändern lassen, wie es auch viele raumthermometer machen. ich 
komme grad nicht auf den code. kleine hinweise? Warum konvergiert die 
formel auf 142?? klar, weil ich integer werte habe aber wie kann ich das 
umgehen?

von Bernd N (Gast)


Lesenswert?

Wenn man einen genauen Meßwert mit dem ADC erzielen möchte dann braucht 
es ein wenig mehr Aufwand.

Beitrag "ADC und Fixed-Point Arithmetik"

Schau dir mal die genannten ATMEL App. Notes an un den daraus 
resultierenden Code.

von Bob (Gast)


Lesenswert?

Tino Kühn schrieb:
> ich muß kurz klarstellen, 10bit, sind 1023 und nicht 1024.

Nochmal klarstellen für den nächsten, der den Thread in Google findet:

Die höchste mit 10 Bit (unsigned) darstellbare Zahl ist 2^10-1 == 1023.
Es können aber 10^2 == 1024 verschiedene Zahlen dargestellt werden. Die 
Null nicht vergessen!

Deswegen wird beim ADC-Umrechnen durch 1024 dividiert, nicht durch 1023.

von Bob (Gast)


Lesenswert?

Heut echt nicht mein Tag...
1
s/10^2/2^10/

Ab ins Bett bevor ich noch mehr Müll poste...

von Tino K. (blumengiesser)


Lesenswert?

1023 ist der letzte wert, 1024 mögliche werte hat es. wollte ich mit 
jedem post sagen, kam so wohl nicht rüber. ich lese grad die app note 
120/121, sehr interessant... ich glaube das wird hier schon was 
längerfristiges...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.