-
Notifications
You must be signed in to change notification settings - Fork 0
/
Blinking.cpp
199 lines (165 loc) · 4.49 KB
/
Blinking.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
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
#include "Blinking.h"
Blinking::Blinking(int sensorPin, double freq, int lightThreshold) : lightsensorPin(sensorPin), threshold(lightThreshold), timer(1000000/60), frequency(freq), lambda(1000000.0/freq) {}
void Blinking::listen(){
detectStartCode();
synchronize();
receiveHeader();
receiveDatas();
}
void Blinking::clear(){
for(int i = 0; i < MAX_DATA_LENGTH; i++){
datas[i].value = 0;
}
}
void Blinking::detectStartCode(){
bool start = false;
int count;
while(!start){
if (analogRead(lightsensorPin) > threshold){
timer.restart(false);
count = 1;
while (count < STARTCODE_LENGTH){
if(timer.nextStep()){
timer.update();
bitRead.value = readBit();
//If we detect a "1" and there should be a "0", we break out of the loop and restart reading start code from the beginning
if (startCode[count] == 0 && bitRead.value == 1){
break;
}
else if (startCode[count] == 1 && bitRead.value == 0){
break;
}
//If what we detect is what we should detect, we continue
else{
count++;
}
}
}
if (count == STARTCODE_LENGTH){
start = true;
}
}
}
if(DEBUG){
Serial.println("Start code detected");
}
}
void Blinking::synchronize(){
int sampleSize = 100;
long elapsedTime = 0;
double count = 1;
long beginning;
long time = micros();
int currentValue = 0;
int bitRead = 1;
int sensorValue;
//Wait to enter synchronization sequence
while (bitRead != currentValue){
bitRead = analogRead(lightsensorPin) > threshold ? 1 : 0;
}
//Start the frequence mesuring
beginning = micros();
//Count the number of "periods"
while(count <= sampleSize){
currentValue = bitRead;
while(bitRead == currentValue){
sensorValue = analogRead(lightsensorPin);
bitRead = sensorValue > threshold ? 1 : 0;
//Mesure minimum and maximum brightness
if (bitRead == 0)
minBrightness = min(minBrightness, sensorValue);
else
maxBrightness = max(maxBrightness, sensorValue);
}
count++;
}
//Initialize variables for reading
elapsedTime = (micros()-beginning);
frequency = (double)sampleSize / (elapsedTime/1000000.0);
lambda = 1000000.0/frequency;
threshold = (minBrightness + maxBrightness) / 2;
timer.setPeriod(lambda);
timer.restart(false);
if(DEBUG){
Serial.print("Frequency : ");
Serial.println(frequency);
Serial.print("Min Brightness : ");
Serial.println(minBrightness);
Serial.print("Max Brightness : ");
Serial.println(maxBrightness);
}
}
/*
* Header Composition
* Data Length = 8 bits; 0000 0000 = 0; 1111 1111 = 255 //Number of groups of data
* Data Size = 4 bits; 0000 = 0 Byte; 1111 = 15 Bytes // We can change 0000 to be 1 to improve the range
*/
void Blinking::receiveHeader(){
Bit buf[12];
readValues(buf, 12);
dataLen = Utils::binToDec(buf, 12);
if(DEBUG){
Serial.println("Header Read");//For debugging
Serial.println(dataLen);
}
}
/*
* Get the data transmitted
*/
void Blinking::receiveDatas(){
readValues(datas, dataLen*8);
}
int Blinking::readBit(){
boolean read = false;
int value;
long lastTime = micros();
long newTime;
//Wait to read the value in the middle of the period
while (!read){
newTime = micros();
if(newTime - lastTime > 2*lambda/5.0){
lastTime = newTime;
value = analogRead(lightsensorPin) > threshold ? 1 : 0;
read = true;
}
}
return value;
}
void Blinking::readValues(Bit* buf, int number){
int count = 0;
while (count < number){
if (timer.nextStep()){
timer.update();
buf[count].value = readBit();
count++;
}
}
}
Bit* Blinking::getDatas(){
return datas;
}
void Blinking::serialPrintDatasAsStrings(){
int index = 0;
while (index < dataLen*8){
int size = 0;
while(Utils::charOfBin(datas, index+size*8) != '\0'){
size++;
}
char* s = (char*)malloc((size+1)*sizeof(char));
for(int i = 0; i < size; i++){
s[i] = Utils::charOfBin(datas,index+i*8);
}
s[size] = '\0';
Serial.print(s);
Serial.print('\t');
free(s);
index += (size+1)*8;
}
Serial.println();
}
void Blinking::serialPrintDatasAsBits(){
for (int i = 0; i < dataLen*8; i++){
Serial.print(datas[i].value);
}
Serial.println();
}