Forum: PC-Programmierung while loop Abbruch


von Jannik B (Gast)


Lesenswert?

Hallo liebes Forum,

ich will bei steigendem Stromverbrauch einen Linearmotor kurz anhalten.
Ich lasse dazu eine ISR alle 0,5s einen counter inkrementieren.
Ich habe folgenden Code:

if(Strom > gewisser_Wert)
{
---warte_counter = 0;  //setze counter zurück
---while(warte_counter <= 4)
---{
------stop_motor();
---}

---if(warte_counter > 4)  //wenn counter > 4 --> 2s vorbei
---{
------start_motor();
---}
}

Auf diese Weise springt der Motor allerdings nicht mehr an.
Es scheint als würde er in der while Schleife hängen bleiben. Mit einem 
break läuft der Code dann nämlich weiter.
Kann man die Abbruchbedingung für die while Schleife überhaupt extern 
inkrementieren oder muss das in der Schleife geschehen?

von Simon (Gast)


Lesenswert?

Wie hast du die Variable warte_counter deklariert?

von Tom (Gast)


Lesenswert?

While heißt while weil er in dieser Schleife bleibt bis sie falsch ist

von Jannik B (Gast)


Lesenswert?

volatile uint8_t wait_count;

von Jannik B (Gast)


Lesenswert?

Tom schrieb:
> While heißt while weil er in dieser Schleife bleibt bis sie falsch
> ist

Schon klar, aber nach 2s ist die Bedingung eigentlich falsch

von Jannik B (Gast)


Lesenswert?

Habs gelöst, lag doch nicht an der Schleife
Danke euch zwei!

von Fragen (Gast)


Lesenswert?

>volatile uint8_t wait_count;

Ist schon mal falsch ;-)

Funktioniert der Interrupt?
Wird der Counter sicher incrementiert?

Funktionieren die Funktionen auch?
stop_motor();
start_motor();

Ist die Bedingung
if(Strom > gewisser_Wert)
erfüllt?

Fragen über Fragen.

von Fragen (Gast)


Lesenswert?

Was wars denn?

von Teddy (Gast)


Lesenswert?

Jannik B schrieb:
> Hallo liebes Forum,
>
> ich will bei steigendem Stromverbrauch einen Linearmotor kurz anhalten.
> Ich lasse dazu eine ISR alle 0,5s einen counter inkrementieren.
> Ich habe folgenden Code:
-warte_counter = 0;  //setze counter zurück
> ---while(warte_counter <= 4)
> ---{
> ------stop_motor();
> ---}

Du musst doch warte_counter auch mal inkrementieren.
Wo machst du es denn?

von C. U. (chriull)


Lesenswert?

Fragen schrieb:
> Was wars denn?

Wenn der Strom zu hoch ist wird der warte_counter auf 0 gesetzt.
Dann 2 Sekunden lang (4 mal warte_counter in ISR erhöht) in der while 
Schleife stop_motor() aufgerufen.
Die Bedingung der zweiten while schleife wird nie erfüllt (warte counter 
> 4) (außer stop_motor() braucht länger als 0,5 Sekunden...), also 
bleibt der Motor stehen.

Besser wäre es die while Schleifen zu vermeiden und z.B. eine 
motor_schutz_aktiv Variable einzuführen und folgendes

if ((Strom > gewisser_Wert) && !motor_schutz_aktiv) {
   stop_motor();
   motor_schutz_aktiv=true;
   warte_counter = 0;
}
if (motor_schutz_aktiv && (warte_counter > 4) {
   motor_schutz_aktiv=false;
   start_motor();
}

regelmäßig in der Hauptschleife aufzurufen.

von Jannik B (Gast)


Lesenswert?

Fragen schrieb:
>>volatile uint8_t wait_count;
>
> Ist schon mal falsch ;-)


Wieso ist die Deklaration falsch? Wir haben im Studium extra diese Art 
der Deklaration für Variablen die in einer ISR geändert werden gelernt, 
damit der Compiler die Variable nicht wegoptimiert.

von Jannik B (Gast)


Lesenswert?

Christian U. schrieb:

> Besser wäre es die while Schleifen zu vermeiden und z.B. eine
> motor_schutz_aktiv Variable einzuführen

Danke Christian, ich werds auch mal auf deine Art versuchen.

Sind Schleifen hierfür zu ineffizient oder warum würdest du drauf 
verzichten?

von C. U. (chriull)


Lesenswert?

Jannik B schrieb:
> Christian U. schrieb:
>
>> Besser wäre es die while Schleifen zu vermeiden und z.B. eine
>> motor_schutz_aktiv Variable einzuführen
>
> Danke Christian, ich werds auch mal auf deine Art versuchen.

Vergiss dann nicht motor_schutz_aktiv richtig zu initialisieren (auf 
false, damit er danach den Motorschutz aktivieren kann)

> Sind Schleifen hierfür zu ineffizient oder warum würdest du drauf
> verzichten?
Wenn dein mC nichts anderes tun soll, kann man ihn gerne in einer 
Schleife Zeit verbraten lassen. So wie in deinem Beispiel ihn 2 Sekunden 
lang den Motor stoppen...
Falls er noch etwas anderes tun sollte ist eine Schleife in der Werte 
eingelesen und aufgrund dessen gewisse Aktionen durchgeführen besser. 
Ohne in dieser Schleife zu warten - da bist du mit deinem warte_counter 
eh schon auf der richtigen Fährte. ("endlicher Automat")

Nochmals anders ausgedrückt - statt deinen while Schleifen könntest du 
ja auch gleich delay() verwenden:
if (strom > gewisser_wert) {
   stop_motor();
   delay(2000); /* Falls der Wert in ms angegeben wird... */
   start_motor();
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.