Forum: Mikrocontroller und Digitale Elektronik Arduino Fade mit for-schleife dimmt nur runter


von J. T. (chaoskind)


Lesenswert?

MoinMoin,

ich hab mir mal so ein ArduinoMega2560 Board bestellt. Eigentlich hab 
ich mich grad mehr oder weniger mit C angefreundet, wollt nun aber auch 
mal in die ArduinoWelt schauen, muss aber sagen, so richtig zurecht komm 
ich nicht.

Ich wollte eine RGB-LED dimmen. Aber irgendwie dimmt sie nur von hell 
nach dunkel, und nicht von dunkel nach hell. Auf allen 3 Kanälen das 
selbe Trauerspiel. Es sind einfach nur nacheinander weg forschleifen. 
Aber es sieht aus, als würd er jede 2te überspringen. Nämlich die zum 
raufdimmen.

Ich hab auch schon versucht, mich auf eine einzelne for-schleife zu 
beschränken. for(R = 255; R >> 0; R--) klappt. Aber umgedreht halt 
nicht.

Hier mal mein Code. Ich benutze die Arduino-Umgebung und diese komische 
Arduino-C-Gequasselchose.
1
/*
2
 Fade
3
 
4
 This example shows how to fade an LED on pin 9
5
 using the analogWrite() function.
6
 
7
 This example code is in the public domain.
8
 */
9
int ledR = 10;
10
int ledG = 9;           // the pin that the LED is attached to
11
int ledB = 8;
12
int brightnessR = 0;    // how bright the LED is
13
int brightnessG = 0;
14
int brightnessB = 255;
15
int fadeAmountR = 3;    // how many points to fade the LED by
16
int fadeAmountG = 4;
17
int fadeAmountB = 5;
18
19
// the setup routine runs once when you press reset:
20
void setup()  { 
21
  // declare pin 9 to be an output:
22
  pinMode(ledR, OUTPUT);
23
  pinMode(ledG, OUTPUT);
24
  pinMode(ledB, OUTPUT);
25
} 
26
27
// the loop routine runs over and over again forever:
28
void loop()  
29
{ 
30
  analogWrite(ledR, brightnessR);
31
  
32
  for (brightnessR = 0; brightnessR << 255; brightnessR++)
33
  {  
34
    analogWrite(ledR, brightnessR);
35
    delay(10);
36
  }
37
  
38
  for (brightnessB = 255; brightnessB >> 0; brightnessB--)
39
  {  
40
    analogWrite(ledB, brightnessB);
41
    delay(10);
42
  }
43
  
44
  for (brightnessG = 0; brightnessG << 255; brightnessG++)
45
  {  
46
    analogWrite(ledG, brightnessG);
47
    delay(10);
48
  }
49
  
50
  for (brightnessR = 255; brightnessR >> 0; brightnessR--)
51
  {  
52
    analogWrite(ledR, brightnessR);
53
    delay(10);
54
  }
55
  
56
  for (brightnessB = 0; brightnessB << 255; brightnessB++)
57
  {  
58
    analogWrite(ledB, brightnessB);
59
    delay(10);
60
  }
61
  
62
  for (brightnessG = 255; brightnessG >> 0; brightnessG--)
63
  {  
64
    analogWrite(ledG, brightnessG);
65
    delay(10);
66
  }
67
  
68
  
69
  
70
71
72
}

Für hilfreiche Antworten wär ich sehr dankbar.

MfG Chaos =)

: Verschoben durch User
von Chris (Gast)


Lesenswert?

Statt der Bitshifts solltest du Vergleiche machen dann könnte es 
eventuell gehen...

von J. T. (chaoskind)


Lesenswert?

Jo läuft. Hatte es auch grad rausgefunden...

Ich hatte es ursprünglich mit while versucht, das klappte aber aus dem 
selben Grund auch nicht.

Ich versteh nur nicht ganz, wieso er denn so sauber ausgedimmt hat, 
wenns geshiftet war. Dann sollte er doch eigentlich nur in 8Stufen 
runterdimmen? 8bits sind numal spätestens nach 8 shifts leer.

So sieht der dimmende Code nun aus, falls es jdm intressiert:
1
/*
2
 Fade
3
 
4
 This example shows how to fade an LED on pin 9
5
 using the analogWrite() function.
6
 
7
 This example code is in the public domain.
8
 */
9
int ledR = 10;
10
int ledG = 9;           // the pin that the LED is attached to
11
int ledB = 8;
12
int brightnessR = 0;    // how bright the LED is
13
int brightnessG = 0;
14
int brightnessB = 255;
15
int dimmSpeed = 30;
16
17
// the setup routine runs once when you press reset:
18
void setup()  { 
19
  // declare pin 9 to be an output:
20
  pinMode(ledR, OUTPUT);
21
  pinMode(ledG, OUTPUT);
22
  pinMode(ledB, OUTPUT);
23
} 
24
25
// the loop routine runs over and over again forever:
26
void loop()  
27
{ 
28
  
29
  while (brightnessR < 255)
30
  {
31
    analogWrite(ledR, brightnessR);
32
    delay(dimmSpeed);
33
    brightnessR++;
34
  }
35
  
36
  
37
  
38
  while (brightnessB > 0)
39
  {
40
    analogWrite(ledB, brightnessB);
41
    delay(dimmSpeed);
42
    brightnessB--;
43
  }  
44
  
45
  
46
  while (brightnessG < 255)
47
  {
48
    analogWrite(ledG, brightnessG);
49
    delay(dimmSpeed);
50
    brightnessG++;
51
  }
52
  
53
  
54
  
55
  while (brightnessR > 0)
56
  {
57
    analogWrite(ledR, brightnessR);
58
    delay(dimmSpeed);
59
    brightnessR--;
60
  }  
61
  
62
  
63
  
64
  
65
    while (brightnessB < 255)
66
  {
67
    analogWrite(ledB, brightnessB);
68
    delay(dimmSpeed);
69
    brightnessB++;
70
  }
71
  
72
  
73
  
74
  while (brightnessG > 0)
75
  {
76
    analogWrite(ledG, brightnessG);
77
    delay(dimmSpeed);
78
    brightnessG--;
79
  }  
80
81
82
}

von g457 (Gast)


Lesenswert?

..eigentlich sollte Dir der Compiler bei dieser..

> for (brightnessR = 0; brightnessR << 255; brightnessR++)

..und allen analogen Zeilen eine Warnung zeigen, in der auch schon des 
Problems Lösung steht.

von g457 (Gast)


Lesenswert?

> Ich versteh nur nicht ganz, wieso er denn so sauber ausgedimmt hat,
> wenns geshiftet war. Dann sollte er doch eigentlich nur in 8Stufen
> runterdimmen? 8bits sind numal spätestens nach 8 shifts leer.

Nein, beim 'ausdimmen' hat er in der Abbruchbedingung um 0 nach rechts 
geshiftet, und das ist eine Identität. Diese Schleifen liefen also 'ganz 
normal' bis zur 0 runter.

von J. T. (chaoskind)


Lesenswert?

Hat er alles ohne Warnung durchkompiliert. Evtl sind die Warnungen 
standardmäßig ausgeschaltet? Ich hab einfach diese Arduino-IDE 
installiert und angefangen.

Danke erstmal für deine Erklärung, aber ich denke, ich werd doch einfach 
weiter bei C bleiben. Da hat man doch irgendwie mehr "Zugriff" auf den 
µC.

Kannst du evtl noch ein paar Worte zur "Identität" verlieren? Was hat 
das damit auf sich? Wenn ich in C um null stellen shifte, dann bleibt 
doch alles gleich, oder nicht? Aber das hier ist ja Arduino. Oder gilt 
das nur für den Fall, das man in einer Schleife ist?

MfG Chaos

von Cpp (Gast)


Lesenswert?

j. t. schrieb:
> Aber das hier ist ja Arduino.
Und das ist C++ und unterscheidet sich von C daher nicht viel.

von Max H. (hartl192)


Lesenswert?

1
for (brightnessG = 255; brightnessG >> 0; brightnessG--)
verhlät sich wie:
1
for (brightnessG = 255; brightnessG ; brightnessG--)
und das verhält sich dann wie:
1
for (brightnessG = 255; brightnessG != 0; brightnessG--)
Und wenn man mit "brightnessG--" vom Positiven kommt verhält sich
1
brightnessG != 0
und
1
brightnessG > 0
gleich

: Bearbeitet durch User
von J. T. (chaoskind)


Lesenswert?

Jau vielen Dank für die anschaulichen Erläuterungen. Ich glaub nun hab 
ichs begriffen. Also kann man sagen, eine Identität ist alles, was nicht 
null ist?

Nuja nun ist erst mal Schlafenszeit, ich werd morgen wieder reinschauen, 
bis dann erstmal

von g457 (Gast)


Lesenswert?

> Also kann man sagen, eine Identität ist alles, was nicht null ist?

Nein, eine Identität ist eine Abbildung, die 'nix macht' (genauer, 
ausführlicher und korrekter ohne Anführungszeichen: [0])

Ad Warnungen: Ein normaler(gm) gcc liefert sowas:
1
$ cat test.cpp 
2
int main()
3
{
4
        int brightnessR;
5
        for (brightnessR = 0; brightnessR << 255; brightnessR++)
6
        {}
7
8
        return 0;
9
}
10
11
$ gcc -o test test.cpp 
12
test.cpp: In function ‘int main()’:
13
test.cpp:4:39: warning: left shift count >= width of type
14
  for (brightnessR = 0; brightnessR << 255; brightnessR++)
15
                                       ^

Mein avr-gcc (für C) liefert die gleiche Warnung ohne die Codezeile, 
avr-gcc für C++ (der Compiler im Arduino-SDK) hab ich gerade keine zur 
Hand, ich würde aber erwarten, dass er das selbe macht.

[0] http://de.wikipedia.org/wiki/Identische_Abbildung

von J. T. (chaoskind)


Lesenswert?

Sehr schön, dann hab ichs nun begriffen! Vielen Dank für eure 
Erläuterungen!

Evtl noch eine kleine Zwischenfrage. Kann es sein, das die Arduinos auf 
den PWM-Ports, wenn man sie nur als DigitalIO benutzt,dennoch PWM-t?

Ich hatte meine RGB-LED erst mal nur an und auschalten wollen, und war 
denn ziemlich entäuscht, über das lasche funzeln. (Vorwiderstand 100 
Ohm).

Als ich dann aber mal dimmen lies, hat mir das leuchten fast die Augen 
aus dem Kopf gedrückt (ein bischen übertrieben), und meine anfängliche 
Entäuschung schnell zurückgetrieben.

MfG Chaos

von Marc S. (marc_s86)


Lesenswert?

dann hast du den port wahrscheinlich mit analogWrite statt mit 
digitalWrite zugegriffen?

von J. T. (chaoskind)


Lesenswert?

Das wäre möglich, meine aber, ich hatte erst ein Beispiel benutzt, in 
dem digitalWrite verwendet wurde. Werd ich nochmal nachprüfen, wenn ich 
zuhaus bin.

MfG Chaos

von Karl H. (kbuchegg)


Lesenswert?

Eine andere Möglichkeit ist, dass du vergessen hast, den Pin auf Output 
zu schalten.

von J. T. (chaoskind)


Lesenswert?

@KarlHeinz

genau das ist es gewesen =)

Wie groß sind eigentlich die PullUps wenn man bei DDRx = 0; den PORTx 
schaltet? Mir schwirrt was von von 10k-100k im Kopf rum, kann das sein? 
Dann sind die RGBs wohl doch nicht so schlecht. Für nen 10k 
Vorwiderstand waren sie dann noch anständig hell, und sollte ich nen µC 
erwischt haben, der die 100k hat, waren sie sogar brutal hell :D

: Bearbeitet durch User
von Cpp (Gast)


Lesenswert?

j. t. schrieb:
> Wie groß sind eigentlich die PullUps wenn man bei DDRx = 0; den PORTx
> schaltet?
Soweit ich mit erinnere ist das irgendwo im Datenblatt gestanden…

von H. Westfahl (Gast)


Lesenswert?

Ich hab mal den korrigierten Code von
Datum: 11.02.2015 23:50
ausprobiert, bei mir blinkt blau, rot und grün
wird ordentlich gedimmt. Woran liegt es?

von J. T. (chaoskind)


Lesenswert?

Nun da der Code bei mir alle drei Kanäle ordentlich dimmt, kann man den 
Code vermutlich schonmal als Fehlerquelle ausschließen.

Evtl hast du einen Kanal falsch angeschlossen? Ich hab rot auf die 10, 
grün auf die 9, und blau auf die 8 vom Arduino geklemmt.

von J. T. (chaoskind)


Lesenswert?

P.S. Falls du es warst, der mir ne PN geschickt hat, ich hatte versucht 
dir zu antworten, aber der GMX-Dämon meinte, deine Adresse gibs nicht.

P.P.S.

Deine Aussage weist gewisse Parallelen auf zu "Ich hab das mal 
ausprobiert, Vollgas gegeben, dann sind mir aber die Ventile 
entgegengeflogen, woran liegt das?".

Wären wir in nem Motorforum, könnte dir dennoch niemand weiterhelfen. 
Man weis nicht, was du wie angeschlossen hast, noch um was für einen 
Motor es geht.

Aber spontan würd ich tippen, blau falsch angeschlossen. Wie gesagt, bei 
mir tut der Code was er soll.

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.