/* PCRD *//** SD card attached to SPI bus as follows:** SDcard01B/CMD MOSI - pin PB3** SDcard01B/DATA0 MISO - pin PB4** SDcard01B/CLK CLK - pin PB5** SDcard01B/CD/DATA3 CS - pin PD4** ADCmonoSPI/CONV - pin PD6** ADCmonoSPI/SDO - pin PD5** ADCmonoSPI/SCK - pin PD7 shared with LED4*/#include <SD.h>const String filename = "log.csv "; // filename for logfileconst int detector=3; // PD3const int eint=2; // PD2const int LED1=8; // PB0const int LED2=9; // PB1const int LED3=10; // PB2const int LED4=7; // PD7const int chipSelect = 4; // CS is PD4const int CONV = 6; // CONV is PD6const int SDO = 5; // SDO is PD5const int ADSCK = 7; // SCK is PD7const int CHANNELS=32; // Number of channelsunsigned int channelT[CHANNELS]; // recordig bufferunsigned int channelA[CHANNELS]; // recordig bufferint interval=0; // seconds counterboolean rise=false; // flag fo recording timechar inChar; // input character from GPSString dataString = ""; // concantenated string with NMEA messages and measured valuesint coll = 0; // collons counter in NMEA messagesunsigned int i = 0; // measurements counter// 1x 100 us per 10 s UTC synchronised; 40 configuration bytesconst 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};// GPS setup for frequency measurement (acounter)//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};// configure GPSvoid setupGPS(){for (int n=0;n<40;n++) Serial.write(cmd[n]);}void errorLED(){while(true){digitalWrite(LED4, HIGH); // turn the LED on (HIGH is the voltage level)delay(100); // wait for a seconddigitalWrite(LED4, LOW); // turn the LED off by making the voltage LOWdelay(100); // wait for a second}}// function for reading $GPRMC NMEA messagevoid ReadGPRMC(){// $GPRMC,091451.00,A,4915.64143,N,01441.50397,E,0.053,,090215,,,A*74coll = 0;while(1) // wait for $GPRMC{// get incoming byte:while (!Serial.available());if (Serial.read() != '$') continue;while (!Serial.available());if (Serial.read() != 'G') continue;while (!Serial.available());if (Serial.read() != 'P') continue;while (!Serial.available());if (Serial.read() != 'R') continue;while (!Serial.available());if (Serial.read() != 'M') continue;while (!Serial.available());if (Serial.read() != 'C') continue;while (!Serial.available());if (Serial.read() != ',') continue;break;}do{while (!Serial.available());inChar = (char)Serial.read();if (inChar == ',') coll++;dataString += inChar;}while (coll < 9); // read only 9 coma separated values}// function for reading $GPGGA NMEA messagevoid ReadGPGGA(){// $GPGGA,091451.00,4915.64143,N,01441.50397,E,1,09,0.90,443.2,M,44.0,M,,*50coll = 0;while(1) // wait for $GPGGA{while (!Serial.available());if (Serial.read() != '$') continue;while (!Serial.available());if (Serial.read() != 'G') continue;while (!Serial.available());if (Serial.read() != 'P') continue;while (!Serial.available());if (Serial.read() != 'G') continue;while (!Serial.available());if (Serial.read() != 'G') continue;while (!Serial.available());if (Serial.read() != 'A') continue;while (!Serial.available());if (Serial.read() != ',') continue;break;}do{while (!Serial.available());inChar = (char)Serial.read();if (inChar == ',') coll++;if (coll > 4) dataString += inChar; // skip first 5 coma separated values}while (coll < 12); // read only 7 coma separated values}void isr() // interrupt service routine driven from 1PPS from GPS{//if (++interval == 10) // 10 seconds{rise=true;//interval = 0;}}void record(){for (int c=16; c<CHANNELS; c++){if (channelT[c]>0){digitalWrite(LED4, HIGH); // LED 16-64break;}}for (int c=9; c<17; c++){if (channelT[c]>0){digitalWrite(LED3, HIGH); // LED 9-16break;}}for (int c=5; c<9; c++){if (channelT[c]>0){digitalWrite(LED2, HIGH); // LED 5-8break;}}for (int c=0; c<5; c++){if (channelT[c]>0){digitalWrite(LED1, HIGH); // LED 0-4break;}}dataString = ""; // make a string for assembling the data to logReadGPRMC(); // read NMEA sentences from GPSReadGPGGA();// make a string for assembling the data to log:dataString += String(i++);//dataString += ",";//Serial.print(dataString);for (int n=0; n<CHANNELS; n++){dataString += ",";dataString += String(channelT[n]);dataString += ",";dataString += String(channelA[n]);//Serial.print(channel[n]);//Serial.print(',');}//Serial.println();// open the file. note that only one file can be open at a time,// so you have to close this one before opening another.digitalWrite(chipSelect, HIGH);char fileNameCharArray[filename.length()];filename.toCharArray(fileNameCharArray, filename.length());File dataFile = SD.open(fileNameCharArray, FILE_WRITE);// if the file is available, write to it:if (dataFile){dataFile.println(dataString);dataFile.close();// print to the serial port too://!!!Serial.println(dataString);}// if the file isn't open, pop up an error:else {//Serial.println("error opening datalog.CSV");errorLED();}digitalWrite(chipSelect, LOW);for (int n=0; n<CHANNELS; n++) // clear recording buffer{channelT[n]=0;channelA[n]=0;}digitalWrite(LED1, LOW); // LED OFFdigitalWrite(LED2, LOW); // LED OFFdigitalWrite(LED3, LOW); // LED OFFdigitalWrite(LED4, LOW); // LED OFF}void setup(){// Open serial communications and wait for port to open:Serial.begin(9600);while (!Serial) {;}//Serial.println("#cvak");pinMode(detector, INPUT);pinMode(eint, INPUT);pinMode(SDO, INPUT);pinMode(LED1, OUTPUT);pinMode(LED2, OUTPUT);pinMode(LED3, OUTPUT);pinMode(LED4, OUTPUT);pinMode(CONV, OUTPUT);//pinMode(SCK, OUTPUT);setupGPS();//Serial.print("#Initializing SD card..."); // inserting a SD Card always reset the processor and call setup// make sure that the default chip select pin is set to// output, even if you don't use it:// see if the card is present and can be initialized:if (!SD.begin(chipSelect)){//Serial.println("Card failed, or not present");// don't do anything more:errorLED();return;}//Serial.println("card initialized.");noInterrupts(); // disable all interruptsattachInterrupt(0, isr, RISING); // initialise interrupt from rising edge of 1PPSfor (int n=0; n<CHANNELS; n++) // clear recoding buffer{channelT[n]=0;channelA[n]=0;}interrupts(); // enable all interrupts//Serial.println("#Hmmm");}void loop(){//byte msb=0,lsb=0;unsigned int val;while (true){unsigned int duration=0; // pulse duration counterwhile (!digitalRead(detector)) // waiting for pulse{if (rise) break;digitalWrite(CONV, HIGH); // start AD conversion}while (digitalRead(detector)){if (rise) break;if (duration < (CHANNELS-1)) duration++;}digitalWrite(ADSCK, HIGH);digitalWrite(CONV, LOW); // start SPIval=0;for (int p=0;p<8;p++){digitalWrite(ADSCK, LOW); // 1 CLKdigitalWrite(ADSCK, HIGH);val= (val<<1)|digitalRead(SDO);}digitalWrite(ADSCK, LOW); // 1 CLKif (rise) // recording time is now{record(); // make recordrise = false;continue; // skip this interrupted impuls}if (channelT[duration] < 65535) channelT[duration]++; /// record duration in apropriate channelif (channelA[duration] < (65535-val)) channelA[duration]+=val; /// record amplitude}}