-
Notifications
You must be signed in to change notification settings - Fork 0
/
IAQ_Led.cpp
115 lines (98 loc) · 3 KB
/
IAQ_Led.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
#include "IAQ_Led.h"
extern Configuration configuration;
Adafruit_NeoPixel *pixels;
bool pixelsRequireUpdate = false;
IAQ_LED::IAQ_LED(uint8_t ledNum) {
if (pixels == NULL) {
pixels = new Adafruit_NeoPixel(2, LED_PIN, NEO_GRB + NEO_KHZ800);
pixels->begin();
};
_ledNum = ledNum;
};
void IAQ_LED::sign(float val) {
float vLow, vMedium, vHigh; // values
float cLow, cMedium, cHigh; // color index
switch (_ledNum) {
case 0:
vLow = configuration.led0_vLow();
vMedium = configuration.led0_vMedium();
vHigh = configuration.led0_vHigh();
cLow = configuration.led0_cLow();
cMedium = configuration.led0_cMedium();
cHigh = configuration.led0_cHigh();
break;
case 1:
vLow = 400;
vMedium = 800;
vHigh = 1000;
cLow = 510;
cMedium = 1020;
cHigh = 1530;
break;
};
float cSignal;
if (val <= vLow) {
cSignal = cLow;
} else if (val <= vMedium) {
cSignal = ((val - vLow) / (vMedium - vLow) * (cMedium - cLow)) + cLow;
} else if (val <= vHigh) {
cSignal = ((val - vMedium) / (vHigh - vMedium) * (cHigh - cMedium)) + cMedium;
} else {
cSignal = cHigh;
};
index2color(round(cSignal));
};
// 0..1529 -> (HUE)359..0 -> / factor 4.25
uint32_t IAQ_LED::index2color(uint16_t colorIndex) {
//uint8_t r,g,b;
colorIndex %= 1530;
// red to magenta
if (colorIndex < (255)) {
r = 255; g = 0; b = colorIndex;
// magenta to blue
} else if (colorIndex < (510)) {
r = 510 - colorIndex; g = 0; b = 255;
// blue to cyan
} else if (colorIndex < (765)) {
r = 0; g = colorIndex - 510; b = 255;
// cyan to green
} else if (colorIndex < (1020)) {
r = 0; g = 255; b = 1020 - colorIndex;
// green to yellow
} else if (colorIndex < (1275)) {
r = colorIndex - 1020; g = 255; b = 0;
// yellow to red
} else if (colorIndex < (1530)) {
r = 255; g = 1530 - colorIndex; b = 0;
};
return uint32_t (r << 16 | g << 8 | b);
};
// pre-defined led brightness adaption profiles: low, high, gamma
float LED_PROFILE[3][3] =
{
{ -1.0, 300.0, 1.5}, // #0
{0.2, 280.0, 1.3}, // #1
{ -0.2, 1024.0, 1.5} // #2
};
void IAQ_LED::setBri(uint16_t lux) {
uint8_t _profile = 0;
float low = LED_PROFILE[_profile][0];
float high = LED_PROFILE[_profile][1];
float gamma = LED_PROFILE[_profile][2];
float bri = (lux > low) ? pow((static_cast<float>(lux) - low) / (high - low), 1.0 / gamma) : 0;
bri = (bri > 1) ? 1 : bri;
if (bri != brightness) {
pixelsRequireUpdate = true; // update if brightness has changed
};
brightness += 0.1 * (bri - brightness);
uint8_t rOut = round(r * brightness);
uint8_t gOut = round(g * brightness);
uint8_t bOut = round(b * brightness);
pixels->setPixelColor(_ledNum, pixels->Color(gOut, rOut, bOut));
};
void IAQ_LED::show(void) {
if (pixelsRequireUpdate) {
pixels->show();
pixelsRequireUpdate = false;
};
};