Advanced - Ultraschallsensor mit LED

Beschreibung

Im Folgenden soll ein Ultraschallsensor (siehe AB Ultraschallsensor) mit vier LED’s (siehe AB Led ansteuern) verbunden werden und je nach Entfernung eines Objektes soll eine andere LED aufleuchten.

Verkabelung

HC-SR04ArduinoSonstiges
VCC5V
GNDGNDüber das Breadboard
Trig2
Echo3
LEDArduinoGND am Breadboard
GELB8über seitlichen Leisten
ROT9über seitlichen Leisten
BLAU10über seitlichen Leisten
GRÜN11über seitlichen Leisten
Schaltplan

Schaltplan

Code

// Angeschlossene LEDs.
int LED_GELB  = 8;
int LED_ROT   = 9;
int LED_BLAU  = 10;
int LED_GRUEN = 11;

// Pins für den Sensor.
int TRIG_PIN = 2;
int ECHO_PIN = 3;

void setup() {
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
  pinMode(LED_GELB, OUTPUT);
  pinMode(LED_ROT, OUTPUT);
  pinMode(LED_BLAU, OUTPUT);
  pinMode(LED_GRUEN, OUTPUT);
}

void loop() {
  // Speichern, wie lange der Schall unterwegs ist.
  long zeit;
  // Speichern des gemessenen Abstandes.
  long abstand;

  // Wir messen den Abstand zum nächsten Objekt.
  digitalWrite(TRIG_PIN, LOW);  // Lautsprecher aus.
  delay(2);
  digitalWrite(TRIG_PIN, HIGH);  // Lautsprecher gibt Ton aus.
  delay(10);
  digitalWrite(TRIG_PIN, LOW);     // Lautsprecher aus.
  zeit = pulseIn(ECHO_PIN, HIGH);  // Hier wird gemessen, wann das Mikrofon den
                                   // Ton hört.
  abstand = zeit * 0.034 / 2;      // Umrechnung des Abstands von Zeit in
                                   // Zentimeter.

  if (abstand < 25) {  // Wenn der Abstand kleiner als 25 Zentimeter ist...
    digitalWrite(LED_ROT, HIGH);  // ... schalte die rote LED an,
    // und alle anderen LEDs aus.
    digitalWrite(LED_GELB, LOW);
    digitalWrite(LED_BLAU, LOW);
    digitalWrite(LED_GRUEN, LOW);
  } else if (abstand < 100) {      // Größer als 25 cm und kleiner als 1m...
    digitalWrite(LED_GELB, HIGH);  // ... schalte die gelbe LED an,
    // und alle anderen LEDs aus.
    digitalWrite(LED_ROT, LOW);
    digitalWrite(LED_BLAU, LOW);
    digitalWrite(LED_GRUEN, LOW);
  } else if (abstand < 200) {       // Größer als 1m und kleiner als 2m...
    digitalWrite(LED_GRUEN, HIGH);  // ... schalte die grüne LED an,
    // und alle anderen LEDs aus.
    digitalWrite(LED_ROT, LOW);
    digitalWrite(LED_BLAU, LOW);
    digitalWrite(LED_GELB, LOW);
  } else if (abstand < 300) {      // Größer als 2m und kleiner als 3m...
    digitalWrite(LED_BLAU, HIGH);  // ... schalte die blaue LED an,
    // und alle anderen LEDs aus.
    digitalWrite(LED_ROT, LOW);
    digitalWrite(LED_GELB, LOW);
    digitalWrite(LED_GRUEN, LOW);
  } else {  // Sonst, wenn die Entfernung größer als 3m, schalte alle LEDs aus.
    digitalWrite(LED_GELB, LOW);
    digitalWrite(LED_ROT, LOW);
    digitalWrite(LED_BLAU, LOW);
    digitalWrite(LED_GRUEN, LOW);
  }
}

Aufgaben

Wie misst ein Ultraschallsensor die Entfernung zu einem Hindernis?

Erkläre was der Echo- und Triggerpin sind und wie sie den Abstand messen.

Was ist bei der LED die Anode und was die Kathode?

  • Die Anode ist der Pluspol und das lange Bein der LED.
  • Die Kathode ist der Minuspol und das kurze Bein der LED.

Häufige Fragen und Probleme

Wieso leuchten einige LEDs nicht?

  • Alle Anschlüsse überprüft und richtig verkabelt?
  • Der Abstand ist wohl nicht klein/groß genug, um in einen der Fälle zu springen und die LED zum Leuchten zu bringen. Gehe etwas näher heran/weiter weg.

Meine LEDs springen während des Leuchtens immer hin und her, was bedeutet das?

Deine Messbahn ist wohl nicht ganz frei von Hindernissen, welche der Sensor als solche erkennt und deshalb eine wechselnde Entfernung angibt. Sorge für eine freie Messbahn, um, vor allem für die grüne und blaue LED, genauere Ergebnisse zu erzielen. Stehe zudem gerade und ruhig beim Messen oder stelle das Gerät auf eine feste Unterlage, denn schon durch leichtes Ruckeln werden andere Bereiche erkannt und somit andere Werte gemessen.

Bluetoothsensor

Beschreibung

Im Folgenden wollen wir sehen, wie wir sehr einfach den Bluetoothsensor “CZ-HC-05 gomcu” auf dem Arduino installieren, um diesen z.B. mit einer Handyapp anzusteuern. Wir laden dazu eine von vielen verfügbaren Apps herunter und programmieren hier keine eigene.

Verkabelung

BluetoothsensorLEDArduino
Langes Bein13
Kurzes BeinGND
VCC5V
GNDGND
TXDPin 0 (RX)
RXDPin 1 (TX)
Schaltplan

Schaltplan

Code

Wir verwenden folgenden Code, um eine LED mit dem Smartphone zu steuern.

WICHTIG: Wenn du neuen Code hochlädst, nimm immer den Bluetoothsensor ab und stecke ihn nachdem der Code hochgeladen ist, wieder ein.

int led = 13;

void setup() {
  Serial.begin(9600);  // Ermöglicht Kommunikation mit BT-Sensor.
  pinMode(led, OUTPUT);
}

void loop() {
  if (Serial.available() > 0) {    // Ist ein neues Zeichen vorhanden?
    char zeichen = Serial.read();  // Wenn ja, speichere das neue Zeichen ab.
    if (zeichen == '0') {          // Ist das Zeichen '0'?
      digitalWrite(led, LOW);      // Wenn ja, schalte die LED aus.
      Serial.println("Led aus.");  // Sendet Statustext.
    }
    if (zeichen == '1') {         // Ist das Zeichen '1'?
      digitalWrite(led, HIGH);    // Wenn ja, schalte die LED an.
      Serial.println("Led an.");  // Sendet Statustext
    }
    delay(1000);  // Warte 1 Sek. bevor das nächste
                  // Zeichen eingelesen wird.
  }
}

Fragen zum Code

Beschreibe, was der Code tut!

Der Arduino wartet immer auf Daten vom Bluetoothsensor. Empängt er Daten, prüft er diese Zeichen für Zeichen (1 Zeichen pro Sekunde).

Welche Zeichen muss man eingeben, damit die LED an und aus geht? Was passiert bei anderen Zeichen?

Die LED leuchtet bei dem Zeichen “1” und geht aus beim Zeichen “0”. Bei allen anderen passiert nichts mit der LED.

Anleitung

Arduino herausnehmen

Arduino herausnehmen

Nimm den Bluetoothsensor aus dem Breadboard.

Code hochladen

Code hochladen

Lade den Code auf den Arduino. Setze den Bluetoothsensor wieder in das Breadboard ein. Die Lampe leuchtet nun schnell.

App runterladen

App runterladen

Lade eine App auf dein Handy herunter, mit welcher du Bluetoothnachrichten verschicken kannst. Wir nutzen hier die App “Bluetooth Terminal” von Querty (Diese App eignet sich besonders gut, da hier nur Zeichenketten verschickt und empfangen werden können).

Bluetoothfenster öffnen

Bluetoothfenster öffnen

Öffne dein Bluetoothfenster und klicke auf HC-05.

Bluetoothsensor auswählen

Bluetoothsensor auswählen

Gib das Passwort “1234” ein und drücke auf ok. Dein Smartphone ist nun mit dem Bluetoothsensor gekoppelt. Die Lampe des Arduino blinkt nun langsamer. Wenn du den Bluetoothsensor aus dem Breadboard ziehst und wieder einsteckst, dann musst du diesen Schritt nicht wiederholen.

App starten

App starten

Öffne die App “Bluettooth Terminal”. Oben wird “not connected” angezeigt. Das heißt, dass die App noch nicht mit der Bluetoothsensor kommuniziert. Immer wenn du den Bluetoothsensor aus dem Breadboard herausziehst und wieder einsteckst, wird wieder “not connected” angezeigt. Führe die folgenden Schritte durch, um eine Verbindung herzustellen.

Mit Bluetooth verbinden

Mit Bluetooth verbinden

Drücke auf die drei Punkte oben rechts und dann auf “connect a device - Secure” oder “connect a device - Insecure” .

Sensor auswählen

Sensor auswählen

Drücke auf den Namen deines Bluetoothsensors “HC-05”. Falls in deinem Klassenraum mehrere Bluetoothsensor verwendet werden, orientiere dich an der IPv6 Adresse deines Bluetoothsensors. Diese ist immer eindeutig und ist in diesem Beispiel “98:D3:33:80:72:7B”.

Sensor verbunden

Sensor verbunden

Oben steht nun “connected: HC-05”. Dein Arduino kann nun Nachrichten empfangen.

Nachricht senden

Nachricht senden

Wenn du auf das Eingabefeld tippst, erscheint deine Tastatur und du kannst Nachrichten senden.

Befehl ausführen

Befehl ausführen

Wenn du eine “1” sendest, so geht das Licht an, und bei einer “0” geht das Licht aus. Der rote Text ist der Text, den das Smartphone gesendet hast. Der blaue Text wurde vom Bluetoothsensor auf dein Smartphone gesandt.

Lampe an

Lampe an

Sende “1”.

Lampe aus

Lampe aus

Sende “0”.

Aufgaben

Füge Code hinzu, sodass die LED drei mal schnell blinkt, wenn “s” gesendet wird und drei Mal langsam blinkt, wenn “o” gesendet wird.

if (zeichen == 's') {
  Serial.println("s");
  digitalWrite(led, HIGH);
  delay(300);
  digitalWrite(led, LOW);
  delay(300);
  digitalWrite(led, HIGH);
  delay(300);
  digitalWrite(led, LOW);
  delay(300);
  digitalWrite(led, HIGH);
  delay(300);
  digitalWrite(led, LOW);
}

if (zeichen == 'o') {
  Serial.println("o");
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(300);
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
  delay(300);
  digitalWrite(led, HIGH);
  delay(600);
  digitalWrite(led, LOW);
}

Sende die Zeichenkette “1010010” (und andere ähnliche Zeichenketten) an den Arduino. Was beobachtest du?

Der Arduino führt pro Sekunde einen der Befehle aus, sodass sie blinkt.

Welche Funktion hat das delay(1000)? Was passiert, wenn wir es auf delay(500) ändern?

Es wird nur ein Zeichen pro Sekunde eingelesen. Nach der Änderung zwei Zeichen pro Sekunde.

Überlege dir, wie du den Arduino programmieren muss, um ein Morsealphabet darzustellen. Finde im Internet ein Morsealphabet. Orientiere dich dazu an Frage 3 und implementiere zunächst die Buchstaben deines Vornamens.

Nutze den Code aus Frage 3 und passe das Zeichen und die Länge der Pausen an, um lange und kurze Lichtsignale zu senden.

CO<sub>2</sub> Sensor

Beschreibung

Mit dem MH-Z19B lässt sich der CO2 Gehalt in der Luft bestimmen.

Hinweis!

Der Sensor liefert zwar sinnvolle Werte, aber sollte nicht für sicherheitsrelevante Anwendungen verwendet werden.

Derzeit sind gefälschte Sensoren im Umlauf, die nicht richtig funktionieren. Woran man diese erkennt, findet man hier: https://revspace.nl/MH-Z19B#Fake_MH-Z19B_.28black_PCB.29

Verkabelung

MH-Z19CLEDsArduino
GNDGND
VIN5V
TX9
RX10
Schaltplan

Schaltplan

Code

#include <MHZ19.h>
#include <SoftwareSerial.h>

int MHZ_TX_PIN = 9;  // TX Pin von MH-Z19B
int MHZ_RX_PIN = 10; // RX Pin von MH-Z19B

// Objekt für den Sensor
MHZ19 co2Sensor;
// Objekt für die Kommunikation mit dem Sensor.
// Verbine Arduino RX mit MH-Z19B TX und 
// Arduino TX mit MH-Z19B RX.
SoftwareSerial co2Serial(MHZ_TX_PIN, MHZ_RX_PIN);

void setup() {
  // Starte serielle Schnittstelle zur Kommunikation mit dem Arduino
  Serial.begin(9600);
  // Starte Kommunikationsschnittstelle für den Co2 Sensor
  co2Serial.begin(9600);
  // Starte den Sensor mit der Kommunikationsschnittstelle
  co2Sensor.begin(co2Serial);
  // Schalte automatische Kalibration ab
  co2Sensor.autoCalibration(false);

  // Gebe dem Sensor Zeit zu starten (30 Sekunden).
  delay(30000);
}

void loop() {
  // Hole den CO_2 Gehalt in ppm vom Sensor
  int co2Gehalt = co2Sensor.getCO2();

  // Gebe diesen Wert zur Kontrolle über die Serielleschnittstelle aus
  Serial.println(co2Gehalt);

  // Gebe dem Sensor Zeit neue Werte zu messen
  delay(1000);
}

Werte als Graph darstellen

Mit dem Seriellen Plotter den man in der Arduino IDE unter Werkzeuge findet, lassen sich die Werte auch einfach als Graph darstellen.

Sensor kalibieren

Wenn man mehrere Sensoren verwendet sieht man, dass die nicht immer die gleichen Werte anzeigen. Dies liegt meistens daran, dass die Sensoren nicht perfekt kalibriert sind. Es gibt zwei verschiedene Möglichkeiten den Sensor zu kalibrieren.

In Software

Nur den Sensor mit dem Arduino verbinden. Danach den Code aus der kalibrierung.zip auf den Arduino hochladen. Den Arduino danach mit dem Sensor eine ca. 400ppm CO2 Umgebung legen (z.B. draußen) und 20 Minuten warten. Nach dieser Zeit sollte im seriellen Monitor die Meldung Sensor kann nun entfernt werden. zu sehen sein. Danach kann der Arduino vom Strom getrennt werden und entweder ein anderer Sensor zum kalibieren angeschlossen werden oder der Arduino wieder mit dem alten Code bespielt werden, falls keine Kalibrierungen mehr durchgeführt werden sollen.

In Hardware

Wenn kein neuer Code auf den Arduino hochgeladen werden soll, kann der Sensor auch nur mit Hardware kalibriert werden.

  1. Den Sensor normal anschließen und ein extra MW-Kabel an HD vom MZ-19B anschließen.
  2. Den Sensor in eine Umgebung mit ca. 400ppm CO2 legen (z.B. nach draußen).
  3. Den Sensor mindestens 20min Werte messen lassen. Diese Werte sollten ab einem Zeitpunkt fast konstant sein.
  4. Das Kabel was mit HD verbunden ist für 7 Sekunden in einen GND des Arduinos stecken und danach wieder entfernen.
  5. Nun ist der Sensor kalibriert und die Werte des Sensors sollten bei ca. 400ppm sein.

Aufgaben

Beschreibe, was der Code tut!

Der Arduino holt sich die Daten vom CO2-Sensor und speichert sie in der Variable co2Gehalt. Anschließend wird der Gehalt über die serielle Schnittstelle ausgegeben.

Häufige Fragen und Probleme

Sensor reagiert nicht sofort auf Änderungen.

Der Sensor misst nur alle paar Sekunden und rechnet mit Durschnittswerten. Daher kann es sein, dass wenn man in den Sensor z.B. pustet sich der Wert erst einige Zeit später ändert.

Der Sensor gibt nach dem Anschalten falsche Werte.

Das ist normal, nachdem der Sensor startet braucht er ein bisschen Zeit, bis er richtige Ergebnisse liefert. Daher warten wir auch im Code am Anfang 30 Sekunden. Wenn (noch) keine Verbindung zum Sensor besteht, wird eine 0 als Wert zurück gegeben. Sonst startet er bei 5000 und geht dann zum richtigen runter. Nach 3-4 Minuten sollte er die richtigen Werte anzeigen.

!Error: Timed out waiting for response oder nur 0 als Ausgabe

Wenn der Sensor richtig verkabelt ist, sollte dir dieser in regelmäßigen Abständen leicht rot blinken. Wenn dies nicht der Fall ist, nochmal die Verkabelung prüfen und den Arduino vom Strom trennen und nochmal verbinden.

Wo finde ich mehr Informationen zum MH-Z19B?

Helligkeitssensor

Beschreibung

Der Helligkeitssensor ist ein Sensor, der Lichtintensität misst. Dazu wird ein Fotowiderstand genutzt, der die Lichtintensität für den Arduino in Zahlen zwischen 0 (hell) und 1023 (dunkel) übersetzt. Der Fotowiderstand übernimmt hierbei die Hauptaufgabe, denn er besitzt einen variablen Widerstand, der abhängig von der Helligkeit ist, die ihn umgibt. Diese Variable kann ausgelesen, in Daten umgewandelt und schlussendlich wiedergegeben werden.
Der Fotowiderstand ist bei der MH-Sensor-Series auf einer Art “Basis-Platine” befestigt, welche auch bei anderen Sensoren benutzt wird. Im Gegensatz zum Hindernissensor benötigt der Helligkeitssensor kein Potentiometer. Es empfiehlt sich, dieses so weit nach links zu drehen, bis die entsprechende LED aus geht, um Licht zu vermeiden, welches das Messergebnis verfälschen könnte.
Darüber hinaus besitzt der Helligkeitssensor 4 Pin-Anschlüsse. Vcc und Gnd für die Stromversorgung und dann noch DO und AO. DO steht für “digital output” und dieser liefert nur einen von zwei Werten: eine “0” für “hell” oder eine “1” für “dunkel”. Viel interessanter ist der “analog output” AO. Dieser liefert nämlich insgesamt 1024 Zahlenwerte von “0” bis “1023” und erlaubt uns also, auch verschiedene Helligkeitsstufen zu erkennen. Als Anzeige verwenden wir den seriellen Monitor.

Verkabelung

HelligkeitssensorArduino
GNDGND
Vcc5V
AOAnalog In (A0-A5)
Schaltplan

Schaltplan

Code

Mithilfe des Programms lässt sich der aktuelle Helligkeitswert als Zahl im seriellen Monitor wiedergeben.

int sensor = A0;  // Bestimme den Analogen Pin A5 als Anschluss für den Sensor

void setup() {
  Serial.begin(9600);  // Beginne die Kommunikation mit dem seriellen Monitor
  pinMode(sensor, INPUT);  // Definiere den Sensor als Input
}

void loop() {
  Serial.println(analogRead(sensor));  // Lies den Wert des Sensors aus
                                       // und drucke diesen im seriellen Monitor
}

Aufgaben

Beschreibe, was der Code tut!

Der Arduino wartet auf Daten vom Helligkeitssensor und zeigt diese dann auf dem seriellen Monitor an.

Teste den Sensor selbst, indem Du die Messwerte mit Licht und denen bei Dunkelheit vergleichst, was ist das Ergebnis?

Aufgaben

Beschreibe, was der Code tut!

Der Arduino wartet auf Daten vom Helligkeitssensor und zeigt diese dann auf dem seriellen Monitor an.

Teste den Sensor selbst, indem Du die Messwerte mit Licht und denen bei Dunkelheit vergleichst, was ist das Ergebnis?

Häufige Fragen und Probleme

Mein Sensor zeigt nur eine 0 oder 1 bzw. Zahlen zwischen 280 und 300.

Achte darauf, dass du den analogen Output des Sensors mit einem Analogen Pin des Arduinos verbunden hast und dass du im Code analogRead benutzt und nicht digitalRead.

Mein Sensor reagiert nicht auf Licht.

Achte hierbei auf die richtige Verkabelung und darauf, dass du im Code analogRead benutzt und nicht digitalRead. Sollte es dann immer noch nicht klappen gucke dir den Fotowiderstand genauer an und vor allem die Lötstellen.

  • Sind diese vielleicht schlecht gelötet, so dass kein Strom fließen kann?
  • Erkennst du vielleicht Beschädigungen am Fotowiderstand?

Ich erreiche nie den Maximalwert für Dunkelheit von 1023.

Damit du das Spektrum von 0 bis 1023 voll ausnutzen kannst, musst du den Fotowiderstand möglichst von allen unerwünschten Lichtquellen fernhalten. Hierbei gilt es auch zu beachten, dass der Fotowiderstand nicht nur von oben auf Licht reagiert, sondern auch von unten und von der Seite. Um die Seiteneffekte einzudämmen, kannst du ein schwarzes oder dunkles Tape nehmen und einen kleinen Streifen davon vorsichtig um den Fotowiderstand kleben. Achte hierbei darauf, dass du den Widerstand nicht versehentlich von oben abklebst. Anschließend kannst du auch noch die kleine grüne LED abkleben, die sich direkt über den Anschlüssen auf dem Sensor befindet.

Ich möchte den seriellen Monitor durch einen anderen Aktor ersetzen.

Wenn du einen Aktor einbauen willst, der abhängig vom Sensor agiert, dann brauchst du dir lediglich das passende Arbeitsblatt für den gewünschten Aktor zu holen und ersetzt dort, wo ein Zahlenwert gefragt ist, den Code durch das dir nun bekannte analogRead() vom Helligkeitssensor.

Aufgepasst!: Der Helligkeitssensor gibt Zahlen zwischen 0 und 1023 aus. Nicht jeder Aktor arbeitet auch mit dieser Spanne. Ein Servomotor arbeitet zum Beispiel nur mit Zahlen zischen 0 und 180. Achte darauf, dass du dann vorher eine Skalierung in den Code einbaust, damit du Werte zwischen 0 und 180 hast. Hierfür kannst du eine weitere Variable nehmen, die du zu Beginn des Codes auf 0 setzt und dann später Beispielsweise wert = analogRead(sensor)/ 5; schreibst. So legst du fest, dass die maximale Zahl nicht mehr 1023 ist, sondern 1023/5, also gerundet 204.

Infrarotfernbedienung und -sensor

Beschreibung

Der Infrarotsensor zusammen mit einer Infrarotfernbedienung dient dazu, den Arduino aus einigen Metern Entfernung zu steuern. Die eingesetzte infrarote Strahlung liegt dabei knapp außerhalb des für Menschen sichtbaren Spektrums.

Unterschiedliche Fernbedienungs-Modelle senden dabei unterschiedliche Signale aus. Die nicht gerade leichte Entschlüsselung dieser Signale wird glücklicherweise von der Bibliothek “IRremote” übernommen, sodass die Nutzung eines Infrarotsensors sehr einfach ist (siehe Bibliotheken einbinden).

Verkabelung

ArduinoLEDInfrarotsensor
13langes Bein
5VPlus
GNDMinus
9out
Schaltplan

Schaltplan

Code

Der Arduino wird wie oben beschrieben aufgebaut und dann wird der unten stehende Code hochgeladen.

Da jede Fernbedienung andere Knöpfe hat und unterschiedliche Signale sendet, müssen wir mit dem seriellen Monitor herausfinden, welchen Zahlencode die verschiedenen Knöpfe der Fernbedienung liefern. Dazu wird der serielle Monitor mit der Lupe Lupe geöffnet. Drückt man nun Knöpfe auf der Infrarotfernbedienung, so sollte die im Infrarotsensor eingebaute LED aufleuchten und zehnstellige Zahlen auf dem seriellen Monitor erscheinen. Drückt man denselben Knopf auf der Fernbedienung, so sollte auch dieselbe Zahl auf dem seriellen Monitor erscheinen.

Achtung!

Es kann sein, dass zwei verschiedene Zahlen beim mehrfachen Drücken desselben Knopfes erscheinen, etwa wenn man den Knopf mal länger und mal kürzer drückt. Man sollte dann die Zahl nehmen, die am häufigsten auftaucht.

Nun sollte man sich die Zahlen notieren, welche zu den Knöpfen gehören, mit welchen man den Arduino später steuern möchte. Diese kann man auch mit der Tastenkombination STRG+C kopieren, nachdem man die Zahl mit der Maus markiert hat. Mit STRG+V fügt man diese an anderer Stelle ein. In diesem Beispiel nutzen wir die Zahlen für die Variablen INFRAROT_SIGNAL_AN und INFRAROT_SIGNAL_AUS im folgenden Programm:

// Skript zum Steuern einer LED mithilfe des Infrarot-Sensors.

// Binde die Bibliothek "IRremote" ein.
#include <IRremote.h>

int irPin  = 9;
int ledPin = 13;

// Erstelle ein Objekt vom Typ IRrecv für den Pin namens irPin.
IRrecv infrarot_empfaenger(irPin);
// Erstelle ein Objekt vom Typ decode_results zum Speichern der empfangenen
// Signale.
decode_results signale;

// Ersetze diese Zahlen mit denen des seriellen Monitors.
long INFRAROT_SIGNAL_AN  = 3772784863;
long INFRAROT_SIGNAL_AUS = 3772817503;

void setup() {
  // Erlaube es, dass Infrarot-Signale empfangen werden können.
  infrarot_empfaenger.enableIRIn();
  pinMode(ledPin, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  // Die Methode decode() gibt TRUE zurück, falls der Funktionsaufruf korrekt
  // ausgeführt wurde, also das Signal dekodiert werden konnte. &signale ist die
  // Adresse des Objektes signale im physischen Speicher des Arduinos.
  if (infrarot_empfaenger.decode(&signale)) {
    Serial.println(signale.value, DEC);
    // Entspricht das empfangene Signal dem an-Knopf?
    if (signale.value == INFRAROT_SIGNAL_AN) {
      // Schalte die LED ein.
      digitalWrite(ledPin, HIGH);
      // Entspricht das empfangene Signal dem aus-Knopf?
    } else if (signale.value == INFRAROT_SIGNAL_AUS) {
      // Schalte die LED aus.
      digitalWrite(ledPin, LOW);
    }
    // Erlaube es, dass weitere Infrarot-Signale empfangen werden können.
    infrarot_empfaenger.resume();
  }
}

Dieses Programm empfängt durch den Infrarotsensor Signale. Entsprechen die Signale dem Drücken der jeweiligen Knöpfe auf der Infrarotfernbedienung, so wird die LED an- oder ausgeschaltet.

Für den Einsatz eines Infrarotsensors sind der Phantasie keine Grenzen gesetzt. Beispielsweise lassen sich hiermit mit einer Fernbedienung für den Fernseher gleichzeitig die Lautstärke und die Helligkeit einer LED regeln, wenn man mithilfe eines Potentiometers den Widerstand des Stromkreises steuert.

Aufgaben

Überlege dir, was man mit einem Arduino und einem Infrarotsensor steuern könnte!

Versuche herauszufinden, aus welcher Entfernung du den Arduino mit deiner Fernbedienung steuern kannst.

Versuche herauszufinden, in welchem Winkel die Fernbedienung maximal zum Sensor gehalten werden darf, damit dieser noch die Signale emfängt.

Versuche herauszufinden, durch welche Materialien das infrarote Licht geblockt wird (z.B. Glas, durchsichtige Folien in verschiedenen Farben, Papier, Pappe, Metal usw.).

Stelle ein Hindernis zwischen dem Sensor und der Fernbedienung auf und versuche den Arduino mit Hilfe eines Spiegels zu steuern. Funktioniert das?

Wie könnte man das Programm abändern, sodass man mit nur einem Knopf die LED an- und ausschalten kann?

Man könnte sich mithilfe einer Variablen merken, ob die LED bereits an ist, und je nachdem sie ein- oder ausschalten.

// Skript zum Steuern einer LED mithilfe des Infrarot-Sensors.

// Binde die Bibliothek "IRremote" ein.
#include <IRremote.h>
int irPin  = 9;
int ledPin = 13;

// Erstelle ein Objekt vom Typ IRrecv für den Pin namens irPin.
IRrecv infrarot_empfaenger(irPin);
// Erstelle ein Objekt vom Typ decode_results zum Speichern der empfangenen
// Signale.
decode_results signale;

// Ersetze diese Zahl mit der des seriellen Monitors.
long INFRAROT_SIGNAL = 3772784863;

// Zum Abspeichern, ob die LED an oder aus ist.
bool ledIsOn = False;

void setup() {
  // Erlaube es, dass Infrarot-Signale empfangen werden können.
  infrarot_empfaenger.enableIRIn();
  pinMode(ledPin, OUTPUT);
  // Initialisiere den seriellen Monitor (mit 9600 Bits pro Sekunde).
  Serial.begin(9600);
}

void loop() {
  // Die Methode decode() gibt TRUE zurück, falls der Funktionsaufruf korrekt
  // ausgeführt wurde, also das Signal dekodiert werden konnte. &signale ist die
  // Adresse des Objektes signale im physischen Speicher des Arduinos.
  if (infrarot_empfaenger.decode(&signale)) {
    Serial.println(signale.value, DEC);
    // Entspricht das empfangene Signal dem an-Knopf?
    if (signale.value == INFRAROT_SIGNAL) {
      // Ist die LED bereits an?
      if (ledIsOn) {
        // Falls ja, schalte sie aus.
        digitalWrite(ledPin, LOW);
      } else {
        // Falls nein, schalte sie an.
        digitalWrite(ledPin, HIGH);
      }
      // Setze den Wert auf das Gegenteil (True -> False oder False -> True).
      ledIsOn = !ledIsOn;
    }
    // Erlaube es, dass weitere Infrarot-Signale empfangen werden können.
    infrarot_empfaenger.resume();
  }
}

Schließe mehrere, verschiedenfarbige LEDs an den Arduino an und programmiere die Fernbedienung so, dass du jede einzeln an- und ausschalten kannst. Programmiere dann eine Taste, mit der du alle an- oder ausschalten kannst.

Programmiere eine Taste deiner Fernbedienung so, dass die LED drei mal blinkt. Dann programmiere zwei weiter Tasten so, dass du mit diesen einstellen kannst, wie schnell die LED beim Drücken der ersten Taste blinkt (schneller oder langsamer).

Häufige Fragen und Probleme

Warum funktioniert mein Infrarotsensor nicht?

  • Falls die eingebaute LED des Infrarotsensors nicht leuchtet, ist dieser vermutlich beschädigt (Achtung: Es könnte Modelle ohne interne LED geben). Da diese Sensoren günstig sind, ist es sinnvoll, mehrere zu bestellen.
  • Sind in der Fernbedienung geladene Batterien?
  • Ist die Verkabelung richtig?
  • Kommen die richtigen Signale an? Mithilfe des seriellen Monitors lässt sich dies überprüfen.

Muss die Fernbedienung direkten “Sichtkontakt” mit dem Infrarotsensor haben?

Nein, denn die meisten Flächen reflektieren die infrarote Strehlung, sodass man den Arduino theoretisch auch um die Ecke steuern kann.

Kann man infrarotes Licht sehen?

Infrarot hat eine Wellenlänge von 780 nm bis 1 mm. Das menschliche Auge kann Wellenlängen von etwa 380 nm bis 780 nm wahrnehmen. Daher ist infrarotes Licht im Allgemeinen unsichtbar für den Menschen. Auch für die meisten Haustiere ist infrarotes Licht unsichtbar. Einige Schlangen, Fische und Insekten hingegen können infrarotes Licht wahrnehmen.

Infrarothindernissensor

Beschreibung

Der Infrarotsensor “Flying fish” ist ein Hindernissensor. Das bedeutet, er kann mithilfe einer Infrarot-LED und einer Photodiode wahrnehmen, wenn sich ein Hindernis in einem gewissen Bereich vor ihm befindet. Die Infrarot-LED sendet hierbei ein Infrarotsignal aus, welches von einem Gegenstand reflektiert und von der Photodiode wieder aufgefangen wird. Der Sensor verfügt darüber hinaus noch über zwei kleine grüne LED’s. Die LED, die sich über dem “Vcc” Pin befindet zeigt an, ob der Sensor mit Strom versorgt wird. Die LED, die sich über dem “Out” Pin befindet leuchtet auf, wenn der Sensor einen Gegenstand wahrnimmt. Auf dem Sensor befindet sich ein Potentiometer, welches genutzt wird, um die Reichweite des Sensors einzustellen. Laut Spezifikation erkennt der Sensor Hindernisse zwischen 2-30 cm. Da der Sensor nur über einen digitalen Input verfügt, können wir lediglich anzeigen lassen, ob sich ein Gegenstand in der eingestellten Reichweite befindet, aber nicht wie weit dieser entfernt ist.

Verkabelung

IR-SensorArduino
GNDGND
Vcc5V
OUT8
Schaltplan

Schaltplan

Code

Mithilfe des Programms kann man beispielhaft eine LED aufleuchten lassen, wenn der IR-Sensor ein Hindernis wahrnimmt.

int IR_SENSOR = 8;   // Setze den Pin 8 als Anschluss für den Sensor
int LED       = 13;  // Setze den Pin 13 als Anschluss für die LED

void setup() {
  pinMode(IR_SENSOR, INPUT);  // Setze den Sensor-Pin als INPUT, da dieser ein
                              // Signal an den Arduino senden soll
  pinMode(LED, OUTPUT);       // Setze die LED als OUTPUT
}

void loop() {
  if (digitalRead(IR_SENSOR) == 0) {  // Auslesen, ob IR-Sensor das Signal gibt,
                                      // dass ein Hindernis vor ihm ist
    digitalWrite(LED, HIGH);  // Wenn ja, soll die LED leuchten
  } else {
    digitalWrite(LED, LOW);  // Wenn nicht, soll die LED nicht leuchten
  }
}

Aufgaben

Beschreibe, was der Code tut!

Der Arduino bekommt den IR-Sensor als Inout und die LED als Output im Setup gesetzt. In der Loop wird geprüft, ob der Infrarotsensor ein Hindernis vor sich hat, dann leuchte die LED, wenn nicht bleibt die LED aus.

Wie funktioniert ein Infrarotsensor?

Siehe in die Beschreibung.

Baut den Code so um, dass wenn der Sensor ein Hindernis entdeckt eine rote LED leuchtet, und bei freier Bahn eine grüne.

int IR_SENSOR = 8;   // Setze den Pin 8 als Anschluss für den Sensor
int LED_rot   = 13;  // Setze den Pin 13 als Anschluss für die LED bei Hindernis
int LED_grün  = 12;  // Setze den Pin 12 als Anschluss für die LED bei freier Bahn

void setup() {
  pinMode(IR_SENSOR, INPUT);  // Setze den Sensor-Pin als INPUT, da dieser ein
                              // Signal an den Arduino senden soll
  pinMode(LED, OUTPUT);       // Setze die LED als OUTPUT
}

void loop() {
  if (digitalRead(IR_SENSOR) == 0) {  // Auslesen, ob IR-Sensor das Signal gibt,
                                      // dass ein Hindernis vor ihm ist
    digitalWrite(LED_rot, HIGH);  // Wenn ja, soll die LED leuchten
  } else {
    digitalWrite(LED_grün, HIGH);  // Wenn nicht, soll die LED nicht leuchten
  }
}

Häufige Fragen und Probleme

Der Infrarotsensor sieht nicht weit genug/ sieht zu weit!

Das Potentiometer kann mit einem kleinen Kreuzschraubenzieher eingestellt werden. Nach rechts drehen steigert die Entfernung, bis ein Objekt wahrgenommen wird. Nach links drehen verringert die Entfernung.

Der Infrarotsensor leuchtet auf, bevor ein Objekt vor ihm ist.

Da der IR-Sensor mit einer IR-LED und Reflexion arbeitet, kann es zu Störungen von außen kommen. Zum einen spielt bei Reflexion von Wellen immer die Farbe des Objektes eine Rolle, von dem reflektiert wird. Das bedeutet, dass wenn gegenüber von dem Sensor eine helle Wand ist, er diese, abhängig vom Licht, ebenfalls als Objekt wahrnehmen kann. Es empfiehlt sich, einen schwarzen Hintergrund zu wählen. Ebenso kann es vorkommen, dass die IR-LED streut und so eine unerwünschte Reflexion das Signal auslöst. Um dies zu verhindern, kann um die beiden Dioden seitlich ein schwarzes Tape gebunden werden, so dass es nach vorne hin offen ist. Der Sensor sollte dabei eingeschaltet sein, um zu verhindern, dass das Tape zu weit vorne angebracht wird und der Sensor das Tape als Hindernis erkennt.

Der Sensor leuchtet, aber die angeschlossene LED nicht.

Es ist darauf zu achten, dass die LED als Output und der Sensor als Input festgelegt ist. Der Sensor soll ein Signal an den Arduino senden und dieser wiederum an die LED.

Konkretes Problem zwischen Potentiometer und Entfernung.

Der Verkäufer sichert eine Reichweite zwischen 2cm und 30 cm zu. Diese ist nicht realistisch. Beim Kalibrieren des Sensors kann es zu einigen Komplikationen kommen, die dazu führen, dass der Sensor automatisch aufleuchtet, sobald man das Potentiometer bis zu einem gewissen Punkt nach rechts dreht. Wenn man nun das Potentiometer wieder so weit zurück dreht, dass der Sensor geradeso nicht aufleuchtet, fällt einem auf, dass die Reichweite dann weit unter dem Maximum liegt. Dies ergibt sich aus den bereits angesprochenen Problemen der Reflexion und der Bauweise des Sensors und lässt sich nur bis zu einem gewissen Punkt verhindern. Daher gilt es, bei diesem Sensor auszuprobieren, unter welchen Bedingungen das beste und leicht replizierbare Ergebnis erzielt werden kann.

Die angeschlossene LED als Feedbacksignal ersetzen.

Wenn das visuelle Feedback z.B. durch ein LCD-Display ersetzt werden soll, lässt sich dieses ganz einfach umsetzen. Einfach nochmal das Material für das Display anschauen und es wie gewohnt anschließen. Danach den Code für den IR-Sensor um den Code bis zu dem Loop für das LCD-Display ergänzen. Im Loop dann klar machen, wann das LCD Display etwas anzeigen soll und unter welcher Bedingung. Anschließend die passenden Zeilen im Code ergänzen und gegebenenfalls etwas umschreiben.

LED ansteuern

Beschreibung

Die LED (light-emitting diode) ist ein elektrisches Bauteil, welches aufleuchtet, wenn ein elektrischer Strom in Durchlassrichtung fließt. Eine LED besitzt in der Regel zwei Beinchen. Das lange Bein ist die Anode und der Pluspol. Hier soll der Strom rein fließen, der von einer Stromquelle kommt. Das kurze Bein der LED ist die Kathode und der Minuspol. Hier soll der Strom raus und in den Ground fließen.

LED Aufbau

LED Aufbau

Verkabelung

Um die LED richtig mit dem Arduino Board zu verbinden, muss die Anode mit einem Pin und die Kathode mit einem Ground verbunden sein. Dies kann geschehen, in dem man die Beine der LED direkt in die Pin-Anschlüsse des Arduinos setzt. Ebenso aber auch, indem man noch weitere Kabel oder ein Steckbrett zwischenschaltet. Die Hauptsache ist, dass die LED richtig herum an den Stromkreis angeschlossen wird.

Schaltplan LED

Schaltplan LED

Code

//  Der Pin Nr. 13 heißt von nun an LED
int LED = 13;

void setup() {
  // Der Pin LED soll ein Signal erhalten können (hier Strom). Er fungiert als
  // Akteur.
  pinMode(LED, OUTPUT);
}

void loop() {
  // Der Pin LED erhält das Signal, dass dort Strom fließen soll.
  digitalWrite(LED, HIGH);

  // Das Programm und das System verweilen in ihrem aktuellen Zustand für
  // 1000ms.
  delay(1000);

  // Der Pin LED erhält das Signal, dass dort kein Strom fließen soll.
  digitalWrite(LED, LOW);

  // Das Programm und das System verweilen in ihrem aktuellen Zustand für
  // 1000ms.
  delay(1000);
}

Der gezeigte Code lässt eine LED, die an den Pin 13 und den Ground angeschlossen ist, für 1 s = 1000 ms aufleuchten und für 1000 ms aus sein. Hierfür wird zunächst bestimmt, dass die LED an Pin 13 ist, und dieser von nun an im Code mit LED beschrieben werden kann.
Im void setup wird bestimmt, ob es sich bei der LED um einen Eingang oder einen Ausgang für ein Signal handelt. Da die LED ein Akteur ist, sie also auf ein Signal wartet und entsprechend des Signals agiert, muss sie als Ausgang bestimmt werden.
Im void loop wird dann der sich zu wiederholende Code geschrieben. Dieser soll in diesem Fall der LED für 1000 ms das ein Signal in Form eines Stromflusses geben und anschließend für 1000 ms dieses wieder Stromfluss unterbrechen. Der void loop wiederholt sich so lange wie eine Spannungsquelle an den Arduino angeschlossen ist.

Hochladen des Programms auf den Arduino

  • Der Arduino wird mit dem USB Kabel am Rechner verbunden.
  • WICHTIG: Wähle unter “Werkzeuge >> PORT” den COMX mit der höchsten Zahl aus (das ist der angeschlossene Arduino).
  • Jetzt wird der Code auf den Arduino hochgeladen, indem man auf drückt. Dabei ist darauf zu achten, dass nicht gleichzeitig die Batterie am Arduino angeschlossen ist.

Aufgaben

Welches der Beine ist die Kathode und welches die Anode?

Bei der LED ist das lange Bein die Anode und das kurze Bein die Kathode.

Woran wird die Kathode und woran die Anode angeschlossen?

Kathode ist der Minuspol und wird also an GND angeschlossen, die Anode ist der Pluspol und wird an einen Pin angeschlossen.

Baut den Code so um, dass die LED 5 Sekunden leuchtet und 2 Sekunden aus ist.

//  Der Pin Nr. 13 heißt von nun an LED
int LED = 13;

void setup() {
  // Der Pin LED soll ein Signal erhalten können (hier Strom). Er fungiert als
  // Akteur.
  pinMode(LED, OUTPUT);
}

void loop() {
  // Der Pin LED erhält das Signal, dass dort Strom fließen soll.
  digitalWrite(LED, HIGH);

  // Das Programm und das System verweilen in ihrem aktuellen Zustand für
  // 5000ms.
  delay(5000);

  // Der Pin LED erhält das Signal, dass dort kein Strom fließen soll.
  digitalWrite(LED, LOW);

  // Das Programm und das System verweilen in ihrem aktuellen Zustand für
  // 2000ms.
  delay(2000);
}

Luftfeuchtigkeitssensor

Beschreibung

Dieses Arbeitsblatt beschreibt den Aufbau einer einfachen Messstation für den Luftfeuchtigkeitssensor AM2302. Die Messwerte können direkt über den seriellen Monitor in der Arduino IDE abgelesen werden. Der Sensor eignet sich perfekt, um die Luftfeuchtigkeit und gleichzeitig auch die Temperatur eines Ökosystems zu ermitteln.

Hinweis!

Der Sensor kann zwar etwas Luftfeuchtigkeit ab, sollte jedoch nicht in zu feuchten Umgebungen benutzt werden, weil es offenen Kabel- und Arduino-Schnittstellen gibt. Es kann zu Geräte- und Personenschäden kommen.

Verkabelung

SensorArduinoSonstiges
+5VÜber Breadboard
-GNDÜber Breadboard
out2
Schaltplan

Schaltplan

Code

Achtung!

Sollte der Sensor merkwürdige Ergebnisse ausgeben, definiere im Code statt #define DHTTYPE DHT22 einfach #define DHTTYPE DHT11. Der DHT11 ist ein Alternativsensor.

#include "DHT.h"      // DHT-Bibliothek von Adafruit einbinden.
#define DHTTYPE DHT22 // Sensortyp wird festgelegt.
                      // Es handelt sich hier um den DHT22 Sensor.
int DHT_PIN = 2;      // Der Sensor wird an PIN 2 angeschlossen.

// Objekt des DHT-Sensors.
DHT dht(DHT_PIN, DHTTYPE);  // Der Sensor wird ab jetzt mit „dth“ angesprochen.

void setup() {
  // Starte serielle Schnittstelle zur Kommunikation mit dem Arduino.
  Serial.begin(9600);
  // Start des DHT22 Sensors.
  dht.begin();
}

void loop() {
  // Vorlaufzeit bis zur nächsten Messung.
  delay(4000);

  // Die Luftfeuchtigkeit wird vom Sensor ausgelesen...
  // ... und in der Variable "Luftfeuchtigkeit" gespeichert.
  float luftfeuchtigkeit = dht.readHumidity();
  // Die Temperatur wird vom Sensor ausgelesen...
  // ... und in der Variable "Temperatur" gespeichert.
  float temperatur = dht.readTemperature();

  // Auf dem seriellen Monitor können nun die Beschriftungen...
  // ... und die dazugehörigen Werte angezeigt werden.
  Serial.print("Luftfeuchtigkeit: ");  // Luftfeuchtigkeit in Prozent.
  Serial.print(luftfeuchtigkeit);
  Serial.println(" %");
  Serial.print("Temperatur: ");  // Temperatur in Grad Celsius.
  Serial.print(temperatur);
  Serial.println(" Grad Celsius");
}

Aufgaben

Messe mit dem Gerät die Temperatur im Raum.

Die Raumtemperatur liegt zwischen 19 und 23 Grad Celsius.

Messe die Luftfeuchtigkeit im Raum.

Die Luftfeuchtigkeit liegt zwischen 40 und 60 Prozent.

Gehe nun nach draußen bzw. halte das Gerät für einige Minuten aus dem Fenster. Wie ändert sich die Temperatur und die Luftfeuchtigkeit?

Häufige Fragen und Probleme

Was kann ich tun, wenn mein Sensor falsche Werte anzeigt?

  • Prüfe zunächst, ob du den Sensor richtig verkabelt hast und alle Kabel richtig drinstecken.
  • Der Sensor benötigt etwas Zeit, um die richtige Temperatur bzw. Luftfeuchtigkeit zu messen. Für exaktere Messwerte warte ein paar Minuten.

Motoren - Rückwärts fahren

Beschreibung

Damit unser Roboter auf der Stelle wenden kann, wollen wir ihm beibringen rückwärts zu fahren. Dazu betrachten wir zuerst unsere verwendeten Motoren.

Der Motor hat zwei verschiedene Stromanschlüsse. Wenn du diese mit dem Plus- und Minuspol einer Batterie verbindest, dreht sich der Motor. Wenn du die Kabel vertauscht, so dreht der Motor in die andere Richtung!

Die Drehrichtung des Motors lässt sich durch das passende Anlegen der Spannung steuern. Wie können wir diesen “Kabeltausch” nun durch Programmcode umsetzen?

Motor mit Getriebe

Motor mit Getriebe

  • Wir ersetzen den Ground (GND) Anschluss durch einen zweiten Pin -> beide Motorpins in einen Digital I/O Pin stecken (1 - 13).

  • Wir müssen zwei Variablen (int) für den Motor anlegen (vorwärts und rückwärts) und im void setup als OUTPUT einstellen.

  • Den Ground ersetzen wir nun durch einen Pin der LOW geschaltet wird. Der andere Pin wird HIGH geschaltet.

Je nachdem welcher Pin auf HIGH und welcher jetzt auf LOW geschaltet wird dreht sich der Motor rückwärts oder vorwärts

Tipp: Sprechende Namen

Gib deinen Variablen sprechende Namen! Man sollte an den Namen direkt die Funktion und Position des angeschlossenen Geräts erkennen. Zum Beispiel:

  • guter Name: motorLinksVorwaerts oder motleftforward oder kurz: mlv
  • schlechter Name: motor1

Verkabelung

Schaltplan

Schaltplan

Code

In diesem Code wird der Motor wie im Schaltplan angeschlossen.

// Pin 11 bekommt den Namen mlv für motor links vorwärts.
// Pin 10 mlr für motor links rückwärts

int mlv = 11;
int mlr = 10;

void setup() {
  pinMode(mlv, OUTPUT);
  pinMode(mlr, OUTPUT);
}

void loop() {
  // Vorwärts fahren
  digitalWrite(mlv, HIGH);
  digitalWrite(mlr, LOW);

  delay(5000);

  // Rückwärts fahren
  digitalWrite(mlv, LOW);
  digitalWrite(mlr, HIGH);

  delay(5000);
}

Aufgaben

Beschreibe, wie sich der Motor im obigen Code verhält! Wie musst du die beiden Pins steuern, damit der Motor stoppt?

Der Motor dreht erst 5 Sekunden vorwärts und danach 5 Sekunden rückwärts. Dies wieder holt er immer wieder. Damit der Motor sich nicht mehr dreht müssen die Pins auf LOW gestzt werden.

digitalWrite(mlv, LOW);
digitalWrite(mlr, LOW);

Was passiert, wenn wir beide Pins auf HIGH stellen?

Wenn beide Pins auf HIGH sind dreht sich der Motor nicht. Dies liegt daran, dass an beiden Pins des Motors nun ca. 5V anlegen und damit kein Spannungspotenzial existiert. Dadurch fließt kein Strom durch den Motor.

Der Motor besteht aus Motoranschlüssen, Motor, Getriebe, Antriebswelle. Notiere auf dem Bild, welcher Teil wie heißt.

TODO

Welche neuen Manöver sind jetzt mit deinem Roboter möglich? Setze einige davon um und präsentiere sie!

Es sind folgende Sachen möglich: rückwärts und vorwärts fahren, sich auf der Stelle drehen und links und rechts Kurven machen. TODO: Code Beispiel

Häufige Fragen und Probleme

Der Motor fährt vorwärts, wenn er rückwärts fahren soll und das Gleiche passiert anders herum.

Der Motor ist falsch herum angeschlossen. Einfach die Pin-Belegung der Motoren tauschen.

Pulsmessung mit dem seriellen Plotter

Beschreibung

Der Pulse Sensor dient dazu seine Herzfrequenz mithilfe des Serial-Plotters in der Arduino-Software darzustellen. Die Messwerte liegen im Bereich 500-530, sodass der Herzschlag zwischen 515 und 525 gut abzulesen sind. Die leuchtende Lampe, mit L bezeichnet unter Pin 13, blinkt im Takt des Herzschlags, sodass man nicht nur auf dem Plotter die graphische Darstellung sieht, sondern auch noch durch die Lampe.

Verkabelung

PulsesensorArduinoSonstiges
-GND
+5V
SA0
Schaltplan

Schaltplan

Code-Beispiel

int SENSOR_PIN = A0;  // Signalleitung an Analog A0 anlegen.
int LED       = 13;  // LED an Port 13 wird verwendet.

// Variable für den Sensworwert im Bereich zwischen 0-1024.
int sensorwert;
// Grenzwert, ab dem die LED an Pin13 später leuchten soll.
int grenzwert = 510;

void setup() {
  // Pin 13 wird als Ausgang deklariert, um den Puls anzuzeigen.
  pinMode(LED, OUTPUT);
  // Serielle Verbindung starten, damit Daten am Seriellen Monitor angezeigt
  // werden können.
  Serial.begin(9600);
}

void loop() {
  // Sensorwert vom Sensor auslesen und unter der Variablen "Sensor"
  // abspeichern.
  sensorwert = analogRead(SENSOR_PIN);
  // Sensorwert über die Serielle Schnittstelle an den PC senden.
  Serial.println(sensorwert);

  if (sensorwert > grenzwert) {  // Es wird geprüft, ob der Sensorwert über dem
                                 // Grenzwert ist. Wenn ja...
    digitalWrite(LED, HIGH);  // ...dann soll die LED zu Deinem Herzschlag
                              // leuchten.
  } else {                    // Ansonsten...
    digitalWrite(LED, LOW);   //  ...ist die LED aus.
  }

  // 10sec Pause für bessere Messwerte.
  delay(10);
}

Aufgaben

Messe deinen Herzschlag im ruhigen Zustand, wie sieht der Graph aus?

Der Graph sollte normal ausschlagen, sodass der Herzschlag zwischen 515 und 525 gut abzulesen ist.

Mache 5 Hampelmänner und messe erneut, wie sieht der Graph nun aus?

Der Graph sollte nun öfter ausschlagen, da sich dein Herzschlag erhöht haben sollte.

Häufige Fragen und Probleme

Meine Werte spielen verrückt und der Graph pendelt komplett aus, was soll ich tun?

  • Man muss aufpassen nicht zu stark auf den Sonser zu drücken beim Messen, sonst kann es passieren, dass er zu sehr ausschaukelt. Im Zweifelsfall einfach den Arduino reseten, danach sollte alles wieder funktionieren.

RFID-Reader

Beschreibung

Der RFID („radio-frequency identification“) Reader wird verwendet, um von RFID Sendern (auch „RFID Tags“ genannt) per Funk einen bestimmten Code auszulesen. Jeder Sender hat dabei eine einmalige ID (UID). Somit können wir den Arduino verwenden, um Schließanlagen oder ähnliche Projekte zu realisieren, bei denen man sich identifizieren soll.

RFID-TAGs können verschiedene Formen haben, wie z.B. Schlüsselanhänger oder Karten im Kreditkartenformat.

Auf dem folgenden Bild sieht man links und rechts zwei RFID-TAGs und in der Mitte den RFID-Empfänger RFID-RC522 mit noch nicht angelöteter Stiftleiste. Es gibt auch Versionen, bei denen die Stiftleiste bereits an den RFID-Empfänger angelötet wurde.

Verkabelung

ArduinoSensorLED
10SDA
13SCK
11MOSI
12MISO
GNDGND
9RST
3.3 V3.3 V
2Langes Bein
Schaltplan

Schaltplan

Code

Es muss eine Library im Arduino Programm hinzugefügt werden. Wir verwenden die Library “MFRC522” von GithubCommunity. Siehe Bibliotheksverwaltung


Zunächst wollen wir die eindeutige ID (UID) unseres RFID TAGS ermitteln. Wir schauen uns einmal mithilfe des folgenden Codes an, wie sie lautet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <MFRC522.h>               // RFID-Bibiothek hinzufügen.
#include <SPI.h>                   // SPI-Bibiothek hinzufügen.
#define SS_PIN 10                  // SDA an Pin 10.
#define RST_PIN 9                  // RST an Pin 9.
MFRC522 mfrc522(SS_PIN, RST_PIN);  // RFID-Empfänger benennen.

void setup() {
  Serial.begin(9600);  // Seriellen Monitor starten.
  SPI.begin();         // SPI-Verbindung aufbauen.
  mfrc522.PCD_Init();  // Initialisierung des RFID-Empfängers.
}

void loop() {
  if (!mfrc522.PICC_IsNewCardPresent()) {  // Wenn kein TAG in Reichweite ist...
    return;  // ...springt das Programm zurück an den Anfang ( zu void loop() )
  }

  if (!mfrc522.PICC_ReadCardSerial()) {  // Wenn kein TAG ausgewählt wurde...
    return;  // ...springt das Programm zurück an den Anfang ( zu void loop() )
  }

  Serial.print("Die ID des RFID-TAGS lautet:");  // Der Text in
                                                 // Anführungsstrichen wird in
                                                 // den Serial Monitor
                                                 // geschrieben.

  for (byte i = 0; i < mfrc522.uid.size; i++) {
    // Dann wird die UID ausgelesen, die aus vier einzelnen Blöcken besteht und
    // der Reihe nach an den Serial Monitor gesendet. Die Endung DEC bedeutet,
    // dass die vier Blöcke der UID als Dezimalzahlen ausgegeben werden, da sie
    // ursprünglich als Hexadezimal Zahl vorliegt. (z.B. F3 F8 A6 0)
    Serial.print(mfrc522.uid.uidByte[i], DEC);
    Serial.print(" ");  // Fügt zwischen die einzelnen Blöcke ein Leerzeichen
                        // ein.
  }
}
Ausgabe des seriellen Monitors.

Ausgabe des seriellen Monitors.

Nun können wir diese ID noch nicht verwenden, da es vier einzelne Zahlenblöcke sind. Daher passen wir den Code etwas an, indem wir einfach alle 4 Blöcke miteinander addieren. Dazu ersetzen wir die Zeilen 27 - 35 mit diesem Code:

27
28
29
30
31
32
33
  int code = 0;  // Diese Variable speichert die UID als zusammenhängende Zahl
                 // ab.
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    code = (code + mfrc522.uid.uidByte[i]);  // Addition der vier Zahlenblöcke.
  }
  Serial.print("Die Kartennummer lautet:");  // Ausgabe des Zahlencodes.
  Serial.println(code);
Ausgabe des seriellen Monitors.

Ausgabe des seriellen Monitors.

Die gewonnene Kennzahl nutzen wir jetzt, um eine LED anzuschalten, wenn der korrekte RFID TAG erkannt wird. Wir ergänzen den Code nach Zeile 33 um die folgenden Zeilen:

  if (code == 396) {
    digitalWrite(2, HIGH);  // ...dann soll die LED an Pin 2 leuchten...
    delay(500);             // für eine halbe Sekunde
    digitalWrite(2, LOW);   // ...und danach wieder aus gehen.
  }

Aufgaben

Beschreibe, was der Code tut!

Die Pins und ein Objekt für den RFID-Empfänger werden gesetzt. Im Setup wird der serielle Monitor gestartet, eine Verbindung aufgebaut und der RFID-Empfänger initialisiert. In der Loop wird getestet ob ein TAG in Reichweite ist und ausgewählt wurde. Die ID des TAGS wird ausgegeben und in vierer Blöcken, der Reihe nach und durch ein Leerzeichen getrennt an den seriellen Monitor gesendet. Zudem wird die Ausgabe des seriellen Moitors addiert, in einen Zahlencode umgewandelt und ausgegeben. Dieser Code wird schließlich zur Steuerung einer LED genutzt.

Was ist ein RFID-Reader und welche Aufgabe hat er?

RFID steht für Radio Frequency Identification. Es wird ein kontaktloser Datenaustausch zwischen einem RFID-Transponder (bei uns der RIFD-RC522) und einem RFID-Schreib-/Lesegerät (hier der Schlüsselnanhänger) ermöglicht. Der Reader hat die Aufgabe verschiedene Objektinformationen z.B. einen Code auszulesen.

RGB-LED

Beschreibung

Eine RGB LED ist eine LED, die in verschiedenen Farben leuchten kann. Sie besteht im Inneren aus drei einzelnen LEDs: einer roten, einer grünen und einer blauen. Da wir jede dieser Farben einzeln steuern können, ist es möglich alle möglichen Farben darzustellen.

Eine RGB LED hat insgesamt 4 Pins. Der längste Pin ist die Kathode(-) oder Anode(+) (Je nach Bautyp der RGB LED) und 3 Pins für die einzelnen Farben.

Verkabelung

Wenn eine gemeinsame Anode (common anode) vorliegt, verkabeln wir:

LEDArduinoSonstiges
längster Pin5V
9rotes Kabel
10grünes Kabel
11blaues Kabel
Schaltplan Common Annode

Schaltplan Common Annode

Achtung

Solltest du andere Pins verwenden wollen, verbinde nur mit Digitalpins, die ein “~” vor der Zahl haben!

Wenn eine gemeinsame Kathode (common cathode) vorliegt, verkabeln wir:

LEDArduinoSonstiges
längster PinGND
9rotes Kabel
10grünes Kabel
11blaues Kabel
Schaltplan Common Cathode

Schaltplan Common Cathode

Achtung

Solltest du andere Pins verwenden wollen, verbinde nur mit Digitalpins, die ein “~” vor der Zahl haben!

Code

Dieser Code lässt die LED nun in verschieden Farben leuchten. analogwrite erlaubt uns, die Leuchtkraft der einzelnen Farben fein einzustellen, indem wir eine eine Zahl zwischen 0 und 255 eingeben.

int red   = 9;
int green = 10;
int blue  = 11;

void setup() {
  pinMode(red, OUTPUT);
  pinMode(green, OUTPUT);
  pinMode(blue, OUTPUT);
}

void loop() {
  analogWrite(red, 255);
  delay(1000);
  analogWrite(green, 255);
  delay(1000);
  analogWrite(blue, 255);
  delay(1000);

  analogWrite(red, 0);
  delay(1000);
  analogWrite(green, 0);
  delay(1000);
  analogWrite(blue, 0);
  delay(1000);
}

Aufgaben

Beschreibe, was der Code tut. In welchen Farben leuchtet die LED? Falls dir die LED zu hell ist, lege ein Taschentuch oder ein gefaltetes Blatt Papier darüber, um die Farben besser zu erkennen.

Ändere die Zahlen ‘0’ und ‘255’ im Code zu anderen Zahlen zwischen ‘0’ und ‘255’. Beschreibe, was passiert, wenn man größere Zahlen wählt!

Je größer die Zahl ist, desto größer ist auch die Leuchtstärke der jeweiligen Farbe.

Ändere die ersten drei Zahlen auf ‘1’ und die letzen drei Zahlen auf ‘227’. Was beobachtest du? Hast du eine Erklärung dafür?

Die LED leuchtet immer in der selben Intensität. Es kommt zu einem Overflow, d.h. es wird wieder von vorne angefangen zu zählen. Die Zahl 256 ist wie eine 0, die Zahl 257 ist eine 1.

Ändere den Code so ab, dass abwechselnd in den Farben deines Lieblingsvereins leuchtet.

Passe die Leuchtintensität an und etnferne einige delays.

Schallsensor

Beschreibung

Im Folgenden messen wir mithilfe eines Schallsensor den Schalldruckpegel für eine gewisse Zeit und berechnen mithilfe der sogenannten diskreten Fourier-Transformation daraus die vorhandenen Frequenzen.

Verkabelung

MF-6402171KabelArduino
A0GelbA0
GSchwarzGND
+Rot5V
D0
Schaltplan

Schaltplan

Code

*/
#include "arduinoFFT.h"

const int SAMPLES = 128;  // SAMPLES-pt FFT. Muss eine Zweierpotenz sein.
                          // Maximal 128 für Arduino Uno.
const int SAMPLING_FREQUENCY = 2048;  // Messwerte je Sekunde. Muss mindestens
                                      // doppelt so hoch wie die höchste
                                      // erwartete Frequenz sein (Stichwort
                                      // Nyquist).

arduinoFFT FFT = arduinoFFT();

unsigned int samplingPeriod;
unsigned long microSeconds;

double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(9600);  // Baudrate für den seriellen Monitor
  samplingPeriod = round(1000000 * (1.0 / SAMPLING_FREQUENCY));  // Periode in Mikrosekunden
  delay(1000);

  // Lese SAMPLES viele Messwerte ein
  for (int i = 0; i < SAMPLES; i++) {
    microSeconds = micros();

    vReal[i] = analogRead(0);  // Lies den Wert des Analog-Pins 0 (A0,
                               // quantisiere ihn und speicher ihn als Realteil.
    vImag[i] = 0;              // Der Imaginärteil ist immer 0.

    // Warte, bis eine Abtastperiode vergangen ist, um sicherzustellen, dass die
    // Werte in gleichmäßigen Abständen gemessen werden.
    while (micros() < (microSeconds + samplingPeriod)) {
      // Tu nichts.
    }
  }

  // Ziehe den Durchschnittswert ab, um die Frequenz 0 zu entfernen.
  // Dies ist optional und kann auch auskommentiert werden.
  double vRealAvg = 0;
  for (int i = 0; i < SAMPLES; i++) {
    vRealAvg = vRealAvg + vReal[i];
  }
  vRealAvg /= SAMPLES;
  for (int i = 0; i < SAMPLES; i++) {
    vReal[i] = vReal[i] - vRealAvg;
  }

  /*
    Führe die schnelle Fourier-Transformation (FFT) auf den samples aus.
    Hierbei werden die alten Messwerte überschrieben.
    Möchte man diese behalten, sollte man aus Speicherplatzgründen nicht den
    Arduino Uno verwenden und die Werte vor der FFT in andere Vektoren
    kopieren.
  */
  FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);

  // Schreibe die Werte auf den seriellen Monitor, um diese in eine csv-Datei
  // kopieren zu können.
  Serial.print("Frequenz;Realteil;Imaginaerteil;Betrag");
  for (int i = 0; i < SAMPLES; i++) {
    Serial.println("");
    Serial.print(1.0 * SAMPLING_FREQUENCY * i / (SAMPLES - 1.0));  // Frequenz
    Serial.print(";");
    Serial.print(vReal[i]);  // Realteil
    Serial.print(";");
    Serial.print(vImag[i]);  // Imaginaerteil
    Serial.print(";");
    Serial.print(sqrt(sq(vReal[i]) + sq(vImag[i])));  // Absolutbetrag der
                                                      // komplexen Zahl Realteil
                                                      // + i*Imaginaerteil
  }
}

void loop() {
  // Tue nichts im loop. Zum erneuten Ausführen muss der Arduino neugestartet
  // werden (roter Knopf).
}

Ablauf

Nachdem der Arduino am Computer und der Schallsensor, wie oben beschrieben, am Arduino angeschlossen ist, öffne den seriellen Monitor und stelle die im Code angegebene Baudrate ein. Es sollten bereits Werte auf dem seriellen Monitor zu sehen sein. Lösche die bisherige Ausgabe. Starte dann den Arduino durch Betätigen des roten Knopfes neu und starte dein Signal, bspw. mithilfe einer Stimmgabel oder von Kopfhörern. Im Setup ist ein delay von einer Sekunde eingebaut, damit man Zeit hat, das Signal zu starten.

Hinweis!

Beachte, dass nur für einen kurzen Zeitraum das Signal aufgenommen wird, da der Speicher des Arduinos sehr schnell voll ist. Bei einer Abtastfrequenz von 2048 Werten je Sekunde und einer Dauer von 128 Abtastungen dauert das Messen nur 62,5 Millisekunden.

Die neuen Werte, die während des Abspielens des Tons aufgenommen wurden, können nun in eine csv-Datei kopiert und anschließend mit Software wie Excel oder R visualisiert werden.

Frequenzspektrum eines 700Hz Signals

Frequenzspektrum eines 700Hz Signals

Grundsätzlich ist auch eine Visualisierung mithilfe des seriellen Plotters der Arduiono IDE möglich. Allerdings ist es in diesem nicht ohne Weiteres möglich, die x-Achse anzupassen, sodass eine Interpretation der Werte schwierig ist.

(Diskrete) Fourier-Transformation

Hinweis!

Die folgende Erklärung kann verwirrend sein, falls du im Unterricht noch keine komplexen Zahlen hattest. Für den Aufbau und den Code ist es aber nicht wichtig, die Mathematik hinter der Fourier-Transformation verstanden zu haben.

Die diskrete (schnelle) Fourier-Transformation (“DFT” für Discrete Fourier Transform bzw. “FFT” für Fast Fourier Transform) ist ein mathematisches Werkzeug, welches ein diskretes, komplexwertiges Signal in seine Frequenzanteile aufspaltet. Intuitiv stellt die DFT das Signal durch eine Summe von Sinus- und Kosinusschwingungen variierender Frequenzen und Amplituden dar. Insbesondere hat ein reines Sinussignal genau eine Frequenz, welche nicht die Amplitude 0 hat. Der Wert dieser DFT ist wieder ein diskretes, komplexwertiges Signal. Mathematisch gesehen wird ein Vektor komplexer Zahlen auf einen weiteren Vektor komplexer Zahlen derselben Länge abgebildet. Da man jede reelle Zahl als komplexe Zahl auffassen kann, die einen Imaginärteil von 0 besitzt, ist die DFT auch für reellwertige Signale definiert. In der Praxis interessiert man sich auch meist nur für reellwertige Signale. Dass man jedoch trotzdem komplexe Zahlen verwendet, liegt daran, dass mit diesen die Darstellung relativ kompakt ist. Etwa steht in der Polarkoordinatendarstellung der Frequenzkoeffizienten der Radius für die Amplitude und der Winkel für die Phasenverschiebung des Signals. Solch eine Interpretation ist mit reellen Zahlen nicht möglich. Die DFT ist invertierbar. Das bedeutet, dass man das ursprüngliche Signal verlustfrei aus dem Frequenzspektrum rekonstruieren kann.

Aufgaben

Werden die Frequenzen vom Messgerät direkt gemessen?

Nein. Die Frequenz ist keine direkt beobachtbare physikalische Größe. Das Messgerät misst den Schalldruckpegel alle paar Millisekunden. Den Schalldruckpegel kann man sich als Lautstärke vorstellen. Allerdings hängt die subjektiv wahrgenommene Lautstärke zusätzlich zum Schalldruckpegel auch von der Frequenz ab. Diese Zuordnung des Schalldruckpegels an verschiedenen Zeitpunkten wird dann mithilfe der diskreten Fourier-Transformation in den sogenannten “Frequenzbereich” übertragen.

Warum ist die Frequenz nicht eine einzige Zahl?

Im Allgemeinen besteht ein akustisches Signal nicht aus einer reinen Frequenz, sondern aus einer Überlagerung (unendlich) vieler Frequenzen. Die Werte der einzelnen Frequenzen spiegeln die Amplituden wider.

Wie könnte man das Frequenzspektrum sinnvoll durch eine einzige Zahl darstellen?

Durch die Frequenz, welche die höchste Amplitude besitzt.

Wie sieht ein Signal aus, welches aus nur einer einzigen, reellwertigen Frequenz besteht?

Wie eine Sinuskurve.

Wie sieht ein Signal aus, welches aus nur einer einzigen, komplexwertigen Frequenz besteht?

Wie eine Sinuskurve, welche in ihrer Phase verschoben ist.

Was macht die Fourier-Transformation?

Die Fourier-Transformation teilt ein zeitliches Signal in seine Frequenzkomponenten auf. Eine Frequenz steht dabei für ein reines Sinus- bzw. Kosinussignal mit ebendieser Frequenz und einer gewissen Amplitude. Diese Transformation ist invertierbar. Das bedeutet, dass man aus solch einer Frequenzaufteilung das ursprüngliche Signal fehlerfrei reproduzieren kann.

Warum zeigt das Frequenzdiagramm bei einem reinen 700Hz Signal auch andere Frequenzen?

Dies kann verschiedene Gründe haben: - Messfehler des Schallsensors - Störungen durch Hintergrundgeräusche - Es können durch die diskrete Abtastung nur endlich viele Frequenzen exakt dargestellt werden. Kann beispielsweise, bedingt durch unsere Abtastfrequenz, eine Frequenz von 696Hz, nicht aber eine von 700Hz, genau erfasst werden, so muss diese Ungenauigkeit durch die anderen Frequenzen ausgeglichen werden.

Visualisiere die von dir gemessenen Beträge der Frequenzen mit einem Programm deiner Wahl (z.B. Excel)!

Visualisiere die von dir gemessenen Frequenzen inklusive Real- und Imaginärteil in einem 3D-Plot! Was fällt dir auf?

Die Frequenzkoeffizienten sind in der Mitte gespiegelt und um 90° gedreht.

Wie könnte man den Aufbau verbessern/erweitern?

  • Die Messwerte automatisch in eine csv-Datei schreiben.
  • Einen Arduino mit mehr Speicher verwenden, um eine präzisere Frequenzauflösung erhalten zu können. Dafür muss man die Anzahl der Abtastungen erhöhen.
  • Die ursprünglichen Abtastwerte (und nicht die Frequenzen) abspeichern/visualisieren, um etwa die Lautstärke im Zeitverlauf darzustellen (man stelle sich ein Audiobearbeitungsprogramm vor, welches die Lautstärke zu jedem Zeitpunkt angibt, um schnell bspw. Stille identifizieren zu können).
  • Mit dem seriellen Plotter die Messwerte sofort visualisieren.

Wie könnte man solch ein Frequenzmessgerät einsetzen?

  • Gitarre stimmen

Häufige Fragen und Probleme

Wenn ich meine selbst gemessenen Frequenzen visualisiere, sehen die Daten in der Mittel gespiegelt aus. Woran liegt das?

Das ist eine Eigenart des Betrags der (diskreten) Fourier-Transformation für reellwertige Signale. Der rechte, gespiegelte Teil kann ignoriert werden.

Mathematisch werden die Frequenzen durch komplexe Zahlen beschrieben. Warum werden sie grafisch als positive relle Zahlen dargestellt?

Kurz gesagt ist es schwer, komplexe Funktionen grafisch darzustellen. Aus folgendem Grund verliert man durch eine grafische Darstellung mit rellen Zahlen aber nur wenig Informationen: Komplexe Zahlen können in Polarkoordinaten dargestellt werden, welche aus einem Radius und einem Winkel bestehen. Der Radius beschreibt die Amplitude, welche für unsere Zwecke bedeutend ist; der Winkel einer Frequenz stellt jedoch nur die Phasenverschiebung dar. Die Frequenz eines reinen 700Hz Signals hat, bei fester Lautstärke, immer den gleichen Radius (Amplitude). Der Winkel (Phase) ist aber unterschiedlich - je nachdem, wann genau man in der Periode angefangen hat zu messen.

Warum nutzen wir komplexe Zahlen, um die frequenzen darzustellen?

Da man die Frequenzen dadurch auf eine elegante Art und Weise darstellen kann und die Sinus- und Kosinussignale somit nicht separat betrachten muss. Fourier selbst, der Namensvater der Fourier-Transformation, hat zu Beginn nur mit reellen Zahlen gearbeitet, was die Darstellung komplizierte.

Warum muss die Anzahl an Abtastwerten eine Zweierpotenz sein?

Das liegt an der verwendeten Implementierung der schnellen Fourier-Transformation. Theoretisch kann diese Operation auch auf Signale mit einer anderen Anzahl an Abtastwerten angewendet werden. In dem Fall muss aber eine andere Bibliothek verwendet werden.

Ein Sinussignal nimmt auch negative Werte an. Der Schalldruckpegel kann aber nicht negativ sein. Wie können wir ihn durch Sinus-/Kosinussignale darstellen?

Man kann eine konstante Funktion als ein Kosinussignal mit einer Frequenz von 0 auffassen. Somit beinhaltet ein reiner Ton auch eine Kosinuskurve der Frequenz 0. Im Code wird der Mittelwert des Signals abgezogen, um dieses Phänomen zu umgehen.

Werden die Frequenzen vom Messgerät direkt gemessen?

Nein. Die Frequenz ist keine direkt beobachtbare physikalische Größe. Das Messgerät misst den Schalldruckpegel alle paar Millisekunden. Den Schalldruckpegel kann man sich als Lautstärke vorstellen. Allerdings hängt die subjektiv wahrgenommene Lautstärke zusätzlich zum Schalldruckpegel auch von der Frequenz ab. Diese Zuordnung des Schalldruckpegels an verschiedenen Zeitpunkten wird dann mithilfe der diskreten Fourier-Transformation in den sogenannten “Frequenzbereich” übertragen.

Warum ist die Frequenz nicht eine einzige Zahl?

Im Allgemeinen besteht ein akustisches Signal nicht aus einer reinen Frequenz, sondern aus einer Überlagerung (unendlich) vieler Frequenzen. Die Werte der einzelnen Frequenzen spiegeln die Amplituden wider.

Wie könnte man das Frequenzspektrum sinnvoll durch eine einzige Zahl darstellen?

Durch die Frequenz, welche die höchste Amplitude besitzt.

Wie sieht ein Signal aus, welches aus nur einer einzigen, reellwertigen Frequenz besteht?

Wie eine Sinuskurve.

Wie sieht ein Signal aus, welches aus nur einer einzigen, komplexwertigen Frequenz besteht?

Wie eine Sinuskurve, welche in ihrer Phase verschoben ist.

Was macht die Fourier-Transformation?

Die Fourier-Transformation teilt ein zeitliches Signal in seine Frequenzkomponenten auf. Eine Frequenz steht dabei für ein reines Sinus- bzw. Kosinussignal mit ebendieser Frequenz und einer gewissen Amplitude. Diese Transformation ist invertierbar. Das bedeutet, dass man aus solch einer Frequenzaufteilung das ursprüngliche Signal fehlerfrei reproduzieren kann.

Warum zeigt das Frequenzdiagramm bei einem reinen 700Hz Signal auch andere Frequenzen?

Dies kann verschiedene Gründe haben: - Messfehler des Schallsensors - Störungen durch Hintergrundgeräusche - Es können durch die diskrete Abtastung nur endlich viele Frequenzen exakt dargestellt werden. Kann beispielsweise, bedingt durch unsere Abtastfrequenz, eine Frequenz von 696Hz, nicht aber eine von 700Hz, genau erfasst werden, so muss diese Ungenauigkeit durch die anderen Frequenzen ausgeglichen werden.

Visualisiere die von dir gemessenen Beträge der Frequenzen mit einem Programm deiner Wahl (z.B. Excel)!

Visualisiere die von dir gemessenen Frequenzen inklusive Real- und Imaginärteil in einem 3D-Plot! Was fällt dir auf?

Die Frequenzkoeffizienten sind in der Mitte gespiegelt und um 90° gedreht.

Wie könnte man den Aufbau verbessern/erweitern?

  • Die Messwerte automatisch in eine csv-Datei schreiben.
  • Einen Arduino mit mehr Speicher verwenden, um eine präzisere Frequenzauflösung erhalten zu können. Dafür muss man die Anzahl der Abtastungen erhöhen.
  • Die ursprünglichen Abtastwerte (und nicht die Frequenzen) abspeichern/visualisieren, um etwa die Lautstärke im Zeitverlauf darzustellen (man stelle sich ein Audiobearbeitungsprogramm vor, welches die Lautstärke zu jedem Zeitpunkt angibt, um schnell bspw. Stille identifizieren zu können).
  • Mit dem seriellen Plotter die Messwerte sofort visualisieren.

Wie könnte man solch ein Frequenzmessgerät einsetzen?

  • Gitarre stimmen

Quelle

Dieses Projekt, insbesondere der Code und das Schaltbild, basiert auf einem Projekt von Clyde Lettsome, siehe https://clydelettsome.com/blog/2019/12/18/my-weekend-project-audio-frequency-detector-using-an-arduino/.

Stromstärke Sensor

Beschreibung

Mit dem Arduino lassen sich über die analogen Pins (A0-A5) Stromspannungen messen. Damit kann man z.B. mithilfe eines Fotowiderstandes die Helligkeit in einem Raum festellen. Wenn man aber nun die Stromstärke messen möchte, muss man diese erst in eine Spannung umwandeln. Der der ACS712 Sensor macht dies mithilfe des Hall-Effekts. Dieser wandelt gibt dann pro gemessenes Ampere 185mV aus, welche wir dann mit dem Arduino messen können.

Mit analogRead(PIN) kann man diese Spannung von 0-5V messen, wobei bei 0V 0 und bei 5V 1023 ausgegeben wird. Alle Spannungen zwischen 0 und 5V verhalten sich linear dazu.

Verkabelung

BauteilArduino
GNDGND
VCC5V
OutA0
Schaltplan

Schaltplan

Code

int ACS_PIN = A0;  // PIN an dem der ACS712 angeschlossen ist

// Solange kein Strom am Sensor fließt, gibt der Sensor eine Spannung von
// circa 2.49 Volt aus. Diese muss also von der gemessenen Spannung abgezogen
// werden. Die Werte 2.49 und 0.185 können verfeinert werden, in dem die
// U-I-Kennlinie des ACS712-Sensors aufgenommen wird. Benötigt wird ein
// Labornetzgerät, an dem man die Stromstärke regeln kann. Es wird eine feste
// Stromstärke eingestellt und der Spannungswert am Seriellen Monitor abgelesen.
float ACS_VOLTAGE_OFFSET = 2.49;
float ACS_GRADE          = 0.185;  // Steigung der U-I-Kennlinie

void setup() {
  pinMode(ACS_PIN, INPUT);  // Aktiviere das Lesen von Werten auf ACS_PIN
  Serial.begin(9600);       // Starte die serielle Schnittstelle
}

// Mit dieser Methode wird die durch den Strom induzierte Hallspannung im ACS712
// gemessen. Wegen des Halleffekts ist die Hallspannung proportional zur
// Stromstärke.
float get_current(int N) {
  float voltage_sum = 0;  // Variable um die gemessene Spannung aufzusummieren

  // N Messungen durchführen.
  for (int n = 0; n < N; n++) {
    float input = analogRead(ACS_PIN);       // Wert zwischen 0 und 1023 am
                                             // Analog-Pin ACS_PIN ablesen.
    float voltage = (input / 1024.0) * 5.0;  // Spannung zwischen 0 V und 5 V
                                             // aus dem abgelesen Wert
                                             // berechnen.
    voltage_sum = voltage_sum + voltage;  // Messwerte der Spannung aufaddieren,
                                          // um später einen Mittelwert zu
                                          // bilden.
  }
  // Mittelwert aus den am Pin A0 gemessenen Spannungen bilden.
  float voltage_avg = voltage_sum / N;

  // Wenn wert die Stromstärke ist, dann folgt aus einer Ausgelichsgeraden aus
  // voltage_avg = 2.49 + 0.185*current, umgestellt nach current ergibt das die
  // Formel.
  float current = (voltage_avg - ACS_VOLTAGE_OFFSET) / ACS_GRADE;

  // Gebe die berechnete Stromstärke zurück.
  return current;
}

void loop() {
  // Stromstärke messen über 10000 Messungen gemittelt.
  float current = get_current(10000);

  // Spannungswert im seriellen Monitor anzeigen.
  Serial.print("I = ");
  Serial.print(current, 2);  // Gebe die Stromstärke mit 5 Nachkommastellen aus
  Serial.println(" A");

  // Warte 500ms
  delay(500);
}

Taster - per Knopfdruck zum Ziel

Beschreibung

Was ist ein Taster?

So wird ein drückbarer Knopf in Fachkreisen genannt.

Der Arduino kann an seinen digitalen Pins nicht nur Spannungen (Strom) ausgeben, um z.B. einen Motor anzuschalten. Er kann auch Spannungen (Daten) einlesen, wie z.B beim Ultraschallsensor. Dieses Mal wollen wir mithilfe eines Tasters eine LED zum Leuchten bringen.

Bei dem Aufbau gibt es dieses Mal eine Besonderheit. Verbindet man den Taster ganz einfach mit dem Arduino und drückt den Taster, dann liegt am Pin des Arduinos eine Spannung an. Die Spannung kann aber nicht so schnell wieder entweichen, sodass unser Arduino denkt, wir halten den Taster für viele Sekunden gedrückt. Das wollen wir natürlich nicht! Um das zu verhindern und so schnell wie möglich klicken zu dürfen, brauchen wir einen Widerstand mit 1000 Ohm (1 K Ohm).

Physik: Widerstände

Man kann sich das so vorstellen, als würden an dem besagten Pin ganz viele Elektronen herumschwirren. Wenn der Taster dann losgelassen wird, kommen keine neuen Elektronen mehr zu dem Pin am Arduino hinzu. Jetzt kommt der Knackpunkt. Die Elektronen, die es sich vorher auf dem Pin gemütlich gemacht haben, sind dann immer noch da und entweichen nur ganz langsam über kleine Kriechströme. Solange sich noch Elektronen auf dem Pin aufhalten, denkt der Arduino, dass der Taster nicht nur kurz sondern ganz lange gedrückt wird. Durch einen Widerstand können die Elektronen deutlich schneller abfließen. Der Arduino erkennt folglich, dass der Taster nur kurz gedrückt wurde. Da der Widerstand die Spannung an dem Eingangspin immer auf 0V „herunterzieht“, wird er auch als „PULLDOWN-“ Widerstand bezeichnet.

ACHTUNG: Wenn man einen zu kleinen Widerstand verwendet, kann beim Drücken des Tasters ein Kurzschluss auf dem Mikrocontroller entstehen.

Verkabelung

Schaltplan

Schaltplan

Code

Wir wollen den Arduino dazu bringen, dass er jedes Mal die LED leuchten lässt, wenn wir den Taster drücken. Damit wir richtig schnell drücken können, lassen wir die LED nur ganz kurz (1/10 Sekunde) aufleuchten.

int LED          = 6;
int taster       = 7;
int tasterStatus = 0;

void setup() {
  pinMode(LED, OUTPUT);
  pinMode(taster, INPUT);
}

void loop() {
  tasterStatus = digitalRead(taster);
  if (tasterStatus == HIGH) {  // wird der Knopf gedrückt, passiert Folgendes:
    digitalWrite(LED, HIGH);   // LED wird angeschaltet
    delay(100);                // LED leuchtet für eine Zehntel Sekunde
    digitalWrite(LED, LOW);    // LED wir ausgeschaltet
  } else {                     // sonst :
    digitalWrite(LED, LOW);    // LED wird ausgeschaltet / bleibt ausgeschaltet
  }
}

Aufgaben

Beschreibe, was der Code tut!

Die Pins für die LED, den Taster und den Tasterstatus werden gesetzt und im Setup die LED als Output und der Taster als Input festgelegt. In der loop wird der Tasterstatus gelesen, wenn er einmal gedrückt wurde soll die LED leuchten, ansonsten bleibt sie aus oder wird ausgeschaltet, da der wiederholt gedrückte Taster als Auschaltoperation verstanden wird.

Baut den dargestellten Aufbau einmal nach, lasst die LED aber durchgehend leuchten bis man sie wieder mit dem Taster auschaltet.

Die Zeilen 14 + 15 dafür entfernen.

Ultraschallsensor - Eine Einführung

Beschreibung

Fledermaus

Verkabelung

Verkabelung

Code

Wir wollen unserem Arduino nun beibringen, eine LED in Pin 13 leuchten zu lassen, wenn ihm etwas zu nahe kommt. Wir verwenden dazu folgenden Code:

int trigPin = 9;
int echoPin = 10;
int ledPin  = 13;

int zeit;     // Hier speichern wir, wie lange der Schall unterwegs ist.
int abstand;  // Hier speichern wir den gemessenen Abstand.

void setup() {
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // Wir messen den Abstand zum nächsten Objekt.
  digitalWrite(trigPin, LOW);  // Lautsprecher aus.
  delay(2);
  digitalWrite(trigPin, HIGH);  // Lautsprecher gibt Ton aus.
  delay(10);
  digitalWrite(trigPin, LOW);     // Lautsprecher aus.
  zeit = pulseIn(echoPin, HIGH);  // Hier wird gemessen, wann das Mikrofon den
                                  // Ton hört.
  abstand = zeit * 0.034 / 2;     // Umrechnung des Abstands von Zeit in
                                  // Zentimeter.

  if (abstand < 12) {  // Wenn der Abstand kleiner als 12 Zentimeter ist.
    digitalWrite(ledPin, HIGH);  // Schalte die LED an.
  } else {                       // sonst
    digitalWrite(ledPin, LOW);   // Schalte die LED aus.
  }
}

Aufgaben

Probiere verschiedene Abstände aus! Wie zuverlässig arbeitet der Sensor auf längere und kürzere Distanzen?

TODO

Was schätzt zu wie breit ist der Winkel, in dem die Sensoren gut arbeiten? Vergleiche das mit dem Winkel deiner Augen!

TODO

Was passiert, wenn du den else-Block weglässt? Kannst du dir einen Apparat vorstellen, bei dem so ein Verhalten gewünscht ist?

Die LED geht nach dem ersten Anschalten nicht mehr aus.

Programmiere ihn so, dass er Hindernissen ausweicht!

TODO

Welche Funktionen fallen dir ein, die man mit noch mit dem Ultraschallsensor umsetzen kann! Welche Funktionen kannst du mit mehr als einem Sensor umsetzen?

Bewegungsensor, Hand in eine Richtung folgen

Wie viele Sensoren wären nötig, damit der Roboter deiner Hand folgt, wenn du sie vor ihm bewegst? Wie könnte ein Code aussehen, der das umsetzt?

Es ist möglich dies mit zwei Sensoren umzusetzen, die leicht Versetzt angeordnet sind.