29
29
30
30
#include < limits.h>
31
31
32
+ #define DEBUG 0
33
+
32
34
// Adjust the following to match where the RF receiver is connected.
33
35
#define RF_SETUP () bitClear(DDRB, 0 )
34
36
#define RF_READ () bitRead(PINB, 0 )
35
37
36
- const unsigned int BUF_SIZE = 1536 ;
38
+ const size_t BUF_SIZE = 1280 ;
37
39
char buf[BUF_SIZE];
38
40
size_t i = 0 ;
39
41
@@ -45,6 +47,13 @@ enum {
45
47
46
48
byte cur_bit = 0 ;
47
49
50
+ struct code {
51
+ byte device[3 ]; // 24-bit (A) or 8-bit (B) device identifier
52
+ byte channel; // 4-bit intra-device channel identifier (= 0 for B)
53
+ bool group; // true iff the group bit is set (false for B)
54
+ bool state; // ON - true, OFF - false
55
+ };
56
+
48
57
void setup ()
49
58
{
50
59
/*
@@ -97,7 +106,7 @@ int next_pulse()
97
106
*
98
107
* This is equivalent to floor(log2(v)) + 1.
99
108
*/
100
- unsigned int numbits (unsigned int v)
109
+ unsigned int num_bits (unsigned int v)
101
110
{
102
111
unsigned int ret = 0 ;
103
112
while (v) {
@@ -125,7 +134,7 @@ int quantize_pulse(int p)
125
134
int sign = (p > 0 ) ? 1 : -1 ;
126
135
p *= sign; // abs value
127
136
p >>= 9 ; // divide by 512
128
- switch (numbits (p)) {
137
+ switch (num_bits (p)) {
129
138
case 0 : // 0µs <= p < 512µs
130
139
return sign * 1 ;
131
140
case 1 : // 512µs <= p < 1024µs
@@ -142,6 +151,102 @@ int quantize_pulse(int p)
142
151
}
143
152
}
144
153
154
+ const char *three_bytes_in_hex (byte s[3 ])
155
+ {
156
+ static char buf[7 ]; // 6 hex digits + NUL
157
+ const char hex[] = " 0123456789ABCDEF" ;
158
+ buf[0 ] = hex[(s[2 ] >> 4 ) & B1111];
159
+ buf[1 ] = hex[(s[2 ] >> 0 ) & B1111];
160
+ buf[2 ] = hex[(s[1 ] >> 4 ) & B1111];
161
+ buf[3 ] = hex[(s[1 ] >> 0 ) & B1111];
162
+ buf[4 ] = hex[(s[0 ] >> 4 ) & B1111];
163
+ buf[5 ] = hex[(s[0 ] >> 0 ) & B1111];
164
+ buf[6 ] = ' \0 ' ;
165
+ return buf;
166
+ }
167
+
168
+ /*
169
+ * Transmit the given code on the serial port.
170
+ */
171
+ void transmit_code (struct code *c)
172
+ {
173
+ Serial.print (three_bytes_in_hex (c->device ));
174
+ Serial.print (' :' );
175
+ Serial.print (c->group ? ' 1' : ' 0' );
176
+ Serial.print (' :' );
177
+ Serial.print (c->channel , HEX);
178
+ Serial.print (' :' );
179
+ Serial.println (c->state ? ' 1' : ' 0' );
180
+ Serial.flush ();
181
+ }
182
+
183
+ /*
184
+ * Parse the given format/code into a struct code and transmit it.
185
+ */
186
+ void parse_code (char format, uint32_t code)
187
+ {
188
+ struct code c;
189
+ static const unsigned char bit_swapper[] = {
190
+ 0 , 8 , 4 , 12 , 2 , 10 , 6 , 14 ,
191
+ 1 , 9 , 5 , 13 , 3 , 11 , 7 , 15 };
192
+
193
+ if (format == ' A' ) { // 32 bits: DDDDDDDDDDDDDDDDDDDDDDDD10GSCCCC
194
+ c.device [0 ] = code >> 8 ;
195
+ c.device [1 ] = code >> 16 ;
196
+ c.device [2 ] = code >> 24 ;
197
+ c.channel = code & B1111;
198
+ c.group = code & B100000;
199
+ c.state = code & B10000;
200
+ }
201
+ else if (format == ' B' ) { // 12 bits: DDDDDDDD011S
202
+ c.device [0 ] = 0 ;
203
+ c.device [1 ] = 0 ;
204
+ c.device [2 ] = 0 ;
205
+ c.channel = 0 ;
206
+ c.group = 0 ;
207
+ c.state = code & 1 ;
208
+ byte d = code >> 4 ;
209
+ c.device [0 ] |= bit_swapper[((d >> 4 ) & B1111)] << 4 ;
210
+ c.device [0 ] |= bit_swapper[(d & B1111)];
211
+ }
212
+ transmit_code (&c);
213
+ };
214
+
215
+ /*
216
+ * Decode commands from buf[0..i], and transmit them over the serial port.
217
+ */
218
+ void decode_buf ()
219
+ {
220
+ int state = -1 ; // Initial state - before SYNC
221
+ char format = 0 ; // 'A' or 'B'
222
+ uint32_t code = 0 ; // Must be large enough to hold largest code
223
+ for (size_t j = 0 ; j < i; j++) {
224
+ char b = buf[j];
225
+ if (state > 0 ) { // Expecting another data bit
226
+ if (b == ' 0' || b == ' 1' )
227
+ code |= ((uint32_t )(b == ' 1' ? 1 : 0 ) << --state);
228
+ else
229
+ state = -1 ; // Revert to initial state
230
+ }
231
+
232
+ if (state == 0 ) { // Finished reading data bits
233
+ parse_code (format, code);
234
+ code = 0 ;
235
+ state = -1 ; // Look for next SYNC
236
+ }
237
+ else if (state == -1 ) { // Looking for SYNC
238
+ if (b == ' A' ) { // SYNC for format A
239
+ format = ' A' ;
240
+ state = 32 ; // Expect 32 data bits
241
+ }
242
+ else if (b == ' B' ) {// SYNC for format B
243
+ format = ' B' ;
244
+ state = 12 ; // Expect 12 data bits
245
+ }
246
+ }
247
+ }
248
+ }
249
+
145
250
void loop ()
146
251
{
147
252
new_state = UNKNOWN;
@@ -163,7 +268,6 @@ void loop()
163
268
new_state = DA3;
164
269
else if (cur_state == SX2 || cur_state == DB1) {
165
270
if (cur_state == SX2) { // cmd format B
166
- buf[i++] = ' \n ' ;
167
271
buf[i++] = ' B' ;
168
272
}
169
273
new_state = DB2;
@@ -199,7 +303,6 @@ void loop()
199
303
new_state = SX2;
200
304
break ;
201
305
case SX3:
202
- buf[i++] = ' \n ' ;
203
306
buf[i++] = ' A' ;
204
307
new_state = DA0;
205
308
break ;
@@ -221,23 +324,19 @@ void loop()
221
324
}
222
325
break ;
223
326
}
224
- if (i >= BUF_SIZE - 5 ) { // Prevent overflowing buf
225
- buf[i++] = ' X' ;
327
+ if (i >= BUF_SIZE) // Prevent overflowing buf
226
328
new_state = UNKNOWN;
227
- }
329
+
228
330
if (cur_state != UNKNOWN && new_state == UNKNOWN) { // => UNKNOWN
229
- // Invalid data: Print buffer.
230
- // ...but only if it has > 8 valid bits
231
- if (i > 8 + 2 ) {
232
- buf[i++] = ' \0 ' ;
233
- Serial.print (buf);
234
- Serial.print (' >' );
235
- Serial.print (cur_state);
236
- Serial.print (' |' );
237
- Serial.print (p);
238
- Serial.print (' <' );
239
- Serial.flush ();
240
- }
331
+ #if DEBUG
332
+ buf[i] = ' \0 ' ;
333
+ Serial.println (buf);
334
+ Serial.flush ();
335
+ #endif DEBUG
336
+ // Reached end of valid data: Decode and transmit buffer.
337
+ // ...but only if it longer than the shortest command
338
+ if (i > 1 + 12 ) // Format B: SYNC + 12 data bits
339
+ decode_buf ();
241
340
i = 0 ; // Restart buffer
242
341
}
243
342
cur_state = new_state;
0 commit comments