Forum: Mikrocontroller und Digitale Elektronik Frage zu analogRead() Arduino


von Kilian K. (kellermaaan)


Lesenswert?

Hallo,

ich habe eine kurze Frage zum analogRead() des Arduinos.
Ich habe eine kleine Funktion mit der ich 3 Analoge Eingänge einlese und 
direkt in eine Spannung umrechne:
1
void getADvalues(double *values) {
2
  values[0] = analogRead(5) * (double)CALCULATE_FACTOR_AD_0_1;
3
  values[1] = analogRead(6) * (double)CALCULATE_FACTOR_AD_0_1;
4
  values[2] = analogRead(7) * (double)CALCULATE_FACTOR_SENSOR;
5
}

Allerdings ist im Moment nur an dem letzten Pin (Pin 7) etwas 
angeschlossen. Wenn ich dort dann z.B. 5V anlege, es wie oben dann 
auslese, bekomme ich ein Ergebnis von ca. 3,73V. Wenn ich aber die 
ersten beiden auskommentiere und nur den letzten einlese, bekomme ich 
ein Ergebnis von 5V.

Könnte mir einer sagen woran das liegt und ob ich das vielleicht beheben 
kann ohne dass ich etwas an die beiden anderen Ports anschließen muss?

Gruß Kilian

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Vielleicht hilft es, zwischen den Aufrufen von analogRead etwas zu 
warten.

Das ist schließlich nur ein ADC, der hinter einem Eingangsmultiplexer 
sitzt, und möglicherweise wird hier zu schnell nach dem Umschalten des 
zu messenden Kanals schon die neue Messung angestoßen.

von Cyblord -. (cyblord)


Lesenswert?

Zeig doch mal den Aufruf von "getADvalues"

von Kilian K. (kellermaaan)


Lesenswert?

Erst einmal danke für die Antwort.
Hab da jetzt mal jeweils ein delay von 200 ms zwischen gehauen, aber 
bekomme immer noch das selbe Ergbnis. Ist das vielleicht noch zu kurz 
oder liegt das noch an etwas anderem? :-/

Edit: Der Aufruf von getADvalues()
1
char fwert[10]={0};
2
    int dataLen = 50;
3
    double *values;
4
5
    delete dataTest;
6
    dataTest = new char[dataLen];
7
    values = new double[3];
8
9
    // AD Werte einlesen und holen
10
    getADvalues(values);
11
    
12
    //data Inhalt löschen
13
    memset(dataTest, 0, dataLen);
14
15
    //JSON string zusammensetzen
16
    strcat(dataTest, "{ \r\n\t\"AD0\": ");
17
    sprintf(fwert, "%.2f", values[0]);
18
    strcat(dataTest, fwert);
19
20
    strcat(dataTest, ",\r\n\t\"AD1\": ");
21
    sprintf(fwert, "%.2f", values[1]);
22
    strcat(dataTest, fwert);
23
24
    strcat(dataTest, ",\r\n\t\"AD2\": ");
25
    sprintf(fwert, "%.2f", values[2]);
26
    strcat(dataTest, fwert);
27
28
    strcat(dataTest, "\r\n}\0");
29
30
    file->data = dataTest;
31
    file->len = strlen(dataTest);
32
    file->index = file->len;
33
    file->pextension = NULL;
34
  
35
    delete values;

Ach ja und wenn ich an den ersten beiden auch eine Spannung anlege 
stimmen die Ergebnisse auch!

: Bearbeitet durch User
von Stefan K. (stefan64)


Lesenswert?

Wie hochohmig ist die Quelle, die an Pin 7 angeschlossen ist?
Und sind die anderen beiden Pins offen oder gegen GND geschaltet?

Ich nehme an, dass die Quelle an Pin 7 zu hochohmig ist, um den 
Sample/Hold Kondensator umzuladen. Da nützt Dir auch kein Delay zwischen 
den ADC-Aufrufen. Wenn ich mich recht erinnere, kann man die 
Zyklenanzahl für S/H konfigurieren, ich weiss aber nicht, wie man beim 
Arduino das steuern kann.

Datenblatt Atmega32 S.209:

"When the channel is selected, the source must drive the S/H capacitor 
through the series resistance (combined resistance in the input path."

Gruß, Stefan

von Kilian K. (kellermaaan)


Lesenswert?

Also die anderen beiden Pins sind offen. Wenn ich dort alledings etwas 
anlege dann stimmen die Werte bei allen dreien.
an Pin 7 ist ein Spannungsteiler von 510k zu 180k und an den beiden 
anderen ein Spannungsteiler mit 510k zu 220k.

von Stefan K. (stefan64)


Lesenswert?

ATmega32 S.209:
"The ADC is optimized for analog signals with an output impedance of 
approximately 10 kΩ or less."

Deine Quelle ist zu hochohmig. Der ADC sieht bei Dir einen 
Eingangswiderstand von 510k parallel zu 180k = 133kOhm. Entweder Du 
machst die Spannungsteiler niederohmiger oder Du schaltest einen Op-Amp 
dazwischen.

Gruß, Stefan

von Kilian K. (kellermaaan)


Lesenswert?

Aber wieso funktioniert es dann wenn ich den entweder alleine einlese 
oder an die beiden anderen Pins ebenfalls etwas anlege. Das verstehe ich 
dann irgendwie nicht... Müsste das dann nicht immer so sein? :-/

von Stefan K. (stefan64)


Lesenswert?

Wenn Du den Pin mehrmals hintereinander samplest, dann wird der 
S/H-Kondensator mit jedem Mal besser auf den korrekten Wert geladen.

> an Pin 7 ist ein Spannungsteiler von 510k zu 180k und an den beiden
> anderen ein Spannungsteiler mit 510k zu 220k.

Da hier alle 3 Spannungen ziemlich ähnlich sind, muss der 
S/H-Kondensator kaum zwischen den Wandlungen umgeladen werden, was einen 
geringen Fehler ergibt. Anders sieht es sicher aus, wenn Du an den 
beiden anderen Pins einen Teiler 1k zu 10k hängst.

Gibt es in Deiner Schaltung einen Grund, der gegen niederohmigere 
Spannungsteiler spricht?

Gruß, Stefan

von Sascha (Gast)


Lesenswert?

Alternativ von ADC Pin nach GND nen 1µF Elko, der lädt dann den S/H 
Kondensator. Ist allerdings dann ein Tiefpass, muss man gucken wie 
schnell sich das Signal ändert was man einlesen will.

von Kilian K. (kellermaaan)


Lesenswert?

OK, danke für die Erklärung!
Im Prinzip nicht. Die Widerstände werden dann wohl nochmal angepasst.
Dann weiß ich ja jetzt Bescheid.

von Stefan F. (Gast)


Lesenswert?

1µF ist gar nicht nötig. Ich mach das immer mit 10nF.

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.