Forum: Mikrocontroller und Digitale Elektronik ADC nicht ganz verstanden oder fehl Interpretation


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von amle (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Guten Tag
Ich habe hier etwas code betreffend einer Abfrage des ADC von Arduino, 
der soweit funktioniert. Jedoch wenn ich 2 ADC Abfrage sind die 
Variablen analgValue0/1 vertauscht, warum?

Siehe demarkieren von !!!!!!!! (ADMUX = ADCH1;)
Kann mir da jemand helfen?
Danke.
1
#include <Arduino.h>
2
#define ADC0 0
3
#define ADC1 1
4
#define ADCH0 ((1 << REFS0) | ADC0)
5
#define ADCH1 ((1 << REFS0) | ADC1)
6
7
volatile int analogValue0;
8
volatile int analogValue1;
9
void setup() {
10
  Serial.begin(115200);
11
  ADC_Init();
12
}
13
14
void loop() {
15
   Serial.print("Value1: ");
16
   Serial.print(analogValue0);
17
   Serial.print("   Value2: ");
18
   Serial.println(analogValue1);
19
}
20
21
// Function:    snaAdcIntSetup()
22
// Description: This funtion sets up the ADC for generating interrupts.
23
// Arguments:   None
24
// Returns:     None
25
void ADC_Init() {
26
  // Set for the first ADC channel.
27
  ADMUX = ADCH1;
28
  // 0=2,1=2,2=4,3=8,4=16,5=32,6=64, 7=128
29
  ADCSRA = (1 << ADEN) | (1 << ADATE) | (1 << ADIE) | (1 << ADPS2) | (0 << ADPS1) | (1 << ADPS0); 
30
  ADCSRB = 0;
31
  sei();
32
  ADCSRA |= (1 << ADSC);
33
}
34
35
// The ADC interrupt function.
36
ISR(ADC_vect) {
37
  int iCannel = ADMUX & ((1 << MUX3) | (1 << MUX2) | (1 << MUX1) | (1 << MUX0));
38
  switch (iCannel) {
39
    case ADC0:
40
      analogValue0 = ADCL | (ADCH << 8);
41
      // !!!!!!!!!!!!! für den zweiten kanal unmarkieren, dann sind die werte vertauscht
42
      //ADMUX = ADCH1;
43
      break;
44
    case ADC1:
45
      analogValue1 = ADCL | (ADCH << 8);
46
      ADMUX = ADCH0;
47
      break;
48
  }
49
  //ADCSRA |= (1 << ADSC);
50
}

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
> analogValue0 = ADCL | (ADCH << 8);

Kleiner Tipp: Das kannst du einfach  "analogValue0 = ADC" schreiben.

Nur zur Erklärung deines Phänomens:

Dein ADC läuft im Free-Running Modus, er misst also fortlaufend. Sobald 
eine Messung fertig ist, wird die ISR aufgerufen. Du schaltest dort den 
Kanal um, aber während dessen läuft bereits die nächste Messung. Der 
Kanalwechsel wirkt sich daher erst auf die  Messung danach aus.

Bei zwei Kanälen läuft es also daher auf die von dir beobachtete 
Vertauschung hinaus. Wenn du mehr als zwei Kanäle hättest, würdest zu 
einen Zirkulären Versatz um 1 Position beobachten.

: Bearbeitet durch User
von amle (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Ja danke, das dachte ich mir und ja den Versatz um 1 habe ich bemerkt, 
leider.

Aber das vorgehen ist doch richtig oder mache ich da was falsch?
Getrennt kann man die IRQ ja nicht definieren ohne grösseren Aufwand?

von Stefan ⛄ F. (stefanus)


Bewertung
1 lesenswert
nicht lesenswert
amle schrieb:
> Aber das vorgehen ist doch richtig oder mache ich da was falsch?

Ja das ist richtig. Gegen den Versatz kannst du im free-running Modus 
nichts machen. Der wäre nur bei Einzelmessungen vermeidbar, die übrigens 
auch Interrupts nutzen könnten.

Wenn du den ADC innerhalb der ISR jedes mal neu starten würdest, hättest 
du weniger Messungen pro Sekunde. Und jedes mal wenn ISR kurz gesperrt 
sind, würde es sich entsprechend verzögern.

Ob das so zu deiner Anwendung passen würde, musst du selbst entscheiden.

: Bearbeitet durch User

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.