PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : problem mit startswitch() ..while (!switched)...



Downad
21.11.2006, 16:57
hallo zusammen,

mein problem ist folgendes.

In dem Programm soll der Asuro vorwärts fahren bis ein Hindernis kommt.
dann darauf reagieren und danach das ursüngliche Progamm weiter machen.

...
#include "asuro.h"
int main(void)
{
while (1) { // das mein programm
while (!switched) { //solange kein taster mache irgendwas}

//taster war gedrückt als
mache nun was anderes und gehe zurück in das ursprungsprogramm
bzw. setze die schleife weiter fort.
switched=0; <--damit müsste ich doch in der while (!switched) { //solange kein taster mache irgendwas} wieder sein.

return 0;
}

doch leider geht das nicht, der interrupt schein noch gesetzt zu sein.

was muss ich machen damit ich wieder in die while (!switched) gelange?

gibt es da soetwas wie eine ResetSwitch() - funktion?


vielen dank für eure hilfe.

Osser
21.11.2006, 18:48
Indent ist ja auch nie verkehrt.... oder?



int main(void)
{
// main loop
while (1) {

while (!switched) {
//solange kein taster mache irgendwas
}

// wharteveryouwantcode hierher
switched=0;

}

while (1);
return 0;
}




Du darfst natürlich kein return 0 in die "main loop" setzen =;
dann geht det janze auch wie's soll.

cu

O.

Downad
21.11.2006, 20:10
die Init(); hab ich im posting weggelasen im original gibt es die

und die return 0 ist ein fragment das ich vergessen hatte im posting zu löschen.


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

SerWrite("\n\r",2);
// 123456789012345678901234567890123456789012
SerWrite("Hallo Ralf, ich beginne mit dem Programm: ",42);
SerWrite("\n\r",2);
"
//sw_pressed kommt aus PollSwitch
int sw_pressed;


while (1) {

while (!switched) {
SerWrite("-nix-",5);
} //end while (!switched)

sw_pressed=PollSwitch();
//ausgabe an terminal
SerWrite("\n\rSchalter: ",12);
PrintInt(sw_pressed);
serWrite("\n\r",2);

if (sw_pressed==1) { //SCHALTER 1
nEck(200, 90, 100);
sw_pressed=0;
} // endif (sw_pressed==1)

if (sw_pressed==2) { //SCHALTER 2
// iSpeed, iEcken, iToGo
nEck(200, 6, 150);
sw_pressed=0;
} //endif (sw_pressed==2)

if (sw_pressed==4) { //SCHALTER 3
// iSpeed, iEcken, iToGo
nEck(200, 12, 50);
sw_pressed=0;
} //endif (sw_pressed==4)

switched=0;
} //end while (1)

// Nie vergessen, reine Vorsichtsmassnahme..
while(1){}
return 0;

} // end int main()


das war der code, wobei die sub nEck nur ein passendes nEck fährt.

das Problem ist/war, dass nach dem ich einmal einen taster gedrückt habe die Anzeige "-nix-" (aus der while(!switched)) nicht mehr erscheint sondern nur noch...
"Schalter: 0" <--also ist er nimmer in der inneren while schleife

Osser
21.11.2006, 21:03
Warum benutzt Du das Signal wenn Du doch die Schalterstellung pollst?
Hab dir mal nen polling code gepostet der geht....





#include <asuro.h>

int sw_pressed;


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

// 123456789012345678901234567890123456789012
SerWrite("\n\rHallo Ralf, ich beginne mit dem Programm:\n\r", 45);

while (1) {

while((sw_pressed = PollSwitch()) == 0x00);


if (sw_pressed & 0x01) { //SCHALTER 1
//nEck(200, 90, 100);
SerWrite("\n\rSchalter 1", 12);
} // endif (sw_pressed==1)
else if (sw_pressed & 0x02) { //SCHALTER 2
// iSpeed, iEcken, iToGo
//nEck(200, 6, 150);
SerWrite("\n\rSchalter 2", 12);

} //endif (sw_pressed==2)
else if (sw_pressed & 0x04) { //SCHALTER 3
// iSpeed, iEcken, iToGo
//nEck(200, 12, 50);
SerWrite("\n\rSchalter 3", 12);
} //endif (sw_pressed==4)
else {
//usw...
SerWrite("\n\rSchalter: n=", 14);
PrintInt(sw_pressed);
}


} //end while (1)

// Nie vergessen, reine Vorsichtsmassnahme..
while(1){}
return 0;

} // end int main()

obstriegel
24.05.2007, 17:33
Hallo! Ich krame diesen Thread wieder aus, weil das Problem nicht gelöst wurde, sondern lediglich eine Lösung mit PollSwitch angeboten wurde.

Ich habe das gleiche Problem mit der Interruptgesteuerten Tasterabfrage. Ich habe lange rumgetestet und herausgefunden, dass scheinbar, wenn der Interrupt einmal aufgerufen wurde, er die ganze Zeit aufgerufen wird und switched immer wieder auf 1 gesetzt wird, aber auch nur, wenn nach der Interruptabfrage ein Pollswitch folgt.

Mein ASURO soll alle Sensoren nutzen und per Interrupt merken, wenn er gegen etwas gefahren ist und dann erst einmal PollSwitch ausführen um zu wissen wo er angestoßen ist. Das Problem ist, die Odometrie soll auch im Interruptbetrieb im Hintergrund laufen und der AD-Wandler eben nur dann für den Taster arbeiten, wenn er wo angestoßen ist.

Ich glaube langsam, dass das nen Fehler in der ASURO-Bibliothek ist, denn die einzige Lösung die ich gefunden habe ist mehr ein Workaround denke ich. Nach dem PollSwitch muss Init() nochmal ausgeführt werden und ein Sleep-Befehl eingefügt werden, dann geht der externe Interrupt der Taster wieder, aber auch z.B. die Odometriemessung ist dann im Eimer und muss neu initialisiert und gestartet werden.

Meinen Testcode könnt ihr unter http://rafb.net/p/A2lxFl56.html ansehen (nopaste).

Mit freundlichen Grüßen,
Pascal Klein

damaltor
24.05.2007, 18:58
der interrupt wird, solange wie die taste gedrückt ist, immer wieder aufgerufen. eine möglichkeit wäre, in der interruptroutine die funktion

cli();

auszuführen. dann sind alle interrupts deaktiviert. dies ist jedoch sehr riskant, da zB die Sleep() und Msleep() funktionen ohne interrupts eine endlosschleife bilden!! mit sei(); werden die interrupts wieder eingeschaltet (in der hauptschleife).

obstriegel
24.05.2007, 21:56
Hallo,

so wie es aussieht bleibt switched aber auch 1, wenn kein Taster mehr gedrückt wird. Ich werde einmal versuchen cli() in der Interruptfunktion und sei() nach der tasterabfrage einzubauen.

Vielen Dank schonmal!

ukuchel
24.08.2007, 07:21
Hallo,
leider habe ich keine Lösung anzubieten, sondern nur eine Bestätigung des Problems:
Der Interrupt für die Kollisionstaster funktioniert nur beim ersten Mal korrekt. Wird ein Taster-Interrupt mit dem Befehl StartSwitch freigegeben und anschließend durch einen Tastendruck ausgelöst, so wird die ISR (Interrupt Service Routine) in der Datei asuro.c

SIGNAL (SIG_INTERRUPT1)
{
switched=1;
StopSwitch();
}


korrekt ausgelöst. Die globale Variable switched wird (auf 1) gesetzt, die Interruptfreigabe wird aufgehoben.
Wird jedoch anschließend der Taster-Interrupt erneut mit StartSwitch freigegeben, so wird die ISR sofort und ohne zusätzlichen Tastendruck ausgelöst.
Folgendes Programm macht dies deutlich, die zweite Ausgabe auf dem Terminal erfolgt auch ohne Tastendruck.


#include "asuro.h"

int i;

void Ausgabe(void)
{
PrintInt(PollSwitch());
SerWrite(" ",3);
PrintInt(switched);
SerWrite("\r\n",2);
}

void Kollision(void)
{
StartSwitch();
while (!switched) {
SerWrite("Taste?",6);
SerWrite("\r\n",2);
}
switched=0;
}

int main(void)
{
Init();
Kollision();
Ausgabe();
BackLED(ON,ON);
Msleep(1000);
Kollision();
Ausgabe();
BackLED(OFF,OFF);
while(1);
return 0;
}

Vermutlich wird in der Routine StopSwitch, die die Interruptfreigabe wieder sperrt und stets sofort nach einem Taster-Interrupt aufgerufen wird, vergessen, ein entsprechendes Register(-bit) im Mega8 zurückzusetzen, um den Ausgangszustand wiederzuerlangen?!
Er wäre schön, wenn jemand, der sich mit den Registern des Mega8 auskennt, sich die entsprechenden Routinen noch einmal anschauen könnte.
Ulli

m.a.r.v.i.n
24.08.2007, 13:29
Hallo,

ist vermutlich wirklich ein Fehler in der AsuroLib. Die Variable switched muß als volatile deklariert sein, da sie in einer Interrupt Routine geändert werden kann.

Probier mal folgende Änderungenin der Lib vorzunehmen. Ich kann es leider derzeit selbst nicht testen. Die AsuroLib muß anschließend neu übersetzt und ins avr/lib Verzeichnis kopiert werden.

Im File asuro.h:


extern volatile int switched;

Im File globals.c:


volatile int switched;

Das gleiche trifft übrigens auch für die Variabale encoder zu.

ukuchel
05.09.2007, 14:01
Hallo m.a.r.v.i.n
ich habe Deine Anregungen ausprobiert, leider ohne Erfolg.
An dem Bild weiter unten siehst Du noch einmal genau, was da nicht klappt.

1. Der Asuro wartet auf einen Tastendruck und sendet jede Sekunde den String "Taste?" (Zeile 16-19).
2. Beim Drücken einer Taste wird die globale Variable switched auf Null gesetzt (Zeile 20).
3. Der Bitwert des entsprechenden Tasters (in diesem Beispiel 16) wird zusammen mit dem Wert switched ( jetzt wieder 0) ausgegeben. Im Terminalfenster erscheint die Zahlenkombination 16 und 0.
4. Jetzt sollte das Programm eigentlich wieder auf einen neuen Tastendruck warten und die Schritte 1-3 wiederholen. Das passiert aber nicht, sondern der Interrupt wird sofort und ohne Tastendruck erneut ausgelöst. Dies erkennt man daran, dass nun im Terminalfenster die Zahlenkombination 0 und 0 erscheint. Die globale Variable switched muss dazu zuvor erneut auf 1 gesetzt worden sein - und zwar durch Aufrufen der ISR SIGNAL (SIG_INTERRUPT1). Da dies nicht durch einen Tastendruck passiert ist, geschieht dies intern im Prozessor.

Mein Fazit: Das permanente Aufrufen der ISR SIGNAL (SIG_INTERRUPT1) muss irgendwie intern im Prozessor durch ein Register-Bit gestoppt werden. Das Abändern der globalen Variablen switched ist ohne Probleme möglich, führt aber nicht zum Erfolg.

Ulli

m.a.r.v.i.n
05.09.2007, 21:36
Hallo Ulli,

ich kann den Fehler inzwischen auch nachvollziehen. Das Problem hängt wohl mit der PollSwitch Funktion zusammen. Lasse ich diese weg, funktioniert es mit den Taster Interrupts wie erwartet. Dann kann aber leider nicht feststellen, welche Taste gedrückt wurde. :-k