sketch_34_IR_fernsteuerung_mit_greifer_hupen_hinderniserkennung

sketch_34_IR_fernsteuerung_mit_greifer_hupen_hinderniserkennung
  /*Dieser Sketch faehrt das Auto, betaetigt den Greifer 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 jetzt zusaetzlich eine Taste fuer Stoppen erforderlich.

  Zusaetzlich wird der US-Sensor abgefragt.
  Wenn in vorwaerts-Richtung ein Hindernis im Abstand < 50cm erkannt wird, faehrt das Auto langsam rueckwaerts
  (back_slow), solange bis ein neuer Befehl von der IR-Fernbedienung kommt.
    
  Achtung: +5Vdc vom L298N muss an den Servo gelegt werden (Stromversorgung ueber USB vom Arduino reicht nicht).*/  
    
  #include <IRremote.h>
  #include "Codes.h"
  #include "Fahrablauf_Module.h"
  #include "Greifer.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(10, OUTPUT);            //Pin D10 als Ausgang fuer den Greifer-Servo  
    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) back_slow();   //wenn geradeaus (in Richtung des US-Sensors) ein Hindernis ist... 
      
   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 A: auf(); break;
      case Z: zu(); break;
      case H: hupen();break;   
      default: break;
      }
    }
    else
    {
    if(millis() - preMillis > 200)
      {
      preMillis = millis();
      }
    }      
  } 
Codes.h
  /*Codes */
  #define F 16718055                           // FORWARD  (Button " ↑ ")   HTML: ....
  #define B 16730805                           // BACK     (Button " ↓ ")
  #define L 16716015                           // LEFT     (Button " ← ")
  #define R 16734885                           // RIGHT    (Button " → ")
  #define S 16726215                           // STOP     (Button " OK ")

  #define H 16750695                           // HUPEN    (Button " 0 ")   
  
  #define A 16738455                           // AUF      (Button " * ")
  #define Z 16756815                           // ZU       (Button " # ")
Fahrablauf_Module.h
  void forward()
  {   
    digitalWrite(7, HIGH);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, LOW);                                                      
    analogWrite(5, 140);              // Setze die Geschwindigkeit 0...255
    digitalWrite(11, HIGH);           // Schalte Motoren LINKS ein 
    digitalWrite(8, LOW);                                
    analogWrite(6, 140);              // Setze die Geschwindigkeit 0...255
    Serial.println("FORWARD");
  }
  
  void back()
  {   
    digitalWrite(7, LOW);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, HIGH);                                                      
    analogWrite(5, 140);             // Setze die Geschwindigkeit 0...255
    digitalWrite(11, LOW);           // Schalte Motoren LINKS ein 
    digitalWrite(8, HIGH);                                
    analogWrite(6, 140);             // 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");  
  }

  void back_slow()
  {   
    digitalWrite(7, LOW);            // Schalte Motoren RECHTS ein 
    digitalWrite(17, HIGH);                                                      
    analogWrite(5, 90);             // Setze die Geschwindigkeit 0...255
    digitalWrite(11, LOW);           // Schalte Motoren LINKS ein 
    digitalWrite(8, HIGH);                                
    analogWrite(6, 90);             // Setze die Geschwindigkeit 0...255
    Serial.println("BACK_SLOW");
  }
  
Greifer.h
  /* Die "for"-Schleife sorgt dafuer, dass der Servo bis zur Erreichung der Zielstellung aktiviert bleibt. 
     Pin D10 ist vor Beendigung auf LOW gesetzt, deshalb laesst sich der Servo per Hand verdrehen.
     Die Ansteuerung des Servos wird beendet, wird stromlos, es wirkt nur noch die Selbsthaltung es Getriebes.
     Aufgrund des Spiels kann ein gegriffener Gegenstand wieder rausrutschen.
     Wenn aber nicht beendet wuerde, drueckte der Greifer weiterhin zu und es fliesst weiter ein hoher Strom.   
     Achtung: void open bzw void close nicht moeglich, da reservierte Begriffe im Compiler (faerbt sich rot)*/
      
  void auf()
   {
    for (int i=0; i<=80 ; i++)
    {
    digitalWrite(10,HIGH);
    delayMicroseconds(900);            //Bei Einstellung von 0,9ms oeffnet Greifer weit genug
    digitalWrite(10,LOW);
    delay(20);                         //Ergaenzung auf Zykluszeit 20ms
    }
    Serial.println("AUF");
   }
  
   void zu() 
   {
    for (int i=0; i<=80 ; i++)
    {
    digitalWrite(10,HIGH);
    delayMicroseconds(500);            //Bei Einstellung von 0,5ms schliesst Greifer eng genug
    digitalWrite(10,LOW);
    delay(20);                         //Ergaenzung auf Zykluszeit 20ms
    } 
    Serial.println("ZU");
   }
Hupen.h
  /*Codes */
  #define F 16718055                           // FORWARD  (Button " ↑ ")   
  #define B 16730805                           // BACK     (Button " ↓ ")
  #define L 16716015                           // LEFT     (Button " ← ")
  #define R 16734885                           // RIGHT    (Button " → ")
  #define S 16726215                           // STOP     (Button " OK ")

  #define H 16750695                           // HUPEN    (Button " 0 ")   
  
  #define A 16738455                           // AUF      (Button " * ")
  #define Z 16756815                           // ZU       (Button " # ")
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 zurück benötigt 
  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 für 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 µs sein, hier gewaehlt 15µs
    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 Mikrosekunden µs, 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 < 50)                    // Wenn der Wert für die Entfernung unter 50 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)
    }
  }