while loop Abbruch

Gast #6498108
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?
Gast #6498143
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.
Gast #6498155
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?
#6498179
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.
Gast #6498232
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.
#6498327
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();
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren