Forum: Mikrocontroller und Digitale Elektronik ADC springt


von bluemol (Gast)


Lesenswert?

Hallo,

Problem mit ADC. Mein ADC am ATmega8 funktionierte bis gestern super.
Leider springen jetzt (auf einmal) die Wandlungsergebnisse. Ich habe
mittlerweile den Sensor, der die Messspannung liefert, ausgetauscht.
Auch habe den ATmega8 gegen einen anderen ATmega8 getauscht, ohne
Erfolg.
Vielleicht habe ich was in der Software ausversehen verstellt, aber ich
habe eine ätlere Sicherung geladen. Die Werte springen immer noch.

Der Status sieht nun so aus:

Der ADC ermittelt zehn oder zwanzig mal anscheinend das richtige
Ergebnis. Dann kommen ein paar Werte die absolut daneben liegen. An der
Software kann es eigentlich nicht liegen, da das Auslesen (testhabler)
in einer Endlosschleife läuft. Somit können keine anderen Fehler
auftauchen.

Meine Initialisierung sieht so aus:

ldi temp, 0b00100000   // 00 AREF extern, 1 Ergebnis links ausgeben
out ADMUX,temp         // Channel 0
ldi temp, 0b10000111   // ADC Enable Prescaler 128 bei 16 MHz
out ADCSRA, temp       // ergibt 125 kHz

Der Aufruf für eine Wandlung geschieht mit der Assembler- Funktion
rcalll SingleADC

SingleADC:
  sbi  ADCSR,ADSC    //ADC starten
ADC_busy:
  sbis  ADCSR,ADIF    //Warten bis Wandlung fertig ist
  rjmp  ADC_busy

  sbi  ADCSR,ADIF    //Interruptflag mittels 1 löschen
  in   r24,ADCH    //Ergebnis auslesen (Achtung auf
              //richtige Reihenfolge)
  ret

Vielleicht sieht jemand den Bug oder hat eine andere Idee....
Bin für jeden Tipp dankbar....

von MSE (Gast)


Lesenswert?

Hi,

Ideen, ohne dass ich mir Deine Software angucke:

wenn irgenwann einmal alles ging und ein Austausch von uC und Sensor
sowie das Laden eines alten Softwarestandes diesen Zustand nicht wieder
herstellen kann, dann liegt es wahrscheinlich an etwas anderem.

- Aderbruch in Kabel?
- Masseverbindung nicht ordentlich?
- Auf der Platine etwas kaputt gegangen? (Leiterbahn durch, Lötstelle
kalt, anderes Bauteil hinüber...?)
- Störeinkopplung von irgendwoher?

oder benutzt Du Port-Pins, auf denen ADC-Eingänge liegen anderweitig?
(Das kann laut Datenblatt die Wandlung ruinieren!)


Gruß, Michael

von bluemol (Gast)


Lesenswert?

Danke für die Fehlersuche- Auffrischung. Ich bin nun systematisch und
acuh chaotisch (sämtlich Lötstellen nach gelötet) vorgegangen. Finde
den blöden Fehler nicht. Was interessant erscheint, wenn ich den ADC
nur alle paar 10ms neu starte habe ich definitiv weniger, nur
vereinzelte Fehler.
Vielleicht sollte ich eine Art Medianbildung über drei Werte in
Betracht ziehen....anstelle von einer Mittelwertbildung....

von MSE (Gast)


Lesenswert?

Medianbildung mag ja ein brauchbares Workaround sein aber es wäre ja
doch schön den Fehler zu finden, nicht?

Hast Du ein Oszilloskop, sodass Du Dir das Eingangssignal ansehen
könntest?
Wie sieht es in Deiner Schaltung mit Blockkondensatoren aus? Sind genug
und an sinnvollen Stellen vorhanden?
Wie ist die Qualität der Versorgungsspannung?

Und noch einmal: Wie sind die nicht für den ADC benutzten Eingangspins
beschaltet?

Gruß, Michael

von bluemol (Gast)


Lesenswert?

Hi Michael,

vielen Dank für Deine Bemühungen. Ich ich hab's gefunden. So ein
kleiner Stützkondensator wollte nicht mehr so recht... gggrrrrr....
Keine Ahnung wie der sich verabschiedet hat...

Noch was anderes:
Im Datenblatt des ATmega8 stehtzum Thema ADC:

± 2 LSB Absolute Accuracy

Die Angabe wird doch so übersetzt:
± 2 LSB Genauigkeit bei Vollausschlag ???
Sprich bei einer Referenzspg. von 5V zeigt der ADC ± 2 LSB falsch an.
Das bedeutet 5V / 255 * 2 = 0.04V.
Bei jeder Messung muss der Fehler im worst case dazu
addiert/subtrahiert werden.
z.B. Messspannung =1.3V  worst case 1.34 bzw. 1.26

Ist doch richtig, oder....

Danke bluemole

von MSE (Gast)


Lesenswert?

Der Rechnungsgang an sich ist richtig, aber wieso gehst Du von einer
8-Bit-Auflösung aus? Benutzt Du nicht die vollen 10 Bit?
Bei 8 Bit wäre es übrigens 5V /256 (nicht /255), bei 10 Bit ist es dann
5V / 1024.

Gruß, Michael

von Thomas O. (Gast)


Lesenswert?

Hallo,

denke mal das die die AVCC Spannung nicht richtig entstört hast,
Filterspule, Kerko und Tantal wie in den AP-Notes beschrieben. Und je
nachdem wie schnell dein Signal steigt kann du hier noch nen
Wiederstand und Kondensator reinmachen um das SIgnal zu glätten.


Wenn du ein Oszi hast schau dir das Signal an das von den Sensoren
kommt, vielleicht schwingt hier was. Bei einen NZC oder so
unwarscheinlich wenn du aber Drucksensoren oder sowas verwendest kommt
das schon mal vor von Motorola gibt z.b. extra AP-Notes dafür. Hatte
ich letztens gepostet einfach mal suchen Datei hieß irgendwie so
MPX.pdf

von bluemol (Gast)


Lesenswert?

Hi Michael,

ich bin gerade am überlegen ob ich doch 10 Bit benutzen soll. Der ADC0
bietet ja 10 Bit an. Ok Du hast natürlich recht 256.
Ich bin mir nicht sicher ob die ± 2 LSB Absolute Accuracy von 8 oder 10
Bit ausgehen. Bzw. ist doch nicht möglich das es bei 8Bit und 10Bit
immer 2LSB sind. Der Controller hat doch keine Ahnung ob ich später 8
oder 10 Bit auslese oder....


Gibt es eine Möglichkeit gleich alle 10 Bit in eine Variable zu  laden.
Oder muss ich das umständlich über eine Union oder ähnliches machen.....

von MSE (Gast)


Lesenswert?

1. Ich denke mal, es handelt sich um +/-2 LSB bei 10 Bit Auflösung.
(Wenn es 2 LSB von 8 Bit wären, dann wäre der 10 Bit-Modus völlig
sinnlos!)

2. In eine Variable laden? Tja, ich bin C-Programmierer, da mach ich
das mit einer int-Variable, die ist 16-Bit lang. Wie das in Assembler
zu lösen ist, kann ich Dir leider nicht sagen.

Gruß, Michael

von bluemol (Gast)


Lesenswert?

Wie machst du es den in C? ich programmiere in beiden Sprachen.
Allerdings ist mir in C momentan nicht besseres als ne union
eingefallen. Erscheint mir ein wenig umständlich.

unsigned int uihelp;
unsigned int uiADC = inp (ADCL);
uihelp = inp(ADCH);
uihelp <= 8;    // 8 x nach links schieben
ucADC &= help;  // endlich alle 16 Bit....drin

geht das vielleicht auch mit einem Befehl???

von MSE (Gast)


Lesenswert?

Einfach so:

unsigned int val = ADC;



Gruß, Michael

von OldBug (Gast)


Lesenswert?

unsigned int uiADC = (ADCH << 8) & ADCL;

von bluemol (Gast)


Lesenswert?

Werde ich gleich mal testen.
Danke für Eure schnelle Hilfe....

von bluemol (Gast)


Lesenswert?

Thomas O. spricht von  " MPX.pdf-Datei" das würde mich mal sehr
interessieren. Ich kann weder auf der mikrocontroller Seite noch im
google die Datei finden. Hat jemand vielleicht den Link da??

von Thomas O. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hier ist sie.

von bluemol (Gast)


Lesenswert?

super

von bluemol (Gast)


Lesenswert?

Hast Du von dem PDF eine Schaltung schon mal ausprobiert?? Wenn ja mit
welchen Erfolg?? Die Schaltung in Bild 2 ist ja ziemlich einfach zum
testen. Ich bau Sie mal auf und schaue mir das Ergebnis an.

von Thomas O. (Gast)


Lesenswert?

Hallo,

ich habe ja den MPX4250AP habe an die Versorgungsspannung direkt an die
2 Pins einen 47pF Kerko hängen am Ausgang einen 100 Ohm Wiederstand
sowie nochmal nen 47pF Kerko parallel. Habe das mit dem Oszi überprüft
udn die Ausgangsspannung ist absolut sauber sogar wenn ich das Oszi auf
0,1V/Raster stelle sieht man absolut nichts mehr.

von Thomas O. (Gast)


Lesenswert?

Hallo,

dazu ist zu sagen das ich schon nach dem LM7805 sehr gut gebügelt habe
und so den ersten Kondensator gespart habe.

von Thomas O. (Gast)


Lesenswert?

Hallo,

so schau meine Schaltung ja auch aus nur den ersten Elko hab ich
weggelassen, weil ich ihn nicht gebraucht habe und die Werte hab ich
halt etwas angepasst.

Wenn ich mir die untersten 8 Bits der 10Bit Wandlung anschaue dann sehe
ich auch ein ganz leichtes flimmern bei einzelnen Leds also wenn die
Spannung z.b. zw. 10 und 11 schwankt, liegt aber nicht am Signal zum
AD-Pin sondern am AVR selbst, da konnte man Softwaremäßig nen
durchschnitt aus z.b. 4 Messungen bilden um das in den Griff zu
bekommen wenn ich auf 8 bit wandle tritt das nicht mehr auf da die
Aufläsung um den Faktor 4 geringer ist.

AD_busy_:
sbis  ADCSR,ADIF  ;Flag, busy?
rjmp  AD_busy_  ;springt raus, wenn fertig

in  temp,ADCL  ;Lese AD-Wert ein
in  temp2,ADCH
;Auf256_:
;ror  temp2    ;xxxxxxxN  c=N
;ror  temp    ;Nnnnnnnn  c=n
;ror  temp2    ;xxxxxxxx  c=N
;ror  temp    ;NNnnnnnn  c=n
;Das Ergebnis steht in temp
out portb,temp ;Hier habe ich die Umwandlung deaktiviert und nehme die
untersten 8bits ist dann von der Auflösung genauer geht aber nicht so
weit rauf also nur bis ca. 1,25V man kann sich aber das 9te Bit
anschauen und dann umschalten also ab 1,25V auf 8bit umstellen
rjmp start

von ...HanneS... (Gast)


Lesenswert?

Hi...

Warum Durchschnitt?

Ich bau immer eine Hysterese ein, übernehme den neuen Wert also nur,
wenn er mehr als einen Wert vom zuvor eingelesenen Wert abweicht.

Falls die Quelle hochohmig ist, sollte auch ein C um die 1n an den
ADC-Eingang, wegen der pulsierenden Belastung der Sample&hold-Schaltung
im ADC.

...HanneS...

von Thomas O. (Gast)


Lesenswert?

Hallo,

das ist auch ne Idee. Muss ich gleich mal implantieren.

von Thomas O. (Gast)


Lesenswert?

Hallo,

also hat fast nichts gebracht Hysterese müsste größer sein, wobei das
ja das gleiche ist wie wenn man die Auflösung verringert.
Also wenn ich  von 10 bit auf 8 gehe sind die Schritte auch großer ist
wie wenn ich so ne 1er Hystereseb reinmache.
Habe vorerst eh nur 7 Bits als Ausgang zur Verfügung sonnst müsste ich
den Reset Pin disablen habe aber noch kein STK500 um das zurücksetzten
zu können. Von daher benutze ich nur 8bits und kann durch das Fehlende
Bit nur bis 2,5V ausgeben lassen.

von Thomas O. (Gast)


Lesenswert?

Hallo,

mal ne andere Frage ich möchte meinen Drucksensor im Auto einsetzten
und im Saugrohr treten ja Pulsationen(Druckschwankungen) auf meine z.b.
im Leerlauf. Um diese Schwankungen zu glätten könnte ich ja einfach
einen großen Kondensator an den Sensorausgang/ADC-Eingang setzten mit
dem Nachteil das der Drucksensor dann verzögert reagiert. Ich würde es
gerne Softwaremäßig lösen da ich das dann jederzeit deaktiviern kann.

Soll ich da einfach die z.b. 20 letzten Werte addieren und dann durch
20 Teilen? Oder wie könnte man das sonst geschickt lösen? Um diese
Schwankungen etwas zu glätten?

von Micahel H. (Gast)


Lesenswert?

Hallo,

hab mal nen Temperaturregler zusammen gestrickt und das so gelöst:

4 Messungen machen und addieren, dann durch 4 teilen ergo Mittelwert
bilden.
Hinten in ein Fifo mit gesamt 16 Werten reinschreiben und anschliessend
schieben, das heisst der älteste Wert "fällt vorn raus".
Summe aller Fifo-Werte und dann durch 16.... da bekommst du so was wie
einen gleitenden Mittelwert

Gruß Michael H.

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.