- LiFePO4 Speicher Test         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: problem mit startswitch() ..while (!switched)...

  1. #1
    Benutzer Stammmitglied
    Registriert seit
    21.03.2004
    Ort
    73061 Ebersbach
    Alter
    55
    Beiträge
    52

    problem mit startswitch() ..while (!switched)...

    Anzeige

    LiFePo4 Akku selber bauen - Video
    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.

  2. #2
    Erfahrener Benutzer Begeisterter Techniker Avatar von Osser
    Registriert seit
    31.10.2006
    Ort
    Köln
    Alter
    53
    Beiträge
    396
    Indent ist ja auch nie verkehrt.... oder?

    Code:
    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.

  3. #3
    Benutzer Stammmitglied
    Registriert seit
    21.03.2004
    Ort
    73061 Ebersbach
    Alter
    55
    Beiträge
    52
    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.

    Code:
    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

  4. #4
    Erfahrener Benutzer Begeisterter Techniker Avatar von Osser
    Registriert seit
    31.10.2006
    Ort
    Köln
    Alter
    53
    Beiträge
    396
    Warum benutzt Du das Signal wenn Du doch die Schalterstellung pollst?
    Hab dir mal nen polling code gepostet der geht....



    Code:
    #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()

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2006
    Beiträge
    10

    Problem in der Asuro-Lib?

    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

  6. #6
    Moderator Robotik Einstein Avatar von damaltor
    Registriert seit
    28.09.2006
    Ort
    Milda
    Alter
    37
    Beiträge
    4.063
    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).
    Read... or die.
    ff.mud.de:7600
    Bild hier  

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    23.12.2006
    Beiträge
    10
    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!

  8. #8
    Benutzer Stammmitglied
    Registriert seit
    25.04.2007
    Beiträge
    54
    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.

    Code:
    #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

  9. #9
    Erfahrener Benutzer Roboter Genie Avatar von m.a.r.v.i.n
    Registriert seit
    24.07.2005
    Ort
    Berlin
    Beiträge
    1.247
    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:

    Code:
    extern volatile int switched;
    Im File globals.c:

    Code:
    volatile int switched;
    Das gleiche trifft übrigens auch für die Variabale encoder zu.

  10. #10
    Benutzer Stammmitglied
    Registriert seit
    25.04.2007
    Beiträge
    54
    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
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken asuro_2.jpg  

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Labornetzteil AliExpress