Hausaufgaben7 Lösung: Unterschied zwischen den Versionen
Zur Navigation springen
Zur Suche springen
Die Seite wurde neu angelegt: „---- → zurück zum Hauptartikel: Termin 7: Ultraschall Notbremse“ |
Keine Bearbeitungszusammenfassung |
||
| (Eine dazwischenliegende Version desselben Benutzers wird nicht angezeigt) | |||
| Zeile 1: | Zeile 1: | ||
Letztendlich werden alle Teile zusammengesetzt: | |||
* Suche nach dem Ziel. | |||
* Rotation des Roboters in Richtung des Ziels. | |||
* Stopp-Funktion. | |||
== Quelltext == | |||
<div style="width:1200px; height:300px; overflow:auto; border: 2px solid #088"> | |||
<pre> | |||
/* Bibliotheken hinzufügen */ | |||
#include "AlphaBot.h" // Header hinzufügen | |||
#include <Servo.h> | |||
/* Instanzen erzeugen */ | |||
AlphaBot Alf = AlphaBot(); // Instanz des AlphaBot mit dem Handle WallE erzeugen | |||
Servo AlfServo; // Servo Instanz | |||
/* KONSTANTEN deklarieren */ | |||
const int TRIG = 11; // US Trigger an D11 | |||
const int ECHO = 12; // US Echo an D12 | |||
static const byte SERVO_PORT_u8 = 9; // Port des Servo Motors | |||
static const int COM_GESCHW_s16 = 9600; // Baude | |||
static const float NaN = 1029; // NaN beim US, keine Objekt in Reichweite | |||
// Globale Variablen | |||
//boolean WinkelErreicht_b = false; // true, wenn 30 cm gefahren | |||
void setup() // Einmalige Systeminitialisierung | |||
{ | |||
Serial.begin(COM_GESCHW_s16); // Serieller Monitor mit 9600 Baud | |||
int PotiWinkel_s16 = 0; // Winkel des Potis | |||
int DrehWinkel_s16 = 0; // Drehwinkel des Roboters | |||
float USAbstand_f32 = NaN; | |||
initUltraschall(); // US initialisieren | |||
AlfServo.attach(SERVO_PORT_u8); // Servo verbinden | |||
/* Suche Ziel */ | |||
PotiWinkel_s16 = sucheZiel(&USAbstand_f32); // Nächstes Ziel wird gesucht | |||
Serial.print("Nächste Ziel: "); | |||
Serial.print(USAbstand_f32); | |||
Serial.print(" m"); | |||
do{ | |||
/* Drehe Roboter */ | |||
DrehWinkel_s16 = PotiWinkel_s16-90; // Links: + | |||
dreheRobot(DrehWinkel_s16); // Links: + | |||
/* Suche Ziel */ | |||
PotiWinkel_s16 = sucheZiel(&USAbstand_f32); // Nächstes Ziel wird gesucht | |||
Serial.print("Nächste Ziel: "); | |||
Serial.print(USAbstand_f32); | |||
Serial.println(" m"); | |||
DrehWinkel_s16 = PotiWinkel_s16-90; // Links: + | |||
} while(abs(DrehWinkel_s16) > 5); // Abbruch der Schleife | |||
Serial.print("* Drehwinkel: "); | |||
Serial.println(DrehWinkel_s16); | |||
AlfServo.write(PotiWinkel_s16); // Finale Servoposition anfahren | |||
Alf.MotorRun(90,90); // Vorwärts auf das Ziel zufahren | |||
} | |||
void loop() // Main Schleife | |||
{ | |||
static const byte SCHWELLWERT_u8 = 10; // Entfernungsschwellwert in cm | |||
float USAbstand_f32 = 0; | |||
USAbstand_f32 = messeUSAbstand(); // US Abstand messen | |||
Serial.println(USAbstand_f32); | |||
if (USAbstand_f32 < float(SCHWELLWERT_u8)) // Schwellwert unterschritten? | |||
{ | |||
Serial.println("Notbremsung"); | |||
Alf.Brake(); // Anhalten | |||
} | |||
} | |||
/* ---------------------------------------------------------------*/ | |||
void initUltraschall() | |||
/* ---------------------------------------------------------------*/ | |||
{ | |||
pinMode(ECHO, INPUT); // Define the ultrasonic echo input pin | |||
pinMode(TRIG, OUTPUT); // Define the ultrasonic trigger input pin | |||
Serial.println("** initUltraschall"); | |||
} | |||
/* ---------------------------------------------------------------*/ | |||
int sucheZiel(float *USAbstand_f32) | |||
/* ---------------------------------------------------------------*/ | |||
{ | |||
/* Lokale Variablen deklarieren */ | |||
boolean ZielGefunden_bit = false; | |||
int ServoPosition_s16 = 0; | |||
int ServoInkrement_s16 = 5; | |||
float MinUSAbstand_f32 = NaN; // kleinster gemessener Abstand in cm, 1029 = NaN | |||
int MinServoPosition_s16 = NaN; // kleinster gemessener Abstand in cm, 1029 = NaN | |||
AlfServo.write(ServoPosition_s16); // Initiale Servoposition anfahren | |||
while (ZielGefunden_bit == false) | |||
{ | |||
if (ServoPosition_s16 >= 0 && ServoPosition_s16 <= 180) | |||
{ | |||
AlfServo.write(ServoPosition_s16); // Der Servo soll sich an die Position drehen | |||
} | |||
delay(200); // Servo-Drehung abwarten | |||
*USAbstand_f32 = messeUSAbstand(); // US Abstand messen | |||
//delay(250);/* Wir warten 15ms, bis der Servo seine Position erreich hat */ | |||
Serial.print("Winkel: "); | |||
Serial.print(ServoPosition_s16); | |||
Serial.print(" - "); | |||
Serial.print(*USAbstand_f32); | |||
if (*USAbstand_f32 > 2 && *USAbstand_f32 < 400) // nur valide Messungen betrachten | |||
{ | |||
if (*USAbstand_f32 < MinUSAbstand_f32) | |||
{ | |||
MinUSAbstand_f32 = *USAbstand_f32; | |||
MinServoPosition_s16 = ServoPosition_s16; | |||
Serial.print(" * "); // räuml. nächstes Ziel markieren | |||
} | |||
} | |||
Serial.println(" cm"); | |||
ServoPosition_s16 += ServoInkrement_s16; | |||
if (ServoPosition_s16 < 0) | |||
{ | |||
ServoPosition_s16 = 0; | |||
ServoInkrement_s16 *= (-1); // Am Ende des Sweeps in die andere Richtung drehen | |||
if (MinUSAbstand_f32 < NaN) // Wurde ein Ziel gefunden? | |||
{ | |||
ZielGefunden_bit = true; | |||
} | |||
Serial.println(ServoInkrement_s16); | |||
} | |||
else if (ServoPosition_s16 > 180) | |||
{ | |||
ServoPosition_s16 = 180; | |||
ServoInkrement_s16 *= (-1); // Am Ende des Sweeps in die andere Richtung drehen | |||
if (MinUSAbstand_f32 < NaN) // Wurde ein Ziel gefunden? | |||
{ | |||
ZielGefunden_bit = true; | |||
} | |||
Serial.println(ServoInkrement_s16); | |||
} | |||
} | |||
/* Rückgabewerte */ | |||
*USAbstand_f32 = MinUSAbstand_f32; // Mindestanstand | |||
return MinServoPosition_s16; // ServoPosition | |||
} // END sucheZiel | |||
/* ---------------------------------------------------------------*/ | |||
float messeUSAbstand() // Abstand in cm | |||
/* ---------------------------------------------------------------*/ | |||
{ | |||
float USAbstand = 0; // Rückgabewert initialisieren | |||
float fSignalLaufzeit = 0; // Messwert der Signallaufzeit | |||
digitalWrite(TRIG, LOW); // setze Trigger auf LOW für 2μs | |||
delayMicroseconds(2); | |||
digitalWrite(TRIG, HIGH); // setze Trigger auf HIGH für mind. 10 us | |||
delayMicroseconds(10); | |||
digitalWrite(TRIG, LOW); // setze Trigger auf LOW | |||
fSignalLaufzeit = pulseIn(ECHO, HIGH); // Messung der Singnallaufzeit des Impulses | |||
USAbstand = fSignalLaufzeit / 58; // Umrechnung Laufzeit in s in Abstand in cm | |||
//Y m =(X s * 344)/ 2; | |||
//X s =( 2 * Y m)/ 344; | |||
//X s = 0.0058 * Y m; | |||
//cm = us /58 | |||
return USAbstand; // Rückgabewert | |||
} // END messeUSAbstand() | |||
/* ---------------------------------------------------------------*/ | |||
void dreheRobot(int DrehWinkel_s16){ // Eingang Winkel in deg, | |||
/* ---------------------------------------------------------------*/ | |||
/* Winkelbereich -90°..90° */ | |||
int nPower = 100; // Default: 90 | |||
int Delay_s16 = 0; | |||
if(DrehWinkel_s16<-90 || DrehWinkel_s16>90){ | |||
Serial.println("ERROR: Winkel außerhalb des gültigen Bereichs."); | |||
} | |||
else{ | |||
// Sollwinkel: | |||
Delay_s16=abs(DrehWinkel_s16)*40/9; // Platzdrehung abwarten Power: 90, 400ms -> 90° | |||
Serial.print("Delay: "); | |||
Serial.print(Delay_s16); | |||
if (DrehWinkel_s16<0){ // | |||
nPower = nPower*(-1); // Winkel_s16<0: Rechtsdrehung | |||
} | |||
Alf.MotorRun(-nPower,+nPower); // Alf Drehung | |||
delay(Delay_s16); | |||
Alf.Brake(); | |||
Serial.print(" - Drehung: "); | |||
Serial.println(DrehWinkel_s16); | |||
} | |||
} | |||
</pre> | |||
</div> | |||
---- | ---- | ||
→ zurück zum Hauptartikel: [[AlphaBot:_Ultraschall_Notbremse|Termin 7: Ultraschall Notbremse]] | → zurück zum Hauptartikel: [[AlphaBot:_Ultraschall_Notbremse|Termin 7: Ultraschall Notbremse]] | ||
Aktuelle Version vom 8. Mai 2022, 17:53 Uhr
Letztendlich werden alle Teile zusammengesetzt:
- Suche nach dem Ziel.
- Rotation des Roboters in Richtung des Ziels.
- Stopp-Funktion.
Quelltext
/* Bibliotheken hinzufügen */
#include "AlphaBot.h" // Header hinzufügen
#include <Servo.h>
/* Instanzen erzeugen */
AlphaBot Alf = AlphaBot(); // Instanz des AlphaBot mit dem Handle WallE erzeugen
Servo AlfServo; // Servo Instanz
/* KONSTANTEN deklarieren */
const int TRIG = 11; // US Trigger an D11
const int ECHO = 12; // US Echo an D12
static const byte SERVO_PORT_u8 = 9; // Port des Servo Motors
static const int COM_GESCHW_s16 = 9600; // Baude
static const float NaN = 1029; // NaN beim US, keine Objekt in Reichweite
// Globale Variablen
//boolean WinkelErreicht_b = false; // true, wenn 30 cm gefahren
void setup() // Einmalige Systeminitialisierung
{
Serial.begin(COM_GESCHW_s16); // Serieller Monitor mit 9600 Baud
int PotiWinkel_s16 = 0; // Winkel des Potis
int DrehWinkel_s16 = 0; // Drehwinkel des Roboters
float USAbstand_f32 = NaN;
initUltraschall(); // US initialisieren
AlfServo.attach(SERVO_PORT_u8); // Servo verbinden
/* Suche Ziel */
PotiWinkel_s16 = sucheZiel(&USAbstand_f32); // Nächstes Ziel wird gesucht
Serial.print("Nächste Ziel: ");
Serial.print(USAbstand_f32);
Serial.print(" m");
do{
/* Drehe Roboter */
DrehWinkel_s16 = PotiWinkel_s16-90; // Links: +
dreheRobot(DrehWinkel_s16); // Links: +
/* Suche Ziel */
PotiWinkel_s16 = sucheZiel(&USAbstand_f32); // Nächstes Ziel wird gesucht
Serial.print("Nächste Ziel: ");
Serial.print(USAbstand_f32);
Serial.println(" m");
DrehWinkel_s16 = PotiWinkel_s16-90; // Links: +
} while(abs(DrehWinkel_s16) > 5); // Abbruch der Schleife
Serial.print("* Drehwinkel: ");
Serial.println(DrehWinkel_s16);
AlfServo.write(PotiWinkel_s16); // Finale Servoposition anfahren
Alf.MotorRun(90,90); // Vorwärts auf das Ziel zufahren
}
void loop() // Main Schleife
{
static const byte SCHWELLWERT_u8 = 10; // Entfernungsschwellwert in cm
float USAbstand_f32 = 0;
USAbstand_f32 = messeUSAbstand(); // US Abstand messen
Serial.println(USAbstand_f32);
if (USAbstand_f32 < float(SCHWELLWERT_u8)) // Schwellwert unterschritten?
{
Serial.println("Notbremsung");
Alf.Brake(); // Anhalten
}
}
/* ---------------------------------------------------------------*/
void initUltraschall()
/* ---------------------------------------------------------------*/
{
pinMode(ECHO, INPUT); // Define the ultrasonic echo input pin
pinMode(TRIG, OUTPUT); // Define the ultrasonic trigger input pin
Serial.println("** initUltraschall");
}
/* ---------------------------------------------------------------*/
int sucheZiel(float *USAbstand_f32)
/* ---------------------------------------------------------------*/
{
/* Lokale Variablen deklarieren */
boolean ZielGefunden_bit = false;
int ServoPosition_s16 = 0;
int ServoInkrement_s16 = 5;
float MinUSAbstand_f32 = NaN; // kleinster gemessener Abstand in cm, 1029 = NaN
int MinServoPosition_s16 = NaN; // kleinster gemessener Abstand in cm, 1029 = NaN
AlfServo.write(ServoPosition_s16); // Initiale Servoposition anfahren
while (ZielGefunden_bit == false)
{
if (ServoPosition_s16 >= 0 && ServoPosition_s16 <= 180)
{
AlfServo.write(ServoPosition_s16); // Der Servo soll sich an die Position drehen
}
delay(200); // Servo-Drehung abwarten
*USAbstand_f32 = messeUSAbstand(); // US Abstand messen
//delay(250);/* Wir warten 15ms, bis der Servo seine Position erreich hat */
Serial.print("Winkel: ");
Serial.print(ServoPosition_s16);
Serial.print(" - ");
Serial.print(*USAbstand_f32);
if (*USAbstand_f32 > 2 && *USAbstand_f32 < 400) // nur valide Messungen betrachten
{
if (*USAbstand_f32 < MinUSAbstand_f32)
{
MinUSAbstand_f32 = *USAbstand_f32;
MinServoPosition_s16 = ServoPosition_s16;
Serial.print(" * "); // räuml. nächstes Ziel markieren
}
}
Serial.println(" cm");
ServoPosition_s16 += ServoInkrement_s16;
if (ServoPosition_s16 < 0)
{
ServoPosition_s16 = 0;
ServoInkrement_s16 *= (-1); // Am Ende des Sweeps in die andere Richtung drehen
if (MinUSAbstand_f32 < NaN) // Wurde ein Ziel gefunden?
{
ZielGefunden_bit = true;
}
Serial.println(ServoInkrement_s16);
}
else if (ServoPosition_s16 > 180)
{
ServoPosition_s16 = 180;
ServoInkrement_s16 *= (-1); // Am Ende des Sweeps in die andere Richtung drehen
if (MinUSAbstand_f32 < NaN) // Wurde ein Ziel gefunden?
{
ZielGefunden_bit = true;
}
Serial.println(ServoInkrement_s16);
}
}
/* Rückgabewerte */
*USAbstand_f32 = MinUSAbstand_f32; // Mindestanstand
return MinServoPosition_s16; // ServoPosition
} // END sucheZiel
/* ---------------------------------------------------------------*/
float messeUSAbstand() // Abstand in cm
/* ---------------------------------------------------------------*/
{
float USAbstand = 0; // Rückgabewert initialisieren
float fSignalLaufzeit = 0; // Messwert der Signallaufzeit
digitalWrite(TRIG, LOW); // setze Trigger auf LOW für 2μs
delayMicroseconds(2);
digitalWrite(TRIG, HIGH); // setze Trigger auf HIGH für mind. 10 us
delayMicroseconds(10);
digitalWrite(TRIG, LOW); // setze Trigger auf LOW
fSignalLaufzeit = pulseIn(ECHO, HIGH); // Messung der Singnallaufzeit des Impulses
USAbstand = fSignalLaufzeit / 58; // Umrechnung Laufzeit in s in Abstand in cm
//Y m =(X s * 344)/ 2;
//X s =( 2 * Y m)/ 344;
//X s = 0.0058 * Y m;
//cm = us /58
return USAbstand; // Rückgabewert
} // END messeUSAbstand()
/* ---------------------------------------------------------------*/
void dreheRobot(int DrehWinkel_s16){ // Eingang Winkel in deg,
/* ---------------------------------------------------------------*/
/* Winkelbereich -90°..90° */
int nPower = 100; // Default: 90
int Delay_s16 = 0;
if(DrehWinkel_s16<-90 || DrehWinkel_s16>90){
Serial.println("ERROR: Winkel außerhalb des gültigen Bereichs.");
}
else{
// Sollwinkel:
Delay_s16=abs(DrehWinkel_s16)*40/9; // Platzdrehung abwarten Power: 90, 400ms -> 90°
Serial.print("Delay: ");
Serial.print(Delay_s16);
if (DrehWinkel_s16<0){ //
nPower = nPower*(-1); // Winkel_s16<0: Rechtsdrehung
}
Alf.MotorRun(-nPower,+nPower); // Alf Drehung
delay(Delay_s16);
Alf.Brake();
Serial.print(" - Drehung: ");
Serial.println(DrehWinkel_s16);
}
}
→ zurück zum Hauptartikel: Termin 7: Ultraschall Notbremse