PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : PollSwitch() + Geradeausfahren



upaucc
04.12.2006, 13:11
Hi,
ich habe einmal die PollSwitch funktion mit waste's geradeaus funktion kombiniert. irgendwie klappt das überhaupt nicht! entweder wird sofort die while-schleife übersprungen und die LED blinkt, oder die motoren laufen nicht an, dh. LED ist grün, bewegen tut sich nix, drückt man jedoch einen taster verlässt er die schleife. hier mal der code:



include "asuro.h"

int main(void){

int speedL, speedR;
int j;
int diff, wegL, wegR;
unsigned int odo[2];
unsigned char flankeL=FALSE, flankeR=FALSE, speed;

Init();

MotorDir(FWD,FWD);
StatusLED(GREEN);
speed=200;
speedL=0;
speedR=0;
wegL=0;
wegR=0;




while(PollSwitch()==0){
OdometrieData(odo);
if((odo[0]<550)&&(flankeL==TRUE)){wegL++; flankeL=FALSE;}
if((odo[0]>650)&&(flankeL==FALSE)){wegL++; flankeL=TRUE;}
if((odo[1]<550)&&(flankeR==TRUE)){wegR++; flankeR=FALSE;}
if((odo[1]>650)&&(flankeR==FALSE)){wegR++; flankeR=TRUE;}
diff=wegR-wegL;
if(diff>0){speedR--;}
else if(diff<0){speedL--;}
else{
speedL=speed;
speedR=speed;
}
if(speedL<0){speedL=0;}
if(speedR<0){speedR=0;}
MotorSpeed(speedL,speedR);
}



MotorDir(BREAK,BREAK);
MotorSpeed(0,0);
while(1){
StatusLED(RED);
for(j=0;j<70;j++){
Sleep(255);
}
StatusLED(GREEN);
for(j=0;j<70;j++){
Sleep(255);
}
}




while(1);
return(0);
}

damaltor
04.12.2006, 13:51
das liegt daran, dass die funktion pollswitch oft falsche werte zurückgibt. gerade kurz nach dem anschalten des asuro sind die werte stark fehlerhaft. deshalb wird manchmal die schleife übersprungen und die led blinkt gleich.

um das zu verhindern müsstest du die funktion einige male abfragen, bevor du mit dem wert arbeitest.

dass die motoren gelegentlich einfach nicht anlaufen, obwohl die led grün ist, liegt glaube ich daran dass du ein paar geschweifte klammern {} falsch gesetzt hast, hab aber nicht genau geschaut.

probier doch erstmal einige kleinere programme selbst zu programmieren, und versuche dabei die allgemeine programmierung zu lernen und zu vertiefen, und vor allem die ganzen kleinen eigenheiten des asuro zu verstehen.
aus dem kopieren von programmcodes lernt man nichts. lass doch den asuro erst mal krumm fahren, und auf die taster reagieren. oder versuch, mithilfe der odometrie selbst eine möglichkeit zu finden, den asuro geradeausfahen zu lassen.
wenn du ein solches programm selbst entwickelt hast, kannst du
-stolz darauf sein
-den code sehr gut verstehen und leicht verändern bzw anpassen
-den code (weil du selbst ihn ja gut verstehst) leicht mit anderen funktionen kombinieren
...und lernen tuste au noch was dabei =)

upaucc
04.12.2006, 13:56
habe die taster schon ausprobiert, dh. ohne regelung fürs geradeausfahren da hat er wunderbar funktioniert. den code für die regelung habe ich nachvollzogen und verstanden. habe auch schon eine for-schleife (pollswitch wird 5mal abgefragt) davor eingebaut gehabt, das bringt auch nix

damaltor
04.12.2006, 13:59
hmm... hast du dich mal mit interrutgesteuerter tastererkennung beschäftigt? das dürfte die sache einfacher machen. in der main-funktion steht dabei nur der code fürs geradeausfahren, und in der interruptroutine steht der code fürs anhalten und blinken.

upaucc
04.12.2006, 14:04
ok. danke. dann werde ich mir das mal ansehen!

damaltor
04.12.2006, 14:09
einige infos gibts in dem asuro buch... wenn du das hast dann solltest du mal reinschaun, damit habe ich interruptprogrammierung auch kapiert =)

mit der neuen lib (version 2.6, in version 3.0 wurden nur sinnlose namensänderungen und kleine aufräumarbeiten durchgeführt) brauchst du gar nicht so weit ein die materie einsteigen. es gibt eine variable namens switched, die sofort 1 wird wenn ein taster gedrückt wird. dadurch könntest du diese variable abfragen und damit erkennen ob ein taster gedrückt wurde.

EDH
04.12.2006, 14:15
dadurch wäre der code fürs blinken aber wieder in der main funktion drinne.

man muss im prinzip blos die libg leicht moduifizieren. das ist besser

und drann denken dat interrupt muss erst mit StartSwitch aktivirt werden ;)

upaucc
04.12.2006, 14:25
eine frage noch, bevor ich mich auf das register stürze. habe mir gerade einmal die test.c vom selftest und da eben die switchtest funktion angeschaut. wäre die taster abfrage stabiler wenn ich jeden der 6 taster analog wie in switchtest programmiere?

damaltor
04.12.2006, 14:28
also von der theorie her ist es egal (wenn eine taste gedrückt wird, ist pollswitch() größer als 0 und wenn nicht, dann eben nicht.

woran das nun liegt bei dir... naja... eben einfach am asuro =)

upaucc
04.12.2006, 15:16
also, SIG_INTERRUPT1 wird anscheinend von den Kollisionstastern verwendet. diesen Interrupt kann ich also mit StartSwitch() aktivieren. Wie kann ich diesen jetzt gestalten? muss ich dazu SIGNAL (SIG_INTERRUPT1) in der Asuro.c umschreiben?
wie kann ich dann meine bedingung aufstellen, dass wenn einer der taster gedrückt wird der interrupt abläuft, muss ich StartSwitch in die while-Bedingung einbauen, oder direkt am Anfang deklarieren?

fragen über fragen... ;)

EDH
04.12.2006, 15:38
wenn du StartWitch aufrufst, wird die interruptroutine automatisch ausgeführt, wenn ein taster gedrückt ist. da musst du keine if abfrage mehr schreiben.

nach der abarbeitung der interruptroutine wird mit der main funktion weitergemacht, als ob nichts gewesen wäre. deshalb solltest du ihn vielicht in der interruptroutine mit while(1) gefangen halten.

damaltor
04.12.2006, 16:27
also du hast 2 möglichkeiten.

entweder: du benutzt am beginn des programms StartSwitch(). dann brauchst du nur abzufragen ob die variable switched = 1 ist. diese wird dann 1, wenn ein taster gedrückt wurde (und muss von hand auf 0 zurückgesetzt werden).


oder

du änderst in der asuro.c SIGNAL (SIG_INTERRUPT1) um. dann wird das, was hier drin steht, sofort ausgeführt, wenn ein taster gedrückt wurde. (um den originalzustand widerherstellen zu können, empfehle ich den originalen code nur auszukommentieren und nicht zu entfernen). dann brauchst du KEIN switched als variable, und auch KEIN StartSwitch. es wird einfach, sowie ein aster gedrückt wurde, das ausgeführt was in der schleife steht.
wichtig hierbei: mit sei(); werden alle interrupts aktiviert; und mit cli(); werden alle interrupts deaktiviert (für gewisse phasen des programmes in denen eine unterbrechung ungünstig wäre).

Hier ein beispielprogramm:




#include "asuro.h"

int main(void)
{
Init();
sei();

while(1){
StatusLED(GREEN);
};

return 0;

}


ANPASSUNG DER ASURO.C:

SIGNAL (SIG_INTERRUPT1){
StatusLED(RED);
}



im programm wird die led nur immer wieder auf grün gesetzt. wird eine taste gedrückt, wird durch die interruptroutine die led rot gemacht.

upaucc
04.12.2006, 18:10
Super! Vielen Dank für die Hilfe!

upaucc
05.12.2006, 08:21
OK, habe das gestern mal ausprobiert, dein code damaltor funktioniert nur wenn man vor der while-schleife StartSwitch() aufruft, dann aber einwandfrei:


#include "asuro.h"

int main(void)
{
Init();
sei();
StartSwitch();

while(1){
StatusLED(GREEN);
};

return 0;

}


ANPASSUNG DER ASURO.C:

SIGNAL (SIG_INTERRUPT1){
StatusLED(RED);
}

vielen dank nochmal!

damaltor
05.12.2006, 15:06
hmm... ich dachte eigentlich das hätte sich hiermit erledigt mit dem startswitch... egal. auf jeden fall ist das evtl ne anregung wie du das problem umgehen kannst welches du am anfang hattest. lass ihn geradeausfahren in der mainfunktion, und interruptgesteuert zurückweichen, wenn er irgendwo anditscht.

upaucc
05.12.2006, 18:04
jawoll, klappt wunderbar

damaltor
05.12.2006, 18:30
na herzlichen glückwunsch! dann weiter so... pass auf dass deine interruptroutine nicht zu lange dauert (gerade mit sleep ist sehr vorsichtig umzugehen). in dieser zeit kann der asuro nämlich NICHTS anderes machen, als das was in der routine steht. viel spaß =)