Inhalt
Material
- HCSR04
- Diverse Kabel
- Steckbrett
Aufbau
Der Abstandssensor ist sehr einfach anzusteuern. Er hat insgesamt folgende vier Anschlüsse:
HCSR04 |
Der gesamte Aufbau ist sehr einfach:
Gesamtaufbau |
Bei mehreren Abstandssensoren würde ein einziger Anschluss für alle TRIG-Signale ausreichen. Der Abstand zwischen zwei TRIG-Signale muss mindestens 20 ms sein. Ein Rechteck-Signal mit 50 Hz ist folglich die maximal mögliche Frequenz zum kontinuierlichen Messen.
Programm
Der Ultraschall-Abstandssensor benötigt zwei Anschlüsse, die initialisiert werden müssen:
#define TRIG 28 #define ECHO 29 void init() { pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT); digitalWrite(TRIG, HIGH); }
Das Programm wird in zwei Threads laufen. Ein Thread erzeugt das Rechteck-Signal zum Triggern des Sensors, während der andere Thread in einer Endlosschleife das Echo-Signal ausliest. Als erstes kommen die Funktionen für das Rechteck-Signal. Dazu wird eine Funktion benötigt, die einen kurzen LOW-Peak erzeugt, um mit einer fallenden Flanke eine Messung auszulösen. Die Funktion sieht wie folgt aus:
#define TRIGTIME 50 void TRIG_tick() { digitalWrite(TRIG, LOW); delayMicroseconds(TRIGTIME); digitalWrite(TRIG, HIGH); delayMicroseconds(TRIGTIME); }
Insgesamt benötigt die Funktion mindestens 100 Mikrosekunden. Diese Funktion wird in einer Endlosschleife kontinuierlich aufgerufen. Ich habe mich dazu entschieden, jede halbe Sekunde eine Messung zu starten. Die Zeit kann beliebig angepasst werden.
#define WAVELENGTH 500 void infiniteRect() { while(1) { TRIG_tick(); delay(WAVELENGTH); } }
Damit ist für das Rechteck-Signal alles vorbereitet.
Die Funktion für das Auslesen ist ein wenig komplexer, beinhaltet aber alles, was unter dem Punkt 'Aufbau' genannt ist. Es wird gewartet, bis das ECHO-Signal auf HIGH ist. Der Zeitpunkt dafür wird mit clock_gettime aus der time.h aufgezeichnet. Anschließend wird gewartet, bis das Signal auf LOW zurück fällt. Der Zeitpunkt dafür wird ebenfalls dokumentiert und eine Differenz zum Startzeitpunkt berechnet. Die Differenz wird mit der Schallgeschwindigkeit multipliziert und damit der gesamte Weg für den Schall berechnet. Da die Schallwelle sich hin und anschließend wieder zurück bewegt, muss die Distanz durch 2 dividiert werden, um die Strecke für eine einzige Richtung zu ermitteln. Dies ist dann die gemessene Distanz zum Objekt. Das ganze in Form einer Funktion sieht folgendermaßen aus:
void infiniteRead() { struct timespec start; struct timespec end; while(1) { while(digitalRead(ECHO) == LOW) { // Abwarten bis Triggersignal eine Messung auslöst. // Sobald ECHO auf HIGH, geht eine Messung los. } // Akutellen Zeitpunkt zum Beginn der Messung bestimmen. clock_gettime(CLOCK_REALTIME, &start); while(digitalRead(ECHO) == HIGH) { // Abwarten bis Messung zuende ist. // Sobald ECHO auf LOW, ist die Messung vorbei. } // Akutellen Zeitpunkt zum Ende der Messung bestimmen. clock_gettime(CLOCK_REALTIME, &end); // Zeitdifferenz in Mikrosekunden unsigned int timediff = (end.tv_nsec - start.tv_nsec)/1000; // 200 ms = 200000 Mikrosekunden if(timediff >= 200000) { // Laut Datenblatt wird nach 200 ms die Messung abgebrochen, // falls kein Echo gemessen wird. std::cout << "Fehlerhafte Messung." << std::endl; } else { /* 1. 343 m/s = 0.0343 cm/Mikrosekunden 2. timediff liegt in Mikrosekunden vor 3. timediff * 0.0343 cm/Mikrosekunden sind doppelte Distanz zum Objekt in cm weil der Schall hin und zurück geht. 4. Division durch 2 um Distanz für nur einen Weg zu haben */ double dist = (timediff*0.0343)/2; std::cout << "Distanz in cm: " << dist << std::endl; } } }
Nun muss das ganze in einer main-Funktion zusammengefasst werden:
int main() { if(wiringPiSetup() == -1) { return 0; } init(); std::thread rect(infiniteRect); infiniteRead(); return 0; }
Die Funktion clock_gettime benötigt eine weitere Bibliothek 'lrt', die beim Kompilieren mit eingebunden werden muss. Außerdem muss man beachten, dass std::thread zum c++11 Standard gehört und dies beim Kompilieren ggf. beachtet werden muss. Beispielsweise wird g++ Version 4.7 benötigt. Die Kommandozeile sah bei mir so aus:
g++-4.7 US.cpp -o US -lwiringPi -lrt -std=c++11
Beim Ausführen dieses Programms wird nun jede halbe Sekunde eine Distanz in cm zu einem Objekt, auf den der Sensor gerichtet ist, auf der Konsole ausgeben.
Ich hoffe dieses Tutorial hat euch bei der Verwendung des HCSR04 weitergeholfen oder euch seinen Nutzen näher gebracht und euch zum Kauf angeregt. Für weitere Informationen zum HCSR04 siehe:
Keine Kommentare:
Kommentar veröffentlichen
Hinweis: Nur ein Mitglied dieses Blogs kann Kommentare posten.