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 ;
}
Kurt B. schrieb:> 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??
break;
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;
}
}
Warum auch immer das nicht geht, wenn das eh in einer eigenen Methode
ist tut's auch ein return;
Was tut eigentlich das while darin ohne Klammern? Hätte ich fast
übersehen. Sicher, dass das genau das tut was du dir wünschst?
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.
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.
Soeren K. schrieb:> Was tut eigentlich das while darin ohne Klammern? Hätte ich fast> übersehen. Sicher, dass das genau das tut was du dir wünschst?
hoffe das ersetzt mir delay schein zu funktionieren oder liegt es daran?
Draco schrieb:> 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.
irgendwo muß ich ja raus zum testen ob sich der ircode geändert hat
??!??
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.
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.
Bernd K. schrieb:> 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.
wo frage ich in der while schleife ab ob der IR Code sich geändert hat??
und wie?
C-Coder schrieb:> Also wird Fadeslow nicht mehr aufgerufen.
ja genau aber wo und wie frage ich das in der for Schleife ab???
bite bitte ein paar zeilen code danke
Draco schrieb:> Jo Break geht nur bei IF oder SWITCH... bei FOR nimmt man Return. Sauber> isses aber nicht.
Da schau, haben wir wieder etwas gelernt was wir wirklich nie lernen
wollten!
Nebenbei, schon mal ein C-Buch gelesen?
Norbert schrieb:> Da schau, haben wir wieder etwas gelernt was wir wirklich nie lernen> wollten!>> Nebenbei, schon mal ein C-Buch gelesen?
Da schau an, also bei C klappt des. C# schmeißt mir da aber nen Error um
den Hals...
>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();
}
}
}
danke für die Antwort
möchte mit IR einen Motor steuern
Faden, Vor, Zurück .....
da währe es sicher besser während dem faden auf eine Eingabe zu
reagieren.
habe schon so viel versucht aber da steck ich fest.
Soeren K. schrieb:> Warum auch immer das nicht geht, wenn das eh in einer eigenen Methode> ist tut's auch ein return;
Mir ist jetzt nicht ganz klar was du meinst, aber bei folgendem Code
1
for(i=0;i<25;i++)
2
{
3
do_something_useful();
4
if(breakflag==TRUE)
5
break;
6
}
wird die for-Schleife verlassen, wenn breakflag TRUE ist.
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
voidFadeslow()
2
{
3
for(a=1;a<=(25);++a)
4
{
5
longcurrent=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!
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??
Kurt B. schrieb:> um den Motor langsam zu faden> aber WIE mache ich das, das die schleife solange läuft bis ein anderer> code eingegeben wird?
Sorry, ich verstehe nicht, was du möchtest. Versuche mal, klar und
strukturiert darzulegen, was du erreichen möchtest!
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?
Kurt B. schrieb:>> Sorry, ich verstehe nicht, was du möchtest. Versuche mal, klar und>> strukturiert darzulegen, was du erreichen möchtest!
ist das verständlich?
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
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
longlast;
2
3
voidloop()
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
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.
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_tvarIRpos=0;
2
uint16_toldIRcode=0;
3
4
5
voidCheckIR()
6
{
7
uint16_tnewIRcode=result.value;
8
9
if(oldIRcode!=newIRcode)
10
{
11
switch(result.value)
12
{
13
case0xff629d:
14
varIRpos=1;
15
break;
16
case0xffa857:
17
varIRpos=2;
18
break;
19
default:
20
varIRpos=0;
21
}
22
oldIRcode=newIRcode;
23
}
24
}
25
26
27
voidmain()
28
29
30
//...
31
32
while(1)
33
{
34
checkIR();
35
36
switch(varIRpos)
37
{
38
case0:
39
break;
40
case1:
41
MoveForward();
42
break;
43
case2:
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.
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
inta;
3
intgeschw=0;
4
intRECV_PIN=3;
5
IRrecvirrecv(RECV_PIN);
6
decode_resultsresults;
7
longcurrent=millis();
8
voidFadeslow();
9
voidsto();
10
intzeit=2700;
11
12
voidsetup()
13
{
14
irrecv.enableIRIn();// Start the receiver
15
pinMode(9,OUTPUT);
16
pinMode(2,OUTPUT);
17
Serial.begin(9600);
18
}
19
20
voidloop()
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
voidFadeslow()
40
{
41
for(a=1;a<=(25);++a)
42
{
43
longcurrent=millis();
44
while(current+zeit>millis())
45
analogWrite(9,geschw);
46
47
geschw=(geschw+1);
48
}
49
}
50
51
voidsto()
52
{
53
geschw=0;
54
}
So, und jetzt nehmen wir nochmal die Funktion Fadeslow:
1
voidFadeslow()
2
{
3
for(a=1;a<=(25);++a)
4
{
5
longcurrent=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
longcurrent=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_ti=0;i<10;i++)
2
{
3
if(IRCodehatsichgeaendert)
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 :(
Kaj schrieb:> Oder einfach eine do-while()-Schleife nutzen.
Stimmt bei C geht's ja auch anders herum.
Kaj schrieb:> Ich glaube das gibt es auch in VBA
Das kann schon sein aber mit VBA/Basic kenne ich mich nicht so aus.
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 ??
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_tvarIRpos=0;
2
uint16_toldIRcode=0;
3
4
5
voidCheckIR()
6
{
7
uint16_tnewIRcode=result.value;
8
9
if(oldIRcode!=newIRcode)
10
{
11
switch(result.value)
12
{
13
case0xff629d:
14
varIRpos=1;
15
oldIRcode=newIRcode;
16
break;
17
case0xffa857:
18
varIRpos=2;
19
oldIRcode=newIRcode;
20
break;
21
}
22
}
23
}
24
25
26
voidmain()
27
28
29
//...
30
31
while(1)
32
{
33
checkIR();
34
35
switch(varIRpos)
36
{
37
case0:
38
break;
39
case1:
40
MoveForward();
41
break;
42
case2:
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.
Draco schrieb:> in den Kopf schießen. <- dachte ich auch schon daran :)
danke für deine Hilfe werde es jetzt mal genauer durgehen , stehe
momentan (ca. 3 Tage schon auf dem Schlauch) hoffe ich schnall das
jetzt.
Ü 50 und neu in der Sache da brauchts ein bischen länger ;).
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