Abfrage in einer FOR Schleife

OP #4498261
Lesenswert?

Hallo,

Meine Frage:

wie kann ich in einer for Schleife (mache 10 mal das)den code einer 
IRemote
abfragen das bei Änderung die Schleife verlassen wird??
danke für eure Hilfe ein paar Zeilen code würden mir sehr weiterhelfen
habe schon alles mögliche gelesen und probiert aber ich schnall das 
nicht:(


anbei Code

#include <IRremote.h>
int a;
int geschw = 0 ;
int RECV_PIN = 3;
IRrecv irrecv(RECV_PIN);
decode_results results;
long current=millis();
void Fadeslow();
void sto();
int zeit = 2700 ;

void setup(){
irrecv.enableIRIn(); // Start the receiver
  pinMode( 9 , OUTPUT);
  pinMode( 2 , OUTPUT);
  Serial.begin(9600);
 }

void loop()
  {
   if (irrecv.decode(&results))
     {
      if(results.value==0xff629d)
        {
         digitalWrite( 2 , HIGH );
         Fadeslow();
        }
    if(results.value==0xffa857)
        {
        digitalWrite( 2 , LOW );
        }
        irrecv.resume();
     }
  }

void Fadeslow()

 {
     for (a=1; a<= ( 25 ); ++a )
      {
        long current=millis();
        while(current+zeit>millis())
        analogWrite(9 , geschw);
           geschw = ( geschw + 1 ) ;
      }
 }

 void sto()
    {
      geschw = 0 ;

    }
OP #4498286
Lesenswert?

danke für die schnelle Antwort
habe ich auch schon probiert ;(
lauft einmal durch und fertig

das bekomme ich bei break

error: break statement not within loop or switch
break statement not within loop or switch

{
     for (a=1; a<= ( 25 ); ++a )
      {
        Serial.print(results.value);
        Serial.println();
        long current=millis();
        while(current+zeit>millis())
        analogWrite(9 , geschw);
        Serial.print("geschw");
        Serial.print(geschw);
        Serial.println();
        geschw = ( geschw + 1 ) ;
        break;
      }

 }
#4498299
Lesenswert?

Kurt B. schrieb:
> ??
>
> mit return das gleiche
> drücke den IR
>
> lauft einmal durch fertig??
>
> bin am verzweifen versuche es schon seit Stunden hinzubekommen

Dann benutze doch mal Klammern oder Einrückungen um dir selber 
klarzumachen was du da machst! Oben ist falsch eingerückt, und unten 
fehlen Klammern oder zumindest eine Einrückung damit du siehst was 
passiert.
Gast #4498303
Lesenswert?

Ja ist ja richtig... so wie du das da programmiert hast. Der fängt oben 
die Schleife an und geht dann unten (Ja: beim ersten Durchgang!) wieder 
aus der schleife raus. Genau da wo dein Break bzw. Return steht.

Auf die Frage von Sören wegen der While Schleife magst du auch nicht 
eingehen wollen.
#4498314
Lesenswert?

Kurt B. schrieb:
> {
>      for (a=1; a<= ( 25 ); ++a )
>       {
>         Serial.print(results.value);
>         Serial.println();
>         long current=millis();
>         while(current+zeit>millis())
>         analogWrite(9 , geschw);
>         Serial.print("geschw");
>         Serial.print(geschw);
>         Serial.println();
>         geschw = ( geschw + 1 ) ;
>         break;
>       }
>
>  }

> lauft einmal durch und fertig

Wo ist das if von dem in Post 1 noch die Rede war? Logisch daß er nach 
einmal abbricht wenn er sofort auf das break kommt.

Und bitte verwende hier im Forum die c und /c tags um code zu posten 
(siehe die Hinweise zur Formatierung in der grauen Box "Antwort 
Schreiben, wichtige Regeln", der blaue Link)


Also:

Erstens Dein Code ist formatiert wie Kraut und Rüben, besorg Dir 
notfalls ein Tool das C++ Code automatisch formatieren kann, dann fallen 
auch fehlende Klammern auf.

Zweitens verwende immer geschweifte Klammern (zum Beispiel bei obigem 
while), auch wenn diese optional sind, gerade bei Deiner chaotischen 
Formatierung schießt Du Dir selbst und auch anderen in den Fuß beim 
Lesen des Codes. Code wird tausend mal öfter gelesen als er 
geschrieben wird, also optimiere ihn stets und mit äußerster Sorgfalt 
fürs angenehme Lesen, auch wenn das mehr Zeit beim Schreiben benötigt.
Gast #4498316
Lesenswert?

1
void loop()
2
  {
3
   if (irrecv.decode(&results))
4
     {
5
      if(results.value==0xff629d)
6
        {
7
         digitalWrite( 2 , HIGH );
8
         Fadeslow();
9
        }
10
    if(results.value==0xffa857)
11
        {
12
        digitalWrite( 2 , LOW );
13
        }
14
        irrecv.resume();
15
     }
16
  }

Wenn eine bestimmte Taste gedrückt wird (0xff629d), läuft Fadeslow 
einmal durch. Dann wird der IR-Decoder wieder abgefragt. Dieses Mal ist 
results.value aber nicht mehr 0xff629d sondern vielleicht 0x00 weil 
keine Taste mehr gedrück ist.
Also wird Fadeslow nicht mehr aufgerufen.
Gast #4498343
Lesenswert?

>geanu da stecke ich fest wie frage ich oder speichere ich den code bis
>ein neuer kommt??

Kannst in Worten beschreiben was passieren soll ?
Soll der IR in Fadeslow abgefragt werden oder reicht es außerhalb ?

Wenn außerhalb dann vielleicht so:
[c]
int temp=0;

void loop()
{
   if (irrecv.decode(&results))
   {
        if(results.value==0xff629d)
        {
          digitalWrite( 2 , HIGH );
          temp = 1;
        }
        if(results.value==0xffa857)
        {
          digitalWrite( 2 , LOW );
          temp = 0;
        }
        irrecv.resume();

        if(temp == 1)
        {
          Fadeslow();
        }
   }
}
Gast #4498364
Lesenswert?

So, nächster Versuch:
@Mods: Wer ist so gnädig und löscht den missglückten ersten Versuch und 
den Kommentar dazu?
1
#include <IRremote.h>
2
int a;
3
int geschw = 0;
4
int RECV_PIN = 3;
5
IRrecv irrecv(RECV_PIN);
6
decode_results results;
7
long current = millis();
8
void Fadeslow();
9
void sto();
10
int zeit = 2700;
11

12
void setup()
13
{
14
    irrecv.enableIRIn();        // Start the receiver
15
    pinMode(9, OUTPUT);
16
    pinMode(2, OUTPUT);
17
    Serial.begin(9600);
18
}
19

20
void loop()
21
{
22
    if (irrecv.decode(&results))
23
    {
24
        if (results.value == 0xff629d)
25
        {
26
            digitalWrite(2, HIGH);
27
            Fadeslow();
28
        }
29
        if (results.value == 0xffa857)
30
        {
31
            digitalWrite(2, LOW);
32
        }
33
        irrecv.resume();
34
    }
35
}
36

37
void Fadeslow()
38
{
39
    for (a = 1; a <= (25); ++a)
40
    {
41
        long current = millis();
42
        while (current + zeit > millis())
43
            analogWrite(9, geschw);
44
        geschw = (geschw + 1);
45
    }
46
}
47

48
void sto()
49
{
50
    geschw = 0;
51

52
}
#4498407
Lesenswert?

Kurt B. schrieb im Beitrag #4498379:
> ?? was ist da anderst??

An der (richtigen) Version erkennst du anhand der Einrückeungen welche 
"Befehle" zu welchem Block gehören. Nimm mal FadeSlow():
1
void Fadeslow()
2
{
3
    for (a = 1; a <= (25); ++a)
4
    {
5
        long current = millis();
6
        while (current + zeit > millis())
7
            analogWrite(9, geschw);
8
        geschw = (geschw + 1);
9
    }
10
}

Der äußere Block wird 25-mal durchlaufen. Der innere Block
1
        while (current + zeit > millis())
2
            analogWrite(9, geschw);

bedeutet, dass "analogWrite(9,geschw)" ausgeführt wird, so lange
"current + zeit" größer ist als der Rückgabewert von "millis()".
Jetzt nehme ich mal an, dass "millis()" die aktuelle Zeit in 
Millisekunden liefert (bin kein Arduino Programmierer).
Da "zeit" gleich 2700 ist, wird die Schleife wohl 2,7 Sekunden 
aufgerufen,
aber immer mit dem gleichen Parameterwert von "geschw". ERST NACH der 
while()-Schleife wird geschw um eins erhöht!
OP #4498442
Lesenswert?

Klaus R. schrieb:
> aber immer mit dem gleichen Parameterwert von "geschw". ERST NACH der
> while()-Schleife wird geschw um eins erhöht!

ja die 2700 sind nur zum testen nacher noch ca. 50
um den Motor langsam zu faden
aber WIE mache ich das, das die schleife solange läuft bis ein anderer 
code
eingegeben wird?

mit
 if(results.value!=0xff629d) geht nicht??

oder
  if(results.value!=result.value) geht nicht??
OP #4498462
Lesenswert?

Klaus R. schrieb:
> Sorry, ich verstehe nicht, was du möchtest. Versuche mal, klar und
> strukturiert darzulegen, was du erreichen möchtest!

also ich möchte einen Motor mit IRemote Fernbedienung steuern
faden, vor , zurück  usw.....

was mir probleme macht das der IRCode beim nächsten durchgang sich 
selbst ändert ohne das ich eine Taste drücke und so die FOR Schleife 
verlassen wird und nur einmal durchläuft

wie kann ich den code speichern oder wie mache ich das die Schleife so 
lange läuft bis eine Taste gedrückt wird?
Gast #4504020
Lesenswert?

Crazy H. schrieb:
> Gibts in C kein Repeat .... Until ?

Nö - das gibt es es nur bei Pascal. Aber es sollte auch mit einer 
while-Schleife funktionieren. Unterschied zwischen beiden:
  while : Wird nur durchlaufen, wenn die Bedingung im Statement erfüllt
          ist

  repeat : Wird mindestens 1x durchlaufen, da die Bedingung erst am
           Schleifenende geprüft wird.

Wenn man möchte, das die while-Schleife mindestens einmal durchlaufen 
wird, so muß man dafür sorgen, das die Bedingung vor Eintritt in die 
Schleife erfüllt ist.
Dies kann man z.B. mit
1
while (true) {
2
..code.....
3
}
 erreichen.
Da dies eine Endlosschleife ist, kann selbige nur mit break verlassen 
werden. Man muß also selbst dafür Sorge tragen durch geeignete Abfragen 
innerhalb der Schleife (z.B. Portabfrage, Interrupt etc.) ein break zu 
generieren.

Zeno
#4504032
Lesenswert?

Speicher das doch in nem Flag und überprüfe dann ob das Flag noch 
gesetzt ist. Das Flag löscht du wenn du die Endgeschwindigkeit erreicht 
hast oder ein anderes Kommando kommt das Fade unterbricht. Wenn du dir 
ein delay über die millis() baust. Dann Blockierst du dir nicht alles 
für die Durchläufe der Schleife. Damit sollte es Durchlaufen bis die 
Endgeschwindigkeit erreicht ist oder ein Kommando gegeben wird das Fade 
stoppen soll. Das Delay kannst du dann mit dem Aufruf einstellen. Wenn 
dir ein Delay <= 255 reicht geht da auch ein uint8_t

Bsp. aus dem Bauch raus, ist nicht getestet
1
long last ;
2

3
void loop()
4
{
5

6

7
    if (irrecv.decode(&results))
8
    {
9
        if (results.value == 0xff629d)
10
        {
11
            Enable_fade = true;
12
            digitalWrite(2, HIGH);
13
        }
14
        
15
        if (results.value == 0xffffff) //anderes Kommando zum stoppen des fadens
16
        {
17
            Enable_fade = false;
18
            
19
        }
20
        
21
        irrecv.resume();
22
      
23
    }
24
  
25
    if(Soll <= geschw)
26
       Enable_fade = false;
27

28
    if(Enable_fade)
29
        Fadeslow(500);
30
}
31

32
void Fadeslow(uint16_t delay)
33
{
34
    
35
    if (last + delay <= millis())
36
    {
37
        geschw++;
38
        analogWrite(9, geschw);
39
        last = millis();
40
    }
41
    
42
}

Gruß JackFrost
Gast #4504036
Lesenswert?

Zeno schrieb:
> Nö - das gibt es es nur bei Pascal. Aber es sollte auch mit einer
> while-Schleife funktionieren. Unterschied zwischen beiden:
>   while : Wird nur durchlaufen, wenn die Bedingung im Statement erfüllt
>           ist

und dann gibt es noch die do-while-Schleife.
Die prinzipiell das gleiche wie die repeat-until-Schleife macht, nur die 
Auswertung invertiert hat.
Gast #4504037
Lesenswert?

>Draco
>Jo Break geht nur bei IF oder SWITCH... bei FOR nimmt man Return. Sauber
isses aber nicht.

Also bei mir gehts:
1
#include <stdio.h>
2

3
int main()
4
{
5
    int a;
6
    printf("Hello, World!\n");
7
         for (a=1; a<= ( 25 ); ++a )
8
      {
9
        printf("Loop-Nr.: %d\n",a);
10
        if(a==3)break;
11
      }
12
      printf("Bin durch, Alter!\n");
13
    return 0;
14
}


Hello, World!
Loop-Nr.: 1
Loop-Nr.: 2
Loop-Nr.: 3
Bin durch, Alter!


Kannste selbst laufen lassen mit:
http://www.tutorialspoint.com/compile_c_online.php
Gast #4504041
Lesenswert?

Mach dir doch einen Ablaufplan..


Z.b.:

- Prüfen welcher IR Code empfangen wurde
-> ist Code unterschiedlich als der vorige -> Variable auf anderen Wert 
setzen
-> Code ausführen solange Variable diesen Wert hat.

- Prüfen welcher IR Code empfangen wurde
-> ist Code unterschiedlich als der vorige -> Variable auf anderen Wert 
setzen
-> Code ausführen solange Variable diesen Wert hat.


...

So in etwa:
1
uint8_t  varIRpos = 0;
2
uint16_t oldIRcode = 0;
3

4

5
void CheckIR()
6
{
7
  uint16_t newIRcode = result.value;
8
   
9
  if(oldIRcode != newIRcode)
10
  {
11
    switch (result.value)
12
    {
13
      case 0xff629d:
14
        varIRpos = 1;
15
        break;
16
      case 0xffa857:
17
        varIRpos = 2;
18
        break;
19
      default:
20
        varIRpos = 0;
21
   }
22
   oldIRcode = newIRcode;
23
  }
24
}  
25

26

27
void main()
28
 
29

30
//...
31

32
while(1)
33
{
34
    checkIR();
35
    
36
    switch(varIRpos)
37
    {
38
       case 0:
39
         break;
40
       case 1:
41
          MoveForward();
42
          break;
43
       case 2:
44
          MoveBackward();
45
          break;
46
    }
47
}


So ganz grob mal hingekritzelt, aber so in die Richtung musst du denken. 
Kann mal natürlich alles noch kürzen, noch in eine Abfrage packen, 
andere Variablen Werte... etc... soll nur ein Denkanstoß sein.
Gast #4504042
Lesenswert?

Crazy H. schrieb:
> Gibts in C kein Repeat .... Until ?
Nö, für was?
Es gibt while(), for(), und do-while(). Und jede Schleife lässt sich 
durch die anderen beiden ersetzen.
Do-while wird mind. 1x durchlaufen, und am ende muss ein ; nach dem 
while stehn.
1
while( Bedingung )
2
{
3
    // Code
4
}
5

6
for(Bedingung)
7
{
8
    // Code
9
}
10

11
do
12
{
13
    // Code
14
}while(Bedingung); // <- Semikolon! Wichtig!
Im gegensatz zu anderen Sprachen gibt es in C keine Abbruch -Bedingung 
sondern eine Lauf -Bedinung bei Schleifen.
Es heißt immer: Laufe so lange wie Bedinung xy erfüllt ist.

Dem TO ist sehr viel mehr geholfen, wenn er sich mal ein C-Buch besorgt 
und das auch liest, anstatt hier wild im nebel zu stochern. Hilfe zur 
Selbsthilfe.

Nehmen wir mal den Code aus dem Anfangsposting:
1
#include <IRremote.h>
2
int a;
3
int geschw = 0 ;
4
int RECV_PIN = 3;
5
IRrecv irrecv(RECV_PIN);
6
decode_results results;
7
long current=millis();
8
void Fadeslow();
9
void sto();
10
int zeit = 2700 ;
11

12
void setup()
13
{
14
    irrecv.enableIRIn(); // Start the receiver
15
    pinMode( 9 , OUTPUT);
16
    pinMode( 2 , OUTPUT);
17
    Serial.begin(9600);
18
}
19

20
void loop()
21
{
22
    if (irrecv.decode(&results))
23
    {
24
        if(results.value==0xff629d)
25
        {
26
            digitalWrite( 2 , HIGH );
27
            Fadeslow();
28
        }
29

30
        if(results.value==0xffa857)
31
        {
32
            digitalWrite( 2 , LOW );
33
        }
34

35
        irrecv.resume();
36
    }
37
}
38

39
void Fadeslow()
40
{
41
    for (a=1; a<= ( 25 ); ++a )
42
    {
43
        long current=millis();
44
        while(current+zeit>millis())
45
            analogWrite(9 , geschw);
46

47
        geschw = ( geschw + 1 ) ;
48
    }
49
}
50

51
void sto()
52
{
53
    geschw = 0 ;
54
}

So, und jetzt nehmen wir nochmal die Funktion Fadeslow:
1
void Fadeslow()
2
{
3
    for (a=1; a<= ( 25 ); ++a )
4
    {
5
        long current=millis();
6
        while(current+zeit>millis())
7
            analogWrite(9 , geschw);
8

9
        geschw = ( geschw + 1 ) ;
10
    }
11
}

1. Bist du sicher das es a <= 25 heißen muss?
2. Warum ist der Schleifenzähler eine globale Variable?
3. Was genau soll die while-Schleife machen? Verzögern? Oder das 
analogWrite solange ausführen wie die Bedinung erfüllt ist?
Ich nehme an, dass die Schleife verzögern soll, also muss da ein ; 
hinter das while:
1
while(current+zeit>millis());
Da man das ; aber durchaus leicht übersehen kann, kann man es auch so 
klarer schreiben, dann ist es offensichtlicher:
1
while(current+zeit>millis())
2
{
3
}

Die Zeile:
1
long current=millis();
Warum steht die global? Warum nicht im Setup? Kennst du die 
Auswirkungen/den Unterschied?
Und "Magic Numbers" sind auch ganz große Grütze!

Entschuldigung, aber da fehlt es an allen Ecken und Enden. Du musst dich 
schon mal mit der Sprache beschäftigen. Und da hilft ein Buch am besten.

Und nein, es ist nicht schlimm Anfänger zu sein, waren wir alle mal. 
Aber man muss sich schon etwas mühe geben, und nicht immer nur rufen:
"Ich hab hier ein Problem, bitte gebt mir die richtige Lösung."

Kurt B. schrieb:
> Meine Frage:
>
> wie kann ich in einer for Schleife (mache 10 mal das)den code einer
> IRemote
> abfragen das bei Änderung die Schleife verlassen wird??
1
for(uint8_t i = 0; i < 10; i++)
2
{
3
    if( IR Code hat sich geaendert )
4
    {
5
        break;
6
    }
7
    /* do what ever you want */
8
}

Zeno schrieb:
> Nö - das gibt es es nur bei Pascal.
Ich glaube das gibt es auch in VBA :)

Zeno schrieb:
> Wenn man möchte, das die while-Schleife mindestens einmal durchlaufen
> wird, so muß man dafür sorgen, das die Bedingung vor Eintritt in die
> Schleife erfüllt ist.
Oder einfach eine do-while()-Schleife nutzen.

--------
Mist, da waren schon welche schneller :(
OP #4504939
Lesenswert?

Kaj schrieb:
> for(uint8_t i = 0; i < 10; i++)
> {
>     if( IR Code hat sich geaendert )
>     {
>         break;
>     }
>     /* do what ever you want */
> }

keiner will mich verstehen ;((

break geht auch nicht da get der Code immer aus der Schleife und kommt 
nicht mehr zurück da der IRCode ja neu eingelesen wird und nicht mehr 
gleich ist  obwohl ich nicht drücke!
Als wie speicher ich den Wert von IRremote so loange bis er sich 
ändert??
das ist mein Problem ??
Gast #4504957
Lesenswert?

Nun sind hier schon so viele Beispiele... wie man den Code speichert, 
vergleicht ob er der gleiche oder ein anderer von dir gespeicherter Code 
ist.

Der ändert dann wirklich nur die Schleife wenn der Code ein anderer, von 
dir gedrückter, vorher gespeicherter und nicht willkürlicher Infrarot 
Code ist. Da sehe ich da oben mindestens drei Beispiele die das so 
handhaben.

Aber hier gerne nochmal:
1
uint8_t  varIRpos = 0;
2
uint16_t oldIRcode = 0;
3

4

5
void CheckIR()
6
{
7
  uint16_t newIRcode = result.value;
8
   
9
  if(oldIRcode != newIRcode)
10
  {
11
    switch (result.value)
12
    {
13
      case 0xff629d:
14
        varIRpos = 1;
15
        oldIRcode = newIRcode;
16
        break;
17
      case 0xffa857:
18
        varIRpos = 2;
19
        oldIRcode = newIRcode;
20
        break;
21
   }
22
  }
23
}  
24

25

26
void main()
27
 
28

29
//...
30

31
while(1)
32
{
33
    checkIR();
34
    
35
    switch(varIRpos)
36
    {
37
       case 0:
38
         break;
39
       case 1:
40
          MoveForward();
41
          break;
42
       case 2:
43
          MoveBackward();
44
          break;
45
    }
46
}

Zum Ablauf... du drückst eine Taste (Vorwärts)... dann Vergleicht die 
Zeile "OldCodeIR != NewCodeIR" ob der Code sich zum alten geändert hat 
-> JA hat er.

Dann vergleicht er in der Tabelle ob der Code von DIR gespeichert wurde 
um eine Änderung herbeizuführen. (Switch(result.value)) -> JA... er soll 
nun vorwärts fahren da Code 0xff629d eingegeben wurde. Er setzt varIRpos 
auf 1, setzt den IR Code zum nächsten Vergleich in OldIRcode und verläßt 
die Switch Abfrage. Dann verläßt er die IR Abfrage. Dann geht er in die 
Abfrage, welche die Variable varIRpos abfragt -> Die sagt "1" -> Er 
fährt forwärts -> verläßt die Abfrage und fragt den IR Code erneut ab... 
du hast keine andere Taste gedrückt, der IR Code kommt trotzdem 
irgendwie rein, durch Aliens oder so - der Code ist aber nicht 
gespeichert... er verläßt die IRCode Abfrage, die Variable varIRPos 
bleibt gleich und er geht wieder in Case 1: MoveForward() - und das geht 
solange bis du den Code Nr zwei: 0xffa857 gedrückt hast....

Du solltest gaaaanz dringend an deinem logischen Verständnis arbeiten 
und sowas zu überblicken, das ist nicht böse gemeint oder so, aber das 
ist ein extrem leichter Ablaufplan - sowas muss einem eigentlich sofort 
in den Kopf schießen.
#4505329
Lesenswert?

Kurt B. schrieb:
> break geht auch nicht da get der Code immer aus der Schleife und kommt
> nicht mehr zurück da der IRCode ja neu eingelesen wird und nicht mehr
> gleich ist  obwohl ich nicht drücke!

Das liegt daran das wenn einmal über
1
if(irrecv.decode(&results))
2
{
3
    //Dein Code
4
   irrecv.resume();
5
    
6
}

wird nur wahr wenn ein Code empfangen wurde. Durch das
1
irrecv.resume();
 setzt du das Flag zurück das ein Code empfangen wurde und das du wieder 
empfangen kannst. Daher wird das nicht erneut erkannt. So kannst du 
erkennen ob der gleiche Code erneut gesendet wurde oder nicht. Daher 
musst du dir das Speichern. Oben gibt es ja ein paar Beispiele wie du 
das machen könntest.

Gruß JackFrost5

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