Rev Author Line No. Line
4136 kakl 1 /* PCRD */
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 detector=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  
30 const int CHANNELS=32; // Number of channels
31  
32 unsigned int channelT[CHANNELS]; // recordig buffer
33 unsigned int channelA[CHANNELS]; // recordig buffer
34 int interval=0; // seconds counter
35 boolean rise=false; // flag fo recording time
36 char inChar; // input character from GPS
37 String dataString = ""; // concantenated string with NMEA messages and measured values
38 int coll = 0; // collons counter in NMEA messages
39 unsigned int i = 0; // measurements counter
40  
41  
42 // function for reading $GPRMC NMEA message
43 void ReadGPRMC()
44 {
45 // $GPRMC,091451.00,A,4915.64143,N,01441.50397,E,0.053,,090215,,,A*74
46 coll = 0;
47 while(1) // wait for $GPRMC
48 {
49 // get incoming byte:
50 while (!Serial.available());
51 if (Serial.read() != '$') continue;
52 while (!Serial.available());
53 if (Serial.read() != 'G') continue;
54 while (!Serial.available());
55 if (Serial.read() != 'P') continue;
56 while (!Serial.available());
57 if (Serial.read() != 'R') continue;
58 while (!Serial.available());
59 if (Serial.read() != 'M') continue;
60 while (!Serial.available());
61 if (Serial.read() != 'C') continue;
62 while (!Serial.available());
63 if (Serial.read() != ',') continue;
64 break;
65 }
66 do
67 {
68 while (!Serial.available());
69 inChar = (char)Serial.read();
70 if (inChar == ',') coll++;
71 dataString += inChar;
72 }
73 while (coll < 9); // read only 9 coma separated values
74 }
75  
76 // function for reading $GPGGA NMEA message
77 void ReadGPGGA()
78 {
79 // $GPGGA,091451.00,4915.64143,N,01441.50397,E,1,09,0.90,443.2,M,44.0,M,,*50
80 coll = 0;
81 while(1) // wait for $GPGGA
82 {
83 while (!Serial.available());
84 if (Serial.read() != '$') continue;
85 while (!Serial.available());
86 if (Serial.read() != 'G') continue;
87 while (!Serial.available());
88 if (Serial.read() != 'P') continue;
89 while (!Serial.available());
90 if (Serial.read() != 'G') continue;
91 while (!Serial.available());
92 if (Serial.read() != 'G') continue;
93 while (!Serial.available());
94 if (Serial.read() != 'A') continue;
95 while (!Serial.available());
96 if (Serial.read() != ',') continue;
97 break;
98 }
99 do
100 {
101 while (!Serial.available());
102 inChar = (char)Serial.read();
103 if (inChar == ',') coll++;
104 if (coll > 4) dataString += inChar; // skip first 5 coma separated values
105 }
106 while (coll < 12); // read only 7 coma separated values
107 }
108  
109 void isr() // interrupt service routine driven from 1PPS from GPS
110 {
111 if (++interval == 10) // 10 seconds
112 {
113 rise=true;
114 interval = 0;
115 }
116  
117 }
118  
119 void record()
120 {
121 for (int c=16; c<CHANNELS; c++)
122 {
123 if (channelT[c]>0)
124 {
125 digitalWrite(LED4, HIGH); // LED 16-64
126 break;
127 }
128 }
129  
130 for (int c=9; c<17; c++)
131 {
132 if (channelT[c]>0)
133 {
134 digitalWrite(LED3, HIGH); // LED 9-16
135 break;
136 }
137 }
138  
139 for (int c=5; c<9; c++)
140 {
141 if (channelT[c]>0)
142 {
143 digitalWrite(LED2, HIGH); // LED 5-8
144 break;
145 }
146 }
147  
148 for (int c=0; c<5; c++)
149 {
150 if (channelT[c]>0)
151 {
152 digitalWrite(LED1, HIGH); // LED 0-4
153 break;
154 }
155 }
156  
157 dataString = ""; // make a string for assembling the data to log
158 ReadGPRMC(); // read NMEA sentences from GPS
159 ReadGPGGA();
160 // make a string for assembling the data to log:
161 dataString += String(i++);
162 //dataString += ",";
163 //Serial.print(dataString);
164  
165 for (int n=0; n<CHANNELS; n++)
166 {
167 dataString += ",";
168 dataString += String(channelT[n]);
169 dataString += ",";
170 dataString += String(channelA[n]);
171 //Serial.print(channel[n]);
172 //Serial.print(',');
173 }
174 //Serial.println();
175  
176 // open the file. note that only one file can be open at a time,
177 // so you have to close this one before opening another.
178 digitalWrite(chipSelect, HIGH);
179 char fileNameCharArray[filename.length()];
180 filename.toCharArray(fileNameCharArray, filename.length());
181 File dataFile = SD.open(fileNameCharArray, FILE_WRITE);
182  
183 // if the file is available, write to it:
184 if (dataFile)
185 {
186 dataFile.println(dataString);
187 dataFile.close();
188 // print to the serial port too:
189 Serial.println(dataString);
190 }
191 // if the file isn't open, pop up an error:
192 else {
193 Serial.println("error opening datalog.CSV");
194 }
195 digitalWrite(chipSelect, LOW);
196  
197  
198 for (int n=0; n<CHANNELS; n++) // clear recording buffer
199 {
200 channelT[n]=0;
201 channelA[n]=0;
202 }
203  
204 digitalWrite(LED1, LOW); // LED OFF
205 digitalWrite(LED2, LOW); // LED OFF
206 digitalWrite(LED3, LOW); // LED OFF
207 digitalWrite(LED4, LOW); // LED OFF
208  
209 }
210  
211 void setup()
212 {
213 // Open serial communications and wait for port to open:
214 Serial.begin(9600);
215 while (!Serial) {;}
216 Serial.println("#cvak");
217  
218 pinMode(detector, INPUT);
219 pinMode(eint, INPUT);
220 pinMode(SDO, INPUT);
221 pinMode(LED1, OUTPUT);
222 pinMode(LED2, OUTPUT);
223 pinMode(LED3, OUTPUT);
224 pinMode(LED4, OUTPUT);
225 pinMode(CONV, OUTPUT);
226 //pinMode(SCK, OUTPUT);
227  
228 Serial.print("#Initializing SD card..."); // inserting a SD Card always reset the processor and call setup
229 // make sure that the default chip select pin is set to
230 // output, even if you don't use it:
231  
232 // see if the card is present and can be initialized:
233 if (!SD.begin(chipSelect))
234 {
235 Serial.println("Card failed, or not present");
236 // don't do anything more:
237 return;
238 }
239 Serial.println("card initialized.");
240  
241 noInterrupts(); // disable all interrupts
242 attachInterrupt(0, isr, RISING); // initialise interrupt from rising edge of 1PPS
243  
244 for (int n=0; n<CHANNELS; n++) // clear recoding buffer
245 {
246 channelT[n]=0;
247 channelA[n]=0;
248 }
249  
250 interrupts(); // enable all interrupts
251  
252 Serial.println("#Hmmm");
253 }
254  
255 void loop()
256 {
257 //byte msb=0,lsb=0;
258 unsigned int val;
259  
260 while (true)
261 {
262 unsigned int duration=0; // pulse duration counter
263  
264 while (!digitalRead(detector)) // waiting for pulse
265 {
266 if (rise) break;
267 digitalWrite(CONV, HIGH); // start AD conversion
268 }
269 while (digitalRead(detector))
270 {
271 if (rise) break;
272 if (duration < (CHANNELS-1)) duration++;
273 }
274  
4137 kakl 275 digitalWrite(ADSCK, HIGH);
4136 kakl 276 digitalWrite(CONV, LOW); // start SPI
277 val=0;
278 for (int p=0;p<8;p++)
279 {
280 digitalWrite(ADSCK, LOW); // 1 CLK
281 digitalWrite(ADSCK, HIGH);
282 val= (val<<1)|digitalRead(SDO);
283 }
4137 kakl 284 digitalWrite(ADSCK, LOW); // 1 CLK
4136 kakl 285  
286 if (rise) // recording time is now
287 {
288 record(); // make record
289 rise = false;
290 continue; // skip this interrupted impuls
291 }
292  
293 if (channelT[duration] < 65535) channelT[duration]++; /// record duration in apropriate channel
294 if (channelA[duration] < (65535-val)) channelA[duration]+=val; /// record amplitude
295 }
296 }