schwankungen am analog in

hallo an alle!
ich bin blutiger anfänger und habe eine frage zu den analogeingängen...

wenn ich mit folgendem code

void setup() {
Serial.begin(9600); 
}

void loop() {
  int sensorValue = analogRead(A0);
  Serial.println(sensorValue, DEC);
  delay(500);
}

die analog in auslese, ohne etwas angeschlossen zu haben bekomme ich an A0 werte wie diese:
298
296
287
283
291

und an A1 diese:
355
354
342
336
345

ist das normal? sollten die werte nicht 0 sein? oder zumindest gleich?
was heißt 355 überhaupt?

sorry für die vielleicht dummen fragen =)

lg,
stefan

Hallo tres

Ohne etwas angeschlossen fängt ein Analogeingang jede Menge Störungen ein und gibt Dir solche Werte. Das ist Normal. Hänge etwas dran.

Wieso willst Du "nichts" messen? :wink:

Grüße Uwe

hey uwe,

wow danke für die schnelle antwort!

naja, ich will ja nicht nichts messen, sondern einfach sicher gehen,
dass, wenn ich etwas messe, es nicht falsche werte liefert weil mein board spinnt =)

hatte testweise einen temperaturfühler dran und da waren die werte dann konstant (+-1)

ok, dann ist das schwanken im "leerlauf" also normal, gut zu wissen!

gruß,
stefan

dass, wenn ich etwas messe, es nicht falsche werte liefert weil mein board spinnt =)

hatte testweise einen temperaturfühler dran und da waren die werte dann konstant (+-1)

Und schon wird ein korrekter Wert angezeigt.

Offene Eingänge fangen, wie Uwe gesagt hat, Störungen ein und entsprechend ist ein Wert sichtbar. Du kannst die Eingänge auch auf GND anschliessen und dann sollten die Werte 0 sein.

Zusammenfassend kann man sagen, dass dein Board stabile Werte liefert, wenn ein sauberes Signal angelegt ist.

Alles ist somit im grünen Bereich. :wink:

Ich würde dir auch einen Pulldown (Up) Widerstand empfehlen. Kurz gesagt ist ein Pulldown ein sehr hochohmiger Widerstand, der zwischen EIngang und Masse geschaltet ist. Die kleinen Störungen leiter er auf Masse ab, aber es darf nicht zu klein dimensioniert sein, sonst verzerrt er das Eingangssignal...

Hallo zusammen,

ich habe am Analog-Eingang A0 den Schleifer eines 1Mohm Potis (das erste beim Griff in die Bastelkiste mit brauchbaren Anschlußdrähten), einen Anschluß an +5V und das Ende an Masse.
Auch ich lese in einer Schleife stark schwankende Werte....
Bis zum Versuch mit einem 10k Poti, welches ich erst mit passenden (Klingeldraht)-Kontakten fürs Steckbrett versehen muß, gehe ich davon aus, dass auch hochohmige "Aufbauten" zusammen mit einigen cm Anschluß ziemlich störempfindlich sind.

Laut Referenz kann man auch beim Analog-IN einen Pull-Up Widerstand "einschalten" , muß mal nachdenken, inwieweit sich ein solcher Wert (20k?) einarbeiten lässt.
Mit dem Poti-Aufbau will ich mich derzeit nur in die Programmierung rund um analoge Werte einschließlich Umrechnung und Ausgabe einarbeiten.

Gruß
Manfred

Hallo ManfredH

Der Analogeingang hat typischerweise einen Eingangswiderstamd von 100MOhm. Also ein 1 MOhm Potentiometer müßte kein Problem sein.

Es ist richtig, daß je hochohmiger eine Schaltung ist, desto größeren Einfluß haben Störungen.
Aber es müßte mit einem 1MOhm Potentiometer funktionieren.

Mit einem Pullup oder Pulldown Widerstand kannst Du bei hochohmiger Spannungsquelle den Meßwert verfälschen. (Spannungsteiler Innenwiderstand Spannungsquelle und Pullxx- Widerstand.
Da ist jedesmal zu überlegen ob ein pullxx Widerstand die Messung verfälschen kann.

Grüße Uwe

Hallo an alle!

Ich habe beim Aufbau eines Klatschschalters mit Hilfe eines Mikrofon-Breakout-Boards und eines Arduino-Mega-2560 ziemlich schwankende Werte feststellen müssen.
So treten Werte (in einem gleichmäßig stillen Raum, der Arduino ist durch einen Trafo mit Strom versorgt) zwischen 0 - 200 auf.
Durch Einsetzen von Kondensatoren (direkt zwischen + und -; zwischen Mikrofon-Signal und -Pol; zwischen Mikrofon-Signal und +Pol) konnte das Verhalten auf obige Werte verbessert werden, sonst wären sie noch extremer.
Auch mit anderen Sensoren tritt dieses Verhalten auf.
Es ist ein klarer Rhytmus feststellbar: zwischen 0,5 und 1 sec.

Ich habe auch schon versucht, um Störungen durch andere analoge Eingänge zu vermeiden, diese entweder auf Ground zu ziehen oder direkt als Ausgang mit Wert 0 zu definieren.... keine Änderung.

Danke für Eure Antworten im Voraus
ReS

hallo zusammen,...

hab gerade auch das problem! ..will mit einem LM35 und einem LDR, temp und helligkeit messen und darüber die relaiskarte ansteuern.
mein code funktioniert, aber ich bekomme immer stör signale rein, wenn ich den LDR teste..

also sobald ich mit der taschen lampe drüber leute, schlatet das relais für licht. aber der für den ventilator, (über LM35 geregelt)
fängt sich störungen ein. kondensator zwischen +5V undGND vom LM35 brignt nix.. :frowning: auch der versuch, die restlichen analogen
eingänge über einen 10Kohm zu definieren, brachte kenen erfolg... X-(

hat mir jemand vieleicht ein tipp?

EDIT: in einem buch habe ich gelesen, dass man sehr oft messen muss und dann einen mittelwert ziehen. (grob gesagt) muss ich das hier auch tun um einen festen wert zu bekommen, der nicht alle 0,1 sek zwischen ca. 20.0°C und ca. 45.0°C ..

anbei der code:

// Außgänge erstellen

int out1 = 2;
int out2 = 3;

int out5 = 6;
int out6 = 7;
int out7 = 8;
int out8 = 9;

// Analoge Eingänge erstellen

int TempSensor = A0;
int LichtSensor = A5;

// Variablen erstellen

float TempSensorWert = 0.0;
float TempSensorWertX = 0.0;
int LichtSensorWert = 0;

//********************************************************************************
//**********_void_setup_ beginnt**************************************************
//********************************************************************************

void setup(){
  Serial.begin(9600);
  
  pinMode(out1, OUTPUT);
  pinMode(out2, OUTPUT);

  pinMode(out5, OUTPUT);
  pinMode(out6, OUTPUT);
  pinMode(out7, OUTPUT);
  pinMode(out8, OUTPUT);
  
  pinMode(TempSensor, INPUT);
  pinMode(LichtSensor, INPUT);
}



void loop(){
    // ***Alle relevanten Werte einlesen (Eingabe)***

    TempSensorWert = analogRead(TempSensor);
    LichtSensorWert = analogRead(LichtSensor);
    
    // ***Rechenoperationen (Verarbeitung) Temp.Sensor***
    
    TempSensorWert = (TempSensorWert * 100.0 * 4.8) / 1024.0;
    TempSensorWertX = TempSensorWert;    
    
    if(TempSensorWertX >= 28.0){  // Wenn Temp über 28°C geht
      TempSensorWertX = 50.0;     // Setze den wert auf 50 (einschalten)
    }
    if(TempSensorWertX <=27.0){
      TempSensorWertX = 24.0;
    }
       
    // ***Ausgabe***
    
    // ** Ausgabe Serieller Monitor
        
    Serial.print("Temp:");
    Serial.print(TempSensorWert);
    Serial.print(",");
    Serial.print(" ");
    Serial.print("Helligkeits Wert:");
    Serial.println(LichtSensorWert);
    

    // *** Ausgabe an Ausgänge***
    
    // *** Temperatur Schalten ***

    if(TempSensorWertX == 50.0){ //
      digitalWrite(out1, LOW);
      digitalWrite(out7, LOW);
      digitalWrite(out8, HIGH);
    }
    if(TempSensorWertX == 24.0){
      digitalWrite(out1, HIGH);
      digitalWrite(out7, HIGH);
      digitalWrite(out8, LOW);
    }
    
    // *** Licht Schalten
    
    if(LichtSensorWert <= 400){ //
    
      digitalWrite(out2, LOW);
      digitalWrite(out5, LOW);
      digitalWrite(out6, HIGH);
    }
    
    if(LichtSensorWert >= 600){
      
      digitalWrite(out2, HIGH);
      digitalWrite(out5, HIGH);
      digitalWrite(out6, LOW);
    }
    delay(500);
}

Wenn die Schwankungen relativ klein sind, bietet sich es an mehrere Messung hintereinander durchzuführen und einen Mittelwert zu bilden.

Eine Hysterese ist bei einem 2-Punkt-Regler auch nicht verkehrt, damit die Ausgänge beim Übergang nicht wild hin-und-her schalten. Gerade bei Relais. Bei dem Licht-Sensor sollte sie wahrscheinlich etwas größer sein.

Serenifly:
Wenn die Schwankungen relativ klein sind, bietet sich es an mehrere Messung hintereinander durchzuführen und einen Mittelwert zu bilden.

Eine kleine Hysterese ist bei einem 2-Punkt-Regler auch nicht verkehrt, damit die Ausgänge beim Übergang nicht wild hin-und-her schalten. Gerade bei Relais.

bereiche zum schalten habe ich definiert.. okay,.. nicht beim lichtsensor.. mache ich noch rein..
was heist denn klein?? die werte schwanken zwiscnen 20 und 45

Eine Hysterese ist mehr als einfach definierte Schaltpunkte. Die sorgt dafür das der Wert erst um einen bestimmten Betrag abfallen oder ansteigen muss damit sich der Ausgang ändert. Das Resultat ist ein Tot-Bereich in der Mitte in dem der letzte Zustand beibehalten wird.

So:

if(wert >= schaltpunkt + hysterese)
{
      Lüfter an
}
else if(wert < schaltpunkt - hysterese)
{
     Lüfter aus
}

Bei Sachen die sich nur langsam ändern wie der Temperatur reichen da 1-2°, aber der Licht-Sensor ändert seinen Wert ja schlagartig um einen großen Betrag. Da also höher machen.

EDIT: Ok, der Code bei dem Licht-Sensor macht das schon so ähnlich :slight_smile:

was heist denn klein?? die werte schwanken zwiscnen 20 und 40

20 und 45°? Das ist nicht gut und kann man auch nicht lassen.

Der LM35 ist aber generell auch nicht der zuverlässigste Sensor. Und dadurch dass der ein mV-Signal ausgibt auch recht störanfällig.

Das hilft vielleicht:
http://forum.arduino.cc/index.php?topic=174236.0

Nochwas:
Bei dem LM35 kannst du locker die interne 1.1V Referenzspannung nehmen. Das ist auch zuverlässiger als die 5V.

Ich gebe mal als Denkanstoss:

  • Erst mal messen, welche Spannungsmaxima und minima am analogen Input zu erwarten sind.
  • Daraus ermitteln, welche max. / min. Spannungen zu erwaren sind.
  • Macht es Sinn, eine externe Referenzspannung zu nutzen ?
    (siehe http://arduino.cc/de/Reference/AnalogReference)

Wichtig ist dabei, die max. analoge Eingangsspannung der Referenz anzupassen, um eine maximale Auflösung zu erhalten.
Diese ist im Standard bei 5V-Ref. eben 0-1023 zwischen 0V und 5V.
Die Auflösung wäre dann: 5V / 1024 = ca. 5mV/Schritt.

Ist z.B. nur in einem Bereich vom 0-1/2V oder weniger/mehr zu messen / gibt es einen zu berücksichtigen Offset ala min. von x bis y Volt, sollte man eine externe Ref-Spannung verwenden, um die Aufläsung zu maximieren.

Der LM35 liefert 10mV/°C. Die 1.1V Referenz reicht daher um bis 110° zu messen :slight_smile:

Den LDR müsste man aber entsprechend anpassen (Spannungsteiler) oder die Referenz umschalten. Wobei man bei letzterem die erste Messung nach dem Umschalten verwerfen muss.

hallo zusammen,

vielen dank für die vielen tipp´s, die haben mir auch holfen! ....irgendwo hab ich gelesen, dass die schwankungen relativ proportional verlaufen, daher und da ich es auch im buch gelesen hab, ahb iche jetzt den mittelwert gezogen! --> und siehe da, s klappt! habe eine stabielen wert!

der aktuelle code sieht wie folgt aus:

// Außgänge erstellen

int out1 = 2;
int out2 = 3;

int out5 = 6;
int out6 = 7;
int out7 = 8;
int out8 = 9;

// Analoge Eingänge erstellen

int TempSensor = A0;
int LichtSensor = A5;

// Variablen erstellen

float TempSensorWert = 0.0;
float TempSensorWertX = 0.0;
int cycles = 20;
int DELAY = 10;

int LichtSensorWert = 0;




//********************************************************************************
//**********_void_setup_ beginnt**************************************************
//********************************************************************************

void setup(){
  Serial.begin(9600);
  
  pinMode(out1, OUTPUT);
  pinMode(out2, OUTPUT);

  pinMode(out5, OUTPUT);
  pinMode(out6, OUTPUT);
  pinMode(out7, OUTPUT);
  pinMode(out8, OUTPUT);
  
  pinMode(TempSensor, INPUT);
  pinMode(LichtSensor, INPUT);
}

/*********************************************************************************
********** void loop beginnt *****************************************************
*********************************************************************************/

void loop(){
    // ***Alle relevanten Werte einlesen (Eingabe)***

    LichtSensorWert = analogRead(LichtSensor);
    
    // ***Rechenoperationen (Verarbeitung) Temp.Sensor***
    
    float TempDurchschnitt = 0.0;
    float TempGerechnet = 0.0;
    for(int i = 0; i < cycles; i++){
    TempSensorWert = analogRead(TempSensor);
    TempSensorWert = (TempSensorWert * 100.0 * 4.8) / 1024.0;
    TempGerechnet += TempSensorWert;
    delay(DELAY);
    }
    TempGerechnet = (TempGerechnet / cycles);
    
    TempSensorWertX = TempGerechnet;    
    
    if(TempSensorWertX >= 25.5){  // Wenn Temp über 28°C geht
      TempSensorWertX = 50.0;     // Setze den wert auf 50 (einschalten)
    }
    if(TempSensorWertX <=24.0){
      TempSensorWertX = 24.0;
    }
       
    // ***Ausgabe***
    
    // ** Ausgabe Serieller Monitor
        
    Serial.print("Temp:");
    Serial.print(TempSensorWert);
    Serial.print(",");
    Serial.print(" ");
    Serial.print("Helligkeits Wert:");
    Serial.println(LichtSensorWert);
    

    // *** Ausgabe an Ausgänge***
    
    // *** Temperatur Schalten ***

    if(TempSensorWertX == 50.0){ //
      digitalWrite(out1, LOW);
      digitalWrite(out7, LOW);
      digitalWrite(out8, HIGH);
    }
    if(TempSensorWertX == 24.0){
      digitalWrite(out1, HIGH);
      digitalWrite(out7, HIGH);
      digitalWrite(out8, LOW);
    }
    
    // *** Licht Schalten
    
    if(LichtSensorWert <= 200){ //
    
      digitalWrite(out2, LOW);
      digitalWrite(out5, LOW);
      digitalWrite(out6, HIGH);
    }
    
    if(LichtSensorWert >= 600){
      
      digitalWrite(out2, HIGH);
      digitalWrite(out5, HIGH);
      digitalWrite(out6, LOW);
    }
    delay(0);
}

EDIT: quote durch code getauscht.. :smiley: danke für den hinweis!

Wenn die Schwankungen proportional sind kannst du das probieren:

64 oder 75 Ohm und 1µF gegen Masse. Das Problem ist dass der LM35 keine hohen Kapazitäten am Ausgang verträgt und dann stark schwingt. Dadurch sind gerade längere Leitungen problematisch.

Du hast jetzt zwar einen stabilen Wert, aber das ist halt nicht wirklich die korrekte Temperatur. Wenn es z.B. nur eine grobe Regelung geht, kann man das natürlich auch so hinbiegen dass er ungefähr der gewünschten Stelle schaltet. Aber wenn man die genaue Temperatur messen will ist das bei so hohen Schwankungen nichts. Kommt dann darauf an wie genau du das haben willst.

Der Unterschied zwischen [code] und [quote] ist, dass auch uncoole 8**)** cool aussehen. :wink:

Na, wie hab ich das hingekriegt, ohne Leerzeichen bei den smiley-Klammern :wink:

michael_x:
8)

Der Unterschied zwischen [code] und [quote] ist, dass auch uncoole 8**)** cool aussehen. :wink:

Na, wie hab ich das hingekriegt, ohne Leerzeichen bei den smiley-Klammern :wink:

danke für den hinweis,.. habs geändert!


@ Serenifly:

danke für den tipp, werde ich im hinterkopf behalten!! die genauigkeit liegt gerade +- 0,3°C ..für das erste passt es so.. :slight_smile:

danke! liebe grüße und gute nacht..

Du hast einen relativen Fehler von +/- 0,3°. So eine Mittelung ist aber eher dazu da um kleine Schwankungen von ein paar mV auszugleichen, die in der Elektronik normal sind. Nicht für eine Abweichung von 25°/250mV. Das heißt was er dir da anzeigt ist nicht die tatsächliche Temperatur.

Du kannst auch einen Mittelwert aus z.B. 5 durchläufen machen dann ist der Wert Stabiler und genauer

in TempSammel;
byte Durchlauf=5; // Variabel für die Durchläufe

void loop(){
for (int i=0;i<(Durchlauf+1);i++){
TempSammel=TempSammel+analogRead(TempSensor);   // Mehrmalsgelesen und addiert
}
TempSensorWert=TempSammel/Durchlauf;                   //Durch 5 für Prezision
TempSammel=0;                                                      // Den Sammler wieder auf Null damit der nächste Wert stimmt
   LichtSensorWert = analogRead(LichtSensor);
    
    // ***Rechenoperationen (Verarbeitung) Temp.Sensor***
    
    TempSensorWert = (TempSensorWert * 100.0 * 4.8) / 1024.0;
    TempSensorWertX = TempSensorWert;
}

Gruß
Der Dani