-
Notifications
You must be signed in to change notification settings - Fork 2
/
Color.cpp
82 lines (65 loc) · 1.82 KB
/
Color.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
#include "Color.h"
#include "Arduino.h"
#define BITS_PER_CHANNEL 8
#define CHANNEL_MAX 0xFF
LED_CONTROLLER_NAMESPACE_USING
Color::Color() {
clear();
}
Color::Color(unsigned long combinedValue) {
setCombinedValue(combinedValue);
}
Color::Color(byte r, byte g, byte b) {
setChannelValues(r, g, b);
}
void Color::setCombinedValue(unsigned long combinedValue) {
// This necessarily depends on specific implementation details.
color[0] = combinedValue >> (2*BITS_PER_CHANNEL);
color[1] = (combinedValue & 0x00FF00) >> (BITS_PER_CHANNEL);
color[2] = combinedValue & 0x0000FF;
}
void Color::setChannelValues(byte r, byte g, byte b) {
color[0] = r;
color[1] = g;
color[2] = b;
}
void Color::clear() {
memset(color, 0, sizeof(color));
}
void Color::setRandom() {
for(int i = 0; i < CHANNELS_PER_COLOR; i++) {
// random value in [0, CHANNEL_MAX]
color[i] = random(CHANNEL_MAX);
}
}
void Color::add(const Color& other) {
for(int i = 0; i < CHANNELS_PER_COLOR; i++) {
unsigned int sum = color[i] + other.color[i];
sum = min(CHANNEL_MAX, sum);
color[i] = (byte)sum;
}
}
Color Color::scaled(float f) {
Color scaledColor = Color();
for(int i = 0; i < CHANNELS_PER_COLOR; i++) {
float s = f * float(color[i]);
s = constrain(s, 0.0, float(0xFF));
scaledColor.color[i] = byte(s);
}
return scaledColor;
}
void Color::send(int dataPin, int clockPin) {
for(int i = 0; i < CHANNELS_PER_COLOR; i++) {
sendColorByte(dataPin, clockPin, color[i]);
}
}
void Color::sendColorByte(int dataPin, int clockPin, byte c) {
for(int bitNum = BITS_PER_CHANNEL-1; bitNum >= 0; bitNum--) {
digitalWrite(clockPin, LOW);
byte mask = 1 << bitNum;
digitalWrite(dataPin, c & mask ? HIGH : LOW);
// Maximum input clock frequency for the WS2801 is 25MHz,
// so no delay is required with a 16MHz Arduino Uno.
digitalWrite(clockPin, HIGH);
}
}