Ultraschall-Abstandswarner mit dem Multi Function Shield
Das Multi Function Shield, das ich ja bereits vorgestellt habe, bietet mit der Möglichkeit zur einfachen Anzeige von Daten auf seinem 4-fach-7-Segment-Display und den freien Anschlusspins eine gute Grundlage, Sensoren ausprobieren.Heute soll mit dem MFS und einem HC-SR04 Ultraschall-Modul ein piepender Abstandswarner realisiert werden, wie er auch in Autos als Einparkhilfe verbaut ist.
Ultraschall - Sender / Empfänger HC-SR04
Das Prinzip der Entfernungsmessung per Ultraschall ist das Folgende: Es wird ein kurzer Schallimpuls im Ultraschallbereich, d. h. außerhalb des Hörbereichs des Menschen, sprich über 20 kHz, ausgesendet. Dieser Schallimpuls wird von gerade Flächen wie Wänden reflektiert und wird vom Modul wieder aufgefangen und dabei wird die Zeit zwischen Senden und Empfangen gemessen.
Da die Schallgeschwindigkeit in der Luft mit 343 m/s bekannt ist, kann man nun die Entfernung berechnen, die der Schall zurückgelegt hat. Ist z. B. vier Millisekunden zwischen Senden und Empfangen vergangen, so ist die einfache Strecke (entspr. 2 ms) 0.343 m/ms mal 2, also 0.686 m oder 68.6 cm.
Um möglichst genau Messergebnisse zu erhalten, wird der im ATmega verbaute Hardware-Timer über die TimerOne-Library angesprochen.
Die MFS-Library verfügt bereits über die Funktionen getSonarDataCm(byte triggerPin, byte echoPin), die die TimerOne-Library nutzt und uns die Zentimeter Entfernung einer Ultraschallmessung zurückgibt.
Technisch funktioniert das so: Wenn am Trigger-Pin 10 µs ein HIGH-Signal anliegt (gesendet vom digitalen Ausgang des Arduinos), sendet der Sensor 8 Ultraschallimpulse aus. Am Echo-Pin liegt anschließend ein Pulssignal an, welches der Zeit entspricht, die bis zum Echo vergangen ist. Die Zeit des Signals kann mit der pulseIn() Funktion gemessen werden (digitaler Eingang des Arduinos). Der Arduino Uno dürfte schnell genug sein, um weit unter einem cm messen zu können. Die Genauigkeit sollte sehr gut sein, wenn auf große Objekte gezielt wird.
Der HC-SR04 verfügt über 4 Pins:
- VCC: wird an 5V des 3x4 Pinheaders des MFS angeschlossen
- GND: wird an GND des 3x4 Pinheaders des MFS angeschlossen
- Trig: wird an GPIO 5 des 3x4 Pinheaders des MFS angeschlossen
- Echo: wird an GPIO 6 des 3x4 Pinheaders des MFS angeschlossen
Danach kann das Modul irgendwo an der Platine befestigt werden. Gemessen wird immer senkrecht zu und ab den Ultraschallköpfen. Für eine mobile Messung empfiehlt sich die Spannungsversorgung mit Batterie oder Akku.
Rechnet man dann den Abstand zwischen Hinterkante Platine und Vorderkante Ultraschallköpfe von den angezeigten cm ab - oder ändert das Programm um diesen Offset hat man einen klasse Entfernungsmesser, um z. B. Räume auszumessen, ähnlich so einem Gerät, nur halt günstiger und mit wieder verwendbaren Komponenten.
Perfekt wird das Teil natürlich mit einem schmucken, selbstentworfenden und gedrucktem 3D-Gehäuse.
Programm
Das Programm basiert auf dem mit der MFS-Library mitgelieferten Beispielprogrämmchen, allerdings mit der einen oder anderen Verbesserung.Hier eine kurze Bedienungsanleitung: Nach dem Einschalten zeigt das Display "1. Aus", was meint, dass der Abstandsmesser / Warner aus ist und "2. Lt" was für "laut" steht. In diesem Modus piept der Abstandswarner neben der Anezige der Zentimeter, und dies je schneller, desto näher er dem reflektierenden Objekt kommt.
Wer das nervige Gepiepe vermeiden will, weil er nicht rückwärts einparkt, sondern nur eine Entfernung messen will, drückt im Aus-Modus einmal die Taste 2. Die Anzeige "LEIS" bestätigt den Leise-Modus. Nochmaliges Drück des Tasters 2 schaltet wieder in den Laut-Modus.
Mit Taster1 wird die Entfernungsmessung gestartet, je wie gewählt lautlos und mit lautem Piepen. Dies ist der An-Modus. Durch nochmaliges Drücken des 1. Tasters wird wieder in den Aus-Modus gewechselt, wo dann auch wieder zwischen Laut- und Leise-Modus gewechselt werden kann.
Im Aus-Modus erlischt die Anzeige nach 2 Sekunden, um Strom zu sparen.
Ich habe ein kleines Video gemacht, um die Funktionen und die Genauigkeit zu demonstrieren. Das Verwackeln möchte man mir verzeihen, irgendwie hatte ich zwei Hände zu wenig.
Source-Code
////////////////////////////////////////////////////////
// (C) 2018 by Oliver Kuhlemann //
// Bei Verwendung freue ich mich über Namensnennung, //
// Quellenangabe und Verlinkung //
// Quelle: http://cool-web.de/arduino/ //
////////////////////////////////////////////////////////
#include <TimerOne.h> // für Timings und Interrupts
#include <MultiFuncShield.h> // API für das Multi Function Shield
#define PinTrigger 5
#define PinEcho 6
byte WarnerAn = 0;
byte Piepen = 1;
void setup() {
pinMode(PinTrigger, OUTPUT);
pinMode(PinEcho, INPUT);
Timer1.initialize(); // TimerOne initialisieren
MFS.initialize(&Timer1); // Multi Function Shield initialisieren
MFS.write("1.aus"); // Warner ist erstmal aus und laut
delay (2000);
MFS.write("2. lt");
delay (2000);
MFS.write("");
}
void loop() {
byte btn = MFS.getButton();
if (WarnerAn == 0) { // im AUS-Modus
if (btn == BUTTON_1_PRESSED) { // anschalten
WarnerAn = 1;
if (Piepen) MFS.beep(5, 95, 1, 0, 0);
MFS.write("an");
}
if (btn == BUTTON_2_PRESSED) { // laut/leise schalten
if (Piepen == 1) { Piepen=0; MFS.write("leis"); delay(1000); MFS.write("");
} else { Piepen=1; MFS.write("laut"); delay(1000); MFS.write(""); }
}
} else { // im AN-Modus
if (btn == BUTTON_1_PRESSED) { // ausschalten
WarnerAn = 0;
MFS.beep(0);
MFS.write("aus");
delay (1000);
MFS.write("");
MFS.blinkDisplay(DIGIT_ALL, OFF);
MFS.initSonar();
} else { // Warnbetrieb
// senden eines 10 Mikrosekunden langen Ultraschall-Pulses über
// PinTrigger. Danach wird die Laufzeit mit Timern gemessen, bis
// das Signal auf den 2. Ultraschallsensor trifft und PinEcho auf
// High setzt. Laufzeit relativ zur Schallgeschwindigkeit ergibt
// dann die Distanz in Zentimetern, die zurückgegeben wird.
int distance = MFS.getSonarDataCm(PinTrigger, PinEcho);
if (distance != 0 && distance < 2000) {
int offPeriod = distance - 6; // hier ggf. eigene Abweichungen angeben
if (offPeriod < 0) offPeriod = 0;
MFS.write(distance);
MFS.setBeepOffPeriod(offPeriod);
// wenn nur noch 10 cm oder weniger, Display blinken lassen
MFS.blinkDisplay(DIGIT_ALL, distance < 11);
}
delay(100);
} // Endif BUTTON_1_PRESSED
} // Endif an/aus
}