basic lightning detector with gps and sd card logging

Dependencies:   AS3935 AdafruitGPS SDFileSystem TSI mbed ConfigFile

main.cpp

Committer:
cmkachur
Date:
2015-06-24
Revision:
5:1d4fd419cfb7
Parent:
4:4d26ba1ae0f7
Child:
6:96b0dbe76357

File content as of revision 5:1d4fd419cfb7:

#include "mbed.h"
#include "GPS.h"
#include "main.h"
#include "TSISensor.h"
#include "SDFileSystem.h"
#include "AS3935.h"

#define FW_VER  2

 // 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;
int day, month,year,hour,minute,seconds; 
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 distance=-1;
long energy=-1;

void DetectLightning()
{
    OriginInt = ld.interruptSource();
    distance = 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
    fprintf(fp,"%02d/%02d/20%02d,", gpsd.month, gpsd.day, gpsd.year);
    fprintf(fp,"%02d:%02d:%02d,", gpsd.hour, gpsd.minute, gpsd.seconds);  
    fprintf(fp,"%7.0f,",gpsd.timef);
    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: ");
    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);
            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);
}     



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;
    }
    
    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);
    
    ld.setOutdoors(); 
    ld.setMinimumLightnings(0);
    ld.setSpikeRejection(2);
    ld.setNoiseFloor(2);

    ld.enableDisturbers();
    ld.setWatchdogThreshold(4);
    IntLightning.rise(&DetectLightning);
    int MinBlysk = ld.getMinimumLightnings();
    int Noise = ld.getNoiseFloor();
    int TuneCap = ld.getTuneCap();
    int SpikeRej = ld.getSpikeRejection();
    int WatchDog = ld.getWatchdogThreshold();
     
    pc.printf("\r\n Min wylad: %i", MinBlysk);
    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
    //Mount the filesystem
    sd.mount();
    mkdir(directory, 0777);
    sd.unmount();

    // get a copy of all config registers
    ld.getConfigRegisters(regBuff, sizeof(regBuff));
   
    // write to the config file 
    writeCfgFile(regBuff, sizeof(regBuff), FW_VER); 
    
    bool gpsFix=false;
    while (1)
    {
        if (OriginInt != -1)
        {
            // the ld detector generated an interrupt, log the event
            IntLightning.disable_irq();
            writeLogFile(OriginInt,distance, energy);
            ld.clearStats();
            OriginInt = -1;
            distance = -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;   
            }    
        }
        
        // update globals with the lastest gps time stamp
        day=gpsd.day;
        month=gpsd.month;
        year=gpsd.year;
        hour=gpsd.hour;
        minute=gpsd.minute;
        seconds=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;
                    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            
    }
  
}