Frage zum ADC Modus

OP #5980976
Lesenswert?

Hallo zusammen,

Ich hätte mal eine Frage zur ADC des Atmega328p.
Man kann den ja im Free Running und im Single Conversion Modus 
betreiben.

Für was brauche ich denn welchen Modus?
Also ich meine, warum sollte ich den nicht immer im Free Running Modus 
haben, wenn ich nicht gerade eine Energiesparende Anwendung habe?

Wieviel schneller ist der Free Running Modus im Vergleich zum Single 
Conversion Modus?

Danke schon mal im Vorraus :)
Gast #5981004
Lesenswert?

Stefan H. schrieb:
> Für was brauche ich denn welchen Modus?

Single Conversion Modus bietet sich an, wenn dein Programm irgendwo eine 
einzelne Messung benötigt und ohne Probleme auf das Messergebnis warten 
kann.

Free Running bietet sich an, wenn

a) Messungen in regelmäßigen Intervallen nötig sind, zum Beispiel um 
Audio aufzuzeichnen
b) Die Messungen automatisch im Hintergrund stattfinden sollen, so dass 
dein Programm jederzeit ohne warten zu müssen das Ergebnis der 
vorherigen Messung  zugreifen kann.

> Wieviel schneller ist der Free Running Modus
> im Vergleich zum Single Conversion Modus?

Der ist gar nicht schneller.
OP #5981030
Lesenswert?

Stefanus F. schrieb:
> Der ist gar nicht schneller.

Stimmt, hab ich gerade im Datenblatt auch gefunden :)


Konkret möchte ich einen MSGEQ7 Chip betreiben.
Das ist ein kleiner Audio Spectrum Analyzer Chip, welcher mir für 7 
Frequenzen die Höhe als Analogwert liefert.
Die 7 Werte frage ich nacheinander ab, rechne ein bisschen damit, und 
frage sie dann erneut ab.


Also hab ich das dann so richtig verstanden:
Ich aktiviere den ADC einmal am Anfang, dann bleibt der an und frage 
dann die werte jedes mal im Single Cenversion Modus ab.
Dann brauche ich für jede Abfrage 13 Zyklen.

Danke schon mal!

Gruß
Angehängte Dateien:
OP #5981062
Lesenswert?

Würde das so klappen?
1
//ADMUX beschreiben, also Channel 0 und Referenz Auswahl 
2
//AVCC with external capacitor at AREF pin
3
//ADLAR auf 1 -> Ergebnis is rechtbündig, da ich nur 8 bit brauche
4
ADMUX &= ~(1<<REFS1) & ~(1<<MUX0) & ~(1<<MUX1) & ~(1<<MUX2) & ~(1<<MUX3);
5
ADMUX |= (1<<REFS0) | (1<<ADLAR);
6
  
7
//Deaktiviere Energiesparen des ADC
8
PRR  &= ~(1<<PRADC);
9
//Aktiviere ADC, single mode ist default,setze Prescaler auf 128 -> 125khz
10
ADCSRA |= (1<<ADEN) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);
11

12
 while (1) 
13
 {
14
  ADCSRA |= (1<<ADSC); //start Conversion
15
  while (ADCSRA & (1<<ADSC)); // warte bis ADCS = 0 -> Converison fertig
16
  gelesener_wert = ADCH; //Nur ADCH Register kopieren, nur 8bit auflösung nötig
17
 }
#5981177
Lesenswert?

Stefan H. schrieb:
> Also ich meine, warum sollte ich den nicht immer im Free Running Modus
> haben, wenn ich nicht gerade eine Energiesparende Anwendung habe?

Und damit hast du schon das erste Beispiel genannt:

Warum sollte man den ADC laufen lassen, wenn man ihn nicht braucht? Die 
Heizung macht man ja auch nur an wenn einem kalt ist ;)

Ein weiteres Beispiel ist eine FFT, hier bietet sich ein konstantes TA 
an. Das kann man im Free Running Mode machen, hat dann aber ggf. ein 
ziemlich krummes TA oder man triggert via Timer und hat so ein passendes 
TA sodass man bei der FFT noch mehr Zeit sparen kann.

Bei einer Audio-Aufzeichnung will man in der Regel auch konstante 
Zeitabstände haben mit einer definierten Länge und da passt gff. die 
Abtastrate des ADCs auch nicht rein.

Und von extern kann man den ADC auch triggern lassen, das Äquivalent 
dazu ist der externe Trigger am Oszilloskope. ;)

Stefan H. schrieb:
> Wieviel schneller ist der Free Running Modus im Vergleich zum Single
> Conversion Modus?

Ich meine der Free-Running-Mode ist um einen Zyklus schneller, genaueres 
weis das Datenblatt.
#5981541
Lesenswert?

Die Datenblattangaben habe ich noch nie richtig kapiert. Wozu immer der 
halbe Zyklus "13,5"?
Besonders ungeschickt ist die Zeitverzögerung, wenn man abwechselnd zwei 
Eingänge wandelt, das halbiert die Wandlungsrate, weil jedesmal neu 
kalibriert wird.
Das Diagramm im Datenblatt ist eher verwirrend, wo sehe ich die 13,5 
Zyklen? Da ist nur ein undefiniert schraffiertes Zeitstück nach dem 13. 
Takt.
Angehängte Dateien:
#5981563
Lesenswert?

Christoph db1uq K. schrieb:
> Die Datenblattangaben habe ich noch nie richtig kapiert. Wozu immer der
> halbe Zyklus "13,5"?

Ich verstehe die Frage nicht. Ein Zyklus hat immer eine ganze Länge 
von ADC-Takten. Er startet und endet mit der steigenden Flanke.

Die S&H Stufe schaltet bei der zweiten fallenden Flanke und folglich 1.5 
ADC-Takte nach dem Start des Zyklus von Sample auf Hold. Ja, das ist 
halt so. War ein Kompromiß beim Design. Man hätte die Sample-Zeit auch 2 
Takte statt 1.5 lang machen können, aber dann wäre der Zyklus 14 statt 
jetzt 13 Takte lang geworden. Oder nur einen Takt Samplezeit, dann müßte 
man den ADC aber noch niederohmiger ansteuern, damit die 
Sample-Kapazität in der kürzeren Zeit auch genau genug aufgeladen wird.

> Besonders ungeschickt ist die Zeitverzögerung, wenn man abwechselnd zwei
> Eingänge wandelt, das halbiert die Wandlungsrate, weil jedesmal neu
> kalibriert wird.

Auch dieser Satz ergibt keinen Sinn. Welche Kalibrierung meinst du? Da 
wird nichts kalibriert. Und daß man mit nur einem ADC bei zwei genutzen 
Kanälen immer nur im Wechsel messen kann und sich die effektive 
Abtastrate dadurch halbiert, ist auch unmittelbar einsichtig.
#5981609
Lesenswert?

Anscheinend habe ich das falsch verstanden,
1
A normal conversion takes 13 ADC clock cycles. The first conversion after the ADC is switched on (ADEN in ADC-SRA is set) takes 25 ADC clock cycles in order to initialize the analog circuitry.
also diese "Kalibrierung" muss nicht jedesmal zwangsweise erfolgen

und
1
In Free Running mode, always select the channel before starting the first conversion. The channel selection may be changed one ADC clock cycle after writing one to ADSC. However, the simplest method is to wait for the first conversion to complete, and then change the channel selection. Since the next conversion has already started automatically, the next result will reflect the previous channel selection. Subsequent conversions will reflect the new channel selection.
das heißt ich muss möglichst früh auf den anderen Eingang umschalten
Gast #5981631
Lesenswert?

Peter D. schrieb:
> Free Running nimmt man, wenn nur ein Eingang einzulesen ist oder in
> einem konstanten Zeitraster vom Timer.
> Will man aber den MUX umschalten, wird es haarig damit.

Ich habe den free Running schon einmal benutzt, um sämtliche ADC Kanäle 
fortlaufen einzulesen und in ein Array einzutragen (je ein integer pro 
Kanal). So habe ich in diesem Array stets die (fast) aktuellen 
Spannungswerte aller ADC Eingänge verfügbar, ohne darauf warten zu 
müssen.

Die Zugriffe darauf müssen allerdings synchronisiert werden, damit man 
nicht liest, während die ISR schreibt.
#5981739
Lesenswert?

Christoph db1uq K. schrieb:
> Oben im Bild von Stefan stehen die Zahlen, first conversion time ist
> (25+13,5) Zyklen statt der (2+13,5) Zyklen bei ständiger Wandlung eines
> einzigen Eingangs

Die halben Taktzyklen halluzinierst du irgendwoher. Es sind 25 oder 13 
Taktzyklen Wandlungs dauer. Der halbe Takt bezieht sich immer nur auf 
den Zeitpunkt, wann der ADC das Analogsignal latched. In manchen 
Anwendungen ist das wichtig.


Peter D. schrieb:
> Free Running nimmt man, wenn nur ein Eingang einzulesen ist oder
> in einem konstanten Zeitraster vom Timer.
> Will man aber den MUX umschalten, wird es haarig damit.

Keineswegs. Man darf jederzeit auf das MUX Register schreiben. Wenn 
gerade eine Wandlung läuft, hat es halt keinen unmittelbaren Effekt. Im 
Freerunning Modus läuft praktisch immer eine Wandlung. Ein Kanalwechsel 
durch das Beschreiben des MUX Registers ist dann halt immer um eine 
Wandlung verzögert. Wirklich praktikabel ist Freerunning auf mehreren 
Eingängen aber in der Tat nur in Verbindung mit dem ADC-Complete 
Interrupt. Die ISR kann dan den ADC-Wert für den letzten Kanal lesen und 
unmittelbar den nächsten Kanal nach MUX schreiben. Den Wert des 
aktuellen Kanals hat sie beim vorigen Aufruf setzen müssen.
#5981889
Lesenswert?

Ok, wir haben den "Auto triggered mode" in verschiedenen Varianten, von 
denen ich den "Free-running mode" benutze, alle zeitkritischen 
Operationen in einer periodische ausgelösten ADC-Complete 
Interrupt-Routine in festen Zeitabständen.
Das Hauptprogramm darf alles andere erledigen, das nicht zeitkritisch 
ist, ich muss nur sicher sein, dass die Interruptroutine nicht länger 
als der Sampleabstand wird.

Meine Anwendung wäre eine DSP-Aufgabe, acht Allpassfilter zweiter 
Ordnung mit acht 16-Bit Multiplikationen zu rechnen. Das ganze habe ich 
vor 10 Jahren mal angefangen aber einschlafen lassen:
https://www.mikrocontroller.net/articles/Hilbert-Transformator_(Phasenschieber)_mit_ATmega
damals gab es noch keinen Arduino, aber die Verhältnisse sind ähnlich.

Mit QO-100 ist das wieder aktuell geworden. Für einen SSB-Sender brauche 
ich eine Samplerate, die ein Mikrofonsignal bis zu 3 kHz sampled, also 
um die 8 kHz, das geht mit dem Arduino noch. Die beiden PWM-Ausgänge 
liefern dann  I und Q für eine I/Q-Modulator.
Für die Verwendung derselben Filter in einen SSB-Empfänger müsste ich I 
und Q eigentlich gleichzeitig wandeln, aber direkt nacheinender sollte 
keinen großen Fehler bewirken. Erst wenn zwei Samples vorliegen würde 
die DSP-Routine einmal rechnen, alles im Interrupt.
Das Hauptprogramm darf bei Bedarf noch gemütlich eine Drehgeber 
abfragen, ein Textdisplay ansteuern und eine PLL einstellen, alles ohne 
Echtzeitanforderungen.
Gast #5982077
Lesenswert?

Man darf immer in das MUX Register schreiben. Allerdings ist der Effekt 
abhängig vom Timing: gleich nach dem Starten des ADCs gilt es noch für 
die aktuelle Wandlung. Nach etwa 1 ADC clock zyklus (könnte ggf. etwas 
mehr sein), gilt der neue MUX wert dann erst für die Wandlung nach der 
gerade laufenden.

Wenn man in der ADC-comlete ISR schnell ist, könnte man noch den ersten 
Fall haben und dann durch kleine Verzögerungen im Aufruf der ISR (z.B. 
kurzer CLI - SEI Block oder ein anderer Interrupt) schon in den 2. Fall 
rutschen. Wenn man sowieso lange genug wartet bzw. rechnet, um in den 2. 
Fall zu rutschen, hat man recht viel Reserve für Verzögerungen.
Gast #5982266
Lesenswert?

Peter D. schrieb:
> andere Interrupts können das soweit
> verzögern, daß die nächste Wandlung schon abgeschlossen ist.

Interrupts können potentiell alles so weit stören, dass es nicht mehr 
korrekt funktioniert. Man muss schon mit Hirn kombinieren - copy-paste 
Programmieren funktioniert selten.
#5982288
Lesenswert?

Stefanus F. schrieb:
> Interrupts können potentiell alles so weit stören, dass es nicht mehr
> korrekt funktioniert.

Wenn man aber erst die nächste Wandlung startet, nachdem der MUX 
umgeschaltet wurde, kann ein anderer Interrupt nur verzögern. Die 
Reihenfolge stimmt aber immer.
Die eine Zeile Codeeinsparung (ADC-Startbefehl) ist den ganzen Ärger 
nicht wert. Wie gesagt, solche Fehler möchte ich nicht debuggen müssen.
Gast #5982289
Lesenswert?

Peter D. schrieb:
> Die eine Zeile Codeeinsparung (ADC-Startbefehl) ist den ganzen Ärger
> nicht wert.

Wenn du jede Wandlung einzeln startest, ist der ADC allerdings bedeutend 
langsamer und hat zudem keine regelmäßige Abtastrate mehr (weil andere 
Interrupts stören).

Ob das noch Ok ist, hängt von der Anwendung ab.

Wenn man so generisch fragt, wie der TO es getan hat, kommt man leider 
immer vom Höckschen auf Stöckchen. Programmieren ist eben kein einfacher 
Job.
Moderator Persönliche Seite #5982396
Lesenswert?

Peter D. schrieb:
> Lieber fehlertolerant programmieren, als falsche Ergebnisse zu erhalten.

In Christophs Kontext wäre eine reduzierte Abtastrate ein falsches 
Ergebnis, da hilft all die vermeintliche Fehlertoleranz dann nichts 
mehr. Wenn man den ADC benutzen will, um damit DSP-Funktionalität zu 
implementieren, geht das nur mit einer bekannten Abtastrate – und die 
konstante Rate ist dabei die einfachste Variante, wie man sie "bekannt" 
macht.
#5982444
Lesenswert?

Welche Abtastrate kann ein Arduino mit 16 MHz Quarz überhaupt erreichen?

Das Datenblatt macht die etwas schwammige Aussage:
1
By default, the successive approximation circuitry requires an input clock frequency between 50kHz and 200kHz to get maximum resolution. If a lower resolution than 10 bits is needed, the input clock frequency to the ADC can be higher than 200kHz to get a higher sample rate.

Der Prescaler kann aus den 16 MHz auf 125 kHz bis 8Mhz Sampletakt 
teilen. Mit der Aussage "A normal conversion takes 13 ADC clock cycles." 
komme ich dann auf eine Wandlungsrate von 9,6 kHz bis 615 kHz mit der 
genannten Einschränkung oberhalb 200 kHz.
#5982503
Lesenswert?

Die Begrenzung liegt bei meiner Aufgabe eher in der Ausführungszeit der 
Interruptroutine. Ich meine dass es damals etwa 60 oder 70% Rechenzeit 
waren, weiß aber nicht mehr ob das mit Clk/64 war (Clk/128 ist 
auskommentiert). Das wären 250 kHz ADC-Takt und 19 kHz Samplerate.

Inzwischen sind 32-bit Controller den 8-Bittern preislich gleichgezogen, 
das ganze ist jetzt eher minimalistische Kunst. Wenn es mit einem 
Arduino noch geht, kann es ein ARM allemal. Dasselbe im CPLD mit 
multiplierless Integerarithmetik wäre noch interessant, vielleicht 
versuche ich das auch noch.
#5982803
Lesenswert?

Christoph db1uq K. schrieb:
> Welche Abtastrate kann ein Arduino mit 16 MHz Quarz überhaupt erreichen?
>
> Das Datenblatt macht die etwas schwammige Aussage:
>
> By default, the successive approximation circuitry requires an
> input clock frequency between 50kHz and 200kHz to get maximum
> resolution. If a lower resolution than 10 bits is needed, the input
> clock frequency to the ADC can be higher than 200kHz to get a higher
> sample rate.

Was ist daran schwammig?

> Der Prescaler kann aus den 16 MHz auf 125 kHz bis 8Mhz Sampletakt
> teilen. Mit der Aussage "A normal conversion takes 13 ADC clock cycles."
> komme ich dann auf eine Wandlungsrate von 9,6 kHz bis 615 kHz mit der
> genannten Einschränkung oberhalb 200 kHz.

Wenn du die Einschränkung ernst nimmst, liegt die einzig erlaubte ADC 
Taktfrequenz bei 125kHz, was ~9.6kHz Abtastrate ergibt. Höhere ADC 
Taktfrequenzen funktionieren (bei geringerer Genauigkeit des ADC) aber 
es gibt keine Garantie oder gar Spezifikation, wieviele Bits es bei 
welcher Frequenz sind.

Christoph db1uq K. schrieb:
> Die Begrenzung liegt bei meiner Aufgabe eher in der Ausführungszeit der
> Interruptroutine.

Ja, klar. Viel Rechnerei kannst du mit einem AVR dann nicht mehr machen. 
Vor allem, wenn du die vollen 10 Bit vom ADC verwenden willst. Aber wie 
du schon sagst, gibt es dafür geeignetere Bausteine. Von den einfachen 
Cortex-M0 über M4 (FP, DSP-Extension) bis hin zu ausgewachsenen DSP.
Moderator Persönliche Seite #5982825
Lesenswert?

Christoph db1uq K. schrieb:
> Wenn es mit den ersten Exemplaren funktioniert ist das keine Garantie,
> das kann teuer werden.

Naja, ist halt die Frage, was du damit anstellen willst. Für eine 
Überwachugn der Batteriespannung genügen auch deutlich weniger Bits an 
Genauigkeit. Die Aussage bedeutet letztlich, dass der ADC nicht etwa 
oberhalb 200 kHz radikal seine Arbeit einstellt, sondern dass er mit 
höher werdender Taktfrequenz nur zunehmend ungenauer wird.
#5982966
Lesenswert?

Das ist zwar nicht der "Arduino-Typ" aber im Datenblatt zum 328P ist die 
Tabelle auch enthalten, nicht im Kapitel ADC sondern weiter hinten 
Kapitel 29.8 Table 29.15. Hier Seite 319:
http://ww1.microchip.com/downloads/en/DeviceDoc/ATmega48A-PA-88A-PA-168A-PA-328-P-DS-DS40002061A.pdf

Für 1 MHz, die Jörg genannt hat ist eine "Resolution, Absolute 
accuracy..." von 3,25 LSB, also des 10. Bits genannt. Das heisst also 
1,625 des neunten Bits oder fast einmal das 8.Bit, das würde also 
stimmen. Auch unter clock frequency ist 1 MHz als obere Grenze genannt.

Das ist doch deutlich präziser als im ADC-Kapitel. Die 662 Seiten hätte 
ich gründlicher durchsehen müssen, danke für den Tip.

Zur Eingangsfrage, ich hatte vom Audio-Analyzer-Chip im Elektor Mai/Juni 
2019 gelesen. So neu ist der nicht, ein Datenblatt von 2004:
https://www.sparkfun.com/datasheets/Components/General/MSGEQ7.pdf
hier im Forum unter MSGEQ7 verlinkt von 2011. Die Amplitudendetektoren 
sind schon drin, da ist doch keine hohe Geschwindigkeit mehr nötig.

Ganz anders "die Mutter aller AVR-Audioanalyzer" von Elm-Chan, das ist 
auch ein Paradebeispiel minimaler Programmierkunst von 2005:
http://elm-chan.org/works/akilcd/report_e.html
Moderator Persönliche Seite #5983094
Lesenswert?

Christoph db1uq K. schrieb:
> Auch unter clock frequency ist 1 MHz als obere Grenze genannt.

Ja, wie schon geschrieben, das haben sie mal nachgereicht. Ursprünglich 
stand in den Datenblättern der AVRs nur der Garantiebereich von 50 bis 
200 kHz drin. Nachdem die Nutzer rausgefunden hatten, dass die Teile 
auch mit 1 MHz noch sauber genug für viele Anwendungen arbeiten (viele 
Leute werden vermutlich sowieso gleich ADLAR setzen und dann nur das 
High-Byte nutzen), hat man dann die 1 MHz mal in die Datenblätter 
überhaupt mit aufgenommen.

Das erklärt aber, warum es in der Prosa nicht so drin steht, nur in den 
Tabellen.

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