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