-         

Ergebnis 1 bis 9 von 9

Thema: while-schleifen abbrechen

  1. #1
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    30
    Beiträge
    220

    while-schleifen abbrechen

    Anzeige

    hallo leute,
    hab heut seit längerer zeit mal wieder meinen roboter ausgepackt und wieder mal programmiert. allerdings stoß ich jetzt auf ein problem, das ich vor längerer zeit schon mal hatte.

    und zwar behindern sich bei manchen programmen von mir while- schleifen gegenseitig, weil sie dann dauerhaft laufen.
    kann mir jemand vielleicht mal die einfachsten möglichkeiten posten, um while-schleifen wieder zu beenden.

    danke schon mal im vorraus.

    gruß

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    02.11.2005
    Alter
    42
    Beiträge
    1.140
    Code:
    if (<Abbruchbedingung>)
    break;
    Ist aber keine wirklich saubere Programmierung. Besser wäre es, wenn Du eine Alternative zur while-Schleife findest oder alle Abbruchbedingungen in das while() mit reinpackst.
    Es gibt m.E. eigentlich nur zwei sinnvolle Anwendungen für while:
    - Hauptschleife ( while(1) )
    - Auf etwas warten (bis ein Flag gesetzt wird oder ähnliches) - dann aber konsequent und nicht unterbrechbar (außer durch Interrupts)

    Gruß,
    askazo

  3. #3
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    30
    Beiträge
    220
    will mit meinem programm einen servo über LED1 mit hilfe der bumper ansteuern.
    hier mein programm dazu:

    // RP6 steuert ein Servo an der SL1-LED mit Sleep()

    #include "RP6RobotBaseLib.h"
    uint8_t i=0;
    uint8_t a=0;
    void bumpersStateChanged(void)
    {

    while(bumper_left && i<5)
    {setLEDs(1);
    sleep(10);
    setLEDs(0);
    sleep(200-10);
    i++;}


    while(bumper_right && a<5)
    {setLEDs(1);
    sleep(20);
    setLEDs(0);
    sleep(200-20);
    i++;}
    }


    int main()
    {
    initRobotBase();
    BUMPERS_setStateChangedHandler(bumpersStateChanged );



    while(true)
    {task_RP6System();
    }
    return 0;
    }



    hab versucht die schleifen mit den variablen i bzw. a wieder abzubrechen. funktioniert aber irgendwie nicht.
    wer kann mir sagen warum?

    gruß

  4. #4
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    Hallo

    Möglicherweise wird der Bumper-Task durch die blockierenden while-Schleifen nicht richtig ausgeführt. Sicherheitshalber würde ich deshalb die Funktionen getBumperLeft() bzw. getBumperRight() verwenden:

    while(getBumperLeft() && (i<5))
    {...

    i bzw. a müssen nach Ende der while-Schleifen wieder mit Startwerten geladen werden.


    Gruß

    mic

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  5. #5
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    30
    Beiträge
    220
    @radbruch: ich hab das jetzt mal mit dem getBumperLeft().... und so ausprobiert. funktioniert bisher noch überhaupt nicht. aber ich habe bisher i bzw. a auch nicht mehr mit startwerten geladen.
    wie kann ich das machen? hab irgendwie gar keine idee wie ich das in der schleife machen kann.

    gruß

  6. #6
    Erfahrener Benutzer Begeisterter Techniker
    Registriert seit
    09.04.2008
    Beiträge
    375
    Da gibt bessere Moglichkeiten für eine Servo anzusteuern. Ich verwende ide ISR (Interrupt Subroutine) die auf 10 kHz lauft. Bei mir in die M32 programmiert, aber geht auch in Robotbase. Bei diese ISR kannst du die Servo's in 10 Positionen fahren von 1 mS bis 2 mS.
    Code:
    //stuurt servopulsen aan tussen 1 en 2mS
    uint8_t servo1 = 15;
    uint8_t servo2 = 15;
    uint8_t servo3 = 11;
    uint8_t servo4 = 19;
    
    void servo(uint8_t nummer,uint8_t puls)
    {
    if(nummer==1) servo1=puls;
    if(nummer==2) servo2=puls;
    if(nummer==3) servo3=puls;
    if(nummer==4) servo4=puls;
    }
    
    /*****************************************************************************/
    // Delays, Stopwatches and Beeper:
    
    
    // ---------------------
    // Internal status bits
    volatile union {
    	uint8_t byte;
    	struct {
    		unsigned beep:1;
    		unsigned unused:7;
    	};
    } controlStatus;
    
    volatile stopwatches_t stopwatches;
    volatile uint8_t delay_timer;
    volatile uint8_t ms_timer;
    volatile uint8_t servo_timer;
    volatile uint16_t sound_timer;
    
    
    
    /**
     * Timer 0 Compare ISR - This timer is used for various
     * timing stuff: The delay timer for blocking delays, 
     * "Stopwatches" for non-blocking delays and the timing of
     * the sound generation with timer2...
     *
     * By default, it runs at 10kHz which means this ISR is called
     * every ~100µs! This is nice for timing stuff!
     */
    ISR (TIMER0_COMP_vect)
    {
    	// Blocking delay (100µs):
    	delay_timer++;
    	servo_timer++;
    	if (servo_timer>250)
    		{
    		servo_timer=0;
    		PORTC |= IO_PC2;
    		PORTC |= IO_PC3;
    		PORTC |= IO_PC5;
    		PORTC |= IO_PC7;
    		}
    	if (servo_timer>servo4) PORTC &= ~IO_PC2;	
    	if (servo_timer>servo3) PORTC &= ~IO_PC3;	
    	if (servo_timer>servo2) PORTC &= ~IO_PC5;
    	if (servo_timer>servo1) PORTC &= ~IO_PC7;
    Sleep function hat das Nachteil das auch alles andere nicht weiter bearbeitet werd.

  7. #7
    Moderator Robotik Visionär Avatar von radbruch
    Registriert seit
    27.12.2006
    Ort
    Stuttgart
    Alter
    54
    Beiträge
    5.781
    Blog-Einträge
    8
    So vielleicht:
    Code:
    // RP6 steuert ein Servo an der SL1-LED mit Sleep()
    
    #include "RP6RobotBaseLib.h"
    
    uint8_t i;
    
    int main(void)
    {
    initRobotBase();
    
    	while(true)
    	{
    		i=0;									// i mit Startwert laden
    		while(getBumperLeft() && (i<5))	// Wenn links gedrückt fünf Impulse senden
    		{
    			setLEDs(1);                // Impuls High senden
    			sleep(10);                 // ca. 10 * 100µs warten
    			setLEDs(0);                // Impuls Low senden
    			sleep(200-10);             // ca. 20ms - 1ms Pause
    			i++;
    		}
    
    		i=0;
    		while(getBumperRight() && (i<5))
    		{
    			setLEDs(1);
    			sleep(20);
    			setLEDs(0);
    			sleep(200-20);
    			i++;
    		}
    	}
    
    	return 0;
    }

    Atmel’s products are not intended, authorized, or warranted for use
    as components in applications intended to support or sustain life!

  8. #8
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    26.01.2008
    Ort
    Allgäu
    Alter
    30
    Beiträge
    220
    @radbruch: danke
    eigentlich ne ganz simple art wie du des jetzt gelöst hast. nur hab ich mir gedacht, dass wenn ich des i=0 in die while- schleifen stecke, dass des i dann immer den wert 0 haben und die while(bumper.....) schleifen nicht mehr korrekt funktionieren.
    aber es scheint ja so zu sein, dass sobald die while(bumper...) schleifen nicht mehr aktiv sind, jetzt der wert von i immer wieder auf 0 zurückgesetzt wird.

    danke nochmals

  9. #9
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    24.01.2008
    Ort
    Schrobenhausen, München
    Alter
    24
    Beiträge
    583
    noch zu deinem ersten entwurf:
    Zitat Zitat von proevofreak
    // RP6 steuert ein Servo an der SL1-LED mit Sleep()

    #include "RP6RobotBaseLib.h"
    uint8_t i=0;
    uint8_t a=0;
    void bumpersStateChanged(void)
    {

    while(bumper_left && i<5)
    {setLEDs(1);
    sleep(10);
    setLEDs(0);
    sleep(200-10);
    i++;}


    while(bumper_right && a<5)
    {setLEDs(1);
    sleep(20);
    setLEDs(0);
    sleep(200-20);
    i++;}
    }


    int main()
    {
    initRobotBase();
    BUMPERS_setStateChangedHandler(bumpersStateChanged );



    while(true)
    {task_RP6System();
    }
    return 0;
    }
    du hast bei der 2. bumper-while-schleife gesagt, mache solange bis ... && a<5

    in der schleife hast du allerdings "i" inkrementiert, das hat radbruch in seinem entwurf aber schon berücksichtigt...

    ich denke, wenn du deine version behalten willst (gibt gründe), dann musst du nur das a durch i ersetzen und hinter jede der beiden schleifen ein "i=0;" einfügen, dann gehts...


    MfG Pr0gm4n

Berechtigungen

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