sketch_34_IR_fernsteuerung_mit_hupen_hinderniserkennung

sketch_34_IR_fernsteuerung_mit_hupen_hinderniserkennung
  /*Dieser Sketch faehrt das Auto und hupt per IR-Fernbedienung.
  Die Codes wurden vorher ermittelt mit Sketch 30 und sind in Codes.h angegeben.
  Fahren auch nach Loslassen der jeweiligen Taste, solange bis eine andere Taste gedrueckt wird.
  Deshalb wird eine Taste fuer Stoppen erforderlich.
  Zusaetzlich wird der US-Sensor abgefragt.
  Wenn in vorwaerts-Richtung ein Hindernis im Abstand < 40cm erkannt wird, faehrt das Auto fuer 1 Sek rueckwaerts
  und stoppt.*/
      
  #include <IRremote.h>
  #include "Codes.h"
  #include "Fahrablaufmodule.h"
  #include "Hupen.h"
  #include "us_hindernisabfrage.h"
    
  #define RECV_PIN  12
  IRrecv irrecv(RECV_PIN);          //IRremote.h den Eingangs Pin mitteilen 
  decode_results results;
  unsigned long val;
  unsigned long preMillis;
  
  void setup()
  {
    Serial.begin(9600);
    pinMode(7, OUTPUT);             //Pins als Ausgaenge fuer Motoren  
    pinMode(17, OUTPUT);
    pinMode(5, OUTPUT);
    pinMode(11, OUTPUT);
    pinMode(8, OUTPUT);
    pinMode(6, OUTPUT);  
    pinMode(2, OUTPUT);             //Pin D2 als Signal Trig zum HC-SR04
    pinMode(19, INPUT);             //Pin D19 (=A5) als Signal Echo vom HC-SR04   
    irrecv.enableIRIn();            // Eingang auf Pin D12 aktivieren
  }
  
  void loop()
  {
   us_hindernisabfrage();           //us-hindernisabfrage wird aufgerufen 
   Serial.println(hindernis);  
   if (hindernis==1)                //wenn geradeaus (in Richtung des US-Sensors) ein Hindernis ist... 
   {
    back();                         //wird 1 Sek zurueckgefahren
    delay (1000);
    stopp();
   }
      
   if (irrecv.decode(&results))    // Wenn IRremote.h ein decodiertes Signal liefert ... 
   { 
    preMillis = millis();
    val = results.value;
    irrecv.resume();                //Timer startet neu (neue Messung durchfuehren)     
    switch(val)
      {
      case F: forward(); break;     //break: Programm springt weiter (wird auch bei for-Schleifen benutzt)
      case B: back(); break;
      case L: left(); break;
      case R: right(); break;
      case S: stopp(); break;
      case H: hupen();break;   
      default: break;
      }
    }
    else
    {
    if(millis() - preMillis > 200)
      {
      preMillis = millis();
      }
    }      
  } 
Codes.h
  /*Codes*/
  #define F 16718055                  // FORWARD  (Button " Pfeil vor ")
  #define B 16730805                  // BACK     (Button " Pfeil rueck ")
  #define L 16716015                  // LEFT     (Button " Pfeil links ")
  #define R 16734885                  // RIGHT    (Button " Pfeil rechts ")
  #define S 16726215                  // STOPP    (Button " OK ")
  #define H 16750695                  // HUPEN    (Button " 0 ")     
  #define A 16738455                  // GREIFER AUF (Button " * ")  hier nicht programmiert
  #define Z 16756815                  // GREIFER ZU  (Button " # ")  hier nicht programmiert
Fahrablaufmodule.h
  void forward()
  {   
    digitalWrite(7, HIGH);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, LOW);                                                      
    analogWrite(5, 150);              // Setze die Geschwindigkeit 0...255
    digitalWrite(11, HIGH);           // Schalte Motoren LINKS ein 
    digitalWrite(8, LOW);                                
    analogWrite(6, 150);              // Setze die Geschwindigkeit 0...255
    Serial.println("FORWARD");
  }
  
  void back()
  {   
    digitalWrite(7, LOW);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, HIGH);                                                      
    analogWrite(5, 100);             // Setze die Geschwindigkeit 0...255
    digitalWrite(11, LOW);           // Schalte Motoren LINKS ein 
    digitalWrite(8, HIGH);                                
    analogWrite(6, 100);             // Setze die Geschwindigkeit 0...255
    Serial.println("BACK");
  }
  
  void left()
  {   
    digitalWrite(7, HIGH);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, LOW);                                                      
    analogWrite(5, 120);              // Setze die Geschwindigkeit 0...255
    digitalWrite(11, HIGH);           // Schalte Motoren LINKS ein 
    digitalWrite(8, LOW);                                
    analogWrite(6,0);                 // Setze die Geschwindigkeit 0...255
    Serial.println("LEFT");
  }
  
  void right()
  {   
    digitalWrite(7, HIGH);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, LOW);                                                      
    analogWrite(5,0);                 // Setze die Geschwindigkeit 0...255
    digitalWrite(11, HIGH);           // Schalte Motoren LINKS ein 
    digitalWrite(8, LOW);                                
    analogWrite(6,120);               // Setze die Geschwindigkeit 0...255
    Serial.println("RIGHT");
  }
  
  void stopp()
  {
    digitalWrite(7, LOW);             // Schalte alle Motoren aus
    digitalWrite(17, LOW);  
    digitalWrite(11, LOW); 
    digitalWrite(8, LOW);  
    Serial.println("STOP");  
  }
Hupen.h
   /*Es wird ein Ton erzeugt mit einem Passive Buzzer (Piezo-Summer).
    Die Tonhoehe (Frequenz) und Tondauer kann programmiert werden.
    Achtung: Der Befehl "tone()" kann nicht verwendet werden, ist in Kollision mit dem Bibliotheksprogramm IRremote.*/ 
     
    void hupen()
    {
     pinMode(4, OUTPUT);                   //an Pin D4 Tonsignal zum Passive Buzzer 
     for (int i=0 ; i<500 ; i++)           //HIGH-LOW wiederholen i-mal
      {
      digitalWrite (4 , HIGH);             // HIGH fuer 1ms
      delay (1);
      digitalWrite (4 , LOW);              // LOW fuer 1ms
      delay (1);
      }                                   
    }
us_hindernisabfrage.h
  /*Dieses Unterprogramm ermittelt die Entfernung zu einem Hindernis und setzt ein Flag ab einem Grenzwert.*/
  
  long dauer=0;                             // in der Variablen "dauer" soll die Zeit gespeichert werden, die eine Schallwelle bis zur Reflektion und zurueck benoetigt 
  long entfernung=0;                        // in der Variablen "entfernung" soll die berechnete Entfernung gespeichert werden. 
  int hindernis;                            // Definiere Flag "hindernis" und setze auf 0 (kein Hindernis)
  
  void us_hindernisabfrage()
  {
    digitalWrite(2, LOW);                   // Hier nimmt man die Spannung fuer kurze Zeit vom Trig-Pin, damit man spaeter beim Senden ein rauschfreies Signal hat
    delay(5);                               // ...fuer die Dauer 5 Millisekunden
    digitalWrite(2, HIGH);                  // Ein HIGH-Signal wird zum Trig-Eingang des HC-SR04 gesendet
    delayMicroseconds(15);                  // Die Dauer muss mindestens 10 Mikrosek sein, hier gewaehlt 15 Mikrosek
    digitalWrite(2, LOW);                   // Wenn das Trig-Signal wieder auf LOW geht, sendet der HC-SR04 Ultraschallwellen aus (8mal, Frequenz 40kHz)
    dauer = pulseIn(19, HIGH);              // Der Arduino zaehlt die Zeit in Mikrosek, bis der reflektierte Schall zum Ultraschallsensor zurueckkehrt
    entfernung = (dauer/2) * 0.03432;       // Nun wird aus der Zeit die Entfernung in Zentimetern berechnet (Bsp.: 10ms entspricht Entfernung 170cm)
    Serial.print(entfernung);               // Der Wert der Entfernung wird an den Serial Monitor uebergeben
    Serial.println(" cm");                  // Hinter dem Wert der Entfernung soll die Einheit "cm" angegeben sowie die Anzeigezeile gewechselt werden
    if (entfernung < 40)                    // Wenn der Wert fuer die Entfernung unter 40 Zentimeter betraegt dann... 
    {
    hindernis = 1;                          // Setze Flag "hindernis" auf 1
    }
    else                                    // Und wenn das nicht so ist...
    {
    hindernis = 0;                          // Setze Flag "hindernis" auf 0  (kein Hindernis)
    }
  }