Go Down

Topic: analogRead liefert schwankende Werte (Read 2187 times) previous topic - next topic

Fleischwolf

Moin Arduino-Freaks,

ich habe Schwierigkeiten mit den Analogeingängen meines Arduino Mega.

Über einen Spannungsteiler möchte ich die eine Spannung zwischen 0 und ca. 12 Volt überwachen. Die Testspannung kann ich regeln und am Analogeingang kommen zwischen 0 und ca. 4 Volt an.

0 Volt Eingangsspannung liefert per Serial.print einen Wert von 0
je höher ich die Spannung nun regle, desto größer der Bereich, in dem die Werte schwanken (z. B. ca. 1 Volt liefert Werte zwischen ca. 50 und 300).

Ich habe es schon mit einem Pulldown Widerstand ("digitalWrite (pin, LOW)") versucht, das brachte aber keine Änderung.

Auch dreimaliges Einlesen mit jeweils "delay (50)" dazwischen und anschließender Durchschnittsbildung hat nichts gebracht.

Was mache ich falsch?

Grüße,

Georg


Code: [Select]
int akkuspannungpin = 0;
int akkuspannung = 0;

void setup (){

 pinMode(akkuspannungpin,INPUT);

 
 Serial.begin(9600);
}

void loop (){

 Serial.print(" Akkuspannung: ");
 Serial.println(akkuspannung);

 
//   ***** Akkuspannung einlesen *****
 akkuspannung = analogRead(akkuspannungpin);
}


Pumbaa

#1
Mar 29, 2010, 12:14 am Last Edit: Mar 29, 2010, 12:16 am by willich Reason: 1
versuch mal die andern analogeingänge auf masse zu ziehen.

Und: digitalWrite(x,LOW) macht keinen Pulldown an, sondern schaltet nen Pullup ab :)

Und versuch mal nen anderen Pin. Rumspielen mit Autobatterien bringt mit sich, dass die Pins (,der chip, du..) bei Dummheiten sterben.

Fleischwolf

Vielen Dank für die Tipps!

Wie ziehe ich die anderen Analog Pins am besten auf Masse, hardwareseitig (alle an Masse anschließen) oder irgendwie per Software?

Ich habe das unbestätigte Gefühl, daß die angezeigten Werte periodisch auf und ab schwanken (geschätzt alle 0,5 Sekunden ein Peak).

Ich dachte immer, mit "digitalWrite(x,LOW)" schalte ich einen Pulldown- und mit "digitalWrite(x,HIGH)" schalte ich einen Pullup Widerstand an. Wie geht statt dessen?

Ist übrigens keine Autobatterie sondern ein 3s Lipo aus dem Modellbau. Macht aber im Bezug auf die Dummheiten keinen Unterschied... :D

Pumbaa

#3
Mar 29, 2010, 09:20 am Last Edit: Mar 29, 2010, 09:20 am by willich Reason: 1
Nen Hardwarepulldown hat der ATmega nicht. Nur Pullup an, oder Pullup aus. Pulldown musste dir basteln :)

Und mit auf "Masse ziehen" meinte ich, die einfach an GND anzuschließen. Sorry.

Webmeister

Quote
Ich habe das unbestätigte Gefühl, daß die angezeigten Werte periodisch auf und ab schwanken (geschätzt alle 0,5 Sekunden ein Peak).


Die Spannungsmessung wird vermutlich von irgendwoher gestört (Versorgungsspannung, lange Leitungen, Taktgeber, Schaltungsaufbau etc.).
Mit einem RC-Glied (Widerstand und Kondensator) als Tiefpass  könnte man die zu messende Spannung etwas filtern.



Schaltung als Tiefpass:
http://www.elektronik-kompendium.de/sites/slt/0206172.htm

Mit einem Oszilloskop sollte die Versorgungsspannung und auch die zu messende Spannung überprüft werden.

Für den Test der Spannungsmessung kann auch ein Potentiometer verwendet werden.

volvodani

Mein Vorschlag sieht folgendermaßem aus.
Ich nutze diesen Filter bei einem Absolutdrucksensor und beim Lambda auslesen in meinem Auto. (Ich hatte genau den gleichen Fehler)
Zitat aus meinem Post aus einem anderen Thread:

Das Problem könnte auch noch ein anders sein uns zwar wäre es wahrscheinlich mit einem Filter vorteilhafter das man die akutellen gelesenen Werten etwas "niedriger" bewertet damit auch eventuelle Fehlerwerte oder große Sprünge nicht sofort zu 100% auf die regelung "durchschlagen". Wir machen das bei Analogwerten in der SPS genauso ich habe das auch in einem meiner Programme genutzt sieher hier:

Code:
Code: [Select]

int LDlast;  // ist global deklaiert !!!!



int get_LD(){                                // Funktion Einlesen Ladedruck
 int LDY;
 int LDX;
 int LDact;
 int LDdis;
 LDact=analogRead(LDin);                    // Einlesen des Ladedruckistwertes
 LDX=LDact*0.1;              // Filter neue Lesewert einfluß ca 10% pro Zyklus
 LDY=LDlast*0.9;             // Filter alter Wert hat einen einfluss von 90%
 LDdis=LDX+LDY;             // Alter + neuer wert ist gefilterter neuer wert
 LDlast=LDdis;                 // "neuer wert ist dann der alte wert für die nächste Runde
 return LDdis;





Bei diesem Filter "dauert" es ca 18-20 Zyklen (Waren bei mit ca 10ms) bis der neue gelesene wert 99,99999% Integriert ist. passt du jetzt die multiplikatoren noch an, also den neuen gelesenen Wert etwas höher "bewerten"  dann sind es weniger Zyklen also die integration ist schneller bis du zu einem Schönen ergebniss kommst. Wichtig die Summe beider Multiplikationsfaktoren muss 1 Sein also 100%.  
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Fleischwolf

Vielen Dank für Eure Hilfe! Problem Nummer 1 ist gelöst, dafür habe ich nun Problem Nummer 2.

Lösung von Problem 1: Zum Testen der Schaltung und des Programms habe ich den Aufbau nicht an einem Akku, sondern einem regelbaren Netzteil betrieben. Laut Multimeter liefert das ca. 40 Jahre alte Netzteil einer Lego Eisenbahn eine saubere Spannung... Nachdem ich das betagte Netzteil gegen einen Akku ausgetauscht hatte, sahen die gemessenen Werte absolut sauber aus. Ohne Eure Tipps wäre ich darauf gar nicht gekommen.


Problem Nummer 2: Die Analogpins 0 bis 7 am Arduino Mega funktionieren wie gewünscht. Die Pins 8 bis 15 liefern Unsinn, so als wären sie nicht angeschlossen. Müssen die höheren Pins im Mega per Software anders angesprochen werden?

Pumbaa

#7
Mar 30, 2010, 09:51 am Last Edit: Mar 30, 2010, 09:55 am by willich Reason: 1
Das schreit nach hier im Forum zu suchen.
Mit denen war was, waren (sind aktuell??) irgendwie fehlerhaft per Software angesteuert. Weiß nicht mehr, ob das schon mit V18 behoben ist. Aber auf jeden Fall gibt's nen workaround, indem man ne Datei ändert.
EDIT: Habs doch gesucht:
Quote

Sorry guys, this will be fixed in Arduino 0018.  In the meantime, you can edit hardware/cores/arduino/wiring_analog.c and change:

ADMUX = (analog_reference << 6) | (pin & 0x0f);

to:

ADMUX = (analog_reference << 6) | (pin & 0x07);

(The change should take effect automatically next time you compile or upload a sketch.)


Sieht so aus, als würd nen Update auf V18 helfen. Oder handbasteln.
Bevor du updatest: ich hatte Probleme mit meinem Mega mit der TimerOne-library nach dem Update.
Hatte danach schwer reproduzierbare Konflike mit anderm Kram.

Go Up