PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Sensorgesteuertes Auto mit Arduino Uno



vangola
24.06.2014, 16:13
Hallo Leute,

ich bin neu auf diesem Forum habe aber eine Fragen zu meinem Projekt und
zwar möchte für meine Prüfung in der Schule ein Auto bauen, welches
durch ein Microcontroller (Arduino Uno) gesteuert werden soll. Das Auto
habe ich schon "gebaut" es hat zwei 3V-Motoren und drei
Ultraschallsensoren (HC-SR04) zur Hinderniserkennung.
Den Code habe ich soweit auch fertig nur habe ich ein kleines Problem.
Hier die Stelle:

scanvorne();
if(cm >= 10){
GoForward();
delay(400);
}
else{
Stop(); }
scanlinks();
if(cm >= 10){
GoLeft();
delay(300);}
else{
Stop();}
scanrechts();
if(cm3 >= 10){
GoRight();
delay(300);}
else{
Stop();}
scanvorne();
if(cm <= 10){
GoBackward();
delay(350);}
else{
Stop();}

Ich möchte dass das Auto nicht rumzuckt wie auf Drogen sondern erst
soweit fährt bis es etwas erkennt und danach ausweicht und nicht wie
jetzt, abscannt 3sec fährt und dann plötzlich die Richtung ändert,
obwohl da nichts ist.

Ich bin ein Anfänger im Programmieren deswegen wird sich der eine oder
andere etwas über einen Code ärgern oder sogar lachen.
Und ich weiß dass mir noch massen an Bauteilen fehlen um alles in
"Echtzeit" durchführen zu lassen, deswegen muss es nur so ne grobe
Richtung haben und so ungefähr arbeiten.

MFG Vangola

P.S. Danke schon mal im Voraus.
28522

Peter(TOO)
24.06.2014, 17:40
Hallo Vangola,

Machen wir das man lesbar:

scanvorne();
if (cm >= 10)
{
GoForward();
delay(400);
}
else
{
Stop();
}

scanlinks();
if (cm >= 10)
{
GoLeft();
delay(300);
}
else
{
Stop();
}

scanrechts();
if (cm3 >= 10)
{
GoRight();
delay(300);
}
else
{
Stop();
}

scanvorne();
if (cm <= 10)
{
GoBackward();
delay(350);
}
else
{
Stop();
}


Du machst eine Abfrage ob vorne frei ist, wenn frei fährst du 400ms geradeaus, wenn nicht wird gestoppt.
Dann fragst du links ab, fährst wenn frei.
Dann das selbe noch für rechts.
und nochmals geradeaus .....

1. Das zweite geradeaus kannst du streichen, das ganze wird in einer Schleife sein und dann fragst du 2x nach geradeaus ab.
2. Wenn vorne frei ist, brauchst du nicht nach links und rechts sehen. Dort wo jetzt Stop(); ist musst du direkt die anderen Abfragen einfügen.


scanvorne();
if (cm >= 10)
{
GoForward();
delay(400);
}
else
{
Stop();

scanlinks();
if (cm >= 10)
{
GoLeft();
delay(300);
}
else
{
Stop();

scanrechts();
if (cm3 >= 10)
{
GoRight();
delay(300);
}
else
{
Stop();
}
}
}



Allerdings hat dein Tierchen jetzt einen Linksdrall.
Da müsste man noch, z.B. mit einer Zufallsauswahl zwischen links und recht auswählen, wenn beides frei ist oder man fährt in die Richtung, in welcher mehr frei ist, jetzt wählst du nur die 10cm.

MfG Peter(TOO)

vangola
24.06.2014, 18:09
Danke für deine Antwort/ Hilfe Peter(TOO)

so habe ich es auch mal ausprobiert, jedoch fuhr/fährt es die ganze Zeit gegen die Wand ohne etwas dagegen zu unternehmen.
Ich habe auch jetzt deinen beispielcode eingefügt und es fährt immer noch gegen die wand.

EDIT:

So ich hab da etwas angepasst und es geht doch einigermaßen, jedoch glaube ich dass die Geschwindigkeit der Motoren etwas zu hoch ist, wäre es vll über PWM zu lösen?
MfG Vangola

Peter(TOO)
24.06.2014, 18:18
Hallo Vangola,

Du postest hier halt auch nur halbe Wahrheiten und nicht deinen Ganzen Code!

Ich habe gerade gesehen, dass da mal cm und cm3 als Variable zu sehen ist ......

MfG Peter(TOO)

vangola
24.06.2014, 18:22
Ich habe für jeden Sensor eigene Abstandsvariable angelegt. (Ist es etwa falsch?)




// Sensor Links
long laengelinks;
long cm2;
// Sensor Vorne
long laengevorne;
long cm;
// Sensor Rechts
long laengerechts;
long cm3;
// Motor Rechts
const int Motor1Pin1 = 1;
const int Motor1Pin2 = 0;
//Motor Links
const int Motor2Pin1 = 2;
const int Motor2Pin2 = 3;

//int Abstand = 10;

void setup()

{
// Sensor PINS
// Serial.begin (9600);
pinMode(11,OUTPUT);
pinMode(10,INPUT);
pinMode(12,OUTPUT);

pinMode(8,OUTPUT);
pinMode(9,INPUT);
pinMode(7,OUTPUT);

pinMode(5,OUTPUT);
pinMode(6,INPUT);
pinMode(4,OUTPUT);

// Motor PINS
pinMode(Motor1Pin1, OUTPUT);
pinMode(Motor1Pin2, OUTPUT);
pinMode(Motor2Pin1, OUTPUT);
pinMode(Motor2Pin2, OUTPUT);

// pinMode(13,OUTPUT);
}

void loop()
{


scanvorne();
if (cm >= 20)
{
GoForward();
delay(300);
}
else
{
Stop();

scanlinks();
if (cm >= 20)
{
GoLeft();
delay(250);
}
else
{
Stop();

scanrechts();
if (cm3 >= 20)
{
GoRight();
delay(250);
}
else
{
Stop();
}
}
}

}




// Sensor Steuerung
void scanvorne()

{
digitalWrite(12,HIGH);


digitalWrite(11,HIGH);
delayMicroseconds(1000);
digitalWrite(11,LOW);

laengevorne = pulseIn(10,HIGH);

cm = (laengevorne/2)/29.1;

Serial.print(cm);
Serial.println("cm1");



}
void scanlinks()

{
digitalWrite(7,HIGH);


digitalWrite(8,HIGH);
delayMicroseconds(1000);
digitalWrite(8,LOW);

laengelinks = pulseIn(9,HIGH);

cm2 = (laengelinks/2)/29.1;

Serial.print(cm2);
Serial.println("cm2");



}

void scanrechts()

{
digitalWrite(4,HIGH);


digitalWrite(5,HIGH);
delayMicroseconds(1000);
digitalWrite(5,LOW);

laengerechts = pulseIn(6,HIGH);

cm3 = (laengerechts/2)/29.1;

Serial.print(cm3);
Serial.println("cm3");



}

//Motoren Steuerung

void GoForward(){

digitalWrite(Motor1Pin1, HIGH);
digitalWrite(Motor2Pin1, HIGH);
digitalWrite(Motor2Pin2, LOW);
digitalWrite(Motor1Pin2, LOW);
}

void GoBackward(){

digitalWrite(Motor1Pin1, LOW);
digitalWrite(Motor1Pin2, HIGH);
digitalWrite(Motor2Pin1, LOW);
digitalWrite(Motor2Pin2, HIGH);

}

void GoLeft(){

digitalWrite(Motor1Pin1, HIGH);
digitalWrite(Motor1Pin2, LOW);
digitalWrite(Motor2Pin1, LOW);
digitalWrite(Motor2Pin2, LOW);
}

void GoRight(){
digitalWrite(Motor2Pin2, LOW);
digitalWrite(Motor2Pin1, HIGH);
digitalWrite(Motor1Pin1, LOW);
digitalWrite(Motor1Pin2, LOW);
}

void Stop(){
digitalWrite(Motor1Pin2, LOW);
digitalWrite(Motor1Pin1, LOW);
digitalWrite(Motor2Pin1, LOW);
digitalWrite(Motor2Pin2, LOW);
}

Peter(TOO)
24.06.2014, 18:46
Hallo,

Ich habe für jeden Sensor eigene Abstandsvariable angelegt. (Ist es etwa falsch?)

Nach Scanlinks() fragst du aber cm ab, also den Wert von Vorn !!

MfG Peter(TOO)

vangola
24.06.2014, 19:01
Hallo,

ja das hab ich auch eben gesehen und korrigiert, danke dir.
Das fährt jetzt einwandfrei, aber wie du es auch gemeint hast, hat es einen Linksdrall.
Ich überlege gerade wie man es macht damit es den Weg mit dem größten Abstand nimmt.

MfG Vangola

Peter(TOO)
24.06.2014, 19:40
if ( (cm2 >= 10) && (cm2 >= 10) ) // links und rechts min. 10cm frei
{
If (cm2 > cm3)
Links();
else
Rechts();
}

Rabenauge
24.06.2014, 21:50
So richtig wird das mit deinem Aufbau nicht funktionieren, denn die Sensoren haben nicht genug Öffnungswinkel (grob zwischen 15 und 25 Grad).
Das heisst, du hast Bereiche (schräg nach vorn) die gar nicht erfasst werden.
Besser wärs, zwei Sensoren schräg nach vorn zu richten, und zwar so, dass sich beide in der Mitte "überlappen", dann kannst du feststellen ob genau vor dem Roboter alles frei ist (sogar ziemlich genau, da du beide Sensoren auswerten kannst) und auch, in welche Richtung mehr Platz ist.
Der Haken dabei ist dann: das braucht Zeit, da du die Sensoren nacheinander permanent abfragen musst. Da kann man noch bisschen tricksen: bei Gradeausfahrt nur einen benutzen, und _wenn_ der nen Ping bekommt, den anderen fragen, ob er auch was sieht.

Wenn man das gut justiert (so dass sich die Erfassungsbereiche grad um die Breite des Roboters überlappen) dürfte man ziemlich gut auch schmale Lücken noch "vermessen" können. Man muss ja nicht die komplette Reichweite benutzen (die Dinger reagieren auf bis zu 5m).

vangola
25.06.2014, 18:18
Danke dir Rebenauge für deinen Beitrag, aber für die Schule reicht es erstmal auch so. Und zudem habe ich tricksen müssen und deswegen sind alle digitalen Pins des Arduinos belegt, da ich auch Pins benutzt habe, um die Sensoren mit Strom zu versorgen und nicht mit Stromumwandler und solchem kram arbeiten zu müssen.

Rabenauge
25.06.2014, 18:28
Muss man auch nicht. Der Arduino liefer ja-wie praktisch- auch feine 5V am entsprechenden Pin. Für nen paar US-Sensoren reicht das locker aber: woher versorgst du die Motoren?
Hoffentlich _nicht_ über den Arduino direkt??

vangola
27.06.2014, 09:12
die motoren werden durch 4 AAA Batterien über ein h-bridge versorgt.

oberallgeier
27.06.2014, 09:39
... um die Sensoren mit Strom zu versorgen und nicht mit Stromumwandler und solchem kram arbeiten zu müssen.Bei meinen WALL R - (klick hier zum Thread) (https://www.roboternetz.de/community/threads/40453-WALL-R-l%C3%A4uft-%28autonomes-Fahrzeug%29)

......
http://www.youtube.com/watch?v=_TFtP1Xxpzk

habe ich den Motor über einen L293D geregelt betrieben, der als Motorversorgung die im Originalfahrzeug enthaltene 3xAA-Station hat. Den Controller mega328 auf einer selbst gebauten Platine, die Sensoren und auch die Versorgung des L293D habe ich mit einem Blöckchen aus 4xAAA-NiMHs versorgt. Dieser Block kommt normalerweise nicht über die zulässige Spannung des Controllers und der sonstigen Peripherie. Spannungwandler wollte/konnte ich im WALL R aus Platzgründen nicht einbauen..