Hi
Ich arbeite an einem Staubsaugerroboter, der mein Tanzstudio möglichst
oft in geraden Bahnen durcharbeiten soll,
Der Roboter hat einen IR- Sensor vorne und wenn der abstand zur wand
unter 10 cm ist setzt das ausscheren und drehen ein.
Ausserdem hat er noch ein paar Buttons bei denen auch entweder ein
ausscheren oder Drehen einsetzten soll und ein Relais, welches eine
Putzwalze ein und ausschält.
Im VOID habe ich die Grundfunktionen wie ausscheren LINKS und RECHTS
definiert und andere Aktionen des Motors, damit der LOOP nicht so lang
wird.
ERST ging auch alles aber dann wollte ich eine Variable einbauen: DIE
RAUMPOSITION. Die soll so gehen: Er fährt los und die die Variable ist
auf 0. Dadurch weiß er, er ist unterwegs zur rechten raumecke und er
soll dann LINKS ausscheren. Ist er mit ausscheren fertig soll die
Variable +1 bekommen und auf 1 wechseln damit er dann in der linken Ecke
weiß , ahhh jetzt muss ich rechts ausscheren.
Auf diese weise würde er den gesamten raum in Bahnen abfahren. Falls mal
was anders ist und er beim ausscheren rückwärts anstößt ändert sich so
wieso alles und es setzt ein Zufall ein.
ABER mit viel Glück fährt er damit durch das Studio.
Mein Problem ist die Variable. Raumpositon. In Zeile 126 und 163 im
Ausscheren versuche ich der Variablen zu sagen: wenn Du das ausscheren
zu ende gemacht hast erhöhe oder reduziere bitte die Variable
Raumposition um den wert 1.
Im LOOP lese ich die Variable aus und benenne sie in Raumecke: 0 ist
links und 1 ist rechts, dann habe einen Switch case: wenn Raumecke
links mach ausscheren rechts und wenn raumecke rechts machs andersrum.
So liebe Leute ich mach das zum ersten ml und habe ich sehr gefreut als
es erst mal funktioniert hat – erinnert Euch an euer erstes mal... abe
jetzt komme ich nicht weiter und bin dankbar für HELP!!
Der Code ist im anhang.
int motor1_A=8; // Motor 1
int motor1_B=9;
int motor2_A=6; // Motor 1
int motor2_B=7;
const int buttonPin_front = 2; // hier sind drei Butons, bei denen der
Roboter die Richtung ändern soll
int buttonState_front = 0;
const int back_buttonPin_l = 3;
int back_buttonState_l = 0;
const int back_buttonPin_r = 4;
int back_buttonState_r = 0;
int myStatus = 1;
int raum_position; // Varible, um klar zu machen, ob er linnks oder
Rechts ausscheren soll, rechte raumseite= 0 - linke raumpos = 1
#define trigPin 13 // Infrarot sender und Empfg
#define echoPin 12
#define relais1 14 // steuert ene Putzwalze, die nur bei Vorwärts an
sein soll
void setup(){ // Pinbelegungen
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motor1_A,OUTPUT);
pinMode(motor1_B,OUTPUT);
pinMode(motor2_A,OUTPUT);
pinMode(motor2_B,OUTPUT);
pinMode(buttonPin_front , INPUT);
pinMode(back_buttonPin_l , INPUT);
pinMode(back_buttonPin_r , INPUT);
pinMode(relais1, OUTPUT);
} // Ab hier kommen die
Grundfunktionen des Motors
void motorStop(){
// motor1
Serial.print("motorStop"); // STOP
Serial.print(",");
digitalWrite(relais1,LOW);
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,LOW);
delay(500);
}
void vorw(){ //Vorwärts
// motor1
Serial.print("vorw");
Serial.print(",");
digitalWrite(relais1,HIGH); //Putzwaltze an
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
}
void rueckw(){
// motor1 // Rückwarts
Serial.print("rueck");
Serial.print(",");
digitalWrite(relais1,LOW); //Putzwaltze AUS
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void ausscheren_motor_l(){ // Ausschereen Links - wenn er in der
rechten raumecke ist, erkennbar über die Variable raum_position = 0
// drehen 1
//motor1
Serial.print("auschrenLL");
Serial.print(",");
digitalWrite(relais1,LOW); //Putzwaltze AUS
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2 ist umgedreht eingebaut- dh gleiche polung low igh M1 und
M2 ist gegenläufig
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
delay(500);
// rückwärts
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(1000);
// drehen 2
//motor1
digitalWrite(motor1_A,HIGH );
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(2000);
raum_position= +1; //hier soll die variable
ramuposition von 0 auf 1 wechseln
}
void ausscheren_motor_r(){
// drehen 1
//motor1
Serial.print("auschrenRR");
Serial.print(",");
digitalWrite(relais1,HIGH);
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2 ist umgedreht eingebaut- dh gleiche polung low igh M1 und
M2 ist gegenläufig
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(500);
// rückwärts
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(1000);
// drehen 2
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
delay(500);
digitalWrite(relais1,LOW);
raum_position = -1; //hier soll die variable
ramuposition von 0 auf 1 wechseln
}
void turn_r(){
// motor1
Serial.print("turnRR");
Serial.print(",");
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void turn_l(){
// motor1
Serial.print("turn-L");
Serial.print(",");
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void loop(){
long duration, distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
// delayMicroseconds(1000); - Removed this line
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
int raumecke = digitalRead (raum_position); // hier soll die variable
raumposition ausgelesen werden in raumecke, 1 = links, 0 = rechts
if (distance > 10){
myStatus=1;
// ............ // wenn er vorwaerts fahren
soll- kein Hindernis
}
else {
if ((distance < 10)||(digitalRead (buttonState_front = HIGH))&&
(raumecke = 0)) {
myStatus=2; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
rechten ecke ist
}
else {
if ((distance < 10)||(digitalRead (buttonState_front = HIGH))&&
(raumecke = 1)) {
myStatus=5; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
linken rechten ecke ist
}
else {
if (digitalRead(back_buttonState_l)==HIGH){
myStatus=3; // anstossen links beim
rueckwärtsfahren
}
else {
if (digitalRead(back_buttonState_r)==HIGH){
myStatus=4; // anstossen rechts beim
rueckwärtsfahren
}
}
switch (myStatus){
case 1: // vorwärts
vorw();
break;
case 2: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht... RECHTE ECKE
motorStop();
delay (1000);
ausscheren_motor_l();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(2000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
case 3: // er stösst rückwärts LINKS an und dreht en wenig und fährt
dann weiter
turn_l();
delay(1000);
vorw();
delay(2000);
break;
case 4: // er stösst rückwärts RECHTS an und dreht en wenig und fährt
dann weiter
turn_r();
delay(1000);
vorw();
delay(2000);
case 5: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht LINKE ECKE
motorStop();
delay (1000);
ausscheren_motor_r();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(2000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
break;
}
} } } }
Was mir auch so auf die Schnelle aufgefallen ist:
Im switch/case hat es beim case 4 kein break-Statement, beim case 5
dafür 2 break-Statements - das war wohl auch anders gedacht...
Tsakalidis Konstantin schrieb:> zu ende gemacht hast erhöhe oder reduziere bitte die Variable> Raumposition um den wert 1.
und 'erhöhen' bzw 'reduzieren' ist im übrigen nicht dasselbe wie eine
Variable einfach auf einen Wert setzen.
1
i=5;
setzt eine Variable auf den Wert 5.
Wenn du sie um 5 erhöhen willst, dann musst du logischerweise den alten
Wert nehmen (zb hat i den Wert 7), dazu dann 5 dazuzählen und dieses
Ergebnis als neuen Wert an die Variable zuweisen
1
i=i+5;
macht also eine Erhöhung. Sieh dir einfach den Ausdruck rechts vom = an.
Diese 'Formel' wird ausgewertet und das Ergebnis davon wird als neuer
Wert in i gespeichert. Und weil da rechts ebenfalls das i vorkommt,
läuft das effektiv darauf hinaus, dass i um 5 erhöht wird.
Selbiges für 'reduzieren'.
Was du vielleicht irgendwo gesehen hast (und schon wieder in den Details
vergessen hast), das ist eine spezielle Schreibweise in C.
1
i+=5;
Beachte: das '+' als Rechenoperation steht links vom =. Diese
Kombinationen '+=', '-=', '*=', etc. etc. sind nichts anderes als
Kurzschreibweisen.
1
i-=8;
ist also einfach nur eine Kurzschreibweise für
1
i=i-8;
bei der der Teil links vom = automatisch als erster Ausdruck für die
rechte Seite vom = genommen wird. Die Rechenoperation steht dabei links
vom =, damit es zu keinen Verwechslungen kommt, wenn man tatsächlich
eine negative Zahl an eine Variable zuweisen will.
1
i=-8;
und
1
i-=8;
sind 2 verschiedene Dinge! Das erste ist eine Zuweisung. Das zweite ist
die Kurzform für
1
i=i-8;
Und ja: Du brauchst ein C Buch oder ein ordentliches C Tutorial. Das
sind eigentlich recht einfache Sachen, die jeder C Programmierer nach
den ersten Tutorieneinheiten drauf haben sollte.
Karl Heinz schrieb:> Und ja: Du brauchst ein C Buch oder ein ordentliches C Tutorial. Das> sind eigentlich recht einfache Sachen, die jeder C Programmierer nach> den ersten Tutorieneinheiten drauf haben sollte.
Und zwar lange bevor man sich an ein Roboter-Projekt macht.
Hallo Jungs,
ich danke euch so sehr! Ich habe ein Buch und mir schon viele Tutorials
angeschaut aber eben: es gibt dann unterschiedliche schreibweisen und
all so was.
Vielen dank für jeden Hinweis!
ich Übe und irgendwann wird der Code stimmen!
Welches Buch würdet Ihr empfehlen?
Dann noch zu der ersten Antwort oben: da stimmt der kommtartext nicht -
erst will ich 1 + und dann 1 minus machen und wenn er bei null anfängt
dann gibt es nur die beiden.
Danke!!
Tsakalidis Konstantin schrieb:> if ((distance < 10)||(digitalRead (buttonState_front = HIGH))&&> (raumecke = 0)) {
das macht auch nicht dass was du willst:
mit
raumecke=0
machst du nicht nur ein falsche Abfrage, sondern setzt raumecke auf 0,
wie schon andere schrieben: C-Buch ;-)
Walter S. schrieb:> machst du nicht nur ein falsche Abfrage, sondern setzt raumecke auf 0,> wie schon andere schrieben: C-Buch ;-)
Wobei
C-Buch alleine ist es auch nicht.
Ehe man ein Projekt angeht, heisst es erst mal 'das Buch durcharbeiten'
und 'üben, üben, üben'. Ohne einen gewissen Grundstock den man sicher
beherrscht macht es keinen Sinn ein Projekt anzufangen.
Tsakalidis Konstantin schrieb:> Danke für den Hinweis - ich suche in meinem Buch und finde das nicht als> beispiel - bitte... was muss denn da hin ==0 ?
Du findest in deinem Buch keine C-Operatoren? Was liest du? Bestimmt
kein C-Buch!
Schlage die Operatoren nach. Schlage = nach und ==. Erkenne den
Unterschied. Versuche zu verstehen. DANN kannst du das konkret in deinem
Code anwenden.
Ok das stimmt sicher aber nun bin ich schon so weit gekommen der macht
auch alles was ich will nur als ich die Variable dazu genommen habe da
wurde es echt schwer und ich komme mit den Antworten hier auch schon ein
ganzes Stück weiter.
Danke!
Karl Heinz schrieb:> Walter S. schrieb:>>> machst du nicht nur ein falsche Abfrage, sondern setzt raumecke auf 0,>> wie schon andere schrieben: C-Buch ;-)>> Wobei> C-Buch alleine ist es auch nicht.>> Ehe man ein Projekt angeht, heisst es erst mal 'das Buch durcharbeiten'> und 'üben, üben, üben'. Ohne einen gewissen Grundstock den man sicher> beherrscht macht es keinen Sinn ein Projekt anzufangen.
Da gehört zum Beispiel auch die Unterscheidung zwischen einer Zuweisung,
die mit einem = geschrieben wird, und einem Vergleich auf Gleichheit,
der mit zwei = geschrieben wird.
1
i=0
und
1
i==0
sind nun mal 2 komplett verschiedene Dinge. Das eine ist eine Zuweisung,
das andere ein Vergleich.
Auch hier wieder: nach den ersten Übungseinheiten sollte man das
eigentlich wissen. Den Fehler macht man dann noch ein paar mal und dann
ist das Thema gegessen und durch.
Wenn man natürlich völlig blank und ohne Vorübungen in ein Projekt
reingeht ....
ist auch ziemlich sicher nicht das, was eigentlich gewollt war.
Neben einem gewissen Grundstock an Basiswissen benötigt man auch
Sorgfalt beim Programmieren! Nur weil der Compiler das akzeptiert,
bedeutet das noch lange nicht, dass es logisch auch richtig ist.
Der Compiler prüft nur, ob du die Regeln der Sprache eingehalten hast.
Die Logik dahinter ist dein Bier.
Dein Pech ist nur, dass in C viele Dinge legal sind (und es dafür auch
einen guten Grund gibt), die dafür sorgen dass deine ganzen Tippfehler
alle zu keiner Verletzung der Sprachregel führen.
1
Das Flugzeug schwimmt den Baum.
ist nach den deutschen Sprachregeln ein korrekter deutscher Satz. Kein
Duden hat daran etwas auszusetzen. Trotzdem ist der Satz unsinnig. Dein
Compiler ist wie der Duden, der an diesem Satz nichts auszusetzen hat.
Solange du die Regeln einhältst, ist für ihn alles in Ordnung.
O.T.:
Karl Heinz schrieb:> Ehe man ein Projekt angeht, heisst es erst mal 'das Buch durcharbeiten'> und 'üben, üben, üben'. Ohne einen gewissen Grundstock den man sicher> beherrscht macht es keinen Sinn ein Projekt anzufangen.
Das sehe ich anders. Ich habe immer ein Projekt benötigt, um eine neue
komplexe Fähigkeit (wie z.B. Programmieren) zu lernen. Es motiviert,
birngt unerwartete Schwierigkeiten, ermöglicht Fehler zu machen, bringt
Erfolgserlebnisse, kurz: Es macht Spass. Und Freude ist das wichtigste
beim Lernen. ;-)
natürlich sollte man keinen Zeit- und Erfolgsdruck haben. Ein
Spassprojekt eben. Und dannach klingt mir der Staubsaugerroboter auch.
Wenn man alle Stunden zusammenrechnet, die in so ein Projekt fließen
können, könnte man wahrscheinlich ziemlich oft das Studio von Hand
saugen... :-)
Hallo
tja so sehe ich das auch - ich muss ein Projekt haben und mich daran
festbeißen dann entwickle ich Lösungen und Wissensdurst :_)
Deshalb fände ich schön, wenn ich noch ein paar Tipps für meinen Code
bekomme.
Ich werde morgen dann alle Tipps versuchen umzusetzen und bin gespannt
ob ich es schaffe.
Also Leute, wenn Ihr noch einen guten tipp habt oder euer geschultes
Auge den einen oder andren Fehler sieht, bitte lasst es mich wissen
Vielen Dank aus der Tanz-zentrale in Leipzig. :-)
if ((distance < 10)||(digitalRead (buttonState_front == HIGH))&&
(raumecke == 0))
aber müsste das doch nun so stimmen oder? soll heißen: entweder wenn die
distance kleiner als 10 cm ist oder der frontbutton an ist UND er in der
rechten raumecke ist.
Tsakalidis Konstantin schrieb:> if ((distance < 10)||(digitalRead (buttonState_front == HIGH))&&> (raumecke == 0))>> aber müsste das doch nun so stimmen oder? soll heißen: entweder wenn die> distance kleiner als 10 cm ist oder der frontbutton an ist UND er in der> rechten raumecke ist.
Nein, das digitalRead und die Klammersetzung macht so kein Sinn!
if(( (distance < 10) || (digitalRead(buttonPinfront) == HIGH)) &&
(raumecke == 0))
Tsakalidis Konstantin schrieb:> schade dass ich nur gesagt bekomme: stimmt so nicht, ich komme selbst> nicht drauf... was ist falsch?
Da unten hat er dir doch den korrekten Ausdruck hingeschrieben...
Schau halt einfach mal nach, welche Parameter die Funktion "digitalRead"
erwartet, und dann schaue was der Ausdruck buttonState_front == HIGH für
ein Datentyp als Ergebnis zurück gibt. Dann sollte klar werden, warum es
nicht geht.
Tipp: Programmieren sollte kein Trial&Error Glückspiel sein. Man muss
verstehen was da passiert. Ehrlich.
Ok das wusste ich nicht dass diese Formulierung dann die richtige ist
Danke.
man kann manchmal nur dann etwas verstehen, wenn man von jemand mit
Erfahrung einen Tipp und ratschlag und einen echten Hinweis bekommt.
nur dann macht auch so ein Forum oder unterrichten überhaupt sinn.
Danke für die hilfe.
und ich lese stundenlang aber es ist echt schwer genau die beispiele zu
finden die man braucht und es dann auch zu verstehen, wenn ich aber ein
Beispiel von euch bekomme, fällt oft der Groschen.
Hier ist mein korrigierter code, bitte falls noch jemand was auffällt...
int motor1_A=8; // Motor 1
int motor1_B=9;
int motor2_A=6; // Motor 1
int motor2_B=7;
const int buttonPin_front = 2; // hier sind drei Butons, bei denen der
Roboter die Richtung ändern soll
int buttonState_front = 0;
const int back_buttonPin_l = 3;
int back_buttonState_l = 0;
const int back_buttonPin_r = 4;
int back_buttonState_r = 0;
int myStatus = 1;
int raum_position; // Varible, um klar zu machen, ob er linnks oder
Rechts ausscheren soll, rechte raumseite= 0 - linke raumpos = 1
#define trigPin 13 // Infrarot sender und Empfg
#define echoPin 12
#define relais1 14 // steuert ene Putzwalze, die nur bei Vorwärts an
sein soll
void setup(){ // Pinbelegungen
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motor1_A,OUTPUT);
pinMode(motor1_B,OUTPUT);
pinMode(motor2_A,OUTPUT);
pinMode(motor2_B,OUTPUT);
pinMode(buttonPin_front , INPUT);
pinMode(back_buttonPin_l , INPUT);
pinMode(back_buttonPin_r , INPUT);
pinMode(relais1, OUTPUT);
} // Ab hier kommen die
Grundfunktionen des Motors
void motorStop(){
// motor1
Serial.print("motorStop"); // STOP
Serial.print(",");
digitalWrite(relais1,LOW);
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,LOW);
delay(500);
}
void vorw(){ //Vorwärts
// motor1
Serial.print("vorw");
Serial.print(",");
digitalWrite(relais1,HIGH); //Putzwaltze an
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
}
void rueckw(){
// motor1 // Rückwarts
Serial.print("rueck");
Serial.print(",");
digitalWrite(relais1,LOW); //Putzwaltze AUS
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void ausscheren_motor_l(){ // Ausschereen Links - wenn er in der
rechten raumecke ist, erkennbar über die Variable raum_position = 0
// drehen 1
//motor1
Serial.print("auschrenLL");
Serial.print(",");
digitalWrite(relais1,LOW); //Putzwaltze AUS
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2 ist umgedreht eingebaut- dh gleiche polung low igh M1 und
M2 ist gegenläufig
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
delay(500);
// rückwärts
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(1000);
// drehen 2
//motor1
digitalWrite(motor1_A,HIGH );
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(2000);
raum_position = raum_position +1; //hier soll die
variable ramuposition von 0 auf 1 wechseln
}
void ausscheren_motor_r(){
// drehen 1
//motor1
Serial.print("auschrenRR");
Serial.print(",");
digitalWrite(relais1,HIGH);
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2 ist umgedreht eingebaut- dh gleiche polung low igh M1 und
M2 ist gegenläufig
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(500);
// rückwärts
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
delay(1000);
// drehen 2
//motor1
digitalWrite(motor1_A,LOW);
digitalWrite(motor1_B,HIGH);
// motor2
digitalWrite(motor2_A,LOW);
digitalWrite(motor2_B,HIGH);
delay(500);
digitalWrite(relais1,LOW);
raum_position = raum_position -1; //hier soll die
variable ramuposition von 1 auf 0 wechseln
}
void turn_r(){
// motor1
Serial.print("turnRR");
Serial.print(",");
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void turn_l(){
// motor1
Serial.print("turn-L");
Serial.print(",");
digitalWrite(motor1_A,HIGH);
digitalWrite(motor1_B,LOW);
// motor2
digitalWrite(motor2_A,HIGH);
digitalWrite(motor2_B,LOW);
}
void loop(){
long duration, distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
// delayMicroseconds(1000); - Removed this line
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
int raumecke = raum_position; // hier soll die variable raumposition
ausgelesen werden in raumecke, 1 = links, 0 = rechts
if (distance > 10){
myStatus=1;
// ............ // wenn er vorwaerts fahren
soll- kein Hindernis
}
else {
if(( (distance < 10) || (digitalRead(buttonPin_front) == HIGH)) &&
(raumecke == 0)) {
myStatus=2; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
rechten ecke ist
}
else {
if(( (distance < 10) || (digitalRead(buttonPin_front ) == HIGH)) &&
(raumecke == 1)) {
myStatus=5; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
linken rechten ecke ist
}
else {
if (digitalRead(back_buttonPin_l) == HIGH){
myStatus=3; // anstossen links beim
rueckwärtsfahren
}
else {
if (digitalRead(back_buttonPin_r) == HIGH){
myStatus=4; // anstossen rechts beim
rueckwärtsfahren
}
}
switch (myStatus){
case 1: // vorwärts
vorw();
break;
case 2: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht... RECHTE ECKE
motorStop();
delay (1000);
ausscheren_motor_l();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(2000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
case 3: // er stösst rückwärts LINKS an und dreht en wenig und fährt
dann weiter
turn_l();
delay(1000);
vorw();
delay(2000);
break;
case 4: // er stösst rückwärts RECHTS an und dreht en wenig und fährt
dann weiter
turn_r();
delay(1000);
vorw();
delay(2000);
break;
case 5: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht LINKE ECKE
motorStop();
delay (1000);
ausscheren_motor_r();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(2000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
}
} } } }
>Ich arbeite an einem Staubsaugerroboter, der mein Tanzstudio möglichst>oft in geraden Bahnen durcharbeiten soll
Unabhängig von dem Programm:
1. Glaubst Du wirklich, dass Dein Roboter geradeaus fährt?
2. Wie willst Du sicherstellen, dass der Roboter (ohne Hindernis) am
Ende seiner Bahn tatsächlich um 180° dreht.
Möchte, beim Umfahren eines Hindernisses, erst gar nicht auf die damit
verbundene Probleme (wie z.B. die alte Bahn zu finden) eingehen.
Die Idee: Durch den Raum, in parallelen Bahnen zu abzufahren, um somit
mit minimalem Fahrweg den Job zu machen, ist bestechend. Ohne gewaltigen
Aufwand ist dies aber nicht praktikabel.
Normale Putzroboter fahren (stimmt natürlich nicht) wie ein besoffener
Seemann durch den Raum und verlassen sich dabei auf die Statistik, dass
alle Raum-/Flächenpunkte irgendwann mal überfahren werden. Darauf, dass
das klappt, würde ich aber auch nichts setzen, was mir lieb ist.
Amateur schrieb:> Die Idee: Durch den Raum, in parallelen Bahnen zu abzufahren, um somit> mit minimalem Fahrweg den Job zu machen, ist bestechend. Ohne gewaltigen> Aufwand ist dies aber nicht praktikabel.
Doch, mein Miele RX1 macht genau das. Und ziemlich gut.
Selbst nach 1 Stunde saugen, stimmt die Ausrichtung immer noch.
Aber, wie gesagt, er hat auch ne Kamera nach oben gerichtet. Das ist
wohl mehr Aufwand.
> Normale Putzroboter fahren (stimmt natürlich nicht) wie ein besoffener> Seemann durch den Raum und verlassen sich dabei auf die Statistik, dass> alle Raum-/Flächenpunkte irgendwann mal überfahren werden. Darauf, dass> das klappt, würde ich aber auch nichts setzen, was mir lieb ist.
Genau deshalb wollte ich auch keinen Roomba.
> Unabhängig von dem Programm:> 1. Glaubst Du wirklich, dass Dein Roboter geradeaus fährt?
Ja weil es sind 2 Gleichstrommotoren mit einer großen übersetzung bzw
untersetzung - 10 cm in in einer SEkunde.
> 2. Wie willst Du sicherstellen, dass der Roboter (ohne Hindernis) am> Ende seiner Bahn tatsächlich um 180° dreht.
Er kommt am ende der bahn an, schehrt diagonalrückwärts im 45 grad
winkel aus und dreht sich wieder so dass er gerade steht dann macht er
180 turn und fährt die bahn zurück, die Bahnen überlappen um ca 30 %
das ist der Plan.
>> Möchte, beim Umfahren eines Hindernisses, erst gar nicht auf die damit> verbundene Probleme (wie z.B. die alte Bahn zu finden) eingehen.>
das ist ein Konzept für einen Raum ohne große Hindernisse - TANZSTUDIO -
trotzdem werde ich ihn auch in einem anderen Raum verwenden, hier geht
es so:
Sobald er bei Ausschehren rückwärts anstößt dreht er um 22,5 Grad und
versucht den raum in der anderen Richtung abzufahren, das kann nun immer
wieder passieren. also es wechseln sich dann die beiden Fahrmuster
längst und quer ab, bzw dann kann auch mal eine Diagonle entstehen und
es ist zufall ob er an jedem Platz war ABER mit einer 12 V batterie mit
56 AH kann er gut 2,5 fahren, und die meisten stellen wird er erwischen
:_)
nun das ist das Konzept mal schauen....
Vorwiegend geht es mir dabei aber um einen leeren Raum.
bitte um hilfe, ich schaffe es nicht, alles macht was es soll, nur meine
buttons gehen nicht, ahhhhh
wenn ich diesen Code benutze tut der Button:
const int buttonPin_front = 2;
const int ledPin = 15;
int buttonState_f = 0;
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin_front, INPUT);
}
void loop(){
buttonState_f = digitalRead(buttonPin_front);
if (buttonState_f == HIGH) {
digitalWrite(ledPin, HIGH);
}
else {
digitalWrite(ledPin, LOW);
}
}
hier habe ich die buttons in meinem Code integriert (Im switch case und
es TUT NICHT: WARUM????
int motor1_A=8; // Motor 1
int motor1_B=9;
int motor2_A=6; // Motor 1
int motor2_B=7;
const int buttonPin_front = 2; // hier sind drei Butons, bei denen der
Roboter die Richtung ändern soll
int buttonState_f = 0;
const int back_buttonPin_l = 3;
int buttonState_r = 0;
const int back_buttonPin_r = 4;
int buttonState_l = 0;
int myStatus = 1;
int raum_position; // Varible, um klar zu machen, ob er linnks oder
Rechts ausscheren soll, rechte raumseite= 0 - linke raumpos = 1
#define trigPin 13 // Infrarot sender und Empfg
#define echoPin 12
#define relais1 14 // steuert ene Putzwalze, die nur bei Vorwärts an
sein soll
#define relais2 15
void setup(){ // Pinbelegungen
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(motor1_A,OUTPUT);
pinMode(motor1_B,OUTPUT);
pinMode(motor2_A,OUTPUT);
pinMode(motor2_B,OUTPUT);
pinMode(buttonPin_front, INPUT);
pinMode(back_buttonPin_l, INPUT);
pinMode(back_buttonPin_r, INPUT);
pinMode(relais1, OUTPUT);
pinMode(relais2, OUTPUT);
} // Ab hier kommen die
Grundfunktionen des Motors die nehme ich jetzt mal raus wegen der
Übersicht, das sind sachen wie: void motorStop()...//
void loop(){
long duration, distance;
digitalWrite(trigPin, LOW); // Added this line
delayMicroseconds(2); // Added this line
digitalWrite(trigPin, HIGH);
// delayMicroseconds(1000); - Removed this line
delayMicroseconds(10); // Added this line
digitalWrite(trigPin, LOW);
duration = pulseIn(echoPin, HIGH);
distance = (duration/2) / 29.1;
buttonState_f = digitalRead(buttonPin_front);
buttonState_l = digitalRead(back_buttonPin_l);
buttonState_r = digitalRead(back_buttonPin_l);
if ((distance > 10) && (buttonState_f == LOW)){
myStatus=1;
// ............ // wenn er vorwaerts fahren
soll- kein Hindernis
}
else {
if( ((distance < 10) || (buttonState_f == HIGH)) &&
(raumecke == 0)) {
myStatus=2; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
rechten ecke ist
}
else {
if(( (distance < 10) || (buttonState_f == HIGH)) &&
(raumecke == 1)) {
myStatus=5; // ....................................................wenn
entfernung unter 10 Cm oder der taster aktiviert wurde und er in der
linken rechten ecke ist
}
else {
if (digitalRead(back_buttonPin_l) == HIGH){
myStatus=3; // anstossen links beim
rueckwärtsfahren
}
else {
if (digitalRead(back_buttonPin_r) == HIGH){
myStatus=4; // anstossen rechts beim
rueckwärtsfahren
}
}
switch (myStatus){
case 1: // vorwärts
vorw();
break;
case 2: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht... RECHTE ECKE
motorStop();
delay (1000);
ausscheren_motor_l();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(4000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
case 3: // er stösst rückwärts LINKS an und dreht en wenig und fährt
dann weiter
turn_l();
delay(1000);
vorw();
delay(2000);
break;
case 4: // er stösst rückwärts RECHTS an und dreht en wenig und fährt
dann weiter
turn_r();
delay(1000);
vorw();
delay(2000);
break;
case 5: // hindernis, wand, er schert rückwärts aus, wechselt die Bahn
und dreht LINKE ECKE
motorStop();
delay (1000);
ausscheren_motor_r();
delay(5000);
Serial.print(raumecke); // um zu überprüfen ob sich die Variable
geändert hat
Serial.print(",");
rueckw();
delay(4000);
motorStop();
delay(500);
vorw();
delay(2000);
break;
}
} } } }
Tsakalidis Konstantin schrieb:> long duration, distance;> ...> ...> distance = (duration/2) / 29.1;
Du deklarierst distance und duration als long.
Dann teilst du erst duration durch zwei und das Ergebnis
dann durch 29.1
Long ist ja ein doppelt grosses int und kennt keine Nachkommastellen.
Ist das so gewollt?
Andere Sache:
Du schreibst von Drehungen um 22,5 und 45 Grad.
Sehe ich das richtig, dass Du das durch die Einschaltdauer der
Motoren erreichen willst?
Das wird nichts.
der distance sensor funktioniert auf den mmm genau, trotzdem danke. Aber
da brauche ich keine hilfe.
Warum solle das über die einschaltdauer der beiden Motoren nicht regeln
lassen?
in 2000 ms drehen die 360 Grad - als beispiel..... trotzdem auch hier
danke für die Ferndiagnose.
Vielleicht gibt es in diesem Forum noch jemand, der mir bezüglich meiner
Buttons helfen kann?
Die funktionieren mit dem ersten code aber aber nicht innerhalb des
Switch cases.... jemand eine Idee?
Vielen Dank und Gruß.
Tsakalidis Konstantin schrieb:> Warum solle das über die einschaltdauer der beiden Motoren nicht regeln> lassen?>> in 2000 ms drehen die 360 Grad - als beispiel..... trotzdem auch hier> danke für die Ferndiagnose.
Das klappt so niemals. Das hängt von vielen Faktoren ab. Vor allem von
der Akkuspannung. Dann gibt's noch Verschmutzung, Schlupf, Spiel im
Getriebe.
Selbst minimale Fehler summieren sich nach ein paar Drehungen so stark,
dass du auch genauso gut zufällig drehen könntest.
Aber ich sage vorher, dass du schon bei der 1. Drehung, bei 20 Fahrten,
20 Winkel haben wirst wie der Bot danach steht.
Wenn du die Drehrate nicht genauer bestimmen kannst oder willst,
empfehle ich eine Zufällige rumfahrerei. Mit Bahnen wird das nichts.
Hallo Tsakalidis,
das Projekt finde ich interessant. Hast Du für uns ein paar Links zu dem
verwendeten Sauger-Aufbau und dem verwendeten fahrbaren Untersatz?
Cyblord ---- schrieb:> Wenn du die Drehrate nicht genauer bestimmen kannst oder willst,> empfehle ich eine Zufällige rumfahrerei.
Da hat er recht, wenn Du nicht genau die Umdrehungen der Räder zählst.
Alternativen:
* Umdrehungen der Räder zählen: Ungenau, wenn mal ein Rad etwas rutscht
oder durch dreht.
* Ein digitaler Kompass funktioniert in Gebäuden oft nicht
* Eine Kamera-Bild auswerten und retro-reflektierende Kugeln am
Saugstauber wären super genau aber aufwendig.
* Mit Ultraschall könntest Du den Abstand zur Wand konstant halten.
butsu schrieb:> Das sehe ich anders. Ich habe immer ein Projekt benötigt, um eine neue> komplexe Fähigkeit (wie z.B. Programmieren) zu lernen.
Das geht mir genau so. Aber vielleicht ist gemeint: Bevor man hier
fragt, sollte man ins Tutorial schauen.
Aber inzwischen sind wir ja eh bei Themen, für die es kein Tutorial
gibt.
VG Torsten
Torsten C. schrieb:> Da hat er recht, wenn Du nicht genau die Umdrehungen der Räder zählst.
Falsch.
Wenn er nicht genau den vom Rad zurückgelegten Weg aufsummiert. Der
hängt neben dem bereits erwähnten Schlupf zb auch vom genauen
Raddurchmesser ab. Der selten bei 2 Rädern auf das 1/100 mm gleich ist.
Was bei einer Umdrehung noch keine Rolle spielt, summiert sich auf
Zig-Metern auf. Dazu kommen noch Hindernisse am Boden wie zb Krümel, die
Wegabweichungen verursachen, unterschiedliche Reibungszahlen, die zb
nicht beeinflussbar durch Feuchtigkeit entstehen, Unebenheiten im
Parkett, etc. etc.
Kurz und gut. Nur durch Umdrehungen zählen bzw. anpassen kriegt man das
Ding nie geradeaus.
>> Das sehe ich anders. Ich habe immer ein Projekt benötigt, um eine neue>> komplexe Fähigkeit (wie z.B. Programmieren) zu lernen.>> Das geht mir genau so. Aber vielleicht ist gemeint: Bevor man hier> fragt, sollte man ins Tutorial schauen.
Nein.
Gemeint ist:
Wenn ich Chriurg werden will, dann sollte ich gefälligst mein Handwerk
zumindest in den Grundlagen an der Uni gelernt haben und vielleicht mal
ein paar Frösche seziert haben ehe ich mich das erste mal an den Tisch
stelle und mir mit dem Skalpell den halben Arm wegschneide.
>> Aber inzwischen sind wir ja auch bei Themen, für die es kein Tutorial> gibt.
Thema schon.
Aber das Problem des TO liegt viel simpler.
Er will nach Schweden auswandern, kann aber kein Wort Schwedisch.
>> VG Torsten
Erstens mal sehe Ich in deinem switch keine Tasterabfragen.
Ich gehe mal davon aus dass du folgende Abfragen meinst:
1
if(((distance<10)||(buttonState_f==HIGH))&&
2
(raumecke==0))
1
if(((distance<10)||(buttonState_f==HIGH))&&
2
(raumecke==1))
Was ich jetzt gerade als mögliches Problem erkenne, denn dein code ist
nicht formatiert und deshalb schlecht leserlich, sind die vielen
delay()s in deinem Code.
Lass mich es einmal so einfach wie möglich zu erklären. Dein Programm
läuft im
1
voidloop()
ab. Wie der name schon sagt, rattert der uC einmal durch diese Schleife
und beginnt dann von vorn. Das Problem jetzt ist dass deine Schleife
anhält sobald ein delay() gerufen wird, und fährt erst weiter wenn die
zeit, in ms nehme ich an, abgelaufen ist.Folglich kann er in dieser
Wartezeit auch nicht auf deine Tastereingaben registrieren.
Tipp: versuch doch mal deinen Code auf pastebin oder sonst irgendwie
leserlicher zu machen. Ausserdem bin ich in diesem Gebiet kein Profi,
also überprüf das selber ebenfalls, z.B. indem du direkt nach dem
scheren eine LED einstellst:
1
ausscheren_motor_r();
2
delay(5000);
3
//An dieser Stelle deine LED einschalten
Schaltet die LED erst 5s ein nachdem er ausgeschert hat? Dann fährt er
erst nach den 5s fort.
Schaltet die LED direkt ein wenn er beginnt zu scheren? Dann liegts an
was Anderem.
Hallo Luxus
vielen Dank. das mit den Delays ist so gewollt, denn wenn erst mal in
einem CASE ist, SOLL er das Ausscheren etc durchlaufen, bevor er wieder
zu den Abfragen kommt. Das heißt ich muss die Abfrage des back-buttons
unmittelbar vor das Rückwärtsfahren IN den case einbauen. GUTER TIPP!!
das werde ich machen. Im Monet habe ich die Backbuttons noch gar nicht
aktiv. Ich kämpfe mit dem Frontbutton:
im Moment ist mein Problem: Wenn er im Vorwärts ist, läuft das Abfragen
sehr schnell, dass merke ich daran: sobald ich die Hand vor den Sensor
halte reagiert er sofort und ich ich sehe auf dem Monitor sofort den
Case 2 (motor stopp, auschscheren etc.)
ABER dann müsste er im Vorwärts auch auf den button Front reagieren, und
den kann ich drücken soviel ich will - er regiert nicht.
oben definiere ich den Button:
const int buttonPin_front = 2;
int buttonState_f = 0;
im loop: die Abfrage:
buttonState_f = digitalRead(buttonPin_front);
if( ((distance < 10) || (buttonState_f == HIGH)) &&
(raumecke == 0))
DAS müsste doch gehen??? tut es aber nicht :(
Hallo Thorsten
ich habe noch keine Fotos, weil ich im Moment noch erst die software mit
den Realais und den Motoren auf dem Tisch zu laufen bringen möchte.
Ich sehe das mit den Motoren ein, das wird schwer mit den Bahnen ABER es
ist auch nicht so tragisch wenn die Bahnen nicht exakt gerade sind, denn
er läuft erst den raum in längsrichtung ab und dann quer und dann wieder
längs.
um exat in die Bahn zu bringen wäre so was machbar:
http://www.hochschule-bochum.de/fileadmin/media/fb_v/labore/photogrammetrie/4._Semester/4_Objektsignalisierung__Beleuchtung__Digitale_Einzelbild.pdf
aber das ist mir zu aufwändig...ich möchte es mal so versuchen... Gruß
Karl Heinz schrieb:> Torsten C. schrieb:> Er will nach Schweden auswandern, kann aber kein Wort Schwedisch.
Es gibt 2 wege eine reise zu machen: zuerst alles packen und alle Kurse
und alle studien zu lesen oder einfach loszufahren. völlig verständlich
dass Leute der ersten Kategorie mit der zweiten ein Problem haben....
der Vorgang des Einfachen-Losfahrens entwürdigt den steinigen Weg der
vorbereitenden Packer. Und ja, das stimmt, ich würde sofort losfahren
und die Sprache unterwegs lernen - haben schon Millionen Leute gemacht,
kein Problem - es gibt eben mehrere Möglichkeiten, nur schade, dass
mache denken, es gibt nur eine einzige Richtige....
Karl Heinz müht sich seit Jahren mit Leuten wie Dir, die unfähig sind zu
lernen, ab. Ich mache es mir einfacher. Du landest gleich in meinem
CSS-File. Schönes Leben noch.