PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [ERLEDIGT] PollSwitch() Problem



Andreas Bullmann
08.03.2013, 19:02
Halli Hallo
ich hab da mal ne Frage ...
Und zwar versuche ich grad über das Programmers Notepad von WinAVR einen Asuro zu programmieren, damit der dann eine Kollision erkennt und dann "ausparkt" umdreht und weiterfährt.
Blöderweise funzt das mit der while Schleife nicht so ganz. Setze ich das Switch= PollSwitch() davor, fährt der nur geradeaus, setze ich das drunter, macht der nur die Unterprogramme und leuchtet nur mal kurz vorne zum Zeichen der main function.
Könntet ihr da mal drüberschauen und mir evtl. sagen was ich falsch mache? Wäre echt lieb.
Die Taster sind aber noch alle intakt, das habe ich schon getestet, indem ich die Unterprogrammaufrufe auskommentiert habe.
Der geht momentan auch davon aus, dass er direkt beim starten seines Programmes ein Hindernis auf der rechten Seite hat.
Achso, bevor ichs vergesse. Den Asuro hab ich schon zusammengelötet bekommen. Allerdings sind die Motoren falsch herum angelötet worden, sodass der Befehlsaufruf MotorDir(FWD,FWD); dafür sorgt, dass der kleine rückwärts fährt, also nicht wundern warum der Quelltext sagt, dass der Roboter rückwärts fahren soll.





/************************************************** *************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* any later version. *
************************************************** *************************/
#include<asuro.h>
void sleep_ms(int ms){
while(ms>0){
Sleep(72);
ms=ms-1;
}
}
void hindernis_rechts(void){
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(2000);
FrontLED(OFF);
StatusLED(YELLOW);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(100,50);
sleep_ms(2000);
BackLED(OFF,OFF);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(5000);
main();
}
void hindernis_links(void){
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(2000);
FrontLED(OFF);
StatusLED(YELLOW);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(50,100);
sleep_ms(2000);
BackLED(OFF,OFF);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(5000);
main();
}
void main (void){
unsigned int Switch;
Init();
while(1){
FrontLED(ON);
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(175,175);
Switch=PollSwitch();
if (Switch!=0){
StatusLED(RED);
if(Switch<=7){
BackLED(OFF,ON);
hindernis_rechts();
}
else
BackLED(ON,OFF);
hindernis_links();
}
else
BackLED(OFF,OFF);
}
}

radbruch
08.03.2013, 19:33
Hallo

Versuche es mal so:


/************************************************** *************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* any later version. *
************************************************** *************************/

#include <asuro.h>

void sleep_ms(int ms)
{
while(ms>0)
{
Sleep(72);
ms=ms-1;
}
}

void hindernis_rechts(void)
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(2000);
FrontLED(OFF);
StatusLED(YELLOW);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(100,50);
sleep_ms(2000);
BackLED(OFF,OFF);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(5000);
}

void hindernis_links(void)
{
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(2000);
FrontLED(OFF);
StatusLED(YELLOW);
BackLED(ON,ON);
MotorDir(FWD,FWD);
MotorSpeed(50,100);
sleep_ms(2000);
BackLED(OFF,OFF);
MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
sleep_ms(5000);
}

int main (void){
unsigned int Switch1, Switch2;
Init();
Switch2=PollSwitch();
while(1)
{
FrontLED(ON);
StatusLED(GREEN);
MotorDir(RWD,RWD);
MotorSpeed(175,175);
Switch1=PollSwitch();
if ((Switch1 == Switch2) && (Switch1 != 0))
{
StatusLED(RED);
if(Switch1<=7)
{
BackLED(OFF,ON);
hindernis_rechts();
}
else
{
BackLED(ON,OFF);
hindernis_links();
}
}
else
BackLED(OFF,OFF);

Switch2=Switch1;
}
}(ungetestet)

Änderungen:

main()-Aufrufe am Ende der Ausweichfunktionen entfernt. else-Zweig in Klammern gesetzt:

else
{
BackLED(ON,OFF);
hindernis_links();
}

und Mehrfachabfrage von PollSwitch() eingefügt.

Gruß

mic

markusj
08.03.2013, 19:37
Ich sehe keinen Grund, warum ein Wandkontakt nicht zu der gewünschten Reaktion führen sollte. Der PollSwitch-Aufruf ist da genau richtig platziert. Du hast aber ein anderes Problem: Deine beiden Hilfsfunktionen dürfen main() nicht wieder aufrufen. Das gibt sonst eine Endlos-Rekursion die letztendlich dein Programm "abstürzen" lässt.

Nachtrag: Mic hat einen weiteren wichtigen Fehler gefunden, die fehlenden geschweiften Klammern im inneren else-Zweig. Aus diesem Grund ist es eine gute Praxis, auch bei einzeiligen Verzweigungen (if, else, for, while und do) immer geschweifte klammern zu setzen.

mfG
Markus

Andreas Bullmann
08.03.2013, 19:49
also muss ich zwei variablen für den pollswitch anlegen? ich seh da Switch1 und Switch2....

Valen
08.03.2013, 20:01
@ Andreas:

Wie schon gesagt in ein Privat Bericht. Wenn einer nicht kann, (in meinen Fall essen muss), kann eine andere Person (weiter) helfen. ;) [EDIT] Sorry Markusj: ... mehrere Personen...

Wie Radbruch schon festgestellt hat. Die Main anrufen am ende dein Hindernis-Funktionen sind nicht notwendig. Wieso du sie dort rein geschrieben hast ist mich nicht ganz klar. Wenn es dein Lösung ist wieder zurück ins Main Hauptprogramm zu gelangen, dann ist das begreiflich aber auch falsch. Zurückkehren zum Hauptprogramm nach Abenden einer Funktion geht in den C-sprache automatisch. Den Prozessor speichert erst die Instruktion-stelle im RAM wo es bis jetzt gekommen ist. Dann wird die Stelle von den Angerufen Funktion in den Instruktion-zeiger Register geladen, womit die Funktion eigentlich gestartet wird. Am ende von den Instruktionen einer Funktion wird ein Spezielle Return-instruktion zugefügt. Das holt wieder die alte Instruktion-stelle von das Hauptprogramm aus das RAM-speicher, und wird wieder im Instruktion-Zeiger Register gesetzt. Dann geht es weiter wo es geendet war.

Die Mehrfachabfrage von PollSwitch ist notwendig weil die Motoren kleine Störungen verursachen können in den Taster-messungen. (Aber vielleicht auch bei die andere Analoge Messungen). Also könnte es passieren das PollSwitch falsch >0 bemerkt wenn die Tastern nicht geprellt sind. Damit wir das raus Filtern können, kontrollieren wir ob die Taster-messung ein Stabile Zustand hat.


In dein:


...
if(Switch<=7){
BackLED(OFF,ON);
hindernis_rechts();
}
else
BackLED(ON,OFF); // Wird hier die if-else Zweig abgebrochen, wegen die Punkt-Comma. Hindernis_links() wird jedenfals ausgeführt, unabhängig von Switch
<=7 oder >7
hindernis_links();

...




Wenn hindernis_links ausgeführt werden soll wenn Switch>7 ist, solltest du das zwischen {} klammern setzen. Aber das bist du vermutlich nur vergessen.