NT-R02BL Datasheet
- Войдите на сайт для отправки комментариев
Чт, 28/03/2013 - 00:26
Есть ли у кого-нибудь пример подключения сего беспроводного приёмника? Хочу получать данные с беспроводного датчика температуры Oregon
Если есть пример скетча, буду рад
http://dx.com/p/nt-r02bl-wireless-high-frequency-receiving-module-150634
001
// Oregon V2 decoder added - Dominique Pierre
002
// Oregon V3 decoder revisited - Dominique Pierre
003
// New code to decode OOK signals from weather sensors, etc.
004
// 2010-04-11 <jcw@equi4.com> <a data-cke-saved-href="<a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a>" href="<a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a>" rel="nofollow"><a href="http://opensource.org/licenses/mit-license.php" rel="nofollow">http://opensource.org/licenses/mit-license.php</a></a>
005
// $Id: ookDecoder.pde 5331 2010-04-17 10:45:17Z jcw $
006
007
class
DecodeOOK {
008
protected
:
009
byte
total_bits, bits, flip, state, pos, data[25];
010
011
virtual
char
decode (word width) =0;
012
013
public
:
014
015
enum
{ UNKNOWN, T0, T1, T2, T3, OK, DONE };
016
017
DecodeOOK () { resetDecoder(); }
018
019
bool
nextPulse (word width) {
020
if
(state != DONE)
021
022
switch
(decode(width)) {
023
case
-1: resetDecoder();
break
;
024
case
1: done();
break
;
025
}
026
return
isDone();
027
}
028
029
bool
isDone ()
const
{
return
state == DONE; }
030
031
const
byte
* getData (
byte
& count)
const
{
032
count = pos;
033
return
data;
034
}
035
036
void
resetDecoder () {
037
total_bits = bits = pos = flip = 0;
038
state = UNKNOWN;
039
}
040
041
// add one bit to the packet data buffer
042
043
virtual
void
gotBit (
char
value) {
044
total_bits++;
045
byte
*ptr = data + pos;
046
*ptr = (*ptr >> 1) | (value << 7);
047
048
if
(++bits >= 8) {
049
bits = 0;
050
if
(++pos >=
sizeof
data) {
051
resetDecoder();
052
return
;
053
}
054
}
055
state = OK;
056
}
057
058
// store a bit using Manchester encoding
059
void
manchester (
char
value) {
060
flip ^= value;
// manchester code, long pulse flips the bit
061
gotBit(flip);
062
}
063
064
// move bits to the front so that all the bits are aligned to the end
065
void
alignTail (
byte
max =0) {
066
// align bits
067
if
(bits != 0) {
068
data[pos] >>= 8 - bits;
069
for
(
byte
i = 0; i < pos; ++i)
070
data[i] = (data[i] >> bits) | (data[i+1] << (8 - bits));
071
bits = 0;
072
}
073
// optionally shift bytes down if there are too many of 'em
074
if
(max > 0 && pos > max) {
075
byte
n = pos - max;
076
pos = max;
077
for
(
byte
i = 0; i < pos; ++i)
078
data[i] = data[i+n];
079
}
080
}
081
082
void
reverseBits () {
083
for
(
byte
i = 0; i < pos; ++i) {
084
byte
b = data[i];
085
for
(
byte
j = 0; j < 8; ++j) {
086
data[i] = (data[i] << 1) | (b & 1);
087
b >>= 1;
088
}
089
}
090
}
091
092
void
reverseNibbles () {
093
for
(
byte
i = 0; i < pos; ++i)
094
data[i] = (data[i] << 4) | (data[i] >> 4);
095
}
096
097
void
done () {
098
while
(bits)
099
gotBit(0);
// padding
100
state = DONE;
101
}
102
};
103
104
// 433 MHz decoders
105
106
107
class
OregonDecoderV2 :
public
DecodeOOK {
108
public
:
109
OregonDecoderV2() {}
110
111
// add one bit to the packet data buffer
112
virtual
void
gotBit (
char
value) {
113
if
(!(total_bits & 0x01))
114
{
115
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
116
}
117
total_bits++;
118
pos = total_bits >> 4;
119
if
(pos >=
sizeof
data) {
120
resetDecoder();
121
return
;
122
}
123
state = OK;
124
}
125
126
virtual
char
decode (word width) {
127
if
(200 <= width && width < 1200) {
128
byte
w = width >= 700;
129
switch
(state) {
130
case
UNKNOWN:
131
if
(w != 0) {
132
// Long pulse
133
++flip;
134
}
else
if
(32 <= flip) {
135
// Short pulse, start bit
136
flip = 0;
137
state = T0;
138
}
else
{
139
// Reset decoder
140
return
-1;
141
}
142
break
;
143
case
OK:
144
if
(w == 0) {
145
// Short pulse
146
state = T0;
147
}
else
{
148
// Long pulse
149
manchester(1);
150
}
151
break
;
152
case
T0:
153
if
(w == 0) {
154
// Second short pulse
155
manchester(0);
156
}
else
{
157
// Reset decoder
158
return
-1;
159
}
160
break
;
161
}
162
}
else
{
163
return
-1;
164
}
165
return
total_bits == 160 ? 1: 0;
166
}
167
};
168
169
class
OregonDecoderV3 :
public
DecodeOOK {
170
public
:
171
OregonDecoderV3() {}
172
173
// add one bit to the packet data buffer
174
virtual
void
gotBit (
char
value) {
175
data[pos] = (data[pos] >> 1) | (value ? 0x80 : 00);
176
total_bits++;
177
pos = total_bits >> 3;
178
if
(pos >=
sizeof
data) {
179
resetDecoder();
180
return
;
181
}
182
state = OK;
183
}
184
185
virtual
char
decode (word width) {
186
if
(200 <= width && width < 1200) {
187
byte
w = width >= 700;
188
switch
(state) {
189
case
UNKNOWN:
190
if
(w == 0)
191
++flip;
192
else
if
(32 <= flip) {
193
flip = 1;
194
manchester(1);
195
}
else
196
return
-1;
197
break
;
198
case
OK:
199
if
(w == 0)
200
state = T0;
201
else
202
manchester(1);
203
break
;
204
case
T0:
205
if
(w == 0)
206
manchester(0);
207
else
208
return
-1;
209
break
;
210
}
211
}
else
{
212
return
-1;
213
}
214
return
total_bits == 80 ? 1: 0;
215
}
216
};
217
218
class
CrestaDecoder :
public
DecodeOOK {
219
public
:
220
CrestaDecoder () {}
221
222
virtual
char
decode (word width) {
223
if
(200 <= width && width < 1300) {
224
byte
w = width >= 750;
225
switch
(state) {
226
case
UNKNOWN:
227
if
(w == 1)
228
++flip;
229
else
if
(2 <= flip && flip <= 10)
230
state = T0;
231
else
232
return
-1;
233
break
;
234
case
OK:
235
if
(w == 0)
236
state = T0;
237
else
238
gotBit(1);
239
break
;
240
case
T0:
241
if
(w == 0)
242
gotBit(0);
243
else
244
return
-1;
245
break
;
246
}
247
}
else
if
(width >= 2500 && pos >= 7)
248
return
1;
249
else
250
return
-1;
251
return
0;
252
}
253
};
254
255
class
KakuDecoder :
public
DecodeOOK {
256
public
:
257
KakuDecoder () {}
258
259
virtual
char
decode (word width) {
260
if
(180 <= width && width < 450 || 950 <= width && width < 1250) {
261
byte
w = width >= 700;
262
switch
(state) {
263
case
UNKNOWN:
264
case
OK:
265
if
(w == 0)
266
state = T0;
267
else
268
return
-1;
269
break
;
270
case
T0:
271
if
(w)
272
state = T1;
273
else
274
return
-1;
275
break
;
276
case
T1:
277
state += w + 1;
278
break
;
279
case
T2:
280
if
(w)
281
gotBit(0);
282
else
283
return
-1;
284
break
;
285
case
T3:
286
if
(w == 0)
287
gotBit(1);
288
else
289
return
-1;
290
break
;
291
}
292
}
else
if
(width >= 2500 && 8 * pos + bits == 12) {
293
for
(
byte
i = 0; i < 4; ++i)
294
gotBit(0);
295
alignTail(2);
296
return
1;
297
}
else
298
return
-1;
299
return
0;
300
}
301
};
302
303
class
XrfDecoder :
public
DecodeOOK {
304
public
:
305
XrfDecoder () {}
306
307
// see also <a data-cke-saved-href="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" href="<a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a>" rel="nofollow"><a href="http://davehouston.net/rf.htm" rel="nofollow">http://davehouston.net/rf.htm</a></a>
308
virtual
char
decode (word width) {
309
if
(width > 2000 && pos >= 4)
310
return
1;
311
if
(width > 5000)
312
return
-1;
313
if
(width > 4000 && state == UNKNOWN)
314
state = OK;
315
else
if
(350 <= width && width < 1800) {
316
byte
w = width >= 720;
317
switch
(state) {
318
case
OK:
319
if
(w == 0)
320
state = T0;
321
else
322
return
-1;
323
break
;
324
case
T0:
325
gotBit(w);
326
break
;
327
}
328
}
else
329
return
-1;
330
return
0;
331
}
332
};
333
334
class
HezDecoder :
public
DecodeOOK {
335
public
:
336
HezDecoder () {}
337
338
// see also <a data-cke-saved-href="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" href="<a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a>" rel="nofollow"><a href="http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki" rel="nofollow">http://homeeasyhacking.wikia.com/wiki/Home_Easy_Hacking_Wiki</a></a>
339
virtual
char
decode (word width) {
340
if
(200 <= width && width < 1200) {
341
byte
w = width >= 600;
342
gotBit(w);
343
}
else
if
(width >= 5000 && pos >= 5
/*&& 8 * pos + bits == 50*/
) {
344
for
(
byte
i = 0; i < 6; ++i)
345
gotBit(0);
346
alignTail(7);
// keep last 56 bits
347
return
1;
348
}
else
349
return
-1;
350
return
0;
351
}
352
};
353
354
// 868 MHz decoders
355
356
class
VisonicDecoder :
public
DecodeOOK {
357
public
:
358
VisonicDecoder () {}
359
360
virtual
char
decode (word width) {
361
if
(200 <= width && width < 1000) {
362
byte
w = width >= 600;
363
switch
(state) {
364
case
UNKNOWN:
365
case
OK:
366
state = w == 0 ? T0 : T1;
367
break
;
368
case
T0:
369
gotBit(!w);
370
if
(w)
371
return
0;
372
break
;
373
case
T1:
374
gotBit(!w);
375
if
(!w)
376
return
0;
377
break
;
378
}
379
// sync error, flip all the preceding bits to resync
380
for
(
byte
i = 0; i <= pos; ++i)
381
data[i] ^= 0xFF;
382
}
else
if
(width >= 2500 && 8 * pos + bits >= 36 && state == OK) {
383
for
(
byte
i = 0; i < 4; ++i)
384
gotBit(0);
385
alignTail(5);
// keep last 40 bits
386
// only report valid packets
387
byte
b = data[0] ^ data[1] ^ data[2] ^ data[3] ^ data[4];
388
if
((b & 0xF) == (b >> 4))
389
return
1;
390
}
else
391
return
-1;
392
return
0;
393
}
394
};
395
396
class
EMxDecoder :
public
DecodeOOK {
397
public
:
398
EMxDecoder () {}
399
400
// see also <a data-cke-saved-href="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=EM+Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=EM+Protocol</a></a>
401
virtual
char
decode (word width) {
402
if
(200 <= width && width < 1000) {
403
byte
w = width >= 600;
404
switch
(state) {
405
case
UNKNOWN:
406
if
(w == 0)
407
++flip;
408
else
if
(flip > 20)
409
state = OK;
410
else
411
return
-1;
412
break
;
413
case
OK:
414
if
(w == 0)
415
state = T0;
416
else
417
return
-1;
418
break
;
419
case
T0:
420
gotBit(w);
421
break
;
422
}
423
}
else
if
(width >= 1500 && pos >= 9)
424
return
1;
425
else
426
return
-1;
427
return
0;
428
}
429
};
430
431
class
KSxDecoder :
public
DecodeOOK {
432
public
:
433
KSxDecoder () {}
434
435
// see also <a data-cke-saved-href="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" href="<a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a>" rel="nofollow"><a href="http://www.dc3yc.homepage.t-online.de/protocol.htm" rel="nofollow">http://www.dc3yc.homepage.t-online.de/protocol.htm</a></a>
436
virtual
char
decode (word width) {
437
if
(200 <= width && width < 1000) {
438
byte
w = width >= 600;
439
switch
(state) {
440
case
UNKNOWN:
441
gotBit(w);
442
bits = pos = 0;
443
if
(data[0] != 0x95)
444
state = UNKNOWN;
445
break
;
446
case
OK:
447
state = w == 0 ? T0 : T1;
448
break
;
449
case
T0:
450
gotBit(1);
451
if
(!w)
452
return
-1;
453
break
;
454
case
T1:
455
gotBit(0);
456
if
(w)
457
return
-1;
458
break
;
459
}
460
}
else
if
(width >= 1500 && pos >= 6)
461
return
1;
462
else
463
return
-1;
464
return
0;
465
}
466
};
467
468
class
FSxDecoder :
public
DecodeOOK {
469
public
:
470
FSxDecoder () {}
471
472
// see also <a data-cke-saved-href="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" href="<a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a>" rel="nofollow"><a href="http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol" rel="nofollow">http://fhz4linux.info/tiki-index.php?page=FS20%20Protocol</a></a>
473
virtual
char
decode (word width) {
474
if
(300 <= width && width < 775) {
475
byte
w = width >= 500;
476
switch
(state) {
477
case
UNKNOWN:
478
if
(w == 0)
479
++flip;
480
else
if
(flip > 20)
481
state = T1;
482
else
483
return
-1;
484
break
;
485
case
OK:
486
state = w == 0 ? T0 : T1;
487
break
;
488
case
T0:
489
gotBit(0);
490
if
(w)
491
return
-1;
492
break
;
493
case
T1:
494
gotBit(1);
495
if
(!w)
496
return
-1;
497
break
;
498
}
499
}
else
if
(width >= 1500 && pos >= 5)
500
return
1;
501
else
502
return
-1;
503
return
0;
504
}
505
};
506
507
OregonDecoderV2 orscV2;
508
OregonDecoderV3 orscV3;
509
CrestaDecoder cres;
510
KakuDecoder kaku;
511
XrfDecoder xrf;
512
HezDecoder hez;
513
VisonicDecoder viso;
514
EMxDecoder emx;
515
KSxDecoder ksx;
516
FSxDecoder fsx;
517
518
#define PORT 2
519
520
volatile word pulse;
521
522
#if defined(__AVR_ATmega1280__)
523
void
ext_int_1(
void
) {
524
#else
525
ISR(ANALOG_COMP_vect) {
526
#endif
527
static
word last;
528
// determine the pulse length in microseconds, for either polarity
529
pulse = micros() - last;
530
last += pulse;
531
}
532
533
void
reportSerial (
const
char
* s,
class
DecodeOOK& decoder) {
534
byte
pos;
535
const
byte
* data = decoder.getData(pos);
536
Serial
.print(s);
537
Serial
.print(
' '
);
538
for
(
byte
i = 0; i < pos; ++i) {
539
Serial
.print(data[i] >> 4, HEX);
540
Serial
.print(data[i] & 0x0F, HEX);
541
}
542
543
// Serial.print(' ');
544
// Serial.print(millis() / 1000);
545
Serial
.println();
546
547
decoder.resetDecoder();
548
}
549
550
551
void
setup
() {
552
Serial
.begin(115200);
553
Serial
.println(
"\n[ookDecoder]"
);
554
555
#if !defined(__AVR_ATmega1280__)
556
pinMode(13 + PORT, INPUT);
// use the AIO pin
557
digitalWrite(13 + PORT, 1);
// enable pull-up
558
559
// use analog comparator to switch at 1.1V bandgap transition
560
ACSR = _BV(ACBG) | _BV(ACI) | _BV(ACIE);
561
562
// set ADC mux to the proper port
563
ADCSRA &= ~ bit(ADEN);
564
ADCSRB |= bit(ACME);
565
ADMUX = PORT - 1;
566
#else
567
attachInterrupt(1, ext_int_1, CHANGE);
568
569
DDRE &= ~_BV(PE5);
570
PORTE &= ~_BV(PE5);
571
#endif
572
}
573
574
void
loop
() {
575
static
int
i = 0;
576
cli();
577
word p = pulse;
578
579
pulse = 0;
580
sei();
581
582
//if (p != 0){ Serial.print(++i); Serial.print('\n');}
583
584
if
(p != 0) {
585
if
(orscV2.nextPulse(p))
586
reportSerial(
"OSV2"
, orscV2);
587
if
(orscV3.nextPulse(p))
588
reportSerial(
"OSV3"
, orscV3);
589
if
(cres.nextPulse(p))
590
reportSerial(
"CRES"
, cres);
591
if
(kaku.nextPulse(p))
592
reportSerial(
"KAKU"
, kaku);
593
if
(xrf.nextPulse(p))
594
reportSerial(
"XRF"
, xrf);
595
if
(hez.nextPulse(p))
596
reportSerial(
"HEZ"
, hez);
597
}
598
599
if
(p != 0) {
600
if
(viso.nextPulse(p))
601
reportSerial(
"VISO"
, viso);
602
if
(emx.nextPulse(p))
603
reportSerial(
"EMX"
, emx);
604
if
(ksx.nextPulse(p))
605
reportSerial(
"KSX"
, ksx);
606
if
(fsx.nextPulse(p))
607
reportSerial(
"FSX"
, fsx);
608
}
609
}