-
Notifications
You must be signed in to change notification settings - Fork 1
/
read.ino
138 lines (117 loc) · 3.25 KB
/
read.ino
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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#define KERUI_BITS 24
#define KERUI_MAX_SIGNAL_LENGTH 255
#define KERUI_UPPER_THRESHOLD 100
#define KERUI_LOWER_THRESHOLD 80
#define KERUI_DURATION_BIT 500
#define KERUI_DURATION_DELIMITER 5000
#define KERUI_RESULT_SUCCESS 0
#define KERUI_RESULT_TIMEOUT_LOW 1
#define KERUI_RESULT_TIMEOUT_HIGH 2
#define KERUI_RESULT_MANY_ERRORS 3
#define KERUI_RESULT_DELIMETER_NOT_FOUND 4
#define KERUI_MAX_ERROR_COUNT 50
#define LED_PIN 13
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
digitalWrite(LED_PIN, HIGH);
delay(2000);
digitalWrite(LED_PIN, LOW);
}
const int rowSize = 2*(KERUI_BITS+1);
int row[rowSize];
byte bits[KERUI_BITS];
void loop() {
digitalWrite(LED_PIN, HIGH);
Serial.println("Waiting for a result...");
int result = keruiReadRow(A0, 2, bits, row);
digitalWrite(LED_PIN, LOW);
if (result == KERUI_RESULT_SUCCESS){
Serial.print("Code: ");
for(int i=0;i<KERUI_BITS; i++){
Serial.print(bits[i]);
}
Serial.println();
Serial.print("Timing: ");
for(int i=0;i<rowSize; i++){
if (i>0) Serial.print(", ");
Serial.print(row[i]);
}
Serial.println();
}
else {
Serial.print("Error: ");
Serial.println(result);
}
}
/**
Returns true if data was read successfully otherwise false
analogPin - pin number to read from. Usualy it is A0
result - must be size of KERUI_BITS
passes - number of required succesful passes
row - can be null. If provided size should be 2*(KERUI_BITS+1). Each pair is LOW/HIGH time in microsecond, the first pair is the delimiter
**/
int keruiReadRow(int analogPin, int passes, byte result[], int row[]){
unsigned long time, time2;
int counter, low, high;
time = millis();
while(analogRead(analogPin)<1);
int successes = 0;
int bitNumber = -1;
byte bitValue;
int errorCount = 0;
int noDelimiterCounter = 0;
while(successes < passes){
// Read LOW signal
time = micros();
counter = 0;
while(analogRead(analogPin)>KERUI_UPPER_THRESHOLD){
counter++;
if (counter > KERUI_MAX_SIGNAL_LENGTH) return KERUI_RESULT_TIMEOUT_LOW;
}
time2 = micros();
low = time2-time;
// Read HIGH signal
counter = 0;
while(analogRead(analogPin)<KERUI_LOWER_THRESHOLD){
counter++;
if (counter > KERUI_MAX_SIGNAL_LENGTH) return KERUI_RESULT_TIMEOUT_HIGH;
}
high = micros()-time2;
if (row){
row[2*(bitNumber+1)] = low;
row[2*(bitNumber+1)+1] = high;
}
if (high > KERUI_DURATION_DELIMITER){
bitNumber = 0;
noDelimiterCounter = 0;
}
else {
if (bitNumber < 0){
if (noDelimiterCounter++ > KERUI_BITS)
return KERUI_RESULT_DELIMETER_NOT_FOUND;
}
else {
if (high < KERUI_DURATION_BIT){
bitValue = 1;
}
else {
bitValue = 0;
}
if (successes>0 && bitValue != result[bitNumber]){
successes = 0;
if (errorCount++ > KERUI_MAX_ERROR_COUNT) {
return KERUI_RESULT_MANY_ERRORS;
}
}
result[bitNumber] = bitValue;
bitNumber++;
if (bitNumber >= KERUI_BITS){
bitNumber = -1;
successes++;
}
}
}
}
return KERUI_RESULT_SUCCESS;
}