Rev Author Line No. Line
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 }