*Solved* Maths + Typecasting = FAIL :(

I may be being a complete tool here, but I can't seem to get some simple maths to work and I think it's something to do with variable types and decimals.

Here's the idea....

I'm trying to fade an RGB LED strip from one colour to another based on time. So you send the device a serial command of 3 bytes for the RGB values and a 2 byte unsigned int for a delay in ms.

              fromRed = red;
              fromGreen = green;
              fromBlue = blue;
              toRed = params[0];
              toGreen = params[1];
              toBlue = params[2];
              
              fading = true;
              fadeTime = ((unsigned int )params[3]) << 8;
              fadeTime |= params[4];
              toTime = millis() + fadeTime;  //Potential bug here. millis() will wrap back round to 0 after 50 days need to deal with this!
              fromTime = millis();

So that bit sets all the variables up, now the next bit of code I've re written many times with different types of variables etc and no matter what I do it just doesn't work. Here's just one basic version to get the idea accross of what I want to do.

               ledRed = fromRed + ((toRed - fromRed) * (millis() - fromTime) / fadeTime))

Now I've tried that with all different variable types as it involves multiplying by a decimal. I've even tried putting some * 100 in there then / the result by 100, so that there shouldn't be any decimals involved in the maths.

Can anyone suggest some variable types or code that will do what I'm after? I also know that doing multiplication and division of floats is much more complex and this is a tiny part of a very complex main loop so efficiency is always best if someone can figure out the best way of doing this I would really appreciate it!

What error/bad behaviour are you seeing exactly?

lol the strangest thing has just happened.

I wrote that 2nd bit of code straight into this forum off the top of my head, because the code in my sketch had been changed and mostly removed as I was trying to rule out possible mistakes.

I was trying to solve this months ago and gave up after a couple of days of getting nowhere and I haven't touched it since. I've now just copied and pasted that code into my sketch and it's almost nearly there! Much much closer than before where it was just flickering random colours.

It's a bit hard to describe what it's actually doing, but as it seems to be almost working I'll have a play and see what I can come up with. If I can't get it 100% I'll do a quick video and upload it so you can see.

OK here's what I have.....

int toRed = 0;
int toGreen = 0;
int toBlue = 0;
int fromRed = 0;
int fromGreen = 0;
int fromBlue = 0;

boolean fading = false;
unsigned int fadeTime = 0;
unsigned long toTime = 0;
unsigned long fromTime = 0;

int r = 0;
int g = 0;
int b = 0;

.......

r = fromRed + ((toRed - fromRed) * (millis() - fromTime) / fadeTime);
g = fromGreen + ((toGreen - fromGreen) * (millis() - fromTime) / fadeTime);
b = fromBlue + ((toBlue - fromBlue) * (millis() - fromTime) / fadeTime);

let's just deal with the red channel....

starting with fromRed = 0, toRed = 255, fadeTime = 5000

This works perfectly! The red channel fades from 0-255 over 5secs.

Now with fromRed = 255, toRed = 0 this is what you can see... (I have no serial debug so these number are a guess based on the brightness observed)

immediately jumps to about 128, then slowly fades to 0, then jumps back to 255, then slowly fades to 0 again.

You need to post all your code so we can see what is happening, that code won't compile as well you know.

nps, but it get's quite complicated :slight_smile:

r = fromRed + ((toRed - fromRed) * (millis() - fromTime) / fadeTime);

One problem I can see is that millis() returns unsigned long, and fromTime and fadeTime also have unsigned type. So the whole calculation will be done as unsigned. This is OK when (toRed - fromRed) is positive, but not otherwise. Try this:

r = fromRed + ((toRed - fromRed) * (long)(millis() - fromTime) / (long)fadeTime);

Brilliant! It's easy when you know how :slight_smile:

Thanks for your help!