01 Der Potentiometer - ein variabler Widerstand
Stell dir vor, du möchtest eine LED durch eine Drehbewegung dimmen. Das Potentiometer-Modul (kurz Poti genannt) ist ein mechanisches Element, der uns dies ermöglichen kann. Im Grunde ist es ein elektrischer Widerstand. Seine Besonderheit besteht darin, dass der elektrische Widerstand sich durch Drehen stufenlos einstellen lässt.
Wir verwenden ein Drehpotentiometer, dessen Drehwinkel zwischen 0 und 270 Grad eingestellt werden kann. Die Drehbewegung wird durch einen Endanschlag begrenzt. Man erhält dadurch einen haptischen Feedback.
In der unteren Grafik ist der interne Aufbau abgebildet. Von den drei Anschlüssen bilden A und B die Enden des runden Widerstandsringes. Zwischen diesen beiden Kontakten herrscht immer der gleiche Widerstandswert (10k Ohm), der nicht verändert werden kann. Entlang des Ringes gleitet ein beweglicher Schleifer (Anschluss C), der Kontakt mit dem Ring hat und darüber gleitet. Es ist der Schleifer, der unterschiedliche Widerstandswerte erzeugen kann.
Kommen wir zur Funktionsweise. Die Anschlüsse A und B werden mit der Stromversorgung VCC und GND des Arduino verbunden. Zwischen diesen Anschlüssen fließt nun Strom. Der Widerstand zwischen diesen beiden Anschlüssen beträgt immer 10K Ohm. Der frei bewegliche Schleifer mit dem Anschluss C wird mit einem analogen Input des Arduino verbunden (z.B. A0). Der Strom, der durch die Anschlüsse A und C fließt, ändert sich je nach der Winkelposition des Schleifers. Ist der Schleifer in der Mittelposition, dann hat der Potentiometer einen Widerstand von 5K Ohm, weil der Strom nur durch die Hälfte des Widerstandsringes fließt. Je weiter der Schleifer von A entfernt ist, desto größer ist der Widerstand. Erreicht er B ist er am größten (10K Ohm). Ist der Schleifer an der Position A, ist der Widerstand gleich null, also kein Widerstand.
Der Sketch
Der Sketch für das Ablesen des Potentiometers ist überschaubar.
int potiPin = A0;
int potiValue = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
potiValue = analogRead(potiPin);
Serial.println(potiValue);
}
Die analogRead() Funktion
Wir lernen eine neue Funktion kennen: das Einlesen von analogen Sensorwerten. Die analogRead() Funktion liest Spannungen zwischen 0 und 5Volt ein und ist auf den Pins A0 bis A15 verfügbar. AnalogRead() hat einen Analog-zu-Digital-Konverter (ADC = Analog-Digital-Konverter). Aus dem Namen selbst geht hervor, dass es sich um einen Wandler/Konverter handelt, der das analoge Signal in ein digitales Signal umwandelt.
Dies bedeutet, dass die 0-5 Volt proportional den Integerwerten 0-1023 (1024 Werte insgesamt) zugeordnet werden. Das Verwenden eines ADC ist eine einfache und effiziente Technik, um Daten eines Sensors einzulesen.
Beispiel:
0 Volt am analogRead-Pin wird der digitale Wert 0 vergeben.
2,5Volt am analogRead-Pin wird der digitale Wert 511 vergeben.
5 Volt am analogRead-Pin wird der digitale Wert 1023 vergeben.
###grafik
Die analogen Eingänge des Arduino haben eine bestimmte Auflösung. Die Auflösung gibt uns Auskunft darüber, wie fein wir Eingangswerte pro Zeiteinheit abstufen können.
####grafiken und infos
ADC-Ports wie z.B. A0 haben eine Auslösung von 10 Bit (2^10) - das ergibt eine Auflösung von 0 bis 1023 Schritten. Mit der Zahl 0 sind es insgesamt 1024 Schritte. Der ADC überträgt 0V bis 5V auf den Bereich von 0 bis 1023 digitalen Schritten. Dabei entspricht ein digitaler Schritt 4,9mV (5/1024 = 4,9mV). Wenn wir also 2,5V am ADC-Port messen erhalten wir den entsprechenden Wert von 512ADC (512 × 4,9mV = 2508,8mV ⇾ 2,5V).
###grafik
Die Lesegeschwindigkeit des analogRead()-Pins um ein analoges Signal zu analysieren beträgt beim Arduino Mega ca. 100 Mikrosekunden (µs), oder anders ausgedrückt sind das 0,0001 Sekunden. Hier ein Vergleich der Sekunden Umrechnung:
1s (Sekunde) = 1.000ms (Millisekunden) = 1.000.000µs (Mikrosekunden)
Auf eine ganze Sekunde hochgerechnet, ergibt sich eine maximale Lesegeschwindigkeit von 10.000 Lesevorgängen pro Sekunde! Das ist ganz schön ordentlich.
Der Sketch im Detail
Die analogen Pins werden von A0-A15 durchnummeriert. Wie bei den digitalen Pins vergeben wir hier eine Pinnummer und eine Variable, um die Werte des Potentiometers zwischenzuspeichern.
int potiPin = A0;
int potiValue = 0;
Während der Strom vom 5 Volt-Pin zum GND-Pin (der Ring des Potentiometers) fließt, wird durch das Drehen am Poti der Widerstand geändert und die Stromspannung am Signal-Pin (Schleifer) dadurch hoch oder runtergeregelt. Diese Veränderung der Spannung wird mit dem analogRead()-Pin eingelesen. Um die vom Poti eingelesene Werte überhaupt für uns sichtbar zu machen, senden wir sie an den seriellen Monitor.
void setup()
{
Serial.begin(9600);
}
Vielleicht ist dir im setup() etwas Wichtiges aufgefallen. Es fehlt etwas: die Initialisierung des analogen Pins, wie wir es z.B. von digitalRead() kennen:
void setup()
{
pinMode(potiPin, INPUT); //Initialisierung eines digitalen Pins
}
In der Arduino-Sprache ist diese Art der Initialisierung für analogRead() nicht nötig. Im Gegensatz zu analogRead() können wir digitale Pins als INPUT oder als OUTPUT einstellen. Da wir bei digitalen Pins die Auswahl zwischen INPUT und OUTPUT haben, ist es sinnvoll eindeutig zu initialisieren.
AnalogRead() Pins werden hauptsächlich als INPUT-Pin genutzt. Aus diesem Grund wird standardmäßig im void setup() auf die Initialisierung verzichtet. Dadurch können wir den Potentiometerwert durch analogRead() sofort abfragen und direkt in einer Variablen zwischenspeichern.
potiValue = analogRead(potiPin);
Durch die Serial.println Funktion können wir den Poti-Wert im seriellen Monitor in Echtzeit ablesen. Beachte, dass wir hier keine " " einsetzen.
Serial.println(potiValue);
digitalRead() – Eine Initialisierung muss nicht unbedingt sein
Tatsächlich gibt es bestimmte Situationen, in der man auf die Initialisierung verzichten kann. Falls du auf die Initialisierung verzichtest, wird ein digitaler Pin standardmäßig als INPUT arbeiten. Also brauchst du nicht unbedingt ein pinMode()-Befehl. Der folgende Code ist völlig legitim und ausführbar:
// 002b_taster_serial
int tasterPin = 2;
void setup()
{
Serial.begin(9600);
// hier fehlt die pinMode()-Funktion, weil der
// digitale Pin als Eingang verwendet wird
}
void loop()
{
int zustandTaster = digitalRead(tasterPin);
Serial.println(zustandTaster);
delay(1);
}
Trotzdem ist es aus Gründen der Übersicht, ratsam die Initialisierung mit pinMode() anzuwenden. Nur wenn bei deinem Projekt jedes Byte zählt und der Speicher sehr knapp ist, kannst du hier darauf verzichten, wenn du eine INPUT-Konfiguration brauchst.