forked from jgillick/arduino-LEDFader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
LEDFader.cpp
155 lines (126 loc) · 2.92 KB
/
LEDFader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
/*
* LED.cpp
*
* Created on: Sep 24, 2013
* Author: jeremy
*/
#include "LEDFader.h"
LEDFader::LEDFader(uint8_t pwm_pin) {
pin = pwm_pin;
color = 0;
to_color = 0;
last_step_time = 0;
interval = 0;
duration = 0;
percent_done = 0;
curve = (curve_function)0;
}
void LEDFader::set_pin(uint8_t pwm_pin) {
pin = pwm_pin;
}
uint8_t LEDFader::get_pin(){
return pin;
}
void LEDFader::set_value(int value) {
color = (uint8_t)constrain(value, 0, 255);
if (curve)
analogWrite(pin, curve(color));
else
analogWrite(pin, color);
}
uint8_t LEDFader::get_value() {
return color;
}
uint8_t LEDFader::get_target_value() {
return to_color;
}
// Set curve to transform output
void LEDFader::set_curve(curve_function c) {
curve = c;
}
// Get the current curve function pointer
LEDFader::curve_function LEDFader::get_curve() {
return curve;
}
void LEDFader::slower(int by) {
float cached_percent = percent_done;
duration += by;
fade(to_color, duration);
percent_done = cached_percent;
}
void LEDFader::faster(int by) {
float cached_percent = percent_done;
// Ends the fade
if (duration <= by) {
stop_fade();
set_value(to_color);
}
else {
duration -= by;
fade(to_color, duration);
}
percent_done = cached_percent;
}
void LEDFader::fade(uint8_t value, unsigned int time) {
// Color hasn't changed or fader is fading to the requested value already
if (value == color || value == to_color) {
return;
}
stop_fade();
percent_done = 0;
if (time <= MIN_INTERVAL) {
set_value(value);
return;
}
duration = time;
to_color = (uint8_t)constrain(value, 0, 255);
// Figure out what the interval should be so that we're chaning the color by at least 1 each cycle
// (minimum interval is MIN_INTERVAL)
float color_diff = abs(color - to_color);
interval = round((float)duration / color_diff);
if (interval < MIN_INTERVAL) {
interval = MIN_INTERVAL;
}
last_step_time = millis();
}
bool LEDFader::is_fading() {
if (duration > 0)
return true;
return false;
}
void LEDFader::stop_fade() {
percent_done = 100;
duration = 0;
}
uint8_t LEDFader::get_progress() {
return round(percent_done);
}
bool LEDFader::update() {
// No fade
if (duration == 0) {
return false;
}
unsigned long now = millis();
unsigned int time_diff = now - last_step_time;
// Interval hasn't passed yet
if (time_diff < interval) {
return true;
}
// How far along have we gone since last update
float percent = (float)time_diff / (float)duration;
percent_done += percent;
// We've hit 100%, set LED to the final color
if (percent >= 1) {
stop_fade();
set_value(to_color);
return false;
}
// Move color to where it should be
int color_diff = to_color - color;
int increment = round(color_diff * percent);
set_value(color + increment);
// Update time and finish
duration -= time_diff;
last_step_time = millis();
return true;
}