forked from jgillick/arduino-LEDFader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLEDFader.cpp
165 lines (134 loc) · 2.95 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
156
157
158
159
160
161
162
163
164
165
/*
* 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) {
if (!pin) return;
color = (uint8_t)constrain(value, 0, 255);
if (curve)
analogWrite(pin, curve(color));
else
analogWrite(pin, color);
}
uint8_t LEDFader::get_value() {
return 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) {
stop_fade();
percent_done = 0;
// No pin defined
if (!pin) {
return;
}
// Color hasn't changed
if (value == color) {
return;
}
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 (!pin)
return false;
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 pin defined
if (!pin) {
return false;
}
// 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;
}