How To : Radar bauen mit Arduino - der Code für den Arduino

mastercad
05.01.2016 22:00:42
Kommen wir jetzt zum Code für den Arduino:

ich programmiere den Arduino vorzugsweise in C++, dafür gibt es ein ausgezeichnetes Plugin für Eclipse unter Baeyebs Arduino Nightly


hier erstmal die beiden Dateien:

die Radar.cpp

C++ code

  1. #include "Radar.h"
  2.  
  3. Servo oServo;             // instance of class Servo
  4. const int iSonicEcho = 6; // sonic echo pin
  5. const int iSonicTrigger = 7;    // sonic trigger pin (tx)
  6. const int iServoSensor = 9;        // data line for servo
  7.  
  8. const int iAverageCount = 10; // count of readings for Average Calculation of Distance
  9.  
  10. int iCurrentPos = 0;     // current Position of Servo
  11. int iEchoValueSummary = 0;        // Summary of All Average Echo Readings
  12. long lDuration;                    // Duration Time between trigger and echo
  13. unsigned long lDistance = 0;     // current distance, calculatet by ResponseTime
  14.  
  15. /* setup the pins, servo and serial port */
  16. void setup() {
  17.     oServo.attach(iServoSensor);
  18.     // make the trigger (tx) pin an output:
  19.     pinMode(iSonicTrigger, OUTPUT);
  20.     // make the echo pin an input:
  21.     pinMode(iSonicEcho, INPUT);
  22.     // initialize the serial port:
  23.     Serial.begin(9600);
  24. }
  25.  
  26. /* loop */
  27. void loop() {
  28.     // scan from 0 to 90
  29.     scan(0, 90);
  30.     // scan from 90 to 0
  31.     scan(90, NULL);
  32. }
  33.  
  34. /* scan a range between iStart and iEnd */
  35. void scan(int iStart, int iEnd) {
  36.  
  37.     iCurrentPos = iStart;
  38.     int iStep = 1;
  39.     int iFrom = iStart;
  40.     int iTo = iEnd;
  41.  
  42.     if (iStart > iEnd) {
  43.         iFrom = iEnd;
  44.         iTo = iStart;
  45.         iStep *= -1;
  46.     }
  47.  
  48.     for (int iCounter = iFrom; iCounter < iTo; iCounter++) {
  49.         iCurrentPos += iStep;
  50.         oServo.write(iCurrentPos);
  51.         calculateDistance();
  52. //        calculateAverageDistance();
  53.         communicateCurrentData();
  54.         delay(100);
  55.     }
  56. }
  57.  
  58. /* calculate distance between trigger and echo from sonic sensor */
  59. void calculateDistance() {
  60.     readEchoFromSonic();
  61. }
  62.  
  63. /* calculate average distance between trigger and echo from sonic sensor iniAverageCount times */
  64. void calculateAverageDistance() {
  65.     iEchoValueSummary = 0;
  66.  
  67.     for (int iAverageIndex = 0; iAverageIndex <= iAverageCount; iAverageIndex++) {
  68.         readEchoFromSonic();
  69.         iEchoValueSummary += lDuration;
  70.     }
  71.     lDuration = (iEchoValueSummary/iAverageCount);
  72. }
  73.  
  74. /* read duration between trigger and echo from sonic sensor in milliseconds */
  75. void readEchoFromSonic() {
  76.     digitalWrite(iSonicTrigger, LOW);
  77.     delayMicroseconds(2);
  78.     digitalWrite(iSonicTrigger, HIGH);
  79.     delayMicroseconds(10);
  80.     digitalWrite(iSonicTrigger, LOW);
  81.  
  82.     lDuration = pulseIn(iSonicEcho, HIGH);
  83. }
  84.  
  85. /* send current calculated data to Serial Port */
  86. void communicateCurrentData() {
  87.     Serial.print("X");
  88.     Serial.print(iCurrentPos);
  89.     Serial.print("V");
  90.     Serial.println(convertMicrosecondsToCm(lDuration));
  91. }
  92.  
  93. long convertMicrosecondsToInches(long microseconds) {
  94.     return microseconds / 74 / 2;
  95. }
  96.  
  97. long convertMicrosecondsToCm(long microseconds) {
  98.     return microseconds / 29 / 2;
  99. }


die Radar.h

C++ code

  1. // Only modify this file to include
  2. // - function definitions (prototypes)
  3. // - include files
  4. // - extern variable definitions
  5. // In the appropriate section
  6.  
  7. #ifndef _Radar_H_
  8. #define _Radar_H_
  9.  
  10. #include "Arduino.h"
  11. #include <Servo.h>
  12.  
  13. //add your includes for the project Radar here
  14.  
  15.  
  16. //end of add your includes here
  17.  
  18.  
  19. //add your function definitions for the project Radar here
  20.  
  21. void scan(int, int);
  22. void readEchoFromSonic();
  23. void calculateDistance();
  24. void communicateCurrentData();
  25. void calculateAverageDistance();
  26. long convertMicrosecondsToInches(long);
  27. long convertMicrosecondsToCm(long);
  28.  
  29. //Do not add code below this line
  30. #endif /* _Radar_H_ */


Um den Servo laufen lassen zu können brauchen wir noch den Header File für den Servo. Den binden wir in Eclipse folgender Maßen ein:

Man wählt im Menü den Menüpunkt Arduino aus, dann klickt man auf Add a Library to the selected Project. Damit öffnet sich ein Fenster, in dem man die verfügbaren Libraries für den Arduino
sieht. Hier wählt man Servo aus und klickt auf Finish. Damit ist das Projekt vorbereitet zum compilieren.

nun zum Code:

in den Zeilen 4 - 6 machen wir die Pins der beiden Bauelemente bekannt. Wie bereits im Planning der Platine besprochen liegt auf 6 der Echo des Sonic Sensors, auf 7 der Trigger und auf 9 der Datenpin des Servo.

in der Funktion setup initialisieren wir, wie gewohnt, die Bauelemente und setzen die Übertragungsrate der seriellen Schnittstelle.

loop ruft lediglich die scan Funktion auf, in der wir eine Range von bis in Grad angeben.

scan bekommt als parameter die Grad von und die Grad bis, innerhalb derer der Servo sich bewegen soll. Diese Range wird durchlaufen und dem Stepper die Position Schrittweise übergeben. Innerhalb der Schleife wird

  • wie bereits erwähnt der Servo auf seine aktuelle Position gesetzt
  • über den Ultraschall Sensor (HR-SC40) für die aktuelle Position des Servo die Entfernung bis zum nächsten Hindernis berechnet
  • die berechneten Daten ausgegeben



calculateDistance läßt den Ultraschall Sensor die aktuelle Distanz erfragen

calculateAverageDistance läßt den Ultraschall Sensor ebenfalls die Distanz erfragen, hier wird aber an Hand der Klassenvariable iAverageCount mehrmals beim Ultraschall Sensor angefragt und aus den Werten ein Durchschnittswert gebildet, da mir die einfache Anfrage ein großes Stück zu ungenau war.

readEchoFromSonic läßt den Sensor eine Distanzmessung durchführen. Dafür wird der Ultraschall Sensor erst resettet (LOW Signal an den Trigger PIN), 2 Microsekunden später wird ein Schallsignal über den Sensor gesendet, was 10 Microsekunden dauert (HIGH Signal an den Trigger PIN), abschließend wird nach 10 Millisekunden der Trigger PIN wieder mit LOW befeuert, was ihn verstummen läßt.

Die Dauer zwischen dem Absenden und dem Empfang des Signals erhält man über den Echo PIN des Ultraschall Sensors mit pulseIn(PIN, HIGH)

communicateCurrentData dient lediglich der Ausgabe der errechneten Daten und der aktuellen Position des Servo über die Serielle Schnittstelle.

convertMicrosecondsToInches berechnet die erhaltene Dauer bis zur Rückantwort des Echo Signales in Inches um, da 2.5 Inch 1cm sind und der Schall in 1 Microsekunde 29 cm zurück legt, errechnen wir aus der erhaltenenen Dauer des Echos / 74 die Strecke in Inches, da das Echo hin und zurück diese Dauer benötigte, teilen wir das Ergebnis durch 2 und haben somit das Ergebnis einer einfachen Strecke zwischen dem Sensor und dem Hindernis.

convertMicrosecondsToCm berechnet die erhaltene Dauer bis zur Rückantwort des Echo Signals in cm, analog zu convertMicrosecondsToInches, nur das hier die erhaltene Dauer durch 29 gerechnet wird. Die Erklärung sollte aus der Erklärung für das konvertieren in Inches schlüssig sein.