Hallo zusammen,
habe ein Problem mit meinem Arduino. Bin auch ein blutiger Anfänger bei
der Programmierung von Arduinos bzw. Mikrocontrollern!
Ziel ist es 27 LEDs anzusteuern. Ich schicke per Python (mit pyserial
package) eine Hexzahl ans Arduino. Das Programm auf dem Arduino hört auf
diese Hexzahl und schaltet demnach LEDs ein.
Bin soweit schon fertig (ja ich habe gesündigt -> delay Funktion - aber
für meine Anwendung ist das ok).
Das einzige Problem was ich habe ist, dass wenn keine Hexzahl am Arduino
ankommt, ich LEDs nacheinander blinken lassen will und sobald eine
Hexzahl kommt diese aber wieder ausgehen sollen und nur die LEDs noch
blinken, denen die Zahl zugewiesen ist.
Hier der Arduino IDE Code:
Danke dir! Ok das funktioniert schonmal, habe es gerade auch mit einer
while do Schleife probiert.
Nur das Ergebnis ist leider noch nicht ganz das was ich haben möchte..
Ursprünglich hatte ich das so:
1
voidloop(){
2
3
4
if(Serial.available()>0)
5
{
6
7
switch(Serial.read()){
8
9
case0x00:
10
{while(1){
11
onof(3);
12
onof(12,13);
13
onof(4);//7
14
onof(24,26);
15
onof(9,11);
16
onof(29);
17
onof(21);
18
onof(15,17);
19
onof(18,19,20);
20
}
21
}
22
break;
23
case0x01:
24
{
25
onof(3);
26
}
27
break;
28
case0x02:
29
{
30
onof(4);
31
}
32
break;
33
case0x03:
34
{
35
onof(5);
36
}
37
break;
Wie schaff ich es, dass ich diese Dauerschleife beende?
Quasi:
Mit Hexzahl 0x00 wird sie angemacht, aber wenn ich eine andere Hexzahl
schicke dann wird sie automatisch beendet.
Ich dachte eigentlich, dasss ich das mit der switch case anweisung schon
erledigt hätte..
Danke!
Kevin B. schrieb:> Das einzige Problem was ich habe ist, dass wenn keine Hexzahl am Arduino> ankommt, ich LEDs nacheinander blinken lassen will und sobald eine> Hexzahl kommt diese aber wieder ausgehen sollen und nur die LEDs noch> blinken, denen die Zahl zugewiesen ist.
Du solltest darüber nachdenken, in Automaten zu programmieren. Hört sich
kompliziert an, ist aber völlig simpel:
- die Hauptschleife wird dauernd schnellstmöglich durchlaufen
- nur wenn es etwas zu tun gibt, wird dorthin kurz verzweigt
- ein delay() ist ein Programmierfehler
Dann sieht das etwa so aus:
1
intcommand,serial,idlecnt;
2
longlastmillis,aktmillis;
3
4
voidloop(){
5
6
aktmillis=millis();// aktuelle Zeit gilt für den gesamten Durchlauf!
7
8
if(Serial.available()){// Kommando gekommen?
9
comand=Serial.read();// Kommando einlesen
10
lastmillis=aktmillis;// Zeit starten
11
serial=1;// serielles Kommando wird ausgeführt
12
}
13
14
if(aktmillis-lastmillis>1000){// Zeit abgelaufen?
15
ledoff();
16
serial=0;// serielles Kommando erledigt
17
if(idlecnt==8)idlecnt=0;
18
elseidlecnt++;
19
lastmillis=aktmillis;// Zeit wieder starten
20
}
21
22
if(serial){// serielles Kommando? --> LED einschalten
23
switch(command){
24
case0x01:ledon(3);break;
25
case0x02:ledon(4);break;
26
case0x03:ledon(5);break;
27
:
28
case0x23:ledon(18,19);break;
29
case0x24:ledon(18,19,20);break;
30
}
31
command=0;// Kommando ausgeführt
32
idlecnt=0;// Leerlaufmuster von vorn anfangen
33
}else// kein serielles Kommando --> Leerlauf
34
switch(idlecnt){
35
case0:ledon(3);break;
36
case1:ledon(12,13);break;
37
case2:ledon(4);break;
38
:
39
case8:ledon(18,19,20);break;
40
}
41
}
42
:
43
:
44
// hier kann jetzt noch beliebiger weiterer Code kommen,
45
// der aber abenfalls nicht blockieren darf!
46
// Also: nur abfragen und abarbeiten und sofort weiter, niemals delay()
47
:
48
:
49
}
50
51
52
voidledon(intledPin)
53
{
54
digitalWrite(ledPin,HIGH);
55
}
56
57
voidledon(intledPin1,intledPin2)
58
{
59
digitalWrite(ledPin1,HIGH);
60
digitalWrite(ledPin2,HIGH);
61
}
62
63
voidledon(intledPin1,intledPin2,intledPin3)
64
{
65
digitalWrite(ledPin1,HIGH);
66
digitalWrite(ledPin2,HIGH);
67
digitalWrite(ledPin3,HIGH);
68
}
69
70
voidledoff(void)
71
{
72
for(int=3;i<=29;i++)
73
digitalWrite(i,LOW);
74
}
BTW: das mit den c-Tags um den Code herum solltest du nochmal üben!
Unknown schrieb:> 3x die gleiche Bezeichnung für ein Unterprogramm ???Kevin B. schrieb:> oder war das C++?^^
Jawoll!
Die Arduino Welt ist in erster Linie eine C++ Wert.
// ---------
Kevin B. schrieb:> Wie schaff ich es, dass ich diese Dauerschleife beende?
Am besten, du kümmerst dich um die wichtigen Dinge.
Denn die Schleife brauchst du da nicht.
Loop() wird ja selber schon in einer Endlosschleife aufgerufen.
Da ist deine innere Endlosschleife nur im Wege.
Und, dass sie dir mehr Probleme macht, als sie dir nutzt, merkst du ja
gerade selber.
Also: Das Denken ändern und weg mit der Schleife.
Viel lieben Dank Lothar genau mit dieser Methode wollte ich das gestern
auch lösen, nur kam nach 8 Stds auf keinen grünen Zweig und hab mir
somit gedacht: "Ach dann mach es einfach mit Delay -.-"
Ich werde deinen Code jetz mal genau durchstudieren und danach werd ich
mich bestimmt nochmal fragend melden.
Danke, hast mir wirklich weitergeholfen!
@ Arduino Fanboy:
Ja das hab ich bereits auch probiert nur damit bleibt er dauerhaft in
der Schleife und blinkt vor sich hin, wobei ich wenn ich beispielsweise
Befehl 0x04 sende nur die zugewiesene LED aufleuchten lassen möchte. Das
fröhliche Herumgeblinke von der Dauerschleife soll nur sein wenn kein
Befehl mehr kommt und sollte an und ausschaltbar sein per Befehl.
Hab's jetz hinbekommen, leider keine schöne Variante:
1
unsignedlongstartMillis1=0;
2
unsignedlongstartMillis2=800;
3
unsignedlongstartMillis3=300;
4
unsignedlongstartMillis4=600;
5
unsignedlongstartMillis5=1400;
6
unsignedlongcurrentMillis1=0;
7
unsignedlongcurrentMillis2=0;
8
unsignedlongcurrentMillis3=0;
9
unsignedlongcurrentMillis4=0;
10
unsignedinterval=2000;
11
12
voidsetup(){
13
14
Serial.begin(9600);
15
// pins 3 - 29 set as output, default will be low
16
pinMode(3,OUTPUT);//Fach1 - rot
17
pinMode(4,OUTPUT);//Fach1 - blau
18
pinMode(5,OUTPUT);//Fach1 - grün
19
20
pinMode(6,OUTPUT);//Fach2 - rot
21
pinMode(7,OUTPUT);//Fach2 - blau
22
pinMode(8,OUTPUT);//Fach2 - grün
23
24
pinMode(9,OUTPUT);//Fach3 - rot
25
pinMode(10,OUTPUT);//Fach3 - blau
26
pinMode(11,OUTPUT);//Fach3 - grün
27
28
pinMode(12,OUTPUT);//Fach4 - rot
29
pinMode(13,OUTPUT);//Fach4 - blau
30
pinMode(14,OUTPUT);//Fach4 - grün
31
32
pinMode(15,OUTPUT);//Fach5 - rot
33
pinMode(16,OUTPUT);//Fach5 - blau
34
pinMode(17,OUTPUT);//Fach5 - grün
35
36
pinMode(18,OUTPUT);//Fach6 - rot
37
pinMode(19,OUTPUT);//Fach6 - blau
38
pinMode(20,OUTPUT);//Fach6 - grün
39
40
pinMode(21,OUTPUT);//Fach7 - rot
41
pinMode(22,OUTPUT);//Fach7 - blau
42
pinMode(23,OUTPUT);//Fach7 - grün
43
44
pinMode(24,OUTPUT);//Fach8 - rot
45
pinMode(25,OUTPUT);//Fach8 - blau
46
pinMode(26,OUTPUT);//Fach8 - grün
47
48
pinMode(27,OUTPUT);//Fach9 - rot
49
pinMode(28,OUTPUT);//Fach9 - blau
50
pinMode(29,OUTPUT);//Fach9 - grün
51
52
}
53
54
voidloop(){
55
56
if(Serial.available()>0)
57
{
58
59
switch(Serial.read()){
60
61
case0x01:
62
{
63
onof(3);
64
}
65
break;
66
case0x02:
67
{
68
onof(4);
69
}
70
break;
71
case0x03:
72
{
73
onof(5);
74
}
75
break;
76
case0x04:
77
{
78
onof2(3,5);
79
}
80
break;
81
case0x05:
82
{
83
onof2(3,4);
84
}
85
break;
86
case0x06:
87
{
88
onof3(3,4,5);
89
}
90
break;
91
case0x07:
92
{
93
onof(6);
94
}
95
break;
96
case0x08:
97
{
98
onof(7);
99
}
100
break;
101
case0x09:
102
{
103
onof(8);
104
}
105
break;
106
case0x0A:
107
{
108
onof2(6,8);
109
}
110
break;
111
case0x0B:
112
{
113
onof2(6,7);
114
}
115
break;
116
case0x0C:
117
{
118
onof3(6,7,8);
119
}
120
break;
121
case0x0D:
122
{
123
onof(9);
124
}
125
break;
126
case0x0E:
127
{
128
onof(10);
129
}
130
break;
131
case0x0F:
132
{
133
onof(11);
134
}
135
break;
136
case0x10:
137
{
138
onof2(9,11);
139
}
140
break;
141
case0x11:
142
{
143
onof2(9,10);
144
}
145
break;
146
case0x12:
147
{
148
onof3(9,10,11);
149
}
150
break;
151
case0x13:
152
{
153
onof(12);
154
}
155
break;
156
case0x14:
157
{
158
onof(13);
159
}
160
break;
161
case0x15:
162
{
163
onof(14);
164
}
165
break;
166
case0x16:
167
{
168
onof2(12,14);
169
}
170
break;
171
case0x17:
172
{
173
onof2(12,13);
174
}
175
break;
176
case0x18:
177
{
178
onof3(12,13,14);
179
}
180
break;
181
case0x19:
182
{
183
onof(15);
184
}
185
break;
186
case0x1A:
187
{
188
onof(16);
189
}
190
break;
191
case0x1B:
192
{
193
onof(17);
194
}
195
break;
196
case0x1C:
197
{
198
onof2(15,17);
199
}
200
break;
201
case0x1D:
202
{
203
onof2(15,16);
204
}
205
break;
206
case0x1E:
207
{
208
onof3(4,5,6);// 15,16,17
209
}
210
break;
211
case0x1F:
212
{
213
onof(3);//18
214
}
215
break;
216
case0x20:
217
{
218
onof(19);
219
}
220
break;
221
case0x21:
222
{
223
onof(20);
224
}
225
break;
226
case0x22:
227
{
228
onof2(18,20);
229
}
230
break;
231
case0x23:
232
{
233
onof2(18,19);
234
}
235
break;
236
case0x24:
237
{
238
onof3(18,19,20);
239
}
240
break;
241
case0x25:
242
{while(1)
243
{
244
/*onof(3);
245
onof2(12,13);
246
onof(7);
247
onof2(24,26);
248
onof2(9,11);
249
onof(29);
250
onof(21);
251
onof2(15,17);
252
onof3(18,19,20);*/
253
254
currentMillis1=millis();
255
currentMillis2=millis();
256
currentMillis3=millis();
257
currentMillis4=millis();
258
259
if(currentMillis1-startMillis1>=interval)
260
{
261
startMillis1=currentMillis1;
262
digitalWrite(3,!digitalRead(3));
263
}
264
if(currentMillis2-startMillis2>=interval){
265
startMillis2=currentMillis2;
266
digitalWrite(4,!digitalRead(4));//11
267
}
268
if(currentMillis3-startMillis3>=interval){
269
startMillis3=currentMillis3;
270
digitalWrite(5,!digitalRead(5));//21
271
//digitalWrite(22, !digitalRead(22));
272
//digitalWrite(23, !digitalRead(23));
273
}
274
275
if(currentMillis4-startMillis4>=interval){
276
startMillis4=currentMillis4;
277
digitalWrite(6,!digitalRead(6));//28
278
}
279
280
if(Serial.read()==0x26)
281
break;
282
}
283
}
284
break;
285
286
}
287
}
288
}
289
voidonof(intledPin)
290
{
291
digitalWrite(ledPin,HIGH);
292
delay(1000);
293
digitalWrite(ledPin,LOW);
294
}
295
296
voidonof2(intledPin1,intledPin2)
297
{
298
digitalWrite(ledPin1,HIGH);
299
digitalWrite(ledPin2,HIGH);
300
delay(1000);
301
digitalWrite(ledPin1,LOW);
302
digitalWrite(ledPin2,LOW);
303
}
304
305
voidonof3(intledPin1,intledPin2,intledPin3)
306
{
307
digitalWrite(ledPin1,HIGH);
308
digitalWrite(ledPin2,HIGH);
309
digitalWrite(ledPin3,HIGH);
310
delay(1000);
311
digitalWrite(ledPin1,LOW);
312
digitalWrite(ledPin2,LOW);
313
digitalWrite(ledPin3,LOW);
314
}
Werd jetz mal die Lösung von Lothar mir aneignen =)
Dennoch Danke!
Kevin B. schrieb:> Hab's jetz hinbekommen, leider keine schöne Variante:> ...
gelesen (und verstanden)?
Lothar M. schrieb:> Bitte beachten, was über jeder Eingabebox steht:Antwort schreiben> Wichtige Regeln - erst lesen, dann posten!>> Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang> ...
Kevin B. schrieb:> mit diesen 2 Zeilen bewirkst du die Dauerschleife zum Blinken, darf ich> fragen für was idlecnt steht?
Auf lang heißt das "LeerlaufZähler". Und der speichert einfach den Index
auf das im Leerlauf darzustellende Bitmuster.
Denn durch das "nicht anhalten! immer weitermachen!" muss ja jeweils der
aktuelle Zustand gespeichert werden.
Und genau dieses "Zustandsspeichern" ist der Automat. Sich was merken
und abhängig davon (und evtl. von weiteren äusseren Einflüssen z.B. eine
abgelaufene Zeit) etwas Anderes tun, das ist ein Zustandsautomat.
@ Kevin B. (nachteule)
>Danke, hast mir wirklich weitergeholfen!
Siehe auch Multitasking.
>Befehl 0x04 sende nur die zugewiesene LED aufleuchten lassen möchte. Das>fröhliche Herumgeblinke von der Dauerschleife soll nur sein wenn kein>Befehl mehr kommt und sollte an und ausschaltbar sein per Befehl.>Hab's jetz hinbekommen, leider keine schöne Variante:
In der Tat. Schon mal über das Thema Quelltextformatierung nachgedacht?
Und die Funktion von Array/Tabellen?
Siehe Strukturierte Programmierung auf Mikrocontrollern
Eher so, siehe Anhang.
Falk B. schrieb:> Eher so, siehe Anhang.
Wird ja langsam... ;-)
Allerdings gefällt mir der mehrmalige Aufruf von millis() nicht, weil
dann im Automaten keine konstante Zeit gewährleistet ist und sich
während der Zustandsauswertung das Prozessabbild ändert. Das kann urige
Auswirkungen haben. Ich würde hier nur einmal am Anfang die aktuelle
Zeit holen und dann mit dieser Zeit weiterarbeiten. Aber das kann jeder
machen, wie er lustig ist...