Funduino Elevator – Arduino Kompatibel

Inhaltsverzeichnis

Aufzugmodell als praktische Anwendungsaufgabe zum Erlernen der Arduino-Entwicklungsumgebung anhand einer Aufgabe mit hohem Alltagsbezug.

Wichtiger Hinweis zur Anleitung

Diese Anleitung zum Funduino Aufzug orientiert sich an praxisorientierten Aufgaben.

Beim Funduino Aufzug handelt es sich um ein Aufzugmodell, auf dem typische und weitverbreitete elektronische Module vorinstalliert sind, die mit der Arduino-Entwicklungsumgebung programmiert und angesteuert werden können. Das Herzstück dieser Platine ist ein herkömmlicher Mikrocontroller mit der Bezeichnung „Arduino MEGA 2560 R3“.
Dadurch ist der Funduino Aufzug nicht nur für den Informatikunterricht interessant, sondern die Arbeit mit ihm vermittelt auch grundlegende Kenntnisse aus den Bereichen Elektronik und Technik.

1. Vorwort und didaktische Überlegungen

Mit diesem vorgefertigten Arduino-Projekt können Schüler ein realitätsnahes Aufzug-Modell konstruieren und programmieren. Für die Verwendung des Projekts werden Materialien von Funduino verwendet, die sich auch in den üblichen Lernsets befinden. Schüler arbeiten also insbesondere mit ihnen bekannten Materialien. Das Modul lässt sich variabel erweitern, um ein höheres Anspruchsniveau im Unterricht anbieten zu können.

Diese Anleitung ist nicht dazu gedacht, die Grundlagen der Arduino-Programmierung zu erlernen. Dazu eignen sich insbesondere Starterkits der Funduino GmbH. Es handelt sich bei dem Funduino Aufzug um eine wesentlich komplexere Programmieraufgabe, um eine anspruchsvolle Aufgabemit hohem Maß an Alltagsbezug zu schaffen.

1.1. Einsatz im Unterricht

1.1.1. Abbau von Hürden und Förderung der Eigenmotivation

Die Programmierung des Aufzugs kann zu einem komplexen Programm führen, welches der Funktion eines echten Aufzugs sehr nahekommt. Bei diesem Modell kann man jedoch auch sehr kleinschrittig vorgehen. Die Lernenden können die einzelnen Module der Reihe nachprogrammieren und kennenlernen.

1.1.2. Befähigung zur eigenständigen Lösung komplexer Problemstellungen

Der Aufbau des Programms kann sehr individuell erfolgen. Es gibt kaum „richtig“ und „falsch“. Wichtig ist am Ende die Funktionalität. Daher werden in dieser Anleitung die Module und deren Programmierung einzeln beschrieben, nicht jedoch eine vollständige Lösung vorgegeben. Ein vollständiger Beispielsketch kann bei der Funduino GmbH angefragt werden.

1.1.3. Nachhaltige Motivation durch kleine Lernerfolge

Jeder Lernabschnitt ist so konzipiert, dass er zu einem greifbaren Ergebnis führt. Diese kleinen Erfolgserlebnisse sind entscheidend für die Aufrechterhaltung der Motivation und das Selbstvertrauen der Lernenden. Die Fortschritte werden regelmäßig reflektiert, wodurch die Lernenden ein Bewusstsein für ihre eigene Entwicklung gewinnen.

1.1.4. Förderung des eigenständigen Arbeitstempos und Teamarbeit

Wir erkennen an, dass jeder Mensch unterschiedlich lernt. Daher ist unser Programm flexibel gestaltet, um Lernenden zu ermöglichen, in ihrem eigenen Tempo zu arbeiten. Gleichzeitig fördern wir Teamarbeit und Kollaboration, da diese Fähigkeiten in der realen Arbeitswelt von großer Bedeutung sind. Gruppenprojekte ermöglichen es den Lernenden, voneinander zu lernen und gemeinsam Lösungen zu entwickeln.

2. Hardware

Der Funduino Aufzug besteht aus einer Vielzahl von Modulen, die nachfolgend beschrieben werden.

2.1. Beschreibung der Konstruktion

Der Funduino Aufzug besteht  aus zwei Teilen.

2.1.1. Die Bodenplatte mit folgenden Bauteilen

  • Auf der Unterseite befindet sich der MEGA 2560 Mikrocontroller
  • Dargestelltes Bedienpanel aus dem Inneren der Aufzuggondel auf der Vorderseite
  • Kleiner Speaker für Statusgeräusche
  • Eingang für externe Spannungsversorgung auf der Rückseite
  • Schiebeschalter für die Zufuhr der externen Spannungsversorgung an den Mikrocontroller
  • Schiebeschalter für die Zufuhr der externen Spannungsversorgung an den Motortreiber
  • L293DD Motortreiber
  • Bluetooth-Schnittstelle
  • MP3-Modul mit microSD-Karte
  • Lautsprecheranschluss für die Ausgabe des MP3-Moduls

2.1.2. Den Aufzugturm mit folgenden Bauteilen

  • Auf der Vorderseite jedem Flur Taster für „Auf“ und „Ab“
  • Auf der Vorderseite oben ein OLED-Display
  • Oben auf dem Rahmen befindet sich der DC-Motor für den Antrieb der Gondel
  • Auf der Rückseite links mittig der Anschluss für den Servo der Tür (Braunes Kabel = GND)
  • Auf der Rückseite oben rechts befinden sich frei belegbare Kontakte (D19, D18, 5V und GND)
  • Auf der Rückseite oben rechts befindet sich ein Steckplatz für einen 360° Servo (D36, 5V, GND), der alternativ als Motor für die Gondel verwendet werden kann.
  • Auf der Rückseite oben rechts befinden sich die Kontakte M1 und M2 für den Anschluss des DC-Motors. Dies sind die Kontakte, die vom Motortreiber L293DD kommend den DC-Motor mit Spannung versorgen.

2.2. Module und Mikrocontroller

Der Aufzug besteht aus zwei Platinen mit diversen elektronischen Komponenten, die alle zeitgleich mit dem Mikrocontroller verbunden sind. Anhand der folgenden Aufstellung erkennt man, wie die Module mit dem Mikrocontroller verbunden sind.

Bei dem Mikrocontroller handelt es sich um den Funduino MEGA2560 R3 oder Arduino MEGA2560 R3. Der Funduino MEGA2560 bildet das Herzstück und die Grundlage für den Funduino Aufzug. Auf dem Mikrocontroller wird das Programm gespeichert. Doch nicht nur das: mit einem Mikrocontroller werden sämtliche Komponenten kontrolliert.

Die folgende Auflistung beschreibt, wie die Komponenten des Aufzugs mit dem Mikrocontroller verbunden sind.

2.2.1. Kapazitive Schalter

Jeder Schalter hat drei Kontakte.

Ein Kontakt ist GND und ist dauerhaft mit GND des Mikrocontrollers verbunden.

Ein Kontakt heißt VCC, hier wird eine 5V-Spannung angelegt, um den Schalter in den Betriebszustand zu versetzen.

Ein Kontakt heißt OUT, hier wird vom Schalter eine Spannung ausgegeben, wenn der Schalter durch eine Berührung aktiviert wurde.

Jeder Taster ist mit zwei digitalen Pins verbunden. Ein Pin, um den Schalter in den Betriebszustand zu versetzen und einer, um den Schaltzustand abzufragen.

2.2.1.1. Schalter auf der Grundplatte des Aufzugs

Door Close
PWR: D32,  OUT: D33

Door Open
PWR: D34,  OUT: D35

Floor 0
PWR: D30,  OUT: D31

Floor 1
PWR: D28,  OUT: D29

Floor 2
PWR: D26,  OUT: D27

Floor 3
PWR: D24,  OUT: D25

Alarm
PWR: D22,  OUT: D23

2.2.1.2. Schalter am Aufzugturm für die Flure

Floor 0 Hoch
PWR: D39,  OUT: D38

Floor 1 Runter
PWR: D41,  OUT: D40

Floor 1 Hoch
PWR: D43,  OUT: D42

Floor 2 Runter
PWR: D45,  OUT: D44

Floor 2 Hoch
PWR: D47,  OUT: D46

Floor 3 Runter
PWR: D49,  OUT: D48

2.2.2. Speaker (passive Buzzer)

D9

2.2.3. Bluetooth

Serial3 (D14, D15)

2.2.4. MP3

RX: D11
TX: D10

2.2.5. Motortreiber L293D

PWM : D8
Motor A: D6
Motor B: D7

2.2.6. Servo Aufzugtür

D37

2.2.7. Servo für alternativen 360 Servomotor

D36 (Rückseite oben rechts)

2.2.8. Frei verfügbare Ports

FreePort: D19, D18 (Rückseite oben rechts)

2.2.9. Lichtschranken

Sensor1: D50
Sensor2: D51
Sensor3: D52
Sensor4: D53

2.2.10. OLED-Display

SDA: D20
SCL: D21

3. Programmierung der Komponenten - Praxisaufgaben

Die einzelnen Module werden in diesem Kapitel beschrieben und anhand von kleinen Beispielen programmiert.

3.1. Kapazitiver Schalter

Die Schalter am Aufzugmodell sind Schalter mit einer sog. „Touch-Funktion“. Es wird kein mechanischer Anschlag benötigt, um den Schalter zu aktivieren. Eine Sensorik erkennt den sich nähernden Finger und löst bei  geringster Berührung eine Schaltfunktion aus. Sobald der Schalter berührt wurde, gibt der Schalter an einem Ausgangskontakt eine Spannung aus und die Hintergrundbeleuchtung des Schalters wird aktiviert. Bei einem erneuten Kontakt wird die Ausgangsspannung deaktiviert und die Hintergrundbeleuchtung erlischt.

Der kapazitive Schalter oder der kapazitive Sensor funktioniert wie ein offener Kondensator. Zwischen der Messelektrode und der GND-Elektrode wird ein elektrisches Feld aufgebaut. Sollte ein Material mit einer Dielektrizitätszahl größer als Luft in das elektrische Feld eindringen, vergrößert sich je nach Material die Kapazität des Feldes. Die Elektronik auf dem Schalter-Modul misst diese Kapazitätserhöhung. Diese neue Kapazität wird von der Elektronik auf dem Modul ausgewertet und führt bei entsprechender Größe zum Schalten des Ausgangs. Es wird dann eine Spannung an den Signal-Pin des Schalter-Moduls geleitet.

Der kapazitive Schalter hat folgende technische Daten:

  • Eingangsspannungsbereich: + 2,7 V bis + 6 V
  • Signalausgang: + 3.3 V
  • Betriebstemperaturbereich: -30 ~ + 70 ℃
  • Bei aktiviertem Schalter leuchtet die Hintergrundbeleuchtung
  • Die Hintergrundbeleuchtung kann per externer Ansteuerung manuell aktiviert werden.

Der kapazitive Schalter hat drei Kontakte.

  • VCC – Spannungsversorgung, versorgt den Sensor mit Strom.
  • GND – Ground
  • OUT – Signalausgang, hier liegt eine Spannung an, wenn die Betätigung des Schalters erkannt wurde.

Mit dem folgenden Sketch testen wir das Modul. Hier wird eine Serielle Schnittstelle gestartet und der Sensorpin wird als INPUT (=Eingang) definiert. Dann kommen wir zur Loop-Methode, die in einer Schleife den Sensorwert ausliest und überprüft, ob der Sensor berührt wurde. Wenn ja, gibt sie „Der Sensor wurde berührt!“ aus.

Für dieses erste Beispiel verwenden wir den Schalter unten rechts auf der Aufzugbasis. Es handelt sich um den Schalter, der für die Türöffnung vorgesehen ist. Dieser Schalter wird über den Pin34 mit Strom versorgt und an Pin35 wird der Schaltstatus abgefragt.

int PowerPin = 34; // Sensor Pin
int sensorPin = 35; // Sensor Pin

void setup()
{
 Serial.begin(9600); // Starten der seriellen Schnittstelle
 pinMode(PowerPin, OUTPUT); // Der Sensor wird am Mikrocontroller als Eingang definiert.
 pinMode(sensorPin, INPUT); // Der Sensor wird am Mikrocontroller als Eingang definiert.
}

void loop()
{
 int sensorWert = digitalRead(sensorPin); //  Sensorwert auslesen

 // Wurde der Sensor berührt?
 if (sensorWert == HIGH)
{
    Serial.println("Der Sensor wurde aktiviert!");
    delay(500);
 }
}

3.1.1. Hintergrundbeleuchtung per Mikrocontroller ein- und ausschalten

Das Modul ist so konzipiert, dass wir die LED der Hintergrundbeleuchtung mithilfe des Mikrocontrollers selbst ein- und ausschalten können.

Das geht, indem wir in der Mitte des Programms den pinMode von INPUT auf OUTPUT (=Ausgang) setzen und den Signalpin des Schalters auf HIGH (=Hoch) setzen. Vergessen Sie nicht, den Pin wieder auf INPUT zu setzen, wenn im weiteren Verlauf der Schaltstatus ausgelesen werden soll.

3.1.2. Schalterstatus zurücksetzen ohne Berührung

Ein Schalter bleibt in der Regel so lange aktiv, bis ein Anwender den Schalter selbst deaktiviert, indem er ihn berührt.  Mit einem kleinen Trick kann der Schalter jedoch auch per Mikrocontroller in den deaktivierten Zustand zurückversetzt werden. Wenn der Schalter also aktiviert ist, und die Hintergrundbeleuchtung in dessen Folge leuchtet, deaktivieren wir kurzzeitig die Spannungsversorgung über den digitalen Pin. Nachdem die Spannung wieder anliegt, ist der Schaltzustand des Schalters aus und auch die Hintergrundbeleuchtung ist aus. Die Sensorik des Schalters ist jedoch aktiv und wartet auf das erneute Einschalten.

3.1.2.1. Beispielcode 1

Im Setup definieren wir den Strom-Pin des Schalters als Ausgang und setzen ihn auf HIGH, was 5V entspricht.

Bei der Schleifenmethode ist alles gleich, außer dass der Schalter nach einer Sekunde, nachdem er berührt wurde, ausgeschaltet wird. Dann schalten wir ihn wieder ein, damit er erneut betätigt werden kann.

int PowerPin = 34; // Spannungsversorgung über den Pin 3 geht an VCC des Sensors.
int sensorPin = 2; // Sensor Ausgangs-Pin

void setup() {
 Serial.begin(9600);
 pinMode(sensorPin, INPUT); // Sensoreingang am Mikrocontroller
 pinMode(PowerPin, OUTPUT); // Spannungsausgang für den Schalter
 digitalWrite(PowerPin, HIGH);
}

void loop() {
 int sensorWert = digitalRead(sensorPin); // Lese Sensorwert.

 // Wurde der Sensor berührt?
 if (sensorWert == HIGH) {
    Serial.println("Der Sensor wurde berührt!");
    delay(1000);
    // Schalte sensor aus.
    digitalWrite(PowerPin, LOW); // Schalte den Strom vom Schalter aus.
    delay(500);
    digitalWrite(PowerPin, HIGH); // Schalte den Strom vom Schalter wieder ein.
 }
}
3.1.2.1. Beispielcode 2

Ein anderes Beispiel wäre, dass wir die LED des Schalters selbst ein- und ausschalten. In diesem Modus kann der Schaltstatus jedoch nicht ausgelesen werden. Die Funktion des manuellen Einschaltens kann zu Testzwecken der LED oder für visuelle Spielereien verwendet werden.

int PowerPin = 34; // VCC von dem Sensor.
int sensorPin = 35; // Sensor Pin

void setup() {
 Serial.begin(9600);
 pinMode(sensorPin, OUTPUT); // Hier wird der Pin des Mikrocontrollers, der mit dem AusagnagsPin des Moduls verbunden ist, als Ausgang festgelegt. Das bedeutet, dass Spannung an das Modul gesendet werden kann, auch wenn dies zunächst merkwürdig erscheint.
 pinMode(PowerPin, OUTPUT);
 digitalWrite(PowerPin, HIGH); //Schalter aktivieren
}

void loop()
{
    digitalWrite(sensorPin, HIGH); // LED des Touch-Moduls aktivieren
    delay(500);
    digitalWrite(sensorPin, LOW); // LED des Touch-Moduls deaktivieren
    delay(500);
 }

Wir haben gelernt, dass der Schalter am Aufzug für zwei unterschiedliche Funktionen verwendet werden kann.

1) Der Mikrocontroller kann eine Spannung an das Touchmodul senden, um die Hintergrundbeleuchtung ein- und auszuschalten.

2) Der Mikrocontroller kann den Schaltstatus des Moduls auslesen.

Der Unterschied besteht darin, dass der entsprechende Pin des Mikrcontrollers als AUSGANG oder als EINGANG definiert werden muss. Dieser Unterschied muss nicht zwingend im Setup erfolgen. Die Art der Verwendung des Pins kann auch im laufenden Programm, bspw. im Loop, verändert werden.

3.2. Lautsprecher (ohne MP3)

Auf der Grundplatte des Aufzugs ist ein kleiner schwarzer Zylinder montiert. Es handelt sich dabei um einen kleinen Lautsprecher, der für akustische Signale verwendet werden kann.

In dieser Anleitung werden wir den Lautsprecher programmieren.

Aufgabe: Mit einem passiven Lautsprecher sollen unterschiedliche Töne und eine Melodie erzeugt werden.

Mit dem Arduino-Mikrocontroller lassen sich auf verschiedene Art und Weise Töne erzeugen. Die einfachste Möglichkeit ist die Tonerzeugung mit einem aktiven Lautsprecher (auch Active-Buzzer oder Piezo-Speaker), der lediglich an die Spannung von 5V angeschlossen wird. Die Tonerzeugung übernimmt eine im Inneren eingebaute Elektronik. Der Nachteil liegt jedoch darin, dass ein „Active-Buzzer“ nur einen einzigen Ton erzeugen kann – Melodien oder Sirenengeräusche sind damit nicht möglich.

Mit einem passiven Lautsprecher (Passive-Buzzer) wie in diesem Aufzugmodell, hat man die Möglichkeit, mithilfe des Arduino Mikrocontrollers verschiedene Töne, Melodien oder Sirenensignale zu generieren, da im „passive Buzzer“ keine Elektronik vorhanden ist, die einen Ton vorgibt.

Die Erzeugung des Tones basiert bei dem Lautsprecher des Aufzugs maßgeblich auf dem Arduino-Befehl „tone(x, y)“, wobei der x-Wert den Pin angibt, an dem der Lautsprecher mit der positiven Seite angeschlossen ist und der y-Wert, der die Tonhöhe angibt.

Ein Beispiel:

tone(9, 100); // Der Lautsprecher an Pin 9 wird mit der Tonhöhe „100“ aktiviert
delay(1000); // Pause mit 1000 Millisekunden, also 1 Sekunde – Der Lautsprecher bleibt für diese Zeit aktiv.
noTone(9); // Der Lautsprecher an Pin 8 wird deaktiviert

3.2.1. Codebeispiel 1: Einfache Tonerzeugung

Für dieses Beispiel wird lediglich ein Lautsprecher an Pin9 und GND angeschlossen. Diese Verkabelung ist auf dem Aufzugmodul bereits vorhanden.

void setup(){} //Im Setup werden keine Informationen benötigt. Die Spannungsausgabe für den Pin an dem der Lautsprecher eine Spannungsausgabe benötigt (PinMode OUTPUT), wird im Sketch durch den Befehl "tone" automatisch festgelegt.

void loop()
{
    tone(9, 100);		//Im Hauptteil wird nun mit dem Befehl "tone ( x , y )" ein Ton abgegeben...
    delay(1000);		//...mit einer Dauer von 1 Sekunde.
    noTone(9);		//Der Ton wird abgeschaltet.
    delay(1000);		//Der Lautsprecher bleibt eine Sekunde aus.
}

3.2.2. Codebeispiel 2: Abwechselnde Tonhöhen

Im zweiten Beispiel werden im Loop nur ein paar Zeilen ergänzt. Dadurch ertönen zwei Töne abwechselnd mit der Tonhöhe “100” bzw. “200”, wie bei einer Sirene. Eine Pause zwischen den Tönen gibt es nicht.

void setup(){}

void loop()
{
    tone(9, 100);
    delay(1000);
    noTone(9);	//An dieser Stelle geht der erste Ton aus.
    Tone(9, 200);	// Der zweite Ton mit der neuen Tonhöhe “200” ertönt.
    delay(1000);	//… und zwar für eine Sekunde.
    noTone(9);	// An dieser Stelle geht der zweite Ton aus und der Loop-Teil des Sketches beginnt von vorn.
}

3.3. Sensoren (Lichtschranken)

Aufgabe: Eine Lichtschranke wird verwendet, um die Anzahl der Lichtstrahlunterbrechungen zu zählen.

Eine Lichtschranke ist eine optoelektronische Vorrichtung, die dazu verwendet wird, das Unterbrechen eines Lichtstrahls zu detektieren. Der Messwert wird in Form einer elektrischen Spannung ausgegeben. Dadurch kann eine Lichtschranke als Alternative für einen Taster oder Schalter verwendet werden und hat den Vorteil, dass keine mechanische Betätigung stattfindet.

Eine Lichtschranke besteht aus einem Sender, der Licht aussendet, und einem Empfänger, der das Licht detektiert. Als Lichtquelle wird häufig ein Laserstrahl verwendet, um die Lichtschranke über eine große Strecke verwenden zu können. Im Kleinformat, so wie in dieser Anleitung, besteht die Lichtquelle aus einer Infrarot-LED, dessen Licht das menschliche Auge nicht erkennen kann.

Der Sender und der Empfänger sind gegenüber voneinander angeordnet, sodass der Lichtstrahl zwischen ihnen verläuft. Wenn ein Objekt den Lichtstrahl unterbricht, zum Beispiel durch Einführung einer undurchsichtigen Fläche oder durch eine Person, die durch den Lichtstrahl läuft, erreicht das Licht nicht mehr den Empfänger und die Lichtschranke erkennt dies als Unterbrechung. Das kann zur Erfassung von Bewegungen, zur Zählung von Objekten oder zur Erkennung von Hindernissen in verschiedenen Alltagsbereichen verwendet werden.

Lichtschranken werden in Bereichen der industriellen Automatisierung, in Sicherheitssystemen, in der Robotik, in Verkehrsüberwachungssystemen und vielen weiteren Bereichen verwendet. Sie bieten eine zuverlässige Methode, um mithilfe von Mikrocontrollern das Vorhandensein oder die Bewegung von Objekten zu erkennen und entsprechende Aktionen auszulösen.

Das Modul enthält eine Status-LED, die leuchtet, sobald das Modul mit Spannung versorgt wird. Wenn die Lichtschranke unterbrochen wird, erlischt die LED und gleichzeitig wird am Signalausgang (Beschriftung OUT) des Moduls eine Spannung von 5V ausgegeben. Diese Spannung wird mithilfe des Arduino-Mikrocontrollers ausgelesen und verarbeitet.

Verkabelung

Um die Lichtschranke mit einem Arduino Mikrocontroller zu verkabeln, werden drei Anschlüsse verwendet.

  • Der VCC-Anschluss der Lichtschranke wird mit dem 5V-Pin des Arduino verbunden.
  • Der GND-Anschluss der Lichtschranke wird mit dem GND-Pin des Arduino verbunden.
  • Der Signalausgang (OUT) der Lichtschranke wird mit dem einem Eingangspin am MEGA 2560 verbunden. Beim Aufzug sind vier Sensoren vorhanden, die mit den Pins D50, D51, D52 und D53 verbunden sind.

Für diese Anleitung verwenden wir zunächst nur den Sensor1 am Pin D50.

Im ersten Sketch lesen wir den Signalausgang der Lichtschranke aus und lassen uns das Ergebnis am seriellen Monitor anzeigen.

3.3.1. Codebeispiel

int messwert = 0; //Unter der Variablen "Messwert" wird später der Messwert der Lichtschranke gespeichert.

void setup()
{ //Hier beginnt das Setup.
    Serial.begin(9600); //Die Kommunikation mit dem Seriellen Port wird gestartet. Das benötigt man, um sich den ausgelesenen Wert im serial monitor anzeigen zu lassen.
}

void loop() //Hier beginnt der Hauptteil
{
    messwert = digitalRead(50); //Die Signalausgabe der Lichtschranke wird ausgelesen und unter der Variable „messwert“ gespeichert. Wenn die Lichtschranke unterbrochen wird, speichert der Mikrocontroller den Wert "1", ansonsten "0".
    Serial.print("Lichtschrankensignal= "); //Ausgabe am seriellen Monitor: „Lichtschrankensignal: " mit einem Leerzeichen hinter dem Doppelpunkt
    Serial.println(messwert); //...und im Anschluss der Messwert "1" bei unterbrochener Schranke, ansonsten "0".
}

Das Ergebnis am seriellen Monitor sieht folgendermaßen aus.

3.4. Lautsprecher (mp3)

Im Funduino Aufzug ist ein MP3-Player-Modul mit der Bezeichnung „DFPlayer Mini MP3 Player Modul“ verbaut. Mit diesem winzigen Modul, das gerade einmal etwas größer als eine microSD Speicherkarte ist, können tolle Projekte mit Tonausgabe umgesetzt werden. An dem Modul kann direkt ein Miniaturlautsprecher angeschlossen werden, ohne dass ein Verstärker benötigt wird. Für die Sprachausgabe eines Modellaufzugs ist es ideal.

Wichtiger Hinweis:Die SD-Karte muss das FAT16 (unüblich) oder das FAT32 Format haben. Die Formatierung deiner Speicherkarte ist sehr einfach. Durch einen Rechtsklick auf den entsprechenden Wechseldatenträger am PC kann „Formatieren…“ ausgewählt werden. In dem Menü kann unter „Dateisystem“ „Fat32“ ausgewählt werden. Achtung, alle Daten auf der Speicherkarte werden bei dem Vorgang gelöscht.

Damit nach dem Aufbau direkt programmiert werden kann, benötigen wir einige Soundfiles im MP3-Format. Diese sollen später mithilfe des Arduino-Mikrocontrollers abgespielt werden. Gesprochene Soundfiles, oder „Sprachdateien“ kann man am Computer oder Laptop selbst aufnehmen.
Wer jedoch nicht gerne seine eigene Stimme hört, kann auch online MP3-Sprachdateien nach eigenen Texten erstellen. Dafür gibt es im Netz diverse Anbieter, die den Service kostenlos anbieten. Man sollte dabei nach dem Begriff „Text zu MP3“ oder „Text-to-MP3“ suchen. Für diese Anleitung speichern wir die MP3-Dateien auf der microSD Karte ab. Die MP3-Dateien nennen wir 0001.MP3, 0002.MP3 und 0003.MP3. Und so weiter. Also immer 0xxx.MP3.

Anschließend wird eine passende Library benötigt. Sie kann über den Bibliotheksverwalter installiert werden. Wir verwenden als Grundlage für diese Anleitung die Library von DFRobot. Wie man in dem Bild sehen kann, gibt es jedoch auch weitere passende Libraries, die andere Vorteile bieten, wie eine geringe Speichernutzung bei abgespeckten Funktionen.

Um mit dem Modul zu arbeiten, rufen wir zunächst einen ganz einfachen Beispielcode auf.

Man findet ihn im Bereich Datei → Beispiele → DFRobotDFPlayerMini → GetStarted

Ohne jegliche Veränderung laden wir den Sketch auf das Arduino Mikrocontrollerboard und starten sofort den seriellen Monitor. Wer alles richtig gemacht hat, wird in diesem Moment auch schon Geräusche oder Töne aus dem Lautsprecher gehört haben.

Der serielle Monitor gibt nun Aufschluss darüber, ob das Modul DFRobotDFPlayerMini richtig angeschlossen wurde und einsatzbereit ist. Sollten Probleme bestehen, findet man z. B. Informationen über die fehlende SD-Karte oder eine ggf. falsche Verkabelung.

Praxistipp: Die Datenübertragung an den seriellen Monitor erfolgt in diesem Sketch mit einer Übertragungsrate von 115200 statt 9600. Der Wert muss im seriellen Monitor eingestellt werden, da sonst nur unleserliche Hieroglyphen angezeigt werden.

Wer nach allen Kontrollen noch nichts aus dem Lautsprecher gehört hat, kann auch die Lautstärke des Lautsprechers erhöhen. Dazu befindet sich im Sketch die Befehlszeile „myDFPlayer.volume(10);“. Hier sollte als Lautstärke dann der Maximalwert (30) eingetragen werden.

Wenn die oben genannten Einstellungen sowie der Aufbau erfolgreich waren, spielt der Arduino Mikrocontroller unmittelbar nach dem Start die erste MP3-Datei ab. Für einen „GettingStarted“ Sketch ist der geöffnete Sketch schon relativ unübersichtlich. Daher sehen wir uns hier einmal den Sketch in seiner Minimalform an.

3.4.1. Codebeispiel

#include "Arduino.h"
#include "SoftwareSerial.h"
#include "DFRobotDFPlayerMini.h"

SoftwareSerial mySoftwareSerial(10, 11); // RX, TX
DFRobotDFPlayerMini myDFPlayer;

void setup()
{
    mySoftwareSerial.begin(9600);
    myDFPlayer.volume(30);  //Lautstärke auf Maximum (30)
}

void loop()
{
    myDFPlayer.play(1);  //Spielt die erste MP3-Datei ab
    delay(3000); // Nach dem Abspielen der Datei pausiert der Sketch für drei Sekunden.
}

3.5. Servomotor der Aufzugtür

Die Aufzugtür wird mithilfe eines Servomotors und einer kleinen Mechanik in Bewegung gesetzt.

In dieser Anleitung möchten wir die Aufzugtür öffnen und schließen.

Aufgabe: Ein Servomotor, auch „Servo“ genannt, soll von einem Arduino-Mikrocontroller angesteuert werden. Der Servo soll dazu in diesem Beispiel drei verschiedene Positionen ansteuern und zwischen den Positionen eine kurze Zeit warten.

Servomotoren sind nicht mit regulären Elektromotoren vergleichbar, da es keine Drehachse gibt, die sich permanent drehen kann. Die Drehachse ist nur in einem kleinen Winkelbereich, meistens ca. 180°, beweglich. Im Inneren des Servos befindet sich ein Potentiometer, welches die durch den Mikrocontroller vorgegebene Winkelposition während des Betriebs permanent überwacht. Durch eine kleine Regelelektronik im Inneren des Servos wird die Position auch bei äußeren mechanischen Einflüssen gehalten und ggf. korrigiert. Die Ansteuerung erfolgt über die Signalleitung in Form einer elektrischen Spannung, die vom Mikrocontroller ausgegeben wird.

Beim Funduino-Aufzug ist auf der Rückseite (mittig links) des Aufzugturms ein Steckplatz für den Servomotor vorhanden. Man muss darauf achten, dass das Kabel mit der braunen Leitung auf GND eingesteckt wird. Nach dem Einstecken ist die Signalleitung für den Servo mit dem Pin D37 des Arduino-MEGA-Mikrocontrollers verbunden.

3.5.1. Beispielcode

#include <Servo.h>	//Die Servobibliothek wird aufgerufen.
Servo servoblau;	//Erstellt für das Programm ein Servo mit dem Namen „servoblau“.

void setup()
{
    servoblau.attach(37); //Servo wird mit Pin 37 verbunden.
}
void loop()
{
    servoblau.write(0);	   //Position 1 ansteuern mit dem Winkel 0°.
    delay(3000);		   //Das Programm stoppt für 3 Sekunden.
    servoblau.write(90);   //Position 2 ansteuern mit dem Winkel 90°.
    delay(3000);		   //Das Programm stoppt für 3 Sekunden.
    servoblau.write(180);  //Position 3 ansteuern mit dem Winkel 180°.
    delay(3000);		   //Das Programm stoppt für 3 Sekunden.
}

Mit diesem Sketch öffnet und schließt sich die Tür des Aufzugs in verschiedenen Öffnungsstufen.

Wenn die Tür sich langsam auf und zu bewegen soll, dann muss man die Winkelangaben in eine Programmschleife setzen, bei der sich der Drehwinkel des Servos nur langsam verändert.

3.6. Motor mit Motortreiber L293D ansteuern

In dieser Anleitung möchten wir den Gleichstrommotor über den L293D steuern. Dazu verwenden wir einen kleinen Sketch, mit dem wir den Motor lediglich vorwärts und rückwärtslaufen lassen.

Der Motortreiber ermöglicht es uns, dass die sogenannte Last (also der Motor) in beiden Richtungen mit genügend Energie betrieben werden kann. Die Ausgänge des Mikrocontrollers können nur eine sehr geringe Stromstärke liefern, mit der sich der Motor nicht bewegen würde.

Grundlagen zum L293D Modul

Das Modul verfügt über zwei Kanäle, es könnte also zwei Motoren getrennt voneinander betreiben. Beim Aufzug verwenden wir nur einen Kanal.

Für die Ansteuerung werden neben der Spannungsversorgung drei Kontakte benötigt. Die Spannungsversorgung ist bereits über die Verkabelung auf der Platine des Aufzugs hergestellt.

Drehrichtung des Motors

Es gibt beim Funduino Aufzug zwei digitale Eingänge am L293D. Diese sind an D6 und an D7 angeschlossen und werden nur mit einem HIGH oder LOW Signal angesteuert. Die Kombination bestimmt dabei die Drehrichtung des Motors.

  • D6= LOW und D7= LOW  – Motorbewegung: Stillstand
  • D6= HIGH und D7= HIGH  – Motorbewegung: Stillstand
  • D6= LOW und D7= HIGH  – Motorbewegung: Linksdrehend
  • D6= HIGH und D7= LOW  – Motorbewegung: Rechtsdrehend

Geschwindigkeit des Motors

Die Geschwindigkeit des Motors richtet sich nach der Höhe der Spannungsversorgung und der Ansteuerung per PWM-Signal am Eingangspin des L293D-Moduls. Ein hohes PWM-Signal bedeutet die maximale Geschwindigkeit und ein kleines PWM-Signal bedeutet Stillstand.

Der Code für die Geschwindigkeit lautet:

analogWrite(GSM1, 200); 

Der Zahlenwert (hier 200), kann zwischen 0 und 255 gewählt werden.

Der Wert „GSM1“ wurde zuvor als Variable für den Pin D8 festgelegt.

3.6.1. Beispielcode

int GSM1 = 8;
int in1 = 6;
int in2 = 7;

void setup()
{
  pinMode(GSM1, OUTPUT);    
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
}
void loop()
{
  digitalWrite(in1, HIGH);  // Motor 1 beginnt zu rotieren
  digitalWrite(in2, LOW);

  analogWrite(GSM1, 200);   // Motor 1 soll mit der Geschwindigkeit "200" (max. 255) rotieren
  delay(2000);

  digitalWrite(in1, LOW);   // Durch die Veränderung von HIGH auf LOW (bzw. LOW auf HIGH) wird die Richtung der Rotation verändert.
  digitalWrite(in2, HIGH);  
  delay(2000);

  digitalWrite(in1, LOW);   // Anschließend sollen die Motoren 2 Sekunden ruhen.
  digitalWrite(in2, LOW);  
  delay(2000);
}

3.7. OLED-Display

Der Aufzug verfügt über eine Anzeige, auf der Statusinformationen dargestellt werden können.

Die Anzeige hat eine Auflösung von 128 × 64 Pixeln und ist in einer Header-Buchse gesteckt. Dadurch kann es auch gegen andere Bildschirme getauscht werden.

OLED-Displayshaben im Vergleich zu LCD-Displays (Liquid Crystal Display – Flüssigkristallanzeige) den Vorteil, dass sie sehr dünn sind und einen guten Kontrast aufweisen. Daher ist diese Technik in vielen Geräten des Alltags immer häufiger zu finden. Die kleinen OLED-Displays im Bereich der Mikroelektronik sind in der Regel monochrome, also einfarbige Displays. Die leuchtenden Pixel haben im Vergleich zur Hintergrundfarbe nur eine Farbmöglichkeit. Selbst zweifarbige OLEDs, die wir z. B. in dieser Anleitung verwenden, sind monochrom. Im oberen Bereich des Displays (Reihe 1–16) können die Pixel nur gelb und unten (Reihe 17–64) nur blau leuchten.

OLED Displays gibt es in vielen Varianten. Sie unterscheiden sich in Farbe, Größe und auch in der Technik der Ansteuerung. Für diese Anleitung nutzen wir ein Display mit einer Auflösung von 128 × 64 Pixel und einer Ansteuerung über den I²C Bus (im Deutschen gesprochen als „I-Quadrat-C“). Das OLED Display befindet sich bei diesem Modul auf einer PCB, welches den Treiberchip SSD1306 und die Anschlusspins enthält.

Pinout

Das Display verfügt über vier Pins:

  • VCC – Pin für die Spannungsversorgung, anzuschließen an den 5V Pin des Mikrocontrollers.
  • GND – Ground-Pin, anzuschließen an den GND Pin des Mikrocontrollers
  • SDA und SCL mit den dafür vorgesehenen Kontakten am Mikrocontroller

Programmierung

Für die Programmierung von OLED Displays gibt es viele Möglichkeiten. Zunächst muss überlegt werden, welche Library man verwenden möchte. Alle Libraries haben Vor- und Nachteile. Alle haben die Gemeinsamkeit, dass durch die Installation der Library auch diverse Beispielsketche mitinstalliert werden, die in der Arduinosoftware unmittelbar nach der Installation im Menüpunkt Datei → Beispiele auftauchen.

Diese Beispiele geben viele Hinweise auf die Möglichkeiten der Programmierung und zeigen auch grafische Anwendungen auf. Jedoch bringen die vielen Möglichkeiten auch den Nachteil mit sich, dass sehr viel interner Speicher des Mikrocontrollers belegt wird. Für konkrete Operationen wie dem Auswerten von Sensordaten bleibt dann zu wenig Speicherplatz übrig. Deswegen befassen wir uns in dieser Anleitung mit einer Bibliothek, die Speicher optimiert und leicht zu bedienen ist. Die Library findet man über den Bibliotheksverwalter unter dem Namen „SSD1306Ascii“.

Um einen ersten Eindruck über die Möglichkeiten zu bekommen, bietet es sich an, zunächst einige Beispielsketche zu testen, die automatisch mit der Installation der Library installiert werden. Ein Sketch heißt „FontSamplesWire“. Man findet ihn in der Arduinosoftware unter dem Menüpunkt:

Datei → Beispiele → SSD1306Ascii → FontSamplesWire.

Nach dem Hochladen tauchen auf dem OLED Display viele verschiedene Schriftarten auf, die in der Library hinterlegt sind. Auf dem UNO Controller nimmt dieser Sketch 96 % des Speicherplatzes ein. Hier wird also auch klar, dass während der regulären Verwendung möglichst wenig verschiedene Schriften verwendet werden sollten.

Die Schriftarten erscheinen bei dem genannten Sketch der Reihe nach auf dem OLED Display:

Ein wesentlich kleinerer Beispielsketch eignet sich gut für die ersten eigenen Programmierungen.

Wir öffnen den Sketch „Hello World“ und Datei → Beispiele → SSD1206Ascii → HelloWorldWire und löschen zunächst alles heraus, was nicht zwingend erforderlich ist.

3.7.1. Beispielcode

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C

SSD1306AsciiWire oled;

void setup() {
  Wire.begin();
  Wire.setClock(400000L);
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
}

void loop()
{
  oled.setFont(System5x7); // Auswahl der Schriftart
  oled.clear(); //Löschen der aktuellen Displayanzeige
  oled.println("Viel"); //Text in der ersten Zeile. "Println" sorgt dabei für einen Zeilensprung.
  oled.print("Erfolg!"); // Text in der zweiten Zeile. Da es keine dritte Zeile gibt, wird hier kein Zeilenumsprung benötigt.
  delay (2000);
}

Außerdem gibt es selbst in dieser „kleinen“ Library viele weitere Funktionen, wie

  • seitliches Scrollen
  • dauerhaftes Auf- und Abscrollen
  • Display um 180° drehen (oled.displayRemap(true);)
  • folgende Textzeile invertieren (oled.setInvertMode(i%2);)
  • gesamtes Display invertieren (oled.invertDisplay(!(i%2));)
  • Buchstabenabstand vergrößern (oled.setLetterSpacing(2);)
  • automatisches Scrollen am Ende des Bildschirms (oled.setScrollMode(SCROLL_MODE_AUTO);)

und vieles mehr. Für jede Funktion beinhaltet die Library einzelne Beispielsketche, die im folgenden Bild markiert wurden

Ausblick

Eine sehr umfangreiche Library trägt den Namen „U8g2“ und ist in der Lage eine Vielzahl von verfügbaren Displays bzw. Displaycontroller anzusteuern.

Auch die enthaltenen Beispiele sind sehr umfangreich und geben insbesondere für grafische Anwendungen Hilfestellungen. Um mit der „U8g2“ Library arbeiten zu können, ist es in jedem Beispielsketch notwendig, das richtige Display zu aktivieren. Dafür muss man wissen, über welchen Displaytreiber das verwendete Display verfügt.
In unserem Fall müssen wir das Display durch Entfernen der zwei Schrägstriche „//“ das entsprechende Display aktivieren. 

Bei OLED Displays mit dem SSD1306 Chip:

U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

Bei OLED Displays mit dem SH1106 Chip:

U8G2_SH1106_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, /* reset=*/ U8X8_PIN_NONE);

Die Ergebnisse sehen dann beispielsweise so aus:

4. Codereferenz

4.1. Funktionen

Zur Steuerung des Arduinoboards und zur Durchführung von Berechnungen.

4.1.1. Mathematik

map(); 

Wandelt einen Zahlenbereich in einen anderen Zahlenbereich um

max(x,y); 

Gibt den höheren Wert zurück

min(x,y); 

Gibt den kleineren Wert zurück

4.1.2. Digitale Ein- und Ausgänge

pinMode(pin, [INPUT \ OUTPUT \ INPUT_PULLUP]);

Setzt den Modus der digitalen Ein- und Ausgänge. Sie können als Eingang, als Ausgang, oder als Eingang mit internem Pull-Up Widerstand gesetzt werden.

digitalWrite(Pin, HIGH or LOW);

Pin= Nummer des digitalen Pins. HIGH bzw. LOW schaltet den Pin auf 5V (HIGH) bzw. auf 0V (LOW)

int var = digitalRead(Pin);

Liest den Status des entsprechenden Pins und speichert HIGH oder LOW.

4.1.3. Analolge Ein- und Ausgänge I/O

analogWrite(pin, var);

Gibt einen analogen Wert am Pin aus, wobei „var“ einen ganzzahligen Wert zwischen 0 und 255 annehmen kann.

int var = analogRead(pin);

Liest den Wert vom analogen Pin. Eine Spannung zwischen 0 und 5V wird als Zahlenwert zwischen 0 und 255 abgespeichert. Beispiel: 2,5 Volt entspricht dem Zahlenwert 128.

4.1.4. Zeit

delay(Zeit);

Pausiert den Sketch für die angegebenen Zeit in Millisekunden

delayMicroseconds(Zeit);

Pausiert den Sketch für die angegebenen Zeit in Mikrosekunden

millis();

Speichert die Zeit in Millisekunden ab dem Beginn des aktuellen Programms

micros();

Speichert die Zeit in Mikrosekunden ab dem Beginn des aktuellen Programms

4.1.5. Erweiterte I/O Funktionen

tone(pin, freq);

Generiert eine Rechteckwelle (bzw. mit angeschlossenem Lautsprecher einen Ton) der vorgegebenen Frequenz. Dafür muss ein Pin mit mit PWM-Funktion verwendet werden.

tone(pin, freq, zeit);

Generiert eine Rechteckwelle (bzw. mit angeschlossenem Lautsprecher einen Ton) der vorgegebenen Frequenz für eine vorgegebene Zeit in Millisekunden. Dafür muss ein Pin mit mit PWM-Funktion verwendet werden.

noTone(pin);

Der Befehl beendet die Abgabe einer Frequenz.

4.2. Variablen - Datentypen und Konstanten

4.2.1. Datentypen

boolean           

0, 1, false (unwahr), true (wahr)

char   

8 Bits: ASCII Zeichen

byte  

8 Bits: 0 bis 255, ohne Vorzeichen

int       

16 Bits: -32,768 bis 32,767 mit Vorzeichen

long    

32 Bits: 2.147.483.648 bis 2.147.483.647 mit Vorzeichen

float   

32 Bits, mit Vorzeichen und Komma (Dezimalstellen)

4.2.2. Konstanten

HIGH \ LOW

INPUT \ OUTPUT

true \ false

LED_BUILTIN

Viele Arduino-Boards haben einen Pin, der mit einer integrierten LED verbunden ist. Die Konstante ist die Nummer des Pins, an den die LED angeschlossen ist. Bei den meisten Boards (bspw. UNO und MEGA) ist diese LED an den digitalen Pin 13 angeschlossen.

4.3. Strukturelemente des Arduinocodes

4.3.1. Vergleichsoperatoren

== „Gleich“

!= „Nicht gleich“

< „Kleiner als“

> „Größer als“

<= „Kleiner oder gleich“

>= „größer oder gleich“

4.3.2. Boolesche Operatoren

&&  „und“

|| „oder“

! „nicht“

4.3.3. Kommentare

// Kommentare zum Sketch werden hinter die beiden Schrägstriche geschrieben. Sie haben keinen Einfluss auf den Sketch und werden nicht auf das Board geladen.

/* Schrägstrich und Sternchen verwendet man für umfangreiche Kommentare, die über die Länge einer Zeile hinaus gehen */

4.3.4. Struktur

Jeder Arduino-Sketch muss die beiden folgenden Funktionen besitzen.

void setup() {}

Dieser Code läuft nur ein einziges Mal zu Beginn der Sketch-Ausführung

void loop() {}

Dieser Code wiederholt sich immer wieder, solange das Arduinoboard mit Spannung versorgt wird.

4.3.5. Rechenzeichen

=  Zuordnung

+  Addition

  Subtraktion

*  Multiplikation

/  Division

% Modulo (ist eine mathematische Funktion, die den Rest aus einer Division zweier ganzer Zahlen benennt)

4.3.6. Kontrollstrukturen

if(Bedingung) {}

Wenn die Bedingung wahr ist, mache dies

else {}

ansonsten mache dies

for(Initialisierung; Bedingung;Zuwachs) {}

mache dies

Die „for“ Anweisung wird verwendet, um einen Anweisungsblock mit einer festgelegten Häufigkeit zu wiederholen.  Beispiel: Der folgende Programmblock wird zehnmal wiederholt. Der Zählvorgang startet bei 0. Die Bedingung lautet, dass die Wiederholung so lange stattfindet, wie x kleiner als 10 ist. Nach jeder Ausführung wird x durch das „++“ um eine Zahl höher. Alternativ kann auch „–“ verwendet werden, um einen „negativen“ Zuwachs zu erreichen. for (x=0; x<10; x++) {Programmblock}

goto name;

Der Befehl „goto“ verursacht einen Sprung  zur Stelle mit dem entsprechenden Namen

name: