-
Notifications
You must be signed in to change notification settings - Fork 6
/
RemoteReceiver.cpp
executable file
·110 lines (92 loc) · 2.38 KB
/
RemoteReceiver.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
#include "RemoteReceiver.h"
#include "Arduino.h"
volatile uint8_t RemoteReceiver::ready;
volatile uint32_t RemoteReceiver::data;
#if REMOTE_RECEIVER_USE_ATTACH_INTERRUPT
void RemoteReceiver::start(uint8_t intr)
#else
void RemoteReceiver::start()
#endif
{
ready = 0;
data = 0;
#if REMOTE_RECEIVER_USE_ATTACH_INTERRUPT
attachInterrupt(intr, &RemoteReceiver::interrupt, CHANGE);
#endif
}
uint8_t RemoteReceiver::dataReady(){
return ready;
}
uint32_t RemoteReceiver::getData(){
if(ready){
ready = 0;
return data;
}
else{
return 0;
}
}
#define SYNC -1
void RemoteReceiver::interrupt(){
static int8_t bits = SYNC;
static unsigned int dataPulseLength;
static unsigned long lastTime = 0;
if(ready){ return; } // We've got a value to be consumed, don't clobber it (alternatively, store the most recent, alternatively, store a ringbuffer)
unsigned long now = micros();
unsigned int length = now - lastTime;
lastTime = now;
if(bits == SYNC){ // synchronizing
static unsigned int lastLength = 0;
unsigned int expectedMin = (lastLength - (lastLength >> 2)) * 31;
unsigned int expectedMax = (lastLength + (lastLength >> 2)) * 31;
if(length > 5000 && lastLength && length > expectedMin && length < expectedMax){
// success, continue to read state
dataPulseLength = length / 31;
lastLength = 0;
bits = 0;
}
else{
lastLength = length;
}
}
else{
// read data bits
static unsigned long int current_data = 0;
static unsigned int pulse0 = 0;
if(pulse0 == 0){
pulse0 = length;
}
else{
unsigned int minPulse = dataPulseLength - (dataPulseLength >> 2);
unsigned int maxPulse = dataPulseLength + (dataPulseLength >> 2);
if(pulse0 > minPulse * 3 && pulse0 < maxPulse * 3 &&
length > minPulse && length < maxPulse){
// read high bit
current_data = (current_data << 1) | 1;
++bits;
}
else if(length > minPulse * 3 && length < maxPulse * 3 &&
pulse0 > minPulse && pulse0 < maxPulse){
// read low bit
current_data = (current_data << 1);
++bits;
}
else{
// failure, return to waiting for sync
bits = SYNC;
current_data = 0;
dataPulseLength = 0;
}
pulse0 = 0; // always reset pulse 0
if(bits == 24){
// Save data
data = current_data;
ready = 1;
// return to sync
current_data = 0;
dataPulseLength = 0;
bits = SYNC;
}
}
}
}