05 Analoger Input
05 Analoger Input
Reflektion
- Serieller Monitor
- Ohmsches Gesetz
Was ist ein analoger Input?
Ein analoger Input ist ein Eingang, an welchem Spannungsunterschiede gemessen werden können. Viele Sensoren sind im Prinzip nichts anderes als ein variabler Widerstand und lassen sich nicht an einem digitalen PIN (EIN/AUS) einlesen. Das Arduino bietet deshalb die analogen Inputs (A0-A5) um die Werte z.B. von Sensoren zu erfassen. Um einen Spannungsunterschied (analoges Signal) feststellen zu können, verfügt das Arduino über einen 6 Kanal, 10-bit Analog zu Digital Konverter (
AD Wandler). Eine Auflösung von 10-bit bedeutet, dass das Arduino einen Spannugsunterschied von 0V zu 5V mit einer Auflösung von 10-bit erfasst. Es liefert demnach 1024 unterschiedliche Werte für diesen Bereich (dies entspricht einer Genauigkeit von 4.9 mV pro Schritt).
Für unsere Zwecke reicht diese Genauigkeit aus. Es gibt jedoch wesentlich genauere Analog zu Digital Konverter, welche z.B. mit 16-bit (65535 Werte) oder sogar 32-bit (ca. 4.3 Mio Werte) arbeiten. Diese verlangen jedoch nach einer aufwändigen Filterung und Schirmung und sind deshalb für uns uninteressant.
Funktionen
Um ein Signal an einem analogen Pin einzulesen verwenden wir die Funktion
analogRead(PIN). Diese Funktion gibt uns direkt eine Zahl zwischen 0 und 1024 zurück. Wir müssen für diese Funktion keinen
pinMode(PIN, MODUS) im setup() aufrufen, wie wir es bei digitalen Pins machen.
Beispiel mit einem Fotoresitor
Ein einfacher Sensor ist der
Fotoresistor. Er verändert seine elektrische Leitfähigkeit (Widerstand) je nach Helligkeitseinfall und lässt sich deshalb als auch als Helligkeitssensor bezeichnen. Um den Sensor anschliessen zu können nutzen wir eine sog.
Spannungsteiler Schaltung.
Spannungsteiler
Mit Hilfe eines Spannungsteilers können wir Unterschiede im Spannungsverhältnis zweier Widerstände zwischen 0V und Vcc (in unserem Fall 5V) messen. Typischerweise ist einer der Widerstände ein Sensor (variabler Widerstand) und einer ein Festwiderstand. Die Schaltung sieht folgendermassen aus...
Die entsprechende Formel, deren Herleitung vom Ohmschen Gesetz in
diesem Wikipedia Eintrag erläutert wird lautet:
Vres = Vcc*(R2/(R1+R2))
Vres = Resultierende Spannung
Vcc = Anliegende Spannung (5V)
R1 = Erster Widerstand (Fotoresistor)
R2 = Zweiter Widerstand (Festwiderstand)
Für unseren Fotoresistor ergibt sich also folgende Schaltung...
Beispiel-Code
Für den Code lassen wir uns die von Arduino gelesenen Werte über den Serial Monitor ausgeben (siehe dazu:
Serial).
#define BRIGHTNESS A0
void setup()
{
Serial.begin(9600);
}
void loop()
{
int reading = analogRead(BRIGHTNESS); // Hier werden die Werte abgerufen
Serial.println(reading); // Anzeigen der Werte über Serial Monitor
}
Betrachten wir die Werte im Serial Monitor, so sehen wir, dass sie sich verändern, sobald wir z.B. die Hand über den Sensor halten.
Das Potentiometer
Das Potentiometer ist eine spezielle Form eines variablen Widerstandes, da es an sich schon als Spannungsteiler funktioniert. Das Potentiometer eignet sich dehalb auch sehr gut um eine schnelle analoge Eingabe zu generieren. Die Funktionsweise lässt sich folgendermassen verinfacht darstellen ...
Um das Potentiometer am Arduino anzuschliessen verwenden wir folgende Schaltung...
Aufgaben:
1. Nutzt die Schaltung mit dem Fotoresistor, um die Helligkeit einer LED zu steuern.
2. Nutz ein Potentiometer um die Blinkgeschwindigkeit einer LED zu steuern.
3. Steuert mit Hilfe des Potentiometers drei LEDs nacheinander (Poti Links = LED_1, Poti Mitte = LED_2, Poti Rechts = LED_3)
Nützliche Funktionen
map(): Mappt einen Wertebereich auf eine neue Skalierung
z.B. map(WERT, 0, 1024, 0, 255)
constrain(): Beschränkt einen Wert auf einen bestimmten Bereich
z.B. constrain(WERT, 0, 255)
Smoothing
Bei analogen Werten besteht das Problem, dass sie durch äussere Einflüsse (z.B. unsaubere Schirmung) oder durch die Ungenauigkeit eines Sensors nicht immer konstant bleiben. Dies können wir durch diverse Filterfunktionen minimieren bzw. ganz verhindern.
Eine der gebräuchlichsten Filter ist der sog. Low Pass Filter. Dieser lässt sich softwareseitig implementieren. Das Prinzip beruht darauf, dass immer ein Anteil des zuletzt gelesenen Wertes mit dem neuen Wert verrechnet wird. Die Teilung von neuem und altem Wert bestimmt dabei die Stärke des Filters – sie sollten zusammen aber immer 1 ergeben (z.B. 0.4*alterWert+0.6*neuerWert). Wird der Anteil des neuen Wertes zu gering (z.B. <0.1) kann es zu grossen Verzögerungen kommen.
aktuellerWert = Faktor*alterWert + Faktor*neuerWert
Der Code dazu sieht folgendermassen aus...
#define BRIGHTNESS A0
int oldValue = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
float currValue = analogRead(BRIGHTNESS); // Hier werden die Werte abgerufen
currValue = 0.4*oldValue + 0.6*currValue; // Smoothing Funktion
Serial.println(currValue); // Anzeigen der Werte über Serial Monitor
oldValue = currValue; // Hier wird der aktuelle Wert als oldValue gespeichert
}