Farbverlauf - Triviale Mathematik?!

Guten Morgen,

habe gerade ein Brett vor dem Kopf.
Gewünscht ist ein linearer Rotverlauf von r1 nach r2 über die Striplänge NUM_LEDS.
r1 und r2 sind als byte deklariert und bewegen sich im zulässigen Bereich.

 for(int i = 0 ; i < NUM_LEDS; i++ ) {
    if (r2 > r1) {leds[i].red = r1 + i * ((r2-r1)/NUM_LEDS);}
    if (r2 < r1) {leds[i].red = r2 - i * ((r1-r2)/NUM_LEDS);}
    if (r2 = r1) {leds[i].red = r2;}
 }

Momentan führt dieses Funktionsfragment nicht zu einem Rotverlauf von r1 nach r2, sondern immer zu r1 über die ganze Länge. Wo liegt der Fehler?

Gruß Helmuth

edit: leds ist ein zweidimensionales Bytearray.

Hallo,

wenn mich nicht alles täuscht, müsste die Formel

leds = r2 + long (i * (int((r1-r2)))/NUM_LEDS);

sein. Bei < i * ((r1-r2) > kommt oft was größeres als ein Byte raus. Wen du die Vorzeichen mit nimmst, dann brauchst du keine Fallunterscheidung.

Hallo Theseus,
super, so funktioniert es.
Danke.

hi,

ich denke, daß es vorher nicht ging, lag einfach am:

if (r2 = r1) {leds[i].red = r2

mit r2 = r1 nimmt r2 den wert von r1 an und diesen weist Du dann red zu.

gruß stefan

@Eisebaer:
Hi, das sollte aber nur passieren, wenn r2 = r1.
War aber ständig so, auch während ich r1 und r2 im Serialmonitor anzeigen ließ und sie nicht identisch waren.
Gruß Helmuth

Hallo,

Eisbaer meinte bestimmt Du mußt == und nicht = verwenden für einen Vergleich. :wink:

63 views z.Zt. : Das haben einige nicht gesehen, vor Eisebaer !

Die Fall-Unterscheidungen sind überflüssig:

byte r1 = 250;
byte r2 = 0;
int i = 1;
int tmp = (r2-r1)* i / 10;  // wird in int gerechnet,  sollte also -25 ergeben
byte rx = r1 +  (r2-r1)* i / 10; // passt -> 225

(long und int casts brauchts auch nicht)

Eisebaer:
hi,

ich denke, daß es vorher nicht ging, lag einfach am:

if (r2 = r1) {leds[i].red = r2

mit r2 = r1 nimmt r2 den wert von r1 an und diesen weist Du dann red zu.

gruß stefan

schlimmer noch. Da die Zuweisung (das = ) immer richtig ist, wird immer, unabhängig von den Werten von r1 bzw r2 diese Bedingung immer erfüllt und somit immer leds[ i ].red auf r2 gesetzt und die vohergehenden IF überschrieben.
Im Endeffekt macht der Code

for(int i = 0 ; i < NUM_LEDS; i++ ) {
    if (r2 > r1) {leds[i].red = r1 + i * ((r2-r1)/NUM_LEDS);}
    if (r2 < r1) {leds[i].red = r2 - i * ((r1-r2)/NUM_LEDS);}
    if (r2 = r1) {leds[i].red = r2;}
 }

nur

for(int i = 0 ; i < NUM_LEDS; i++ ) {
    leds[i].red = r2;
 }

Grüße Uwe

schlimmer noch. Da die Zuweisung (das = ) immer richtig ist, wird immer, unabhängig von den Werten von r1 bzw r2 diese Bedingung immer erfüllt

noch viel schlimmer wenn r1 == 0 ist: dann erkennt if (r2=r1) auf false, setzt r2 auch 0 , lässt aber leds[ i ].red unverändert!

Aber inzwischen gibt es diese 3 überflüssigen if ja gar nicht mehr... :wink:

hi,

ich denke, daß es vorher nicht ging, lag einfach am:

Code:
if (r2 = r1) {leds*.red = r2mit r2 = r1 nimmt r2 den wert von r1 an und diesen weist Du dann red zu.*
gruß stefan[/quote]
schlimmer noch. Da die Zuweisung (das = ) immer richtig ist, wird immer, unabhängig von den Werten von r1 bzw r2 diese Bedingung immer erfüllt und somit immer leds[ i ].red auf r2 gesetzt und die vohergehenden IF überschrieben.
Im Endeffekt macht der Code
Code:
for(int i = 0 ; i < NUM_LEDS; i++ ) {
if (r2 > r1) {leds.red = r1 + i * ((r2-r1)/NUM_LEDS);}
if (r2 < r1) {leds.red = r2 - i * ((r1-r2)/NUM_LEDS);}
_ if (r2 = r1) {leds*.red = r2;}
}nur*

Code:
for(int i = 0 ; i < NUM_LEDS; i++ ) {
leds*.red = r2;
}*

Grüße Uwe[/quote]
davon abgesehen, das es wegen der inzwischen nicht mehr gebrauchten IFs nicht mehr aktuell ist:
genau das ja habe ich ja gemeint, aber was auch wichtig ist: if (r2 = r1) {leds[ i ].red = r2; ist nicht nur immer TRUE, sondern bewirkt noch dazu, daß r2 von r1 überschrieben wird. deshalb das anfangs von helmuth beschriebene phänomen, das alle LEDs mit dem wert von r1 befeuert werden.
gruß stefan_

Und das passiert genau den Leuten, die von einer anderen Programiersprache kommen. (mich eingeschlossen)

Es ist eine simple if Anweißung - Und der Fehler in der Syntax. "=" statt "=="
Warum meckert ein C (++) Compiler dort nicht ?
Wirklich Sinn macht ein "=" dort nicht, im Sinne das man dies auch bewußt so schreibt ?

Er meckert nicht weil Zuweisungen ihren Wert zurückgeben. Damit kann man sowas machen:

int val1, val2;
val1 = val2 = 5;

Das ist aber unschön und sollte sowieso vermieden werden. Es kann auch gerade auf dem AVR nicht immer das machen was man denkt:
http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_assign_chain

Man kann das machen:

if(true == val)

Dann meckert er, da man einem Literal natürlich nichts zuweisen kann. Aber wenn man wie in diesem Fall zwei Variablen vergleicht bringt das auch nichts

Dieser Anfängerfehler ist mir zu letzten Mal passiert! auf Holz klopf

Danke an alle.