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