Forum: Mikrocontroller und Digitale Elektronik adc ist sehr unruhig


von Ratsuchender (Gast)


Lesenswert?

Hallo,

also ich bin mit meinem Latein so langsam an Ende... ich habe zwei 
ADC-Kanäle, die ich auslesen möchte und sie sind so derartig verrauscht, 
dass ich die Ergebnise eigentlich komplett verwerfen möchte...

Den Pin AREF habe ich offen liegen (ohne Stützkondensator), da das 
Datenblatt behauptet man bräuchte ihn nicht beschalten, wenn man die 
internen Referenzspannungen wählt. Der Chip, Atmega 128RFA1 kann 
wahlweise bei 1.5V, 1.6V, AVDD (=1.8V) oder AREF(extern) betrieben 
werden...
Meint ihr ich sollte einen Kondensator zwischen GND und AREF anlöten, 
obwohl das Datenblatt die als unnötig erachtet?

Ich habe mitlerweile auch etwas im Forum gelesen und dabei den Tipp 
gefunden, nicht genutzte Kanäle per 1Mohm an GND zu legen... Dies wäre 
nur mit erheblichem Aufwand möglich... und würde ich kaum als primäre 
Ursache für das Fehlverhgalten deuten...

...ich möchte mich ungern an diesen beiden Notnageln versuchen, bevor 
nicht andere Möglichkeiten bedacht sind...

... möglicherweise sind auch Timing-Probleme vorhanden, Der Chip läuft 
mit 16Mhz. Folgenden Programmcode verwende ich:

uint16_t ReadChannel(uint8_t mux)
{
  uint8_t i;
  uint16_t result;

 ADCSRA |= ((1<<ADPS2) | (1<<ADPS0));   //ADC-Frequenz auf 500khz
 ADCSRA &=~ (1<<ADPS1);

 ADCSRA |=  (1<<ADEN);
 ADMUX = mux;                           //Kanal "0" oder "1"
 ADMUX |= (1<<REFS1);                   //1.6 Volt Referenz nutzen
 ADMUX |= (1<<REFS0);´                  //laut Datenblatt am genauesten
 ADCSRA &= ~(1<<ADEN);

ADCSRA |=  (1<<ADEN);
ADCSRA |= (1<<ADSC);   //eine Messnug starten

while ( ADCSRA & (1<<ADSC) )
{;}
result = ADCW;
resul=0;

for( i=0; i<10; i++ )
{
  ADCSRA |= (1<<ADSC);
  while ( ADCSRA & (1<<ADSC) )
  {;}
  result += ADCW;
  ADCSRA &= ~(1<<ADEN);
  return result;
}

(ich möchte bewußt nicht den arithm. Mittelwert haben, daher Aufaddition 
von 10 Werten ohne zu dividieren, um Rauschen zu reduzieren)

ferner wird im Programm die Datenrichtung wie folgt festgelegt:

DDRF  &= ~(1<<DDF0);  // Pin PF0 als Eingang
PORTF &= ~(1<<PF0);   // Pull-Up ausmachen

DDRF  &= ~(1<<DDF1);  // Pin PF1 als Eingang
PORTF &= ~(1<<PF1);   // Pull-Up ausmachen

Der ADC-Eingang 1 wird verwendet, um einen (schwankenden und 
OP-verstärkten Messwert aufzunehmen. Hier könnte ich mir Schwankungen 
also erklären, gleichwohl sie problematisch wären...

Der ADC-Eingang 0 hingegen nimmt nur ein Signal der Batterie, bzw. 
Netzteilversorgung auf. Dieses ist mittels 100K-Spannungsteiler auf 
einen Bereich von 1,65 Volt reduziert und müsste eigentlich sehr stabil 
sein...


...hat jemand eine Idee, an welchen Stellschrauben ich noch drehen 
könnte?

mfg

von Spess53 (Gast)


Lesenswert?

Hi

> ADCSRA |= ((1<<ADPS2) | (1<<ADPS0));   //ADC-Frequenz auf 500khz

Das ist schon recht flott

'By default, the successive approximation circuitry requires an input 
clock frequency between 50 kHz and 200 kHz to get maximum resolution.'

>Meint ihr ich sollte einen Kondensator zwischen GND und AREF anlöten,
>obwohl das Datenblatt die als unnötig erachtet?

Das verwundert mich aber. Wird in allen AVR Datenblättern und Appnotes 
empfohlen.

Wo kommen Die Eingangssignale her?

MfG Spess

von Peter D. (peda)


Lesenswert?

Ich benutze den ADC des ATmega8 und ATtiny861 und da ist er saustabil. 
Ich kann nicht mal ein 11. Bit rauskitzeln, wenn ich 64 Werte addiere.


Ich vermute, das ist bei Dir ein Layoutproblem. Ich benutze 2-Layer, die 
Unterseite ist dabei GND, nur von kurzen Leiterzügen (<20mm) 
unterbrochen. VCC führe ich kammartig an einem Rand der Platine, also 
nicht im Zickzack von IC zu IC.
100nF Pillen an jedem (A)VCC-Anschluß und 100..470µF pro Platine.
5V VCC kommt aus nem 10W Schaltnetzteilmodul bzw. 5W DCDC-Wandler.


Peter

von Ratsuchender (Gast)


Lesenswert?

Also das Datenblatt schreibt:

"When using the internal 1.5V or 1.6V references no external de-coupling 
capacitor must be connected to AREF. High capacitive loading will 
de-stabilize the internal voltage amplifier"

Daher habe ich bewußt keinen Kondi zwischengelegt.

Die ADC-Frequenz darf laut Datenblatt für Single Ended Conversion CLKADC 
<= 4 MHz gewählt werden.

Bei 4Mhz habe ich nochmehr Müll herausbekommen, daher ist sie jetzt auf 
"nur" 500khz.
Bei maximalem Vorteiler könnte ich sie auch nur noch auf 125khz senken, 
da ist also nicht mehr so viel Spielraum...

Das eigentlich stabil erwartete Signal von der Versorgungsspannung wird 
aus einem schlichten Spannungsteiler gewonnen. Mnidestens hier müsste 
die Konvertierung ja eigentlich problemlos klappen...

9Volt --> 82kohm --> Signalabgriff mit ADC Pin 0 --> 18kohm --> GND


Ideen?

von Peter D. (peda)


Lesenswert?

Spess53 schrieb:
> 'By default, the successive approximation circuitry requires an input
> clock frequency between 50 kHz and 200 kHz to get maximum resolution.'

Ich benutze 125kHz und es funktioniert.


Peter

von avion23 (Gast)


Lesenswert?

Ratsuchender schrieb:
> ei 4Mhz habe ich nochmehr Müll herausbekommen, daher ist sie jetzt auf
> "nur" 500khz.
> Bei maximalem Vorteiler könnte ich sie auch nur noch auf 125khz senken,
> da ist also nicht mehr so viel Spielraum...
Wie kommst du zu der Aussage?

f_adc solltest du auf 125kHz stellen.

>9Volt --> 82kohm --> Signalabgriff mit ADC Pin 0 --> 18kohm --> GND

Eingangsimpedanz sollte < 10kΩ sein. fixen mit 1nF - 100nF zwischen gnd 
und adc.

von Spess53 (Gast)


Lesenswert?

Hi

>9Volt --> 82kohm --> Signalabgriff mit ADC Pin 0 --> 18kohm --> GND

Ist etwas gross. Datenblatt:

RAIN Analog Input Resistance typ. 2 k

@Peter

Der ADC vom Atmega 128RFA1 tickt etwas anders.

Single Ended Conversion CLKADC <= 4 MHz 10 Bits
Single Ended Conversion CLKADC > 8 MHz 8 Bits

MfG Spess

von Peter D. (peda)


Lesenswert?

Ratsuchender schrieb:
> for( i=0; i<10; i++ )
> {
>   ADCSRA |= (1<<ADSC);
>   while ( ADCSRA & (1<<ADSC) )
>   {;}
>   result += ADCW;
>   ADCSRA &= ~(1<<ADEN);
>   return result;
> }

Dieser Code macht nur eine Messung und nicht 10.


Peter

von Ratsuchender (Gast)


Lesenswert?

sorry, hab ein paar geschweifte Klammern nicht mit kopiert... es werden 
zehn Messungen aufaddiert...

wodran könnte man denn eigentlich erkennen, ob der ADC beschädigt wurde?
Ich verstärke nämlich ein Photodiodensignal, welches in einer meist 
dunklen Kammer aufgenommen wird. Während dem Aufbau und den beginnenden 
Testphasen war es allerdings auch häufig taghell, so dass die 
OP-Schaltung aus dem dann zu großen Photostrom ein Signal erzeugt hat, 
welches den Bereich von ungefähr 4 Volt erreicht hat... im normalen 
Betrieb erwarte ich nur höchsten 1,5 Volt... kann es sein, dass der ADC 
dabei beschädigt wurde?... dumme Frage, natürlich kann das sein, aber 
wie könnte ich dies mit Sicherheit feststellen? Immerhin bekomme ich ja 
durchaus Werte digitalisiert, nur schwanken diese eben enorm... Gibt es 
eine Testmöglichkeit eine Beschädigung sicher auszuschließen?

Und dann noch eine Frage zu der Eingangsimpedanz des Spannungsteilers: 
Genügt es 100nF noch parallel zu frickeln oder sollte ich den 
Spannungsteiler um Faktor zehn verringern auf 10kohm, das würde 
allerdings dauerhafte Verlustströme von 100uA mit sich bringen...

mfg

von Knut (Gast)


Lesenswert?

Ich würde grundsätzlich immer 1nF an jeden Eingang packen, bringt viele 
Vorteile, wenig Nachteile. Bei den XMegas is das sogar empfohlen. Wenn 
man den ADC übertaktet kann das zum einfrieren führen!

Was auch hilft währe mal die Schaltung...



Gruß Knut

von Ralph (Gast)


Lesenswert?

Sieh dir die Signale die du dort messen willst mal auf einem Oszilloskop 
an.

Wenn die da stabil sind, dann sollten sie das am ADC auch sein.

Vor allem kannst du dannn mal sehen wir groß der ADC Anteil und wie groß 
der Signal Anteil bei deinem Rauschen ist.

Danach weißt du ob du ein Problem im µC oder bei der Signalaufbereitung 
hast.

Oder beides.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Ratsuchender schrieb:
> welches den Bereich von ungefähr 4 Volt erreicht hat... im normalen
> Betrieb erwarte ich nur höchsten 1,5 Volt... kann es sein, dass der ADC
> dabei beschädigt wurde?
Nicht, wenn die Versorgungsspannung 5V beträgt.

Zeig doch mal dein Layout...

von Peter D. (peda)


Lesenswert?

Ratsuchender schrieb:
> Genügt es 100nF noch parallel zu frickeln

100nF ist o.k., habe ich auch so gemacht.

Ich hab nen Spanungsteiler mit 1M dran, geht ohne Probleme.


Peter

von Ratsuchender (Gast)


Lesenswert?

mann mann mann,

gleich eine ganze Reihe Fehler haben sich eingeschlichen, aber jetzt 
scheint es zu funktionieren... mancmalmuss man eben an mehr als nur 
einer Stellschraube drehen...

allen herzlichen Dank mit bei den vielen Ratschlägen.

von Jo Sto (Gast)


Lesenswert?

Da ich gerade mit ähnlichen Problemen kämpfe - was has du alles 
geändert?

von Roland (Gast)


Lesenswert?

C oder LC an Aref...
eingangsimpedanz am analogen input entsprechend klein halten allenfalls 
inpedanzwandler oder C (gilt hauptsächlich wenn mehrere analoge inputs 
verwendet werden, wenn umgeschaltet wird, bei zu hoher eingangsimpedanz 
ist eine "störung" messbar...
wenn der ADC eingeschalten wird, das resultat der ersten messung 
verwerfen, da es gemäss datenblatt fehlerhaft sein kann...
wenn man nicht sicher ist, beispielcode aus datenblatt verwenden, der 
funktiniert...

--> anweisungen des datenblatts bringt segen...

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.