Arduino-Kurs – #4 – ADC-Wandler

In den vorherigen Teilen des Kurses haben wir uns mit dem Lesen von digitalen Signalen beschäftigt. So konnten wir zum Beispiel prüfen, ob eine Taste gedrückt wurde. Die Welt um uns herum ist jedoch nicht digital, manchmal sind 2 Zustände (1/0) nicht genug.

Deshalb werden wir uns jetzt mit einem Analog-Digital-Wandler, kurz ADC, beschäftigen.
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>

Kurze theoretische Einführung

Die Elektronik lässt sich in digitale und analoge Technik unterteilen. Bei der digitalen Technik kann ein bestimmter Eingang oder Ausgang nur einen von zwei Zuständen annehmen. Hoch (1) oder niedrig (0). In der Praxis bedeutet dies, dass der Arduino an seinem Eingang 0 V oder 5 V (vereinfacht ausgedrückt) erkennt.

Leider lassen sich nicht alle Dinge in der Welt um uns herum auf so einfache Art und Weise beschreiben. Wenn wir einen Abstandssensor anschließen, möchten wir die genaue Entfernung zu einem Hindernis wissen und nicht nur eine Information nach dem Motto: Hindernis sichtbar, kein Hindernis sichtbar.

Ein solcher Sensor könnte eine zum Abstand proportionale Spannung ausgeben. Die Messung würde dann darin bestehen, die Spannung abzulesen, z.B. von 0-5V. Dies ist der analoge Ansatz. Daher werden wir in den folgenden Beispielen geeignete Arduino-Peripheriegeräte verwenden, die es uns ermöglichen, die an speziellen Eingängen der Schaltung anliegende Spannung zu messen.

Achtung!
Bevor wir zum Testen übergehen, denk daran, dass du nur Spannungen im Bereich von 0-5V an die Eingänge des Arduino UNO anschließen kannst. Andere Spannungswerte können die Platine und sogar den Computer, an den Sie den Chip anschließen, beschädigen!

Der so genannte ADC (Analog-Digital-Wandler) wird zur Verarbeitung des analogen Signals verwendet. Dies ist eins der beliebtesten Peripheriegeräte in Mikrocontrollern. Seine Aufgabe ist es, die am Eingang des Systems anliegende Spannung abzutasten und in eine digitale Form umzuwandeln.

Zum Beispiel für einen Linearwandler:
				
					    Spannung    => Vom ADC ausgelesener Wert
      [V]           (gerundet)
       0	=>	0
       1	=>	51
       2	=>	102
       3	=>	154
       4	=>	205
       5	=>	255
				
			
In diesem Fall wird ein 8-Bit-Wandler gezeigt, weil der ausgelesene Wert 256 Kombinationen haben kann (beginnend bei 0). In Wirklichkeit gibt es verschiedene Wandler, z. B. 12-Bit- oder 16-Bit-Wandler. Ein Wandler, der mehr Bits hat, sollte genauer sein, weil sein Maximalwert höher ist (er arbeitet über denselben Bereich, aber mit einer höheren Auflösung).

Es ist interessant zu wissen, dass Analog-Digital-Wandler relativ langsam arbeiten. Natürlich werden wir das in unseren Programmen nicht bemerken, aber wenn wir den ADC mit anderen Mikrocontroller-Peripheriegeräten vergleichen, schneidet er nicht so gut ab.

Eine Messung mit dem ADC dauert 0,0001 s,
d.h. es können maximal 10.000 Messungen pro Sekunde durchgeführt werden!

Zweitens sind diese Wandler teuer in der Herstellung. Wie du dich aus der zweiten Lektion über den Arduino UNO erinnerst, haben wir 6 Analogeingänge (A0-A5) zur Verfügung. In der Tat gibt es nur einen ADC im Mikrocontroller, an den ein Multiplexer angeschlossen ist. Dadurch ist es möglich, die Spannung auf 6 Kanälen zu messen.

Damit ist die theoretische Einführung abgeschlossen. Nun können wir zum ersten Programm übergehen.

Fertige Sets für Forbot-Kurse
 Satz von Elementen   Garantierte Unterstützung   Versand in 24 Stunden

Sie können jetzt ein Set von mehr als 70 Elementen, die für die Kursübungen notwendig sind, bei unseren Händlern kaufen!

Beliebtes Paket: Arduino MeisterRobotik Meister

ADC in der Praxis

Es ist an der Zeit zu sehen, wie der ADC in der Praxis funktionieren wird. Baue dazu die Schaltung wie in der Abbildung unten gezeigt auf. Ein Potentiometer erscheint hier in der Rolle eines Spannungsteilers.

Die programmtechnische Nutzung des ADC ist simpel und beschränkt sich auf die Verwendung der Funktion analogRead(ADC Kanal), bei der wir den ausgewählten Pin (A0-A5) durch den ADC-Kanal ersetzen.

Es bleibt uns nichts anderes übrig als unser erstes einfaches Programm. Wir beschränken uns zunächst nur darauf, den gelesenen Wert an den Computer zu senden. Dazu verwenden wir natürlich den UART, den wir im vorherigen Teil des Kurses kennengelernt haben.
				
					int ausgelesenerWert = 0;

void setup() {
  Serial.begin(9600);//Start der Kommunikation über UART
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Lesen des Spannungswertes
  Serial.println(ausgelesenerWert);//Wir senden ihn an das Terminal
  delay(200);//Wir warten, um die Ergebnisse bequemer zu lesen
}
				
			
Beim Drehen des Potentiometers erhalten wir auf dem Monitor Werte von 0 bis 1023. Das bedeutet, dass der ADC im Arduino UNO 10 Bit hat.

Sind solche trockenen Werte für uns nützlich? Das ist schwer zu sagen. Es wäre besser, das Ergebnis in verständlichen Einheiten abzulesen. Zum Beispiel in Volt, richtig?

Einfaches Voltmeter

Diese Aufgabe ist einfach und besteht nur darin, den gelesenen Wert entsprechend umzuwandeln. Wir wissen, dass die Eingangsspannung zwischen 0 und 5 V schwankt, und wir erhalten 1024 Werte vom ADC (wir zählen von 0 bis 1023). Das heißt:

1024 => 5V 1 => x

1024x = 1*5

x = (1*5V)/1024 = ~0,0049V


Einfach ausgedrückt: Jede Erhöhung der Eingangsspannung um ~0,0049 V erhöht die ADC-Anzeige um eins. Das heißt, um das Ergebnis in Volt zu erhalten, muss man nur eine Zeile hinzufügen:
				
					int ausgelesenerWert = 0;//Wert vom ADC lesen
float Spannung = 0;//Wert umgerechnet auf Spannung in V

void setup() {
  Serial.begin(9600);//Start der Kommunikation über USART
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Lesen des Spannungswertes
  Spannung = ausgelesenerWert * (5.0/1024.0); //Umrechnung des Wertes in Spannung
  Serial.println(Spannung);//Senden der gemessenen Spannung
  delay(200);//Wir warten, um die Ergebnisse bequemer zu lesen
}
				
			

Beachte, dass die Spannungsvariable als Float-Typ deklariert wurde, d. h. als ein Typ, der die Speicherung von Fließkommazahlen erlaubt.

Die Zahlen, die im obigen Code durch sich selbst geteilt werden, wurden mit der Anmerkung „.0“ geschrieben; dies ist eine Information für den Compiler, um sie als Fließkommazahlen zu behandeln. Andernfalls wäre das Ergebnis einer solchen Operation eine ganze Zahl!

Von nun an sollte auf dem Bildschirm des Computers ein Wert von 0-5V angezeigt werden. Wir haben also gerade ein sehr einfaches, aber funktionierendes Voltmeter gebaut. Kann man damit auch die Spannung anstelle eines Potentiometers zum Beispiel an einer Batterie messen? Ja, aber nur, wenn man sehr vorsichtig ist.

Denke daran, dass der Anschluss einer höheren Spannung als 5V den Arduino irreversibel beschädigt! Versuche daher gar nicht erst, die im Set enthaltene 9V-Batterie an unser Voltmeter anzuschließen.

Wenn du jedoch irgendwo eine gewöhnliche AA-Batterie mit 1,5 V auftreiben kannst (z. B. in TV-Fernbedienungen), kannst du ein wenig damit experimentieren:

  1. Verbinde den Minuspol (GND) der Batterie mit einem Kabel mit der
  2. Verbinde das Kabel von Pin A5 mit dem Pluspol der Batterie
  3. Lese die Spannung am Computer ab.

In meinem Fall lag die Spannung bei einer neuen Batterie knapp über 1,6 V, also war alles normal. Es sollte also nur als ein Experiment betrachtet werden.

Ein einfaches Voltmeter auf einem Arduino.

Siehst du schon eine praktische Anwendung für ADC-Messungen (abgesehen von einem Voltmeter)? Wenn nicht, schau dir die folgende Übung an.

Steuerung des Programmbetriebs durch den ADC

Das frühere Programm war nur dazu gedacht, die Funktionsweise des Wandlers zu demonstrieren. Wir können nun das an die Schaltung angeschlossene Potentiometer verwenden, um den Betrieb des Programms zu beeinflussen. Zu diesem Zweck fügen wir dem Arduino eine einzelne LED hinzu.

Die Werte des Wandlers liegen zwischen 0 und 1023, was relativ klein ist. Was passiert, wenn wir die ausgelesene Zahl als Verzögerungswert im Programm verwenden? Hier ist der schnellste Weg, ein Gerät zu bauen, das eine LED mit einer durch ein Potentiometer gesteuerten Frequenz blinken lässt:

				
					int ausgelesenerWert = 0; //Variable für die Speicherung von ADC-Messwerten

void setup() {
  pinMode(2, OUTPUT); //Konfiguration der Ausgänge für die LED
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Auslesen des Wertes aus dem ADC
  digitalWrite(2, HIGH);//Diode einschalten
  delay(ausgelesenerWert);//Abhängigkeit des ADC-Timeouts
  digitalWrite(2, LOW);//Diode ausschalten
  delay(ausgelesenerWert);//Abhängigkeit des ADC-Timeouts
}
				
			

Hausaufgabe 4.1

Beobachte, was bei einer der Endpositionen des Potentiometers passiert. Was denkst du, was die Ursache dafür ist?

Anzeige an den Dioden

Es ist Zeit für ein etwas aufwendigeres Projekt. Dieses Mal werden wir je nach Stellung des Potentiometerschiebers die entsprechende Diode einschalten. Zunächst müssen alle Komponenten miteinander verbunden werden. Mein Anschlussvorschlag sieht wie folgt aus:

Die Aufgabe ist einfach, wir teilen einfach den maximalen Wert, den wir vom ADC ablesen können, also 1023, durch 5 und bilden daraus die Schaltbedingungen der einzelnen Dioden. Wir können dafür aber auch die sehr komfortable map()-Funktion verwenden.

Ihre Anwendung sieht in der Praxis so aus:
				
					skalierterWert = map(ausgelesenerWert, 0, 1023, 1, 5);
				
			
Mit dieser Funktion lässt sich ein bestimmter Wert schnell skalieren. Das erste Argument wird als der zu skalierende Wert angegeben. In unserem Fall ist dies die Information des ADC. Der zweite und dritte Parameter sind der Bereich des Eingangswertes, während die letzten beiden Parameter der Bereich des Ausgangswertes (nach der Skalierung) sind.

Die obige Codezeile ergibt immer einen Wert im Bereich von 1-5. In der Praxis kann dies wie folgt verwendet werden:
				
					int ausgelesenerWert = 0;

void setup() {
  pinMode(8, OUTPUT); //Konfiguration der LED-Ausgänge
  pinMode(9, OUTPUT);
  pinMode(10, OUTPUT);
  pinMode(11, OUTPUT);
  pinMode(12, OUTPUT);
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Auslesen des Wertes aus dem ADC
  ausgelesenerWert = map(ausgelesenerWert, 0, 1023, 1, 5);//Skalierung der Werte
  
  if (ausgelesenerWert == 1) { //Erster Bereich
      digitalWrite(8, HIGH); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(11, LOW); 
      digitalWrite(12, LOW); 
  } else if (ausgelesenerWert == 2) { //Zweiter Bereich
      digitalWrite(8, LOW); 
      digitalWrite(9, HIGH); 
      digitalWrite(10, LOW); 
      digitalWrite(11, LOW); 
      digitalWrite(12, LOW);       
  } else if (ausgelesenerWert == 3) {  //Dritter Bereich
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, HIGH); 
      digitalWrite(11, LOW); 
      digitalWrite(12, LOW);       
  } else if (ausgelesenerWert == 4) {  //Vierter Bereich
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(11, HIGH); 
      digitalWrite(12, LOW);       
  } else {  //Anderer, d.h. fünfter Bereich
      digitalWrite(8, LOW); 
      digitalWrite(9, LOW); 
      digitalWrite(10, LOW); 
      digitalWrite(11, LOW); 
      digitalWrite(12, HIGH);       
  }
  delay(50); //Verzögerung, um den ADC nicht zu schnell zu lesen 
}
				
			

Mir ist klar, dass sich erfahrene Entwickler an den Kopf fassen werden, wenn sie die oben genannten Bedingungen sehen. Aber wir haben alles unter Kontrolle. Wir werden uns bald mit der switch/case-Konstruktion befassen, die solche langen Bedingungen erleichtern wird

Überprüfe, was mit den einzelnen LEDs passiert, wenn du das Potentiometer drehst. Wenn alles richtig angeschlossen wurde, sollte beim Drehen des Reglers jeweils eine andere Diode aufleuchten.

Bei einer der Endstellungen des Potentiometers kann man feststellen, dass sich die Dioden seltsam verhalten. Am besten ist es dann, durch Ausprobieren den Maximalwert des ADC zu ändern, der in der map()-Funktion eingestellt ist.


In meinem Fall verhielt sich die Schaltung bereits beim Wechsel von 1023 auf 1021 korrekt.

Hausaufgabe 4.2

Wenn du Glück hast (viel Umgebungslärm), kannst du ein spektakuläres Experiment durchführen. Verwende die Schaltung mit den 5 Dioden, die du zuvor angeschlossen hast. Trenne das Kabel, das zum Potentiometer führt, und lasse es in der Luft hängen.

Was passiert, wenn du deine Hand in die Nähe des Kabels bringst (ohne das Ende zu berühren)? Hasst du eine Idee, warum das so ist? In meinem Fall, als der Draht in der Luft hing, leuchteten 3 LEDs, aber ich brauchte meine Hand nur bis auf 2 cm an den Draht heranzuführen, dann leuchteten alle LEDs. Habt ihr eine Idee, warum das so ist?

Wenn dieser Effekt bei euch nicht so ausgeprägt ist, könnt ihr am Ende des Kabels eine „Antenne“ anbringen, z.B.: aus Alufolie.

Diese Erfahrung sollte dir in Erinnerung bleiben als Beweis dafür, dass du keine Schaltkreiseingänge in der Luft „hängen“ lassen darfst. Siehe, welche Probleme das verursachen kann!

Bei Dunkelheit aktiviertes Licht

Es ist an der Zeit, ein neues Element zu verwenden und etwas zu bauen, das praktische Anwendungen hat. In dieser Übung werden wir einen Fotowiderstand verwenden, ein Element, dessen Widerstand sich mit dem einfallenden Licht ändert (je mehr wir es beleuchten, desto geringer wird der Widerstand).

Mit Hilfe des Fotowiderstands können wir einen Spannungsteiler bauen, der von der Lichtmenge in der Umgebung abhängt. Baue die Schaltung wie in der folgenden Abbildung gezeigt auf. Der Fotowiderstand soll zusammen mit einem 1k-Widerstand einen Teiler bilden.
Wenn eine große Lichtmenge auf den Fotowiderstand fällt, ist sein Widerstand minimal und die Spannung an dem Punkt, der mit dem Arduino verbunden ist, ist relativ „hoch“. Wenn das Licht aussetzt, erhöht sich der Widerstand des Fotowiderstands, und die Spannung am Teiler ist niedrig.

Mit einer solchen Schaltung können wir eine Leuchte bauen, die sich bei Dunkelheit einschaltet. Der Code ist sehr einfach (wie immer):
				
					int ausgelesenerWert = 0; //Variable zur Speicherung des ADC-Wertes

void setup() {
  pinMode(8, OUTPUT); //Konfiguration des Wertes aus dem ADC
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Auslesen des Wertes aus dem ADC
  
  if (ausgelesenerWert < 100) {
     digitalWrite(8, HIGH);//Diode einschalten    
  } else {
     digitalWrite(8, LOW);//Diode ausschalten      
  }
  
  delay(50);
}
				
			
Wie man sieht, gibt es eine Bedingung, die für das Ein- oder Ausschalten der Diode verantwortlich ist. Die Frage ist, wie man diesen Schaltwert auswählt? Vorzugsweise manuell…

In meinem Fall habe ich ihn anfangs auf 500 eingestellt und ihn dann schrittweise verringert, bis die Diode im richtigen Moment (als ich den Sensor mit der Hand abdeckte) eingeschaltet wurde.

Anstelle einer blauen Diode kann man nun einfach ein paar stärkere weiße Dioden anschließen (über einen Transistor) und schon hat man ein funktionierendes Licht, das selbst weiß, wann es leuchten soll. Was aber, wenn wir es in einen anderen Raum bringen, wo die Bedingungen minimal anders sind? Müssen wir dann wieder den Arduino mehrmals programmieren, um den richtigen Schwellenwert zu wählen? Ja, es sei denn…

Bei Dunkelheit aktiviertes Licht v2

Dieses Mal ist die Aufgabe offensichtlich. Wie zuvor wollen wir ein Licht schaffen, das sich bei Dunkelheit einschaltet. Allerdings sollte es viel einfacher zu justieren sein. Hast du eine Idee, wie man das erreichen kann?

Ich habe ein Potentiometer verwendet, das an einen anderen Analogeingang (A4) angeschlossen ist:

Anstatt das Einschalten der Diode von einem festen Grenzwert abhängig zu machen, können wir die Einschaltschwelle nun stufenlos mit einem Potentiometer einstellen. Die Änderung im Programm ist sehr einfach und beschränkt sich auf die Bearbeitung von 3 Codezeilen:

				
					int ausgelesenerWert = 0; //Variable für die Speicherung von ADC-Messwerten
int prog = 0; //Lichteinschaltschwelle - einstellbar über Potentiometer

void setup() {
  pinMode(8, OUTPUT); //Konfiguration der Ausgänge für die Diode
}

void loop() {
  ausgelesenerWert = analogRead(A5);//Auslesen des Wertes aus dem ADC
  prog = analogRead(A4);//Auslesen des Wertes aus dem ADC
  
  if (ausgelesenerWert < prog) { //ist es dunkler als die eingestellte Schwelle?
     digitalWrite(8, HIGH);//Diode einschalten    
  } else {
     digitalWrite(8, LOW);//Diode ausschalten      
  }
  
  delay(50);
}
				
			
Wie lässt sich die Schaltung am schnellsten justieren?
  1. Stelle das Gerät in das Licht, bei dem die Diode ausgeschaltet sein soll
  2. Dreh das Potentiometer auf die Stellung, in der die Diode ausgeschaltet wird
  3. Geschafft!
Von nun an sollte eine minimale Verdunkelung des Fotowiderstands unser Beispiellicht einschalten!

Die Verwendung des ADC ist sehr einfach, es ist also an der Zeit, die Hausaufgaben eigenständig durchzuführen. Denke daran, alle Lektionen gut zu beherrschen. Mit der Zeit werden wir viele Funktionen in den Programmen verwenden. Es bleibt dann nicht mehr viel Zeit, um zu den Grundlagen zurückzukehren!

Hausaufgabe 4.4

Erweitere das Programm der intelligenten Beleuchtung so, dass es beim Einschalten der Diode (einmalig) an den PC sendet, welche Spannung am Teiler aufgetreten ist.

Hausaufgabe 4.5

Versuche, ein einfaches Spiel zu programmieren. Nachdem du das Programm gestartet hast, drehe das Potentiometer an eine beliebige Stelle und drücke die Taste. Der Arduino sollte dann eine Meldung auf dem PC anzeigen:

Gib eine Zahl an:

Wenn die an den Arduino gesendete Zahl mit dem ADC-Wert um +/- 50 übereinstimmt, hat der Spieler gewonnen. Wenn nicht, leuchtet eine gelbe LED auf und der Spieler hat 2 weitere Versuche. Jedes Mal, wenn eine falsche Zahl eingegeben wird, leuchtet eine rote LED auf der Kontaktplatte auf. Wenn der Spieler hingegen gewinnt, leuchtet eine grüne LED auf. Tipp: Für diese Aufgabe benötigst du eine neue Funktion, die bisher im Kurs noch nicht verwendet wurde – schau selbst in der Dokumentation nach, was die Funktion toInt macht und überlege, wie sie dir bei dieser Hausaufgabe helfen kann. Vielleicht findest du auch dieses Beispiel hilfreich.

Hausaufgabe 4.6

Verwende zwei Fotowiderstände als separate Spannungsteiler. Platziere sie an den äußersten Seiten der Kontaktplatte. Idealerweise sollte man sie sogar minimal nach außen kippen. Zeige die Werte der beiden Sensoren im Terminal an. Was passiert, wenn du mit der Hand vor der Leiterplatte winkst (einen Schatten wirfst) oder sie mit einer Taschenlampe beleuchtest?

Kannst du durch die Analyse des Unterschieds zwischen den Messwerten der beiden Sensoren ein Programm schreiben, das feststellt, auf welcher Seite der Platte sich die stärkere Lichtquelle befindet? Versuche, die Richtung mit den 5 Dioden zu bestimmen (mehr links, Mitte, mehr rechts, usw.)!

Zusammenfassung

In diesem Teil des Arduino-Kurses habe ich, meiner Meinung nach, eines der interessantesten Peripheriegeräte beschrieben, den ADC. Analogwandler werden sehr oft verwendet, wenn ein Chip Informationen aus der Umgebung ausliest. Wichtig ist, dass ADCs nicht nur beim Arduino verfügbar sind, so dass das praktische Wissen aus diesem Teil stets auf dem neuesten Stand sein wird.

Zu beachten ist, dass das komplette Set der Komponenten, die für alle Übungen benötigt werden, bei Botland erhältlich ist. Der Kauf der Sets unterstützt zukünftige Veröffentlichungen auf Forbot!
Bestellen Sie ein Set mit Elementen und beginnen Sie mit dem Lernen in der Praxis! Hier gehts zum Shop >>
Nach oben scrollen