Code zum auslesen des ADC - Wie geht das?

Moin!

Bin gerade bei einem Projekt mit FFT. Dafür nutze ich die FFL Library von openmusic labs. Das ganze läuft zwar gut aber:

Nun wollte ich code für die dynamische Pegelstellung miteinbauen. Beim ansehen der Werte aus dem ADC kommen aber sehr seltsame Werte bei raus. (700 in ruhe, schon mal um 1500 bei Musik)

Das ist der Code zum auslesen, wie er bei einem Beispiel dier FFT Lib dabei war: (ADC im freerun)

while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int

Kann mir bitte jemand erklären was hier passiert? Insbesondere die beiden unteren Zeilen werfen die fragen auf.

byte m = ADCL; // fetch adc data

byte j = ADCH;
k = (j << 8) | m; // form into an int

Kürzer:

k = ADCW;

Insbesondere die beiden unteren Zeilen werfen die fragen auf.

Bei mir auch.

Immer vorausgesetzt, dass die Variable k passend deklariert ist:

k -= 0x0200; // form into a signed int

Zieht vom ADC-Wert 512 ab. Damit wird der Wertebereich 0...1023 auf -512...511 verschoben, symmetrisch um die 0 herum - warum auch immer.

k <<= 6; // form into a 16b signed int

Multiplikation mit 64. Genauigkeit wird damit nicht gewonnen, aber vielleicht nützt diese andere Quantisierung bei der weiteren Rechnung.

Gruß Walter

Hi

Die letzte Zeile macht den 10-bit-Wert nur linksbündig - sollte der AVR von Haus schon können (ohne das Abziehen der 512).

MfG

(ohne das Abziehen der 512).

Für die FFT wird der Mittelwert über alle Messungen (nahe) Null sein müssen.
bzw. benötigt es eine um Null schwankende Wechselspannung.

Es gibt schon AVR, deren ADC negative Werte liefern können.
Aber der ATMega328P gehört nicht dazu.

Ui dankeschön für die ganzen Antworten!

Ich habe auch schon an VU Metern mit Arduino gearbeitet dort habe ich es ähnlich gemacht:

sample = analogRead(IN);
sample -= 512;
sample = abs(sample);

Also so ziemlich das gleiche.

Dankeschön!