PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : while-schleifen abbrechen



proevofreak
01.09.2008, 13:15
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ß

askazo
01.09.2008, 13:30
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

proevofreak
01.09.2008, 13:42
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ß

radbruch
01.09.2008, 17:07
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

proevofreak
01.09.2008, 17:31
@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ß

RP6conrad
01.09.2008, 22:13
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.

//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.

radbruch
01.09.2008, 22:19
So vielleicht:

// 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;
}

proevofreak
04.09.2008, 10:24
@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

Pr0gm4n
04.09.2008, 11:37
noch zu deinem ersten entwurf:

// 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