-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathOpenLightController.ino
More file actions
186 lines (149 loc) · 5.86 KB
/
Copy pathOpenLightController.ino
File metadata and controls
186 lines (149 loc) · 5.86 KB
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
* This file is part of the OpenLightController distribution (https://github.com/Craft4Cube/OpenLightController).
* Copyright (c) 2020 Lukas Schmid.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <Wire.h>
#include <FastLED.h>
//**** User Configuration ****
#define LED_DATA 10
#define LED_TYPE WS2812
#define LED_COUNT 32
#define SLAVE_ADDR 0x10
//** End User Configuration **
CRGB ledOutputBuffer[LED_COUNT]; //Current RGB values to be written out.
CRGB ledTargetBuffer[LED_COUNT]; //Target RGB values to be faded to.
CRGB ledOriginBuffer[LED_COUNT]; //Previous RGB valuse to be faded from.
byte ledStepsLeft[LED_COUNT]; //Steps left until fade is complete
byte ledTotalSteps[LED_COUNT]; //Amount of steps to pass for complete fade
byte ledStepTime[LED_COUNT]; //Time left until next step
byte ledStepDelay[LED_COUNT]; //Time between steps in ms
volatile byte registerIndex; //Current selected I2C register
volatile byte registers[256]; //I2C registers
enum Commands {
NoOperation = 0x00,
SetLedColorRGB = 0x01,
SetLedColorRangeRGB = 0x02,
SetLedColorHSV = 0x11,
SetLedColorRangeHSV = 0x12,
ClearOutputBuffer = 0xFF
};
void setup() {
//Initialize I2C bus in slave mode, and register event handlers
Wire.begin(SLAVE_ADDR);
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
//Initialize leds
FastLED.addLeds<WS2812, LED_DATA, RGB>(ledOutputBuffer, LED_COUNT);
}
void loop() {
//Handle I2C commands
switch (registers[0]) {
default: case NoOperation:
break;
case SetLedColorRGB:
setLedTargetColor(registers[1], CRGB(registers[2], registers[3], registers[4]), registers[5], registers[6]);
registers[0] = NoOperation;
break;
case SetLedColorRangeRGB:
setLedTargetRangeColor(registers[1], registers[2], CRGB(registers[3], registers[4], registers[5]), CRGB(registers[6], registers[7], registers[8]), registers[9], registers[10]);
registers[0] = NoOperation;
break;
case SetLedColorHSV:
setLedTargetColor(registers[1], CHSV(registers[2], registers[3], registers[4]), registers[5], registers[6]);
registers[0] = NoOperation;
break;
case SetLedColorRangeHSV:
setLedTargetRangeColor(registers[1], registers[2], CHSV(registers[3], registers[4], registers[5]), CHSV(registers[6], registers[7], registers[8]), registers[9], registers[10]);
registers[0] = NoOperation;
break;
case ClearOutputBuffer:
setLedTargetRangeColor(0, LED_COUNT, CRGB::Black, CRGB::Black, 0, 1);
registers[0] = NoOperation;
break;
}
//Actually fade every single led
for (byte led = 0; led < LED_COUNT; led++) {
//Are there any steps left to fade
if (ledStepsLeft[led] > 0) {
//Do we still have to wait
if (ledStepTime[led] == 0) {
//We do not have to wait anymore, therfore
//decrement the current step and reset the time value
ledStepsLeft[led]--;
ledStepTime[led] = ledStepDelay[led];
} else {
//We still have to wait, therfore just decrement the time value
ledStepTime[led]--;
}
//Calculate fade percentage
float blendPercentage = ledStepsLeft[led];
blendPercentage /= ledTotalSteps[led];
//Set the new output color
ledOutputBuffer[led] = blend(ledOriginBuffer[led], ledTargetBuffer[led], 255 - (blendPercentage * 255));
}
}
//Write the output buffer to the leds
FastLED.show();
//Wait 1 ms
delay(1);
}
//Called when I2C master tries to read a value
void requestEvent() {
Wire.write(registers[registerIndex]);
registerIndex++;
}
//Called when I2C master tries to write a value
void receiveEvent(int len) {
//Read first byte as index
registerIndex = Wire.read();
//If more bytes are available, write the to memory at specified index
while (Wire.available()) {
byte value = Wire.read();
registers[registerIndex] = value;
registerIndex++;
}
}
void setLedTargetColor(byte led, CRGB targetColor, byte stepDelay, byte stepCount) {
//Set led origin color to current color
ledOriginBuffer[led] = ledOutputBuffer[led];
//Set target color to specified color
ledTargetBuffer[led] = targetColor;
//Set total steps to step count with minimum of 1
ledTotalSteps[led] = max(stepCount, 1);
//Set current steps to step count with minimum of 1
ledStepsLeft[led] = max(stepCount, 1);
//Set step delay to sepcified delay
ledStepDelay[led] = stepDelay;
//Set step time left to specified delay
ledStepTime[led] = stepDelay;
}
void setLedTargetRangeColor(byte ledMin, byte ledMax, CRGB targetMinColor, CRGB targetMaxColor, byte stepDelay, byte stepCount) {
//Cap led values to total led count
ledMax = min(ledMax, LED_COUNT);
ledMin = min(ledMin, LED_COUNT);
//For each led in given range
for (byte led = ledMin; led < ledMax; led++) {
//Get led count relative to current range
float ledCount = ledMax - ledMin;
//Get led index relative to current range
float ledIndex = led - ledMin;
//Get led position in current range
float percentage = ledIndex / ledCount;
//Calculate color for current led
CRGB targetColor = nblend(targetMinColor, targetMaxColor, percentage);
//Set led target color
setLedTargetColor(led, targetColor, stepDelay, stepCount);
}
}