struct RGB { int r; int g; int b; };
class RGBLED {
private:
int _rAct;
int _gAct;
int _bAct;
int _rStart;
int _gStart;
int _bStart;
int _rEnd;
int _gEnd;
int _bEnd;
int _rPin;
int _gPin;
int _bPin;
void _set(RGB color);
unsigned long _tFadeStart;
unsigned long _tFade;
unsigned long _tlast;
bool _isFading;
public:
RGBLED(int rPin, int gPin, int bPin);
void on(RGB color);
void off();
void fadeOff(unsigned long fadeTime);
void fadeTo(RGB color, unsigned long fadeTime);
void update();
bool isFading() { return _isFading; }
};
RGBLED::RGBLED(int rPin, int gPin, int bPin) :
_rPin{ rPin },
_gPin{ gPin },
_bPin{ bPin },
_rAct{ 0 },
_gAct{ 0 },
_bAct{ 0 },
_rStart{ 0 },
_gStart{ 0 },
_bStart{ 0 },
_tlast{ 0 },
_isFading{false}
{
pinMode(rPin, OUTPUT);
pinMode(gPin, OUTPUT);
pinMode(bPin, OUTPUT);
}
void RGBLED::_set(RGB color)
{
if (color.r < 0) color.r = 0;
if (color.g < 0) color.g = 0;
if (color.b < 0) color.b = 0;
if (color.r > 255) color.r = 255;
if (color.g > 255) color.g = 255;
if (color.b > 255) color.b = 255;
_rAct = color.r;
_gAct = color.g;
_bAct = color.b;
analogWrite(_rPin, _rAct);
analogWrite(_gPin, _gAct);
analogWrite(_bPin, _bAct);
}
void RGBLED::on(RGB color)
{
this->_set(color);
}
void RGBLED::fadeTo(RGB color, unsigned long fadeTime)
{
if (fadeTime <= 0)
{
this->_set(color);
return;
}
else
{
_tFadeStart = millis();
_tFade = fadeTime;
_isFading = true;
_rEnd = color.r;
_gEnd = color.g;
_bEnd = color.b;
_rStart = _rAct;
_gStart = _gAct;
_bStart = _bAct;
}
}
void RGBLED::update()
{
if(_isFading)
{
unsigned long now = millis();
if (((unsigned long)now - _tFadeStart) > _tFade)
{
this->_set((RGB) { _rEnd, _gEnd, _bEnd });
_isFading = false;
return;
}
if (((unsigned long)now - _tlast) > 200)
{
int Dr = _rEnd - _rStart;
int Dg = _gEnd - _gStart;
int Db = _bEnd - _bStart;
unsigned long Dt = now - _tFadeStart;
int r = _rStart + (Dt * Dr / _tFade);
if (r < 0) r = 0;
if (r > 255) r = 255;
int g = _gStart + (Dg * Dt / _tFade);
if (g < 0) g = 0;
if (g > 255) g = 255;
int b = _bStart + (Db * Dt / _tFade);
if (b < 0) b = 0;
if (b > 255) b = 255;
this->_set((RGB) { r, g, b });
Serial.println("Time");
Serial.print(r);
Serial.print(" = ");
Serial.print(_rStart);
Serial.print(" + ( ");
Serial.print(Dr);
Serial.print(" * ");
Serial.print(Dt);
Serial.print(" / ");
Serial.print(_tFade);
Serial.println(" ) ");
_tlast = now;
}
}
}
#define PIN_LED_DAY_R 10
#define PIN_LED_DAY_G 11
#define PIN_LED_DAY_B 12
#define PIN_LED_NIGHT_R 7
#define PIN_LED_NIGHT_G 8
#define PIN_LED_NIGHT_B 9
RGBLED SunLight(PIN_LED_DAY_R, PIN_LED_DAY_G, PIN_LED_DAY_B);
RGBLED MoonLight(PIN_LED_NIGHT_R, PIN_LED_NIGHT_G, PIN_LED_NIGHT_B);
RGB CLDayLight;
RGB CLNightLight;
void setup()
{
CLDayLight = { 255, 255, 255 };
CLNightLight = { 0, 0, 0 };
SunLight.on(CLDayLight);
SunLight.fadeTo(CLNightLight, 10000);
MoonLight.fadeTo(CLDayLight, 10000);
delay(500);
Serial.println(F("Setup Done!"));
}
void loop()
{
SunLight.update();
MoonLight.update();
}
Serial Output (Each second line shows correctly fading up of the "MoonLight", but incorrect fading down of the "SunLight". Corresponding LEDs on the bradboard: Sunloght goes on and then off after ca. one sec, nightlight Fades on in 10 sec):
Starting Setup
Setup Done!
Time
0 = 255 + ( -255 * 502 / 10000 )
Time
12 = 0 + ( 255 * 503 / 10000 )
Time
0 = 255 + ( -255 * 703 / 10000 )
Time
17 = 0 + ( 255 * 704 / 10000 )
Time
0 = 255 + ( -255 * 904 / 10000 )
Time
23 = 0 + ( 255 * 905 / 10000 )
Time
0 = 255 + ( -255 * 1105 / 10000 )
Time
28 = 0 + ( 255 * 1106 / 10000 )
Time
0 = 255 + ( -255 * 1306 / 10000 )
Time
33 = 0 + ( 255 * 1307 / 10000 )
Time
0 = 255 + ( -255 * 1507 / 10000 )
Time
38 = 0 + ( 255 * 1508 / 10000 )
Time
0 = 255 + ( -255 * 1708 / 10000 )
Time
43 = 0 + ( 255 * 1709 / 10000 )
Time
0 = 255 + ( -255 * 1909 / 10000 )
Time
48 = 0 + ( 255 * 1910 / 10000 )
Time
0 = 255 + ( -255 * 2110 / 10000 )
Time
53 = 0 + ( 255 * 2111 / 10000 )
Time
0 = 255 + ( -255 * 2311 / 10000 )
Time
58 = 0 + ( 255 * 2312 / 10000 )
Time
0 = 255 + ( -255 * 2512 / 10000 )
Time
64 = 0 + ( 255 * 2513 / 10000 )
Time
0 = 255 + ( -255 * 2713 / 10000 )
Time
69 = 0 + ( 255 * 2714 / 10000 )
Time
0 = 255 + ( -255 * 2914 / 10000 )
Time
74 = 0 + ( 255 * 2915 / 10000 )
Time
0 = 255 + ( -255 * 3115 / 10000 )
Time
79 = 0 + ( 255 * 3116 / 10000 )
Time
0 = 255 + ( -255 * 3316 / 10000 )
Time
84 = 0 + ( 255 * 3317 / 10000 )
Time
0 = 255 + ( -255 * 3517 / 10000 )
Time
89 = 0 + ( 255 * 3518 / 10000 )
Time
0 = 255 + ( -255 * 3718 / 10000 )
Time
94 = 0 + ( 255 * 3719 / 10000 )
Time
0 = 255 + ( -255 * 3919 / 10000 )
Time
99 = 0 + ( 255 * 3920 / 10000 )
Time
0 = 255 + ( -255 * 4121 / 10000 )
Time
105 = 0 + ( 255 * 4122 / 10000 )
Time
0 = 255 + ( -255 * 4322 / 10000 )
Time
110 = 0 + ( 255 * 4323 / 10000 )
Time
0 = 255 + ( -255 * 4523 / 10000 )
Time
115 = 0 + ( 255 * 4524 / 10000 )
Time
0 = 255 + ( -255 * 4724 / 10000 )
Time
120 = 0 + ( 255 * 4725 / 10000 )
Time
0 = 255 + ( -255 * 4925 / 10000 )
Time
125 = 0 + ( 255 * 4926 / 10000 )
Time
0 = 255 + ( -255 * 5126 / 10000 )
Time
130 = 0 + ( 255 * 5127 / 10000 )
Time
0 = 255 + ( -255 * 5327 / 10000 )
Time
135 = 0 + ( 255 * 5328 / 10000 )
Time
0 = 255 + ( -255 * 5529 / 10000 )
Time
141 = 0 + ( 255 * 5530 / 10000 )
Time
0 = 255 + ( -255 * 5730 / 10000 )
Time
146 = 0 + ( 255 * 5731 / 10000 )
Time
0 = 255 + ( -255 * 5931 / 10000 )
Time
151 = 0 + ( 255 * 5932 / 10000 )
Time
0 = 255 + ( -255 * 6132 / 10000 )
Time
156 = 0 + ( 255 * 6133 / 10000 )
Time
0 = 255 + ( -255 * 6333 / 10000 )
Time
161 = 0 + ( 255 * 6334 / 10000 )
Time
0 = 255 + ( -255 * 6534 / 10000 )
Time
166 = 0 + ( 255 * 6535 / 10000 )
Time
0 = 255 + ( -255 * 6735 / 10000 )
Time
171 = 0 + ( 255 * 6736 / 10000 )
Time
0 = 255 + ( -255 * 6937 / 10000 )
Time
176 = 0 + ( 255 * 6938 / 10000 )
Time
0 = 255 + ( -255 * 7138 / 10000 )
Time
182 = 0 + ( 255 * 7139 / 10000 )
Time
0 = 255 + ( -255 * 7339 / 10000 )
Time
187 = 0 + ( 255 * 7340 / 10000 )
Time
0 = 255 + ( -255 * 7540 / 10000 )
Time
192 = 0 + ( 255 * 7541 / 10000 )
Time
0 = 255 + ( -255 * 7741 / 10000 )
Time
197 = 0 + ( 255 * 7742 / 10000 )
Time
0 = 255 + ( -255 * 7942 / 10000 )
Time
202 = 0 + ( 255 * 7943 / 10000 )
Time
0 = 255 + ( -255 * 8143 / 10000 )
Time
207 = 0 + ( 255 * 8144 / 10000 )
Time
0 = 255 + ( -255 * 8345 / 10000 )
Time
212 = 0 + ( 255 * 8346 / 10000 )
Time
0 = 255 + ( -255 * 8546 / 10000 )
Time
217 = 0 + ( 255 * 8547 / 10000 )
Time
0 = 255 + ( -255 * 8747 / 10000 )
Time
223 = 0 + ( 255 * 8748 / 10000 )
Time
0 = 255 + ( -255 * 8948 / 10000 )
Time
228 = 0 + ( 255 * 8949 / 10000 )
Time
0 = 255 + ( -255 * 9149 / 10000 )
Time
233 = 0 + ( 255 * 9150 / 10000 )
Time
0 = 255 + ( -255 * 9350 / 10000 )
Time
238 = 0 + ( 255 * 9351 / 10000 )
Time
0 = 255 + ( -255 * 9551 / 10000 )
Time
243 = 0 + ( 255 * 9552 / 10000 )
Time
0 = 255 + ( -255 * 9753 / 10000 )
Time
248 = 0 + ( 255 * 9754 / 10000 )
Time
0 = 255 + ( -255 * 9954 / 10000 )
Time
253 = 0 + ( 255 * 9955 / 10000 )