Lamp-Da 0.1
A compact lantern project
Loading...
Searching...
No Matches
elk_decoder.h
Go to the documentation of this file.
1
5#ifndef UTILS_ELK_DECODER
6#define UTILS_ELK_DECODER
7
8#include <array>
9#include <cstdint>
10
11namespace lampda {
12namespace utils {
14namespace ELK {
15
16enum class Type : uint8_t
17{
18 INVALID = 0,
19 ONOFF,
24 MIC_ONOFF,
25 MIC_MODE,
27 LED_ORDER,
28 SET_TIME,
29 TIMING,
30};
31
32struct Package
33{
34 Type type = Type::INVALID;
35
36 uint8_t dataSize = 0;
37 std::array<uint8_t, 5> data;
38};
39
43inline bool decode_ELK_message(const uint8_t* msg, uint16_t len, Package& package)
44{
45 package.type = Type::INVALID;
46 package.dataSize = 0;
47
48 // basic check: ELK messages are 9 char long
49 if (len != 9)
50 return false;
51 // Must start with 7E and end with EF
52 if (msg[0] != 0x7E || msg[8] != 0xEF)
53 return false;
54
55 switch (msg[2])
56 {
57 case 0x01: // BRIGHTNESS [0-100]
58 {
59 if (msg[3] > 100)
60 return false;
61
62 package.type = Type::BRIGHTNESS;
63 package.data[0] = msg[3]; // [0; 100]
64 package.dataSize = 1;
65 return true;
66 }
67 case 0x02: // PATTERN_SPEED [0-100]
68 {
69 if (msg[3] > 100)
70 return false;
71
72 package.type = Type::PATTERN_SPEED;
73 package.data[0] = msg[3]; // [0; 100]
74 package.dataSize = 1;
75 return true;
76 }
77 case 0x03:
78 {
79 // PATTERN_SELECT [0-28]
80 if (msg[4] == 0x03)
81 {
82 const uint8_t patternId = (msg[3] >= 128) ? (msg[3] - 128) : msg[3];
83 if (patternId > 28)
84 return false;
85
86 package.type = Type::PATTERN_SELECT;
87 package.data[0] = patternId; // [0; 28]
88 package.dataSize = 1;
89 return true;
90 }
91 // MIC_MODE: 0 = Classic, 1 = Soft, 2 = Dynamic, 3 = Disco.
92 else if (msg[4] == 0x04)
93 {
94 const uint8_t micMode = (msg[3] >= 128) ? (msg[3] - 128) : msg[3];
95 if (micMode > 3)
96 return false;
97
98 package.type = Type::MIC_MODE;
99 package.data[0] = micMode; // [0; 3]
100 package.dataSize = 1;
101 return true;
102 }
103 break;
104 }
105 case 0x04: // ONOFF
106 {
107 if (msg[3] > 0x01)
108 return false;
109
110 package.type = Type::ONOFF;
111 package.data[0] = msg[3];
112 package.dataSize = 1;
113 return true;
114 }
115 case 0x05: // COLOR_SELECT
116 {
117 if (msg[3] == 0x03)
118 {
119 package.type = Type::COLOR_SELECT;
120 package.data[0] = msg[4];
121 package.data[1] = msg[5];
122 package.data[2] = msg[6];
123 package.dataSize = 3;
124 return true;
125 }
126 break;
127 }
128 case 0x06: // MIC_SENSITIVITY [0-100]
129 {
130 if (msg[3] > 100)
131 return false;
132
133 package.type = Type::MIC_SENSITIVITY;
134 package.data[0] = msg[3]; // [0; 100]
135 package.dataSize = 1;
136 return true;
137 }
138 case 0x07: // MIC_ONOFF
139 {
140 if (msg[3] > 0x01)
141 return false;
142
143 package.type = Type::MIC_ONOFF;
144 package.data[0] = msg[3];
145 package.dataSize = 1;
146 return true;
147 }
148
149 case 0x81: // LED_ORDER
150 {
151 if (msg[3] <= 0 or msg[3] > 3)
152 return false;
153 if (msg[4] <= 0 or msg[4] > 3)
154 return false;
155 if (msg[5] <= 0 or msg[5] > 3)
156 return false;
157 // should contain only one 1, one 2 and one 3
158 if (msg[3] + msg[4] + msg[5] != 1 + 2 + 3)
159 return false;
161
162 package.type = Type::LED_ORDER;
163 package.data[0] = msg[3];
164 package.data[1] = msg[4];
165 package.data[2] = msg[5];
166 package.dataSize = 3;
167 return true;
168 }
169 case 0x82: // TIMING
170 {
171 package.type = Type::TIMING;
172 package.data[0] = msg[3];
173 package.data[1] = msg[4];
174 package.data[2] = msg[5];
175 package.data[3] = msg[6];
176 package.data[4] = msg[7];
177 package.dataSize = 5;
178 return true;
179 }
180 case 0x83: // SET_TIME
181 {
182 package.type = Type::SET_TIME;
183 package.data[0] = msg[3];
184 package.data[1] = msg[4];
185 package.data[2] = msg[5];
186 package.data[3] = msg[6];
187 package.dataSize = 4;
188 return true;
189 }
190 default:
191 break;
192 }
193 return false;
194}
195
196} // namespace ELK
197} // namespace utils
198} // namespace lampda
199#endif
bool decode_ELK_message(const uint8_t *msg, uint16_t len, Package &package)
Decode a given message, assuming it it a ELK control message.
Definition: elk_decoder.h:43
Type
Definition: elk_decoder.h:17
@ PATTERN_SPEED
set the current pattern speed
@ PATTERN_SELECT
select a display pattern in a list
@ BRIGHTNESS
set a brightness
@ COLOR_SELECT
set output as a target color
@ ONOFF
turn output onand off
@ MIC_SENSITIVITY
set microphone sensitivity
@ LED_ORDER
set the new RGB led ordering
@ SET_TIME
set the system time to a set time
@ MIC_ONOFF
turn on/off the microphone
@ TIMING
set a desired on/off time
@ MIC_MODE
set the pattern changes type with the microphone
@ INVALID
invalid value
Program scope.
Definition: control_fixed_modes.hpp:12
Definition: elk_decoder.h:33