2018-07-10 15:50:17 +02:00
# include <ESP32Servo.h>
2018-08-16 12:31:50 +02:00
# include "esp32-hal-ledc.h"
//----- Taster ------------
# define TASTERPIN 17
2018-07-10 15:50:17 +02:00
//----- Werte für den Servo -----
# define SERVOPIN 16 // Pin an dem der Servomotor angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
2018-08-16 12:31:50 +02:00
# define SERVO_45GRAD_LINKS 140 // Wert um den Servo 45 Grad nach links zu drehen ... der kann je nach Servo anders sein
# define SERVO_45GRAD_RECHTS 35 // Wert um den Servo 45 Grad nach rechtss zu drehen ... der kann je nach Servo anders sein
2018-07-10 15:50:17 +02:00
# define SERVO_0GRAD_MITTE 90 // Wert um den Servo in die Mitte zu drehen ... der kann je nach Servo anders sein
2018-08-16 12:31:50 +02:00
# define SERVO_10GRAD_MITTE 135
# define SERVO_M10GRAD_MITTE 40
# define SERVO_SCHWENK_LI -5
# define SERVO_SCHWENK_RE 5
# define SERVO_SCHWENK_MS 15
2018-07-10 15:50:17 +02:00
//----- Werte für den Ultraschallsensor -----
# define US_TRIG 12 // Pin an dem der TRIG Pin des Ultraschallsensor angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define US_ECHO 14 // Pin an dem der ECHO Pin des Ultraschallsensor angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
2018-08-16 12:31:50 +02:00
# define US_STOP_ABSTAND_CM 15 // Wenn der gemessene Abstand kleiner ist, hält der CodeRacer an
2018-07-10 15:50:17 +02:00
//----- Werte für die Motoren -----
2018-08-16 12:31:50 +02:00
# define MOTORRE_MAX_TEMPO 255 // Geschwindigkeit Motor1 ... ein Wert zwischen 0 und 255
# define MOTORRE_TEMPO 205 // Geschwindigkeit Motor1 ... ein Wert zwischen 0 und 255
# define MOTORLI_MAX_TEMPO 255 // Geschwindigkeit Motor1 ... ein Wert zwischen 0 und 255
# define MOTORLI_TEMPO 200 // Geschwindigkeit Motor1 ... ein Wert zwischen 0 und 255
2018-07-10 15:50:17 +02:00
# define MOTORRE_SPEED 2 // Pin an dem der SPEED/ENABLE Pin des rechten Motors angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define MOTORRE_FWRD 4 // Pin an dem der FORWÄRTS Pin des rechten Motors angeschlossen ist. Was vorwärts und rückwärts ist, muss probiert und vielleicht umgesteckt werden.'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
2018-08-16 12:31:50 +02:00
# define MOTORRE_BACK 15 // Pin an dem der RÜCKWÄRTS Pin des rechten Motors angeschlossen ist. Was vorwärts und rückwärts ist, muss probiert und vielleicht umgesteckt werden.'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define MOTORLI_SPEED 21 // Pin an dem der SPEED/ENABLE Pin des linken Motors angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define MOTORLI_FWRD 22 // Pin an dem der FORWÄRTS Pin des linken Motors angeschlossen ist. Was vorwärts und rückwärts ist, muss probiert und vielleicht umgesteckt werden.'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define MOTORLI_BACK 23 // Pin an dem der RÜCKWÄRTS Pin des linken Motors angeschlossen ist. Was vorwärts und rückwärts ist, muss probiert und vielleicht umgesteckt werden.'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
2018-07-10 15:50:17 +02:00
# define RACER_LINKS_MS 200 // Die Zeit in Millisekunden, die der Racer braucht um sich 45 Grad nach links zu drehen
# define RACER_RECHTS_MS 200 // Die Zeit in Millisekunden, die der Racer braucht um sich 45 Grad nach rechts zu drehen
2018-08-16 12:31:50 +02:00
# define MOTORPWM_LINKS 5 // PWM-Kanal für linken Motor
# define MOTORPWM_RECHTS 6 // PWM-Kanal für rechten Motor
2018-07-10 15:50:17 +02:00
//----- Werte für die LEDs -----
# define LED_VORWAERTS 26 // Pin an dem die VORWÄRTS LED angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define LED_STOP 25 // Pin an dem die STOP LED angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define LED_LINKS 27 // Pin an dem die LINKS LED angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
# define LED_RECHTS 33 // Pin an dem die RECHTS LED angeschlossen ist. 'GPIO' muss man weglassen -> also z.B. nicht GPIO88 sondern nur 88.
//----- Variablen, die wir brauchen um uns Werte zu merken ----
long abstand_vorn_cm , abstand_links_cm , abstand_rechts_cm ;
2018-08-16 12:31:50 +02:00
int schwenkPosition = SERVO_0GRAD_MITTE ;
int schwenkRichtung = SERVO_SCHWENK_LI ;
long schwenkMillis = millis ( ) ;
bool coderracer_activ = false ;
2018-07-10 15:50:17 +02:00
//----- Objekte die wir haben. z.B. den Servo ----
2018-08-16 12:31:50 +02:00
Servo dummy_myservo ; // ein Servo-Objekt anlegen, um den Servo Motor steuern zu können (Timer 0 überspringen)
2018-07-10 15:50:17 +02:00
Servo myservo ; // ein Servo-Objekt anlegen, um den Servo Motor steuern zu können
//---- Hier startet der Code zum Einstellen aller wichtigen Dinge. Setup() wird einmal ausgeführt. ----
void setup ( ) {
// Monitor
Serial . begin ( 115200 ) ; // Serial Monitor aktivieren. Mit dem Monitor kann man sich Werte und Meldungen anzeigen lassen.
2018-08-16 12:31:50 +02:00
// Taster
pinMode ( TASTERPIN , INPUT_PULLUP ) ;
2018-07-10 15:50:17 +02:00
// Ultraschallsensor
pinMode ( US_TRIG , OUTPUT ) ; // Ultraschallsensor: TRIG ist ein Ausgangspin. Es wird ein Signal zum Ultraschallsensor gesendet
pinMode ( US_ECHO , INPUT ) ; // Ultraschallsensor: ECHO ist ein Eingangspin. Es wird ein Signal vom Ultraschallsensor empfangen
// Servo
myservo . attach ( SERVOPIN ) ; // dem Servo Objekt "sagen" an welchen Pin am Schaltkreis der Server angeschlossen ist
// Linker Motor
pinMode ( MOTORLI_FWRD , OUTPUT ) ; // Linker Motor FORWARD ist ein Ausgang.
pinMode ( MOTORLI_BACK , OUTPUT ) ; // Linker Motor BACKWARD ist ein Ausgang.
2018-08-16 12:31:50 +02:00
ledcSetup ( MOTORPWM_LINKS , 5000 , 8 ) ; // channel 1, 50 Hz, 8-bit width
ledcAttachPin ( MOTORLI_SPEED , MOTORPWM_LINKS ) ; // Linker Motor SPEED mit Kanal 1 verbunden
analogWrite ( MOTORLI_SPEED , 0 ) ; // Linken Motor sicherheitshalber ausschalten :-)
2018-07-10 15:50:17 +02:00
// Rechter Motor
pinMode ( MOTORRE_FWRD , OUTPUT ) ; // Rechter Motor FORWARD ist ein Ausgang.
pinMode ( MOTORRE_BACK , OUTPUT ) ; // Rechter Motor BACKWARD ist ein Ausgang.
2018-08-16 12:31:50 +02:00
ledcSetup ( MOTORPWM_RECHTS , 5000 , 8 ) ; // channel 2, 50 Hz, 8-bit width
ledcAttachPin ( MOTORRE_SPEED , MOTORPWM_RECHTS ) ; // Rechter Motor SPEED mit Kanal 2 verbunden
analogWrite ( MOTORRE_SPEED , 0 ) ; // Rechten Motor sicherheitshalber ausschalten :-)
2018-07-10 15:50:17 +02:00
pinMode ( MOTORRE_SPEED , OUTPUT ) ; // Rechter Motor SPEED ist ein Ausgang.
2018-08-16 12:31:50 +02:00
digitalWrite ( MOTORRE_SPEED , 0 ) ; // Rechten Motor sicherheitshalber ausschalten :-)
2018-07-10 15:50:17 +02:00
// LEDs
pinMode ( LED_VORWAERTS , OUTPUT ) ; // LED Vorwärts ist ein Ausgang
pinMode ( LED_STOP , OUTPUT ) ; // LED Stop ist ein Ausgang
pinMode ( LED_LINKS , OUTPUT ) ; // LED Links ist ein Ausgang
pinMode ( LED_RECHTS , OUTPUT ) ; // LED Rechts ist ein Ausgang
// alle LEDS aus
digitalWrite ( LED_VORWAERTS , LOW ) ;
digitalWrite ( LED_STOP , LOW ) ;
digitalWrite ( LED_LINKS , LOW ) ;
digitalWrite ( LED_RECHTS , LOW ) ;
2018-08-16 12:31:50 +02:00
// Servo in die Mitte Stellen
ServoMitte ( ) ;
2018-07-10 15:50:17 +02:00
}
//---- Hier startet unsere endlose Schleife - die immer wieder von vorn angefangen wird, wenn wir am Ende angekommen sind. Da ist unser "Fahr"Code drin, der den CodeRacer steuert
void loop ( ) {
2018-08-16 12:31:50 +02:00
// Taster abfragen
RacerStartStop ( ) ;
if ( true = = coderracer_activ ) {
// Abstand messen -> nach vorn
abstand_vorn_cm = AbstandMessen ( ) ;
// Zum anfahren muss das Tempo höher sein - also jetzt wieder Tempo runter ...
RacerNormalTempo ( ) ;
// Abstandssensor schon verstellen ... dann hat er das bis zur nächsten Messung auch geschafft
ServoSchwenk ( ) ;
// Ist die Bahn frei?
if ( abstand_vorn_cm < US_STOP_ABSTAND_CM ) {
// Nein! Der Abstand nach vorn ist kleiner als erlaubt!
// Racer anhalten
RacerAnhalten ( ) ;
// Nach links schauen!
ServoLinks ( ) ;
// Abstand messen und merken.
abstand_links_cm = AbstandMessen ( ) ;
// Nach rechts schauen!
ServoRechts ( ) ;
// Abstand messen und merken.
abstand_rechts_cm = AbstandMessen ( ) ;
// Welcher Abstand ist größer?
if ( abstand_links_cm > abstand_rechts_cm ) {
// Links ist mehr Platz!
RacerLinks ( ) ;
// Servo in die Mitte Stellen
ServoMitte ( ) ;
}
else {
// Rechts ist mehr Platz!
RacerRechts ( ) ;
// Servo in die Mitte Stellen
ServoMitte ( ) ;
}
2018-07-10 15:50:17 +02:00
}
else {
2018-08-16 12:31:50 +02:00
// Ja! Die Bahn ist frei
RacerVorwaerts ( ) ;
2018-07-10 15:50:17 +02:00
}
}
}
//-------------- Funktionen und Prozeduren -------------------------
2018-08-16 12:31:50 +02:00
void RacerStartStop ( void ) {
if ( digitalRead ( TASTERPIN ) = = LOW ) {
if ( false = = coderracer_activ ) {
coderracer_activ = true ;
digitalWrite ( LED_STOP , LOW ) ;
} else {
coderracer_activ = false ;
digitalWrite ( LED_STOP , HIGH ) ;
}
delay ( 100 ) ; // Taster prellen ...
while ( digitalRead ( TASTERPIN ) = = LOW ) {
// do nothing just wait ...
delay ( 200 ) ;
}
}
if ( false = = coderracer_activ ) {
RacerAnhalten ( ) ;
ServoMitte ( ) ;
digitalWrite ( LED_STOP , HIGH ) ;
} else {
digitalWrite ( LED_STOP , LOW ) ;
}
}
2018-07-10 15:50:17 +02:00
void RacerAnhalten ( void ) {
Serial . println ( " RACER_ANHALTEN " ) ; // Meldung am Monitor ausgeben
// Rechten Motor abschalten
digitalWrite ( MOTORRE_FWRD , LOW ) ;
digitalWrite ( MOTORRE_BACK , LOW ) ;
// Linken Motor abschalten
digitalWrite ( MOTORLI_FWRD , LOW ) ;
digitalWrite ( MOTORLI_BACK , LOW ) ;
// Motoren beide ausschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , 0 ) ;
analogWrite ( MOTORLI_SPEED , 0 ) ;
2018-07-10 15:50:17 +02:00
// LEDs setzen
digitalWrite ( LED_VORWAERTS , LOW ) ;
digitalWrite ( LED_STOP , HIGH ) ;
digitalWrite ( LED_LINKS , LOW ) ;
2018-08-16 12:31:50 +02:00
digitalWrite ( LED_RECHTS , LOW ) ;
delay ( 1000 ) ;
}
void RacerNormalTempo ( void ) {
Serial . println ( " RACER_NORMAL_TEMPO " ) ; // Meldung am Monitor ausgeben
analogWrite ( MOTORRE_SPEED , MOTORRE_TEMPO ) ;
analogWrite ( MOTORLI_SPEED , MOTORLI_TEMPO ) ;
2018-07-10 15:50:17 +02:00
}
void RacerVorwaerts ( void ) {
Serial . println ( " RACER_VORWAERTS " ) ; // Meldung am Monitor ausgeben
// Rechten Motor auf vorwärts stellen
digitalWrite ( MOTORRE_FWRD , HIGH ) ;
digitalWrite ( MOTORRE_BACK , LOW ) ;
// Linken Motor auf vorwärts stellen
digitalWrite ( MOTORLI_FWRD , HIGH ) ;
digitalWrite ( MOTORLI_BACK , LOW ) ;
// Motoren beide anschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , MOTORRE_MAX_TEMPO ) ;
analogWrite ( MOTORLI_SPEED , MOTORLI_MAX_TEMPO ) ;
2018-07-10 15:50:17 +02:00
// LEDs setzen
digitalWrite ( LED_VORWAERTS , HIGH ) ;
digitalWrite ( LED_STOP , LOW ) ;
digitalWrite ( LED_LINKS , LOW ) ;
digitalWrite ( LED_RECHTS , LOW ) ;
}
void RacerLinks ( void ) {
Serial . println ( " RACER_LINKS " ) ; // Meldung am Monitor ausgeben
// LEDs setzen
digitalWrite ( LED_VORWAERTS , LOW ) ;
digitalWrite ( LED_STOP , LOW ) ;
digitalWrite ( LED_LINKS , HIGH ) ;
digitalWrite ( LED_RECHTS , LOW ) ;
// Rechten Motor auf vorwärts stellen
digitalWrite ( MOTORRE_FWRD , HIGH ) ;
digitalWrite ( MOTORRE_BACK , LOW ) ;
// Linken Motor auf rückwärts stellen
digitalWrite ( MOTORLI_FWRD , LOW ) ;
digitalWrite ( MOTORLI_BACK , HIGH ) ;
// Motoren beide anschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , MOTORRE_MAX_TEMPO ) ;
analogWrite ( MOTORLI_SPEED , MOTORLI_MAX_TEMPO ) ;
2018-07-10 15:50:17 +02:00
// Warten bis der RAcer sich gedreht hat
delay ( RACER_LINKS_MS ) ;
// Motoren wieder auschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , 0 ) ;
analogWrite ( MOTORLI_SPEED , 0 ) ;
2018-07-10 15:50:17 +02:00
}
void RacerRechts ( void ) {
Serial . println ( " RACER_RECHTS " ) ; // Meldung am Monitor ausgeben
// LEDs setzen
digitalWrite ( LED_VORWAERTS , LOW ) ;
digitalWrite ( LED_STOP , LOW ) ;
digitalWrite ( LED_LINKS , LOW ) ;
digitalWrite ( LED_RECHTS , HIGH ) ;
// Rechten Motor auf rückwärts stellen
digitalWrite ( MOTORRE_FWRD , LOW ) ;
digitalWrite ( MOTORRE_BACK , HIGH ) ;
// Linken Motor auf vorwärts stellen
digitalWrite ( MOTORLI_FWRD , HIGH ) ;
digitalWrite ( MOTORLI_BACK , LOW ) ;
// Motoren beide anschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , MOTORRE_MAX_TEMPO ) ;
analogWrite ( MOTORLI_SPEED , MOTORLI_MAX_TEMPO ) ;
2018-07-10 15:50:17 +02:00
// Warten bis der RAcer sich gedreht hat
delay ( RACER_RECHTS_MS ) ;
// Motoren wieder auschalten
2018-08-16 12:31:50 +02:00
analogWrite ( MOTORRE_SPEED , 0 ) ;
analogWrite ( MOTORLI_SPEED , 0 ) ;
2018-07-10 15:50:17 +02:00
}
void ServoRechts ( void ) {
Serial . println ( " SERVO_RECHTS " ) ; // Meldung am Monitor ausgeben
myservo . write ( SERVO_45GRAD_RECHTS ) ; // Servo auf den Winkel rechts drehen
delay ( 1000 ) ; // Kurz warten, dass der Servo die Stellung erreicht
}
void ServoLinks ( void ) {
Serial . println ( " SERVO_LINKS " ) ; // Meldung am Monitor ausgeben
myservo . write ( SERVO_45GRAD_LINKS ) ; // Servo auf den Winkel links drehen
delay ( 1000 ) ; // Kurz warten, dass der Servo die Stellung erreicht
}
void ServoMitte ( void ) {
Serial . println ( " SERVO_MITTE " ) ; // Meldung am Monitor ausgeben
myservo . write ( SERVO_0GRAD_MITTE ) ; // Servo auf den Winkel links drehen
2018-08-16 12:31:50 +02:00
schwenkPosition = SERVO_0GRAD_MITTE ; // Servo schaut direkt nach vorn
schwenkMillis = millis ( ) ;
2018-07-10 15:50:17 +02:00
delay ( 1000 ) ; // Kurz warten, dass der Servo die Stellung erreicht
}
2018-08-16 12:31:50 +02:00
void ServoSchwenk ( void ) {
if ( millis ( ) - schwenkMillis > SERVO_SCHWENK_MS ) {
Serial . println ( " SERVO_SCHWENK " ) ; // Meldung am Monitor ausgeben
schwenkPosition = schwenkPosition + schwenkRichtung ;
if ( schwenkPosition < = SERVO_M10GRAD_MITTE ) {
schwenkPosition = SERVO_M10GRAD_MITTE ;
schwenkRichtung = SERVO_SCHWENK_RE ;
}
if ( schwenkPosition > = SERVO_10GRAD_MITTE ) {
schwenkPosition = SERVO_10GRAD_MITTE ;
schwenkRichtung = SERVO_SCHWENK_LI ;
}
myservo . write ( schwenkPosition ) ; // Servo auf den Winkel links drehen
schwenkMillis = millis ( ) ;
}
}
2018-07-10 15:50:17 +02:00
long AbstandMessen ( ) {
long abstand_cm , echo_dauer ;
// Messung starten - ein kurzer Pulse "HIGH" wird zum TRIG pin des Ultraschallsensors geschickt
digitalWrite ( US_TRIG , LOW ) ;
delayMicroseconds ( 2 ) ;
digitalWrite ( US_TRIG , HIGH ) ;
delayMicroseconds ( 10 ) ;
digitalWrite ( US_TRIG , LOW ) ;
// Messung der Dauer in Mikrosekundenmeasure bis das ECHO Pin vom Ultraschallsensor HIGH wird
2018-08-16 12:31:50 +02:00
pinMode ( US_ECHO , INPUT ) ;
2018-07-10 15:50:17 +02:00
echo_dauer = pulseIn ( US_ECHO , HIGH ) ;
// convert into cm ... 344m/sec is the speed of noise - thus 34400cm/sec ... or 34,400cm/milisec ... or 0,0344cm/microsec
// the echo has to go the distance twice - forth and back - so the duration has to be the half of the measured one
// distance_cm = echo_duration/2 * 0,0344 or distance_cm = echo_duration/2 / 29,1 or distance_cm = echo_duration * 0,0172
// distance_cm = (echo_duration/2) / 29.1;
abstand_cm = echo_dauer * 0.0172 ;
//Messwert am Monitor anzeigen
Serial . print ( " ABSTAND_MESSEN. Der Abstand in cm ist: " ) ;
Serial . println ( abstand_cm ) ;
return ( abstand_cm ) ;
}
2018-08-16 12:31:50 +02:00
void analogWrite ( uint8_t pin , uint8_t speed ) {
if ( pin = = MOTORLI_SPEED ) { ledcWrite ( MOTORPWM_LINKS , speed ) ; }
if ( pin = = MOTORRE_SPEED ) { ledcWrite ( MOTORPWM_RECHTS , speed ) ; }
}
2018-07-10 15:50:17 +02:00