![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
basic lightning detector with gps and sd card logging
Dependencies: AS3935 AdafruitGPS SDFileSystem TSI mbed ConfigFile
main.cpp.orig
- Committer:
- cmkachur
- Date:
- 2015-07-01
- Revision:
- 12:7c58c7a6b25c
File content as of revision 12:7c58c7a6b25c:
#include "mbed.h" #include "GPS.h" #include "main.h" #include "TSISensor.h" #include "SDFileSystem.h" #include "AS3935.h" #include "ConfigFile.h" #include "datetime.h" #include "time.h" #include <string> #define FW_VER 3 // frdm-kl25z as3935 connections for spi1 // ------------------------------------------------ // Header -- kl25z -- SD/MMC // J2-20 -- PTE1 -- MOSI // J9-13 -- PTE4 -- CS // J2-14 -- GND -- Vss (GND) // J9-9 -- PTE2 -- SCK // J9-11 -- PTE3 -- MISO AS3935 ld(PTE1, PTE3, PTE2, PTE4, "ld", 1000000); // MOSI, MISO, SCK, CS, SPI bus freq (hz) InterruptIn IntLightning(PTA12); //IRQ AS3935 // frdm-kl25z sd card connections spi0 // ------------------------------------------------ // Header -- kl25z -- SPI // J2-8 -- PTD2 -- MOSI // J2-6 -- PTD0 -- CS // J9-12 -- GND -- Vss (GND) // J9-4 -- P3V3 -- Vdd (+3.3v) // J2-12 -- PTD1 -- SCK // J9-14 -- GND -- Vss (GND) // J2-10 -- PTD3 -- MISO SDFileSystem sd(PTD2, PTD3, PTD1, PTD0, "sd"); // MOSI, MISO, SCK, CS Serial pc(USBTX, USBRX); GPS gpsd(PTE20, PTE21); DigitalOut red(LED_RED); DigitalOut green(LED_GREEN); //DigitalOut blue(LED_BLUE); don't use the blue led, due to a board error, writing to the blue led kills spi bool debug=false; void writeLogFile(int interruptSource, int distance, long energy); char logName[]="lightning_data.csv"; int rdistance, rinterrupt; char directory[]="/sd/lightning_data"; int OriginInt=-1; int gDistance=-1; long energy=-1; struct tm Clock; typedef struct { unsigned int bOutdoorMode; unsigned int noiseFloor; unsigned int wdogThresh; unsigned int bClrStat; unsigned int minNumLight; unsigned int spikeRej; unsigned int maskDisturber; }sys_cfg_t; // default configuration values sys_cfg_t sysCfg = { .bOutdoorMode = 1, .noiseFloor = 2, .wdogThresh = 2, .bClrStat = 0, .minNumLight = 0, .spikeRej = 2, .maskDisturber = 0, }; void DetectLightning() { OriginInt = ld.interruptSource(); gDistance = ld.lightningDistanceKm(); energy = ld.getEnergy(); } void writeLogFile(int interruptSource, int distance, long energy) { char logFilePath[128]; static bool header=false; FILE *fp; sprintf(logFilePath, "%s/%s", directory,logName); sd.mount(); fp = fopen(logFilePath, "a"); if(fp == NULL) { // retry wait_ms(200); fp = fopen(logFilePath, "a"); if (fp == NULL) { printf("Could not open file %s for writing\r\n",logFilePath); sd.unmount(); printf("unmount sd card \r\n"); return; } } if (debug) pc.printf("Opened log file %s\r\n",logFilePath); // write the log file header if (header == false) { fprintf(fp,"# date,time,raw timestamp,latitude,longitude,distance,interrupt,energy\r\n"); header = true; } // write to the current log file char time_str[32]; time_t seconds = time(NULL); seconds -= 14400; // 14400 = 60*60*4, kludgy way of setting edt struct tm *tminfo = localtime(&seconds); strftime(time_str, 32, "%m/%d/%Y,%T", tminfo); fprintf(fp,"%s,%ld,",time_str,seconds); fprintf(fp,"%5.7f,%5.7f,", gpsd.lat_deg, gpsd.lon_deg); fprintf(fp,"%d,",distance); fprintf(fp,"%d,",interruptSource); fprintf(fp,"%ld",energy); fprintf(fp,"\r\n"); fflush(fp); f_sync((FIL*)fp); fclose(fp); sd.unmount(); pc.printf("Event: "); pc.printf(" %s - ", time_str); switch (interruptSource) { case 1: pc.printf("Noise level too high\r\n"); break; case 4: pc.printf("Disturber\r\n"); break; case 8: pc.printf("Lightning detection, distance=%dkm energy=%ld\r\n", distance, energy); if (sysCfg.bClrStat) ld.clearStats(); break; default: pc.printf("Unknown interrupt %d\r\n", OriginInt); } if (debug) pc.printf("Closed log file %s\r\n",logFilePath); } void writeCfgFile(unsigned char *pBuff, unsigned char buffLen, unsigned char fwVer) { char cfgFilePath[128]; FILE *fp; unsigned char cnt = 0; sprintf(cfgFilePath, "%s/%s", directory, "config_data.csv"); sd.mount(); fp = fopen(cfgFilePath, "w"); if(fp == NULL) { // retry wait_ms(200); fp = fopen(cfgFilePath, "w"); if (fp == NULL) { printf("Could not open file %s for writing\r\n",cfgFilePath); sd.unmount(); printf("unmount sd card \r\n"); return; } } if (debug) pc.printf("Opened log file %s\r\n",cfgFilePath); // write the header fprintf(fp,"# FW_VER,REG0,REG1,REG2,REG3,REG4,REG5,REG6,REG7,REG8\r\n"); // write the firmware version fprintf(fp,"%d,", fwVer); // write all the configuration registers for (cnt = 0; cnt < buffLen && cnt < MAX_CONFIG_REGS; ++cnt) fprintf(fp,"0x%x,", pBuff[cnt]); fflush(fp); f_sync((FIL*)fp); fclose(fp); sd.unmount(); if (debug) pc.printf("Closed cfg file %s\r\n",cfgFilePath); } bool readCfgFile(char *paDirectory, sys_cfg_t *paSysCfg) { bool bRetVal = false; FILE *fp; sys_cfg_t lSysCfg; typedef struct { const char *token; unsigned int *value; }token_map_t; token_map_t tokenMap[] = { {"outdoor_mode", &lSysCfg.bOutdoorMode}, {"noise_floor", &lSysCfg.noiseFloor}, {"watchdog_threshold", &lSysCfg.wdogThresh}, {"clear_stat", &lSysCfg.bClrStat}, {"minimum_num_light", &lSysCfg.minNumLight}, {"spike_reject", &lSysCfg.spikeRej}, {"mask_disturber", &lSysCfg.maskDisturber}, }; ConfigFile *plCfgFile; string fileName; int count = sizeof(tokenMap) / sizeof(token_map_t); char szValue[8]; if ((NULL == paDirectory) || (NULL == paSysCfg)) return false; // start with whatever configuration params are passed in, in case some params are not found in the file lSysCfg = *paSysCfg; plCfgFile = new ConfigFile(); fileName = paDirectory; fileName += "/"; fileName += "zeus.cfg"; sd.mount(); fp = fopen(fileName.c_str(), "r"); printf ("\n\rReading configuration file [%s]\n\r", fileName.c_str()); // try to read values from the configuration file if (plCfgFile->read((char *)fileName.c_str())) { for (int i = 0; i < count; ++i) { if (plCfgFile->getValue((char *)tokenMap[i].token, szValue, sizeof(szValue))) { if (1 == sscanf(szValue, "%d", tokenMap[i].value)) { printf ("Convert success %s[%d]\n\r", tokenMap[i].token, *(tokenMap[i].value)); } } } // copy out the new found values *paSysCfg = lSysCfg; bRetVal = true; } else { printf ("Failed to read configuration file[%s]\n\r", fileName.c_str()); // try to create a default configuration file for (int i = 0; i < count; ++i) { if (snprintf(szValue, sizeof(szValue), "%d", *(tokenMap[i].value))) { if (plCfgFile->setValue((char *)tokenMap[i].token, szValue)) { printf ("Token creation success %s[%s]\n\r", tokenMap[i].token, szValue); } } } if (plCfgFile->write((char *)fileName.c_str(), NULL, DOS)) printf ("Success: Created default configuration file [%s]\n\r", fileName.c_str()); else printf ("Failed to create default configuration file [%s]\n\r", fileName.c_str()); } if (plCfgFile) delete plCfgFile; if (fp != NULL) fclose(fp); sd.unmount(); return bRetVal; } int main() { unsigned char regBuff[MAX_CONFIG_REGS]; char c; Timer refresh_Timer; //sets up a timer for use in loop; how often do we print GPS info? const int refresh_Time = 1000; //refresh time in ms TSISensor tsi; // touch slider unsigned long measFreq; rdistance=-1; rinterrupt=-1; pc.baud(9600); // initializations for gps green = 1; gpsd.setBaud(9600); gpsd.sendCommand(PMTK_SET_NMEA_OUTPUT_RMCGGA); gpsd.sendCommand(PMTK_SET_NMEA_UPDATE_1HZ); gpsd.sendCommand(PGCMD_ANTENNA); gpsd.day=01; gpsd.month=01; gpsd.year=15; gpsd.hour=1; gpsd.minute=1; gpsd.seconds=1; red = 1; green = 1; pc.printf("Touch slider to start lightning detector application\r\n"); while(1) { green = 1; // turn led off wait_ms(200); if (tsi.readPercentage()) break; green = 0; // turn led on wait_ms(200); if (tsi.readPercentage()) break; } //Mount the filesystem sd.mount(); mkdir(directory, 0777); sd.unmount(); // read configuration values fro SD file system to allow override of defaults in sysCfg readCfgFile(directory, &sysCfg); pc.printf("\r\nInitialize lightning detector\r\n"); //initializations for lightning detector ld.init(); ld.clearStats(); /* The precision of the calibration will depend on the accuracy of the resonance frequency of the antenna. It is recommended to first trim the receiver antenna before the calibration of both oscillators is done. */ measFreq = ld.tuneAntenna(IntLightning); ld.calibrateRCOs(IntLightning); if (sysCfg.bOutdoorMode) ld.setOutdoors(); else ld.setIndoors(); ld.setMinimumLightnings(sysCfg.minNumLight); ld.setSpikeRejection(sysCfg.spikeRej); ld.setNoiseFloor(sysCfg.noiseFloor); if (sysCfg.maskDisturber) ld.disableDisturbers(); else ld.enableDisturbers(); ld.setWatchdogThreshold(sysCfg.wdogThresh); IntLightning.rise(&DetectLightning); int MinLight = ld.getMinimumLightnings(); int Noise = ld.getNoiseFloor(); int TuneCap = ld.getTuneCap(); int SpikeRej = ld.getSpikeRejection(); int WatchDog = ld.getWatchdogThreshold(); pc.printf("\r\n Min lightning: %i", MinLight); pc.printf("\r\n"); pc.printf(" Gain: 0x%02x\r\n",ld.getGain()); pc.printf(" Noise: %i", Noise); pc.printf("\r\n"); pc.printf(" Tune CAP: %i", TuneCap); pc.printf("\r\n"); pc.printf(" Spike rej: %i", SpikeRej); pc.printf("\r\n"); pc.printf(" Watchdog: %i", WatchDog); pc.printf("\r\n"); pc.printf(" LCO calibration: %ld Hz\n\r", measFreq); refresh_Timer.start(); //starts the clock on the timer // get a copy of all config registers ld.getConfigRegisters(regBuff, sizeof(regBuff)); pc.printf("\n\rSystem Registers:\n\r"); for (int i = 0; i < sizeof(regBuff); ++i) pc.printf("REG%d [0x%02x]:\n\r", i, regBuff[i]); pc.printf("\n\r"); // write to the config file writeCfgFile(regBuff, sizeof(regBuff), FW_VER); bool gpsFix=false; bool rtcRunning=false; while (1) { if (OriginInt != -1) { // the ld detector generated an interrupt, log the event IntLightning.disable_irq(); writeLogFile(OriginInt,gDistance, energy); //ld.clearStats(); OriginInt = -1; gDistance = -1; energy = -1; IntLightning.enable_irq(); } c = gpsd.read(); //queries the GPS if (debug) { if (c) { printf("%c", c); //this line will echo the GPS data if not paused continue; } } //check if we recieved a new message from GPS, if so, attempt to parse it, if ( gpsd.newNMEAreceived() ) { if ( !gpsd.parse(gpsd.lastNMEA()) ) { continue; } } // if the rtc is not running, update the rtc clock with the latest gps time stamp if ( rtcRunning == false ) { // update rtc with the lastest gps time stamp SetDateTime(gpsd.year+2000, gpsd.month-1, gpsd.day, gpsd.hour, gpsd.minute, gpsd.seconds); } //check if enough time has passed to warrant printing GPS info to screen //note if refresh_Time is too low or pc.baud is too low, GPS data may be lost during printing if (refresh_Timer.read_ms() >= refresh_Time) { if (gpsd.fix) { // got a gps fix if (gpsFix == false) { // first time fix obtained gpsFix = true; // bug check - rtc may not be running. check if it is incrementing time_t seconds_a = time(NULL); // get the current rtc second count wait(2); // wait two seconds time_t seconds_b = time(NULL); // get the current rtc second count if (seconds_a != seconds_b) { // rtc must be running rtcRunning = true; pc.printf("RTC is running\r\n"); } else { // rtc is not running, we need to update the rtc every pass through the while loop rtcRunning = false; // the gps time will update the rtc pc.printf("RTC is not running\r\n"); } // set the rtc with the latest gps time SetDateTime(gpsd.year+2000, gpsd.month-1, gpsd.day, gpsd.hour, gpsd.minute, gpsd.seconds); pc.printf("GPS fix obtained on %02d/%02d/20%02d_%02d:%02d:%02d (UTC)\r\n",gpsd.month,gpsd.day,gpsd.year,gpsd.hour,gpsd.minute,gpsd.seconds); //pc.printf("Touch slider to suspend application\r\n"); pc.printf("Waiting for lighting detection...\r\n"); } //red = 1; // turn led off //pc.printf("turn green on\r\n"); green = 0; // turn led on wait_ms(50); } else { gpsFix = false; pc.printf("Waiting for GPS FIX\r\n"); red = 0; // turn led on } // restart the timer for the gps print loop // writeLogFile(-2); refresh_Timer.reset(); } else { //red = 0; // turn led on //pc.printf("turn green off\r\n"); green = 1; // turn green led off } // end else refresh timer } }