-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathRGBStripe.cpp
110 lines (97 loc) · 3.42 KB
/
RGBStripe.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
#include "RGBStripe.h"
#include "Arduino.h"
#include "util.h"
RGBStripe::RGBStripe(const char* name, pin_type red, pin_type green, pin_type blue) : Actor(name), redPin(red), greenPin(green), bluePin(blue) {
pinMode(redPin, OUTPUT);
pinMode(greenPin, OUTPUT);
pinMode(bluePin, OUTPUT);
configuredValue = { 0, 0, 0};
currentValue = { 0, 0, 0};
targetValue = {0, 0, 0};
}
bool isOff(RGB& rgb) {
return rgb.red == 0 && rgb.green == 0 && rgb.blue == 0;
}
void set(RGB& rgb, color color) {
rgb.red = rgb.green = rgb.blue = color;
}
void set(RGB& destination, const RGB& source) {
destination.red = source.red;
destination.green = source.green;
destination.blue = source.blue;
}
void RGBStripe::printStatus(Stream& stream) {
stream.print(name);
stream.print("=");
if(isOff(targetValue) && !isOff(configuredValue))
stream.println("OFF");
else {
stream.print("RGB");
printByte(stream, configuredValue.red);
printByte(stream, configuredValue.green);
printByte(stream, configuredValue.blue);
stream.println();
}
}
void RGBStripe::nextRot() {
targetValue.red = random(128, 256);
targetValue.green = random(128, 256);
targetValue.blue = random(128, 256);
lastRot = millis();
}
void RGBStripe::setCommand(const char* const command) {
lastRot = 0;
if(strncmp(command, "OFF", 3) == 0) {
set(targetValue, 0);
} else if(strncmp(command, "ON", 2) == 0) {
if(isOff(configuredValue)) {
set(configuredValue, 255);
}
set(targetValue, configuredValue);
} else if(strncmp(command, "RGB", 3) == 0) {
configuredValue.red = readColor(command, 3);
configuredValue.green = readColor(command, 6);
configuredValue.blue = readColor(command, 9);
set(targetValue, configuredValue);
} else if(strncmp(command, "ROT", 3) == 0) {
unsigned int seconds = atoi((const char*)command[3]);
rotDelay = max(5, seconds) * 1000;
nextRot();
}
}
unsigned char factor(unsigned int delta0, unsigned int delta1, unsigned int delta2) {
return delta0 > max(delta1, delta2) ? 2 : 1;
}
bool RGBStripe::fade() {
const int deltaRed = abs(currentValue.red - targetValue.red);
const int deltaGreen = abs(currentValue.green - targetValue.green);
const int deltaBlue = abs(currentValue.blue - targetValue.blue);
bool change = false;
if(currentValue.red != targetValue.red) {
currentValue.red += getDirection(currentValue.red, targetValue.red)/* * factor(deltaRed, deltaGreen, deltaBlue)*/;
change = true;
}
if(currentValue.green != targetValue.green) {
currentValue.green += getDirection(currentValue.green, targetValue.green)/* * factor(deltaGreen, deltaRed, deltaBlue)*/;
change = true;
}
if(currentValue.blue != targetValue.blue) {
currentValue.blue += getDirection(currentValue.blue, targetValue.blue)/* * factor(deltaBlue, deltaRed, deltaGreen)*/;
change = true;
}
return change;
}
void RGBStripe::execute() {
unsigned long now = millis();
if(lastRot > 0 && now - lastRot > rotDelay) {
nextRot();
}
if(needToFade() && now - lastUpdate > fadeDelay) {
lastUpdate = now;
if(fade()) {
analogWrite(redPin, currentValue.red);
analogWrite(greenPin, currentValue.green);
analogWrite(bluePin, currentValue.blue);
}
}
}