4485 |
kakl |
1 |
/* PCRD Japan */ |
|
|
2 |
|
|
|
3 |
/* |
|
|
4 |
* SD card attached to SPI bus as follows: |
|
|
5 |
** SDcard01B/CMD MOSI - pin PB3 |
|
|
6 |
** SDcard01B/DATA0 MISO - pin PB4 |
|
|
7 |
** SDcard01B/CLK CLK - pin PB5 |
|
|
8 |
** SDcard01B/CD/DATA3 CS - pin PD4 |
|
|
9 |
|
|
|
10 |
** ADCmonoSPI/CONV - pin PD6 |
|
|
11 |
** ADCmonoSPI/SDO - pin PD5 |
|
|
12 |
** ADCmonoSPI/SCK - pin PD7 shared with LED4 |
|
|
13 |
*/ |
|
|
14 |
|
|
|
15 |
#include <SD.h> |
|
|
16 |
|
|
|
17 |
const String filename = "log.csv "; // filename for logfile |
|
|
18 |
|
|
|
19 |
const int ADreset=3; // PD3 |
|
|
20 |
const int eint=2; // PD2 |
|
|
21 |
const int LED1=8; // PB0 |
|
|
22 |
const int LED2=9; // PB1 |
|
|
23 |
const int LED3=10; // PB2 |
|
|
24 |
const int LED4=7; // PD7 |
|
|
25 |
const int chipSelect = 4; // CS is PD4 |
|
|
26 |
const int CONV = 6; // CONV is PD6 |
|
|
27 |
const int SDO = 5; // SDO is PD5 |
|
|
28 |
const int ADSCK = 7; // SCK is PD7 |
|
|
29 |
|
4488 |
kakl |
30 |
const int CHANNELS=512; // Number of channels |
4485 |
kakl |
31 |
|
|
|
32 |
//unsigned int channelT[CHANNELS]; // recordig buffer |
4488 |
kakl |
33 |
unsigned char channelA[CHANNELS]; // recordig buffer |
4485 |
kakl |
34 |
boolean rise=false; // flag fo recording time |
|
|
35 |
char inChar; // input character from GPS |
|
|
36 |
String dataString = ""; // concantenated string with NMEA messages and measured values |
|
|
37 |
int coll = 0; // collons counter in NMEA messages |
|
|
38 |
unsigned int num = 0; // measurements counter |
|
|
39 |
unsigned int count; // measurements per 10 s |
|
|
40 |
|
|
|
41 |
// 1x 100 us per 10 s UTC synchronised without FIX; 40 configuration bytes |
|
|
42 |
const char cmd[40]={0xB5, 0x62, 0x06, 0x31, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x00, 0x80, 0x96, 0x98, 0x00, 0xE0, 0xC8, 0x10, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0xC6, 0x51}; |
|
|
43 |
|
|
|
44 |
// airborne <1g; 40 configuration bytes |
|
|
45 |
const char cmd2[44]={0xB5, 0x62 ,0x06 ,0x24 ,0x24 ,0x00 ,0xFF ,0xFF ,0x06 ,0x03 ,0x00 ,0x00 ,0x00 ,0x00 ,0x10 ,0x27 ,0x00 ,0x00 ,0x05 ,0x00 ,0xFA ,0x00 ,0xFA ,0x00 ,0x64 ,0x00 ,0x2C ,0x01 ,0x00 ,0x3C ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x00 ,0x52 ,0xE8}; |
|
|
46 |
|
|
|
47 |
// configure GPS |
|
|
48 |
void setupGPS() |
|
|
49 |
{ |
|
|
50 |
for (int n=0;n<40;n++) Serial.write(cmd[n]); |
|
|
51 |
for (int n=0;n<44;n++) Serial.write(cmd2[n]); |
|
|
52 |
} |
|
|
53 |
|
|
|
54 |
void errorLED() |
|
|
55 |
{ |
|
|
56 |
while(true) |
|
|
57 |
{ |
|
|
58 |
digitalWrite(LED4, HIGH); // turn the LED on (HIGH is the voltage level) |
|
|
59 |
delay(100); // wait for a second |
|
|
60 |
digitalWrite(LED4, LOW); // turn the LED off by making the voltage LOW |
|
|
61 |
delay(100); // wait for a second |
|
|
62 |
} |
|
|
63 |
} |
|
|
64 |
|
|
|
65 |
// function for reading $GPRMC NMEA message |
|
|
66 |
void ReadGPRMC() |
|
|
67 |
{ |
|
|
68 |
// $GPRMC,091451.00,A,4915.64143,N,01441.50397,E,0.053,,090215,,,A*74 |
|
|
69 |
coll = 0; |
|
|
70 |
while(1) // wait for $GPRMC |
|
|
71 |
{ |
|
|
72 |
// get incoming byte: |
|
|
73 |
while (!Serial.available()); |
|
|
74 |
if (Serial.read() != '$') continue; |
|
|
75 |
while (!Serial.available()); |
|
|
76 |
if (Serial.read() != 'G') continue; |
|
|
77 |
while (!Serial.available()); |
|
|
78 |
if (Serial.read() != 'P') continue; |
|
|
79 |
while (!Serial.available()); |
|
|
80 |
if (Serial.read() != 'R') continue; |
|
|
81 |
while (!Serial.available()); |
|
|
82 |
if (Serial.read() != 'M') continue; |
|
|
83 |
while (!Serial.available()); |
|
|
84 |
if (Serial.read() != 'C') continue; |
|
|
85 |
while (!Serial.available()); |
|
|
86 |
if (Serial.read() != ',') continue; |
|
|
87 |
break; |
|
|
88 |
} |
|
|
89 |
do |
|
|
90 |
{ |
|
|
91 |
while (!Serial.available()); |
|
|
92 |
inChar = (char)Serial.read(); |
|
|
93 |
if (inChar == ',') coll++; |
|
|
94 |
dataString += inChar; |
|
|
95 |
} |
|
|
96 |
while (coll < 9); // read only 9 coma separated values |
|
|
97 |
} |
|
|
98 |
|
|
|
99 |
// function for reading $GPGGA NMEA message |
|
|
100 |
void ReadGPGGA() |
|
|
101 |
{ |
|
|
102 |
// $GPGGA,091451.00,4915.64143,N,01441.50397,E,1,09,0.90,443.2,M,44.0,M,,*50 |
|
|
103 |
coll = 0; |
|
|
104 |
while(1) // wait for $GPGGA |
|
|
105 |
{ |
|
|
106 |
while (!Serial.available()); |
|
|
107 |
if (Serial.read() != '$') continue; |
|
|
108 |
while (!Serial.available()); |
|
|
109 |
if (Serial.read() != 'G') continue; |
|
|
110 |
while (!Serial.available()); |
|
|
111 |
if (Serial.read() != 'P') continue; |
|
|
112 |
while (!Serial.available()); |
|
|
113 |
if (Serial.read() != 'G') continue; |
|
|
114 |
while (!Serial.available()); |
|
|
115 |
if (Serial.read() != 'G') continue; |
|
|
116 |
while (!Serial.available()); |
|
|
117 |
if (Serial.read() != 'A') continue; |
|
|
118 |
while (!Serial.available()); |
|
|
119 |
if (Serial.read() != ',') continue; |
|
|
120 |
break; |
|
|
121 |
} |
|
|
122 |
do |
|
|
123 |
{ |
|
|
124 |
while (!Serial.available()); |
|
|
125 |
inChar = (char)Serial.read(); |
|
|
126 |
if (inChar == ',') coll++; |
|
|
127 |
if (coll > 4) dataString += inChar; // skip first 5 coma separated values |
|
|
128 |
} |
|
|
129 |
while (coll < 12); // read only 7 coma separated values |
|
|
130 |
} |
|
|
131 |
|
|
|
132 |
void isr() // interrupt service routine driven from 1PPS from GPS |
|
|
133 |
{ |
|
|
134 |
{ |
|
|
135 |
rise=true; |
|
|
136 |
} |
|
|
137 |
|
|
|
138 |
} |
|
|
139 |
|
|
|
140 |
void record() |
|
|
141 |
{ |
4487 |
kakl |
142 |
for (int c=67; c<CHANNELS; c++) |
4485 |
kakl |
143 |
{ |
|
|
144 |
if (channelA[c]>0) |
|
|
145 |
{ |
|
|
146 |
digitalWrite(LED4, HIGH); // LED 16-64 |
|
|
147 |
break; |
|
|
148 |
} |
|
|
149 |
} |
|
|
150 |
|
4487 |
kakl |
151 |
for (int c=33; c<64; c++) |
4485 |
kakl |
152 |
{ |
|
|
153 |
if (channelA[c]>0) |
|
|
154 |
{ |
|
|
155 |
digitalWrite(LED3, HIGH); // LED 9-16 |
|
|
156 |
break; |
|
|
157 |
} |
|
|
158 |
} |
|
|
159 |
|
4487 |
kakl |
160 |
for (int c=17; c<32; c++) |
4485 |
kakl |
161 |
{ |
|
|
162 |
if (channelA[c]>0) |
|
|
163 |
{ |
|
|
164 |
digitalWrite(LED2, HIGH); // LED 5-8 |
|
|
165 |
break; |
|
|
166 |
} |
|
|
167 |
} |
|
|
168 |
|
4487 |
kakl |
169 |
for (int c=0; c<16; c++) |
4485 |
kakl |
170 |
{ |
|
|
171 |
if (channelA[c]>0) |
|
|
172 |
{ |
|
|
173 |
digitalWrite(LED1, HIGH); // LED 0-4 |
|
|
174 |
break; |
|
|
175 |
} |
|
|
176 |
} |
|
|
177 |
|
|
|
178 |
dataString = ""; // make a string for assembling the data to log |
4488 |
kakl |
179 |
//* |
|
|
180 |
ReadGPRMC(); // read NMEA sentences from GPS |
|
|
181 |
ReadGPGGA(); |
|
|
182 |
//*/ |
4485 |
kakl |
183 |
// make a string for assembling the data to log: |
|
|
184 |
dataString += String(num++); |
|
|
185 |
//dataString += ","; |
4488 |
kakl |
186 |
Serial.print(dataString); |
4485 |
kakl |
187 |
|
|
|
188 |
// open the file. note that only one file can be open at a time, |
|
|
189 |
// so you have to close this one before opening another. |
|
|
190 |
digitalWrite(chipSelect, HIGH); |
|
|
191 |
char fileNameCharArray[filename.length()]; |
|
|
192 |
filename.toCharArray(fileNameCharArray, filename.length()); |
|
|
193 |
|
|
|
194 |
File dataFile; |
|
|
195 |
|
|
|
196 |
dataFile = SD.open(fileNameCharArray, FILE_WRITE); |
|
|
197 |
if (dataFile) |
|
|
198 |
{ |
|
|
199 |
dataFile.print(dataString); |
|
|
200 |
dataFile.close(); |
|
|
201 |
} |
|
|
202 |
else |
|
|
203 |
{ |
|
|
204 |
errorLED(); |
|
|
205 |
} |
|
|
206 |
|
4488 |
kakl |
207 |
for (int i=0; i<(CHANNELS/32); i++) |
4485 |
kakl |
208 |
{ |
|
|
209 |
dataString = ""; |
|
|
210 |
for (int n=0; n<32; n++) |
|
|
211 |
{ |
|
|
212 |
dataString += ","; |
|
|
213 |
dataString += String(channelA[(i*32)+n]); |
|
|
214 |
}; |
|
|
215 |
|
|
|
216 |
dataFile = SD.open(fileNameCharArray, FILE_WRITE); |
|
|
217 |
if (dataFile) |
|
|
218 |
{ |
|
|
219 |
dataFile.print(dataString); |
|
|
220 |
dataFile.close(); |
|
|
221 |
} |
|
|
222 |
else |
|
|
223 |
{ |
|
|
224 |
errorLED(); |
|
|
225 |
} |
4487 |
kakl |
226 |
} |
4485 |
kakl |
227 |
|
4487 |
kakl |
228 |
dataString = ","; |
|
|
229 |
dataString += String(count); |
|
|
230 |
dataFile = SD.open(fileNameCharArray, FILE_WRITE); |
|
|
231 |
if (dataFile) |
|
|
232 |
{ |
|
|
233 |
dataFile.println(dataString); |
|
|
234 |
dataFile.close(); |
|
|
235 |
} |
|
|
236 |
else |
|
|
237 |
{ |
|
|
238 |
errorLED(); |
|
|
239 |
} |
4485 |
kakl |
240 |
|
|
|
241 |
|
|
|
242 |
digitalWrite(chipSelect, LOW); |
|
|
243 |
|
4488 |
kakl |
244 |
//*!!! control print |
4487 |
kakl |
245 |
//TODO print to I2C display |
4488 |
kakl |
246 |
Serial.print(":"); |
4487 |
kakl |
247 |
Serial.print(count); |
|
|
248 |
Serial.print("*"); |
4488 |
kakl |
249 |
for(int j=0;j<36;j++) {Serial.print(channelA[j]); Serial.print(' ');} |
4487 |
kakl |
250 |
Serial.println(); |
4488 |
kakl |
251 |
//*/ |
4487 |
kakl |
252 |
|
4485 |
kakl |
253 |
for (int n=0; n<CHANNELS; n++) // clear recording buffer |
|
|
254 |
{ |
|
|
255 |
channelA[n]=0; |
|
|
256 |
} |
|
|
257 |
|
|
|
258 |
digitalWrite(LED1, LOW); // LED OFF |
|
|
259 |
digitalWrite(LED2, LOW); // LED OFF |
|
|
260 |
digitalWrite(LED3, LOW); // LED OFF |
|
|
261 |
digitalWrite(LED4, LOW); // LED OFF |
|
|
262 |
|
|
|
263 |
} |
|
|
264 |
|
|
|
265 |
void setup() |
|
|
266 |
{ |
|
|
267 |
// Open serial communications and wait for port to open: |
|
|
268 |
Serial.begin(9600); |
|
|
269 |
while (!Serial) {;} |
|
|
270 |
//Serial.println("#cvak"); |
|
|
271 |
|
|
|
272 |
pinMode(ADreset, OUTPUT); |
|
|
273 |
pinMode(eint, INPUT); |
|
|
274 |
pinMode(SDO, INPUT); |
|
|
275 |
pinMode(LED1, OUTPUT); |
|
|
276 |
pinMode(LED2, OUTPUT); |
|
|
277 |
pinMode(LED3, OUTPUT); |
|
|
278 |
pinMode(LED4, OUTPUT); |
|
|
279 |
pinMode(CONV, OUTPUT); |
|
|
280 |
//pinMode(SCK, OUTPUT); |
|
|
281 |
|
|
|
282 |
setupGPS(); |
|
|
283 |
|
|
|
284 |
//Serial.print("#Initializing SD card..."); // inserting a SD Card always reset the processor and call setup |
|
|
285 |
// make sure that the default chip select pin is set to |
|
|
286 |
// output, even if you don't use it: |
|
|
287 |
|
|
|
288 |
// see if the card is present and can be initialized: |
|
|
289 |
if (!SD.begin(chipSelect)) |
|
|
290 |
{ |
|
|
291 |
//Serial.println("Card failed, or not present"); |
|
|
292 |
// don't do anything more: |
|
|
293 |
errorLED(); |
|
|
294 |
return; |
|
|
295 |
} |
|
|
296 |
//Serial.println("card initialized."); |
|
|
297 |
|
|
|
298 |
noInterrupts(); // disable all interrupts |
|
|
299 |
attachInterrupt(0, isr, RISING); // initialise interrupt from rising edge of 1PPS |
|
|
300 |
|
|
|
301 |
for (int n=0; n<CHANNELS; n++) // clear recoding buffer |
|
|
302 |
{ |
|
|
303 |
channelA[n]=0; |
|
|
304 |
} |
|
|
305 |
|
|
|
306 |
interrupts(); // enable all interrupts |
|
|
307 |
|
|
|
308 |
//Serial.println("#Hmmm"); |
|
|
309 |
} |
|
|
310 |
|
|
|
311 |
void loop() |
|
|
312 |
{ |
4487 |
kakl |
313 |
unsigned int val; |
|
|
314 |
unsigned int treshold = 1; |
|
|
315 |
|
|
|
316 |
count = 0; |
4485 |
kakl |
317 |
while (true) |
|
|
318 |
{ |
4488 |
kakl |
319 |
count++; |
4485 |
kakl |
320 |
digitalWrite(ADSCK, HIGH); |
|
|
321 |
digitalWrite(CONV, HIGH); // start AD conversion |
|
|
322 |
digitalWrite(ADreset, HIGH); // reset Peack Detector |
|
|
323 |
digitalWrite(CONV, LOW); // start SPI |
|
|
324 |
digitalWrite(ADreset, LOW); // start Peack Detector |
|
|
325 |
val=0; |
4488 |
kakl |
326 |
for (int p=0;p<9;p++) |
4485 |
kakl |
327 |
{ |
|
|
328 |
digitalWrite(ADSCK, LOW); // 1 CLK |
|
|
329 |
digitalWrite(ADSCK, HIGH); |
|
|
330 |
val= (val<<1)|digitalRead(SDO); |
|
|
331 |
} |
|
|
332 |
digitalWrite(ADSCK, LOW); // 1 CLK |
4488 |
kakl |
333 |
|
|
|
334 |
if (channelA[val] < 255) channelA[val]++; |
4485 |
kakl |
335 |
|
|
|
336 |
if (rise) // recording time is now |
|
|
337 |
{ |
|
|
338 |
record(); // make record |
|
|
339 |
digitalWrite(ADreset, HIGH); // reset Peack Detector |
|
|
340 |
rise = false; |
|
|
341 |
count = 0; |
|
|
342 |
digitalWrite(ADreset, LOW); // start Peack Detector |
|
|
343 |
continue; // skip this interrupted impuls |
|
|
344 |
} |
|
|
345 |
} |
|
|
346 |
} |