Bmag incl gps rettelse

Dependencies:   mbed WDT MODSERIAL BME280

main.cpp

Committer:
MAA
Date:
2017-04-07
Revision:
13:45b333983206
Parent:
12:2b46960a5d41
Child:
14:400ecb93c6a2

File content as of revision 13:45b333983206:

#include "main.h"

//change GPSACQTIMELIMITINSECONDS to change the duration in seconds, allowed for the gps to get gps fix. 
//After this duration, an error indication will occur if fix is not present.
#define GPSACQTIMELIMITINSECONDS 60 

//to change battery low indication change this value
#define BATTERYLOWLIMIT 10.5 

//change BARCODE string inside double quotes to barcode of BMAG equipment
char BARCODE[6] = "12345";


//Global GPS variables
bool GPS_Data_Rdy = false;
bool GPS_Data_Valid = false;
bool GGA_Fix_Present = false;
bool firstLineWritten = false;
bool fileNameUpdated = false;
bool lastErrStatus = true;
bool firstErrsWritten = false;
char tmpGpsRxString[128];
int missingGpsCnt = 0;
int GpsCntWithoutMagData = 0;
int magCntWithoutGpsData = 0;

string INTERPRETERID = "";
char interpreterTmpID[10];

//global system variables
bool run = true;
bool toggler = true;
int togglecount = 0;
bool magMissingPrompt = false;

//global BMAG variables
bool BMAG_Data_Rdy = false;
bool magTimeSetManually = false;
char tmpBMAGRxString[128];
char magnTarr[15];
int magTimePromptCount = 0;
int timeSetManuallyCount = 0;


//batteryvoltage
char batteryvoltagearr[5];
string batteryvoltage;

//Write to file prototype
bool writeToUsb(string line, FILE * f);

int main(void){
    
    //initializing watchdog, timeout 10 seconds
    Watchdog wd;
    wd.init(10.0);
    
    //Led outputs
    DigitalOut redLed(p24);
    DigitalOut greenLed(p23);
    
    //MagTime manually set by user input
    DigitalIn timeSetManuallyButton(p30);
    timeSetManuallyButton.mode(PullUp);
    
    redLed = 0;
    greenLed = 0; 
    
    //init of battery strings
    memset(batteryvoltagearr,'\0',5);
    batteryvoltage = "";   
    
    //Analog battery reading
    AnalogIn battery(A5);  

    string currentFilename, nextFilename; 
    
    currentFilename = "/usb/tempFile.sps";
    
    //Initializing string buffer for GPS data
    string GPS_String_Buff;
    GPS_String_Buff.resize(128);
    memset(tmpGpsRxString,'\0',128);
    
    //Initializing string buffer for BMAG data
    string BMAG_String_Buff;
    BMAG_String_Buff.resize(128);
    memset(tmpBMAGRxString,'\0',128);
    
    //debug comm setup
    dbg.baud(115200);
    dbg.printf("Init...\r\n");
    
    //setting up USB device
    USBHostMSD msd("usb");
    
    //USB message
    display.write_lines("Mounting", "USB pen");    
    wait_ms(1000);
    
    while(!msd.connect()){
        dbg.printf("Trying to connect to usb flash disk\r\n");
        wait_ms(500);      
    }
    
    //Opening a file on usb disk
    FILE * fp = fopen(currentFilename.c_str(), "a");
    wait_ms(100);
    
    //initializing SPS generation 
    SPS spsGen;
    
    //GPS communication init
    gps.baud(9600);
    gps.attach(&rxCallback, MODSERIAL::RxIrq);
    
    //GPS message    
    display.write_lines("GPS", "Startup"); 
    
    //BMAG communication init
    bmag.baud(115200);
    bmag.attach(&bmagrxCallback, MODSERIAL::RxIrq);
    
    //Start comms with the GPS, Enabling GPRMC and  GPGGA
    gps.printf("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n");   
    
    dbg.printf("Init.... Done!\r\n");
 
    //init interpreterid
    int barcodeint = atoi(BARCODE);
    memset(interpreterTmpID,'\0',10);
    sprintf(interpreterTmpID,"%4x", barcodeint);
    INTERPRETERID.assign(interpreterTmpID);
    
    //Init Done!
    display.clear_display();  
    display.write_lines("Init", "Done");
    
    //Init errorhandler
    ErrorHandler dispTxtHandler(&batteryvoltage, &GGA_Fix_Present, &magParser);
    dispTxtHandler.setErrorState(NONE); 
            
    //infinite loop running after initialization
    while(run) {
        
        //if the gps rx buffer is full, flush the buffer
        if(gps.rxBufferFull()){
            gps.rxBufferFlush();    
        }
        
        if(bmag.rxBufferFull()){
            bmag.rxBufferFlush();    
        }
        
        if((0.00036621652)*battery.read_u16() < BATTERYLOWLIMIT){
            dispTxtHandler.setErrorState(BATTERY_LOW);
            redLed = 1;
            greenLed = 0;    
        }
        
        if(BMAG_Data_Rdy){
            
            //if mag data is present but gps data is not
            if(magCntWithoutGpsData < 100){
                magCntWithoutGpsData += 1;
            }
            
            magMissingPrompt = false;
            
            bmag.move(tmpBMAGRxString, bmag.rxBufferGetCount());            
                      
            //copy c_string to string
            BMAG_String_Buff.assign(tmpBMAGRxString); 
                         
            //clear tmpRxBuffer
            memset(tmpBMAGRxString,'\0',128); 
            
            magParser.parseBMAGString(BMAG_String_Buff); 
            
            GpsCntWithoutMagData = 0;
            
            //update filename when date is available with gga fix
            if(!fileNameUpdated && GGA_Fix_Present){
                spsGen.generateSpsFilename(gpsNMEA.currentDATEFromGPRMC);
                nextFilename.assign(spsGen.getSpsFileName());
                fclose(fp);
                currentFilename.assign(nextFilename);
                nextFilename = "";
                
                fopen(currentFilename.c_str(), "a");
                
                fileNameUpdated = true;
                
                //add header to top of file                
                writeToUsb(spsGen.getHeaderString(), fp);                            
                                                    
            }             
            
            //if date has changed, ensure new file creation.
            spsGen.generateSpsFilename(gpsNMEA.currentDATEFromGPRMC);
            if(currentFilename != spsGen.getSpsFileName()){
                fileNameUpdated = false;            
            }  
            
            //read battery voltage
            sprintf(batteryvoltagearr, "%0.1f",(0.00036621652)*battery.read_u16());
            batteryvoltage.assign(batteryvoltagearr);
            
            if((toggler && (missingGpsCnt < GPSACQTIMELIMITINSECONDS)) || (toggler && dispTxtHandler.getMagTimePromtStatus())){
                //show battery voltage and gps fix status for 10 mag reading cycles                
                dispTxtHandler.setErrorState(DISPLAY_VBAT_FIX);
                                
                togglecount += 1;
                if(togglecount >= 10){
                    toggler = false;
                    togglecount = 0;    
                }
                          
            }
            
            if((!toggler && missingGpsCnt < GPSACQTIMELIMITINSECONDS) || (!toggler && dispTxtHandler.getMagTimePromtStatus())){                
                //show magnT reading for 10 mag reading cycles
                dispTxtHandler.setErrorState(DISPLAY_MAG_MEASUREMENT);
                
                togglecount += 1;
                if(togglecount >= 10){
                    toggler = true;
                    togglecount = 0;    
                }
            }

            
            //if gga fix is not present for a prolonged period of time, prompt user
            if((missingGpsCnt > GPSACQTIMELIMITINSECONDS) && !dispTxtHandler.getMagTimePromtStatus()){
        
                //Prompt user to set mag time manually
                dispTxtHandler.setErrorState(NO_FIX);
            }
            
            
            //if gps data is missing for more than 60 mag reading cycles
            if(magCntWithoutGpsData > 60){
                //show error indication of gps data missing
                dispTxtHandler.setErrorState(NO_GPS);
                                
                //set led error status
                redLed = 1;
                greenLed = 0;
            }
            
            //generate default sps string
            spsGen.UpdateCurrentString(TAG, IDENTIFIERID, GROUP, gpsNMEA.currentDATEFromGPRMC, gpsNMEA.currentUTCFromGPRMC, TIMEZONE, ENCODING, SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION, BARCODE,gpsNMEA.currentLatitude, gpsNMEA.currentLongitude, GGA_Fix_Present, batteryvoltage, magParser.getMagTimeStr(), magParser.getMagNTStr(), magParser.getMagSq(), &dbg);
            
            //write data strings to sps file
            if(GGA_Fix_Present){
                    
                missingGpsCnt = 0;
           
                if(!firstLineWritten){ 
                    writeToUsb(spsGen.getHeaderString(), fp);
                    firstLineWritten = true;    
                }                                   
                     
                writeToUsb(spsGen.getCurrentString(), fp);
                
                if(!lastErrStatus && firstErrsWritten){
                    spsGen.UpdateCurrentErrString("ERRE", IDENTIFIERID, GROUP, gpsNMEA.currentDATEFromGPRMC, gpsNMEA.currentUTCFromGPRMC, TIMEZONE, ENCODING, SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION, gpsNMEA.currentLatitude, gpsNMEA.currentLongitude, GGA_Fix_Present, magParser.getMagTimeStr(), magParser.getMagNTStr(), magParser.getMagSq(), &dbg);                
                    writeToUsb(spsGen.getCurrentErrString(), fp);
                    lastErrStatus = true;
                    firstErrsWritten = false;
                    firstLineWritten = false;    
                }
            }
                
            if(!GGA_Fix_Present){
                
                if(missingGpsCnt <=  GPSACQTIMELIMITINSECONDS){        
                    missingGpsCnt += 1;
                }    
                
                if(!firstLineWritten){ 
                    writeToUsb(spsGen.getHeaderString(), fp);
                    firstLineWritten = true;    
                }
                
                writeToUsb(spsGen.getCurrentString(), fp);  
                    
                if(lastErrStatus && !firstErrsWritten){
                    spsGen.UpdateCurrentErrString("ERRS", IDENTIFIERID, GROUP, gpsNMEA.currentDATEFromGPRMC, gpsNMEA.currentUTCFromGPRMC, TIMEZONE, ENCODING, SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION, gpsNMEA.currentLatitude, gpsNMEA.currentLongitude, GGA_Fix_Present, magParser.getMagTimeStr(), magParser.getMagNTStr(), magParser.getMagSq(), &dbg);                
                    writeToUsb(spsGen.getCurrentErrString(), fp);
                    lastErrStatus = false;
                    firstErrsWritten = true;   
                }     
                    
            }
            
            //if user has been notified of time settings needed on bmag, pushbutton can be held for a few cycles to circumvent the set mag time display prompt.
            if(!timeSetManuallyButton && dispTxtHandler.getMagTimePromtStatus()){  
                timeSetManuallyCount += 1;
                
                if(timeSetManuallyCount > 3){
                    magTimeSetManually = true;  
                }                
            }    

            //show message on display
            display.clear_display();                
            display.write_lines(dispTxtHandler.getLine1(), dispTxtHandler.getLine2());
            
            BMAG_Data_Rdy = false;    
        }
        
        if(GpsCntWithoutMagData > 20 && !magMissingPrompt){
                
                //show error if mag data not present
                dispTxtHandler.setErrorState(NO_MAG_DATA);
                display.clear_display(); 
                display.write_lines(dispTxtHandler.getLine1(), dispTxtHandler.getLine2()); 
                redLed = 1;
                greenLed = 0;
                magMissingPrompt = true;        
        }
        

        
        if(GPS_Data_Rdy){
            
            //clear mag data string counter, counting mag data received since last gps string received
            magCntWithoutGpsData = 0;
            
            //if gps data has been received without mag data since last gps string, increment counter.
            if(GpsCntWithoutMagData < 200){
                
                GpsCntWithoutMagData += 1;
                
            }
                                 
            gps.scanf("%s", &tmpGpsRxString);
            
            //copy c_string to string
            GPS_String_Buff.assign(tmpGpsRxString);
            
            //clear tmpRxBuffer
            memset(tmpGpsRxString,'\0',128);
            
            //printing GPS string buffer
            dbg.printf(GPS_String_Buff.c_str());
            dbg.printf("\r\n");
 
            //Validate CRC
            GPS_Data_Valid = gpsNMEA.ValidateData(GPS_String_Buff);
         
            //store valid string, either gga or rmc
            if(GPS_Data_Valid){
                 gpsNMEA.StoreString(GPS_String_Buff/*, &dbg*/);   
            }
            
            //Get gga fix flag
            GGA_Fix_Present = gpsNMEA.GGAFixVerification();
            
            //Assign value to error flag
            spsGen.setErrStatus(GGA_Fix_Present);  
            
            //Clearing RX buffer.
            GPS_String_Buff = "";
            GPS_String_Buff.resize(128);
            
            //parse current date 
            gpsNMEA.ParseCurrentDateFromGPRMC();
            
            //parse current time
            gpsNMEA.ParseCurrentUTCFromGPRMC();
            
            //parse gps coordinates
            gpsNMEA.ParseCurrentLatitudeFromGPRMC();
            gpsNMEA.ParseCurrentLongitudeFromGPRMC();
            
            //clearing flags
            GPS_Data_Valid = false;
            GPS_Data_Rdy = false;     
                
            if(!GGA_Fix_Present && GpsCntWithoutMagData < 20){
                //Missing GGA fix LED indicator
                greenLed = 0;
                redLed = 1;
            }
            
            
            if((GGA_Fix_Present && GpsCntWithoutMagData < 20) || (magTimeSetManually && GpsCntWithoutMagData < 20)){
                //GGA fix LED indicator / time set manually unless battery is low
                if(getErrorState() != BATTERY_LOW){
                    greenLed = 1;
                    redLed = 0;                    
                }     
            }                      
            
                
        }   

        //If connection to USB flash disk is lost, reconnect to the flash disk
        if(!msd.connected()){
            
            //USB message
            display.clear_display(); 
            display.write_lines("USB pen", "Missing!");
            
            //reestablish usb connection
            while(!msd.connect()){
                dbg.printf("Trying to reconnect to usb flash disk\r\n");
                wait_ms(200);
                msd.connect();
            }
                
            //Reopening a file on usb disk
            fp = fopen(currentFilename.c_str(), "a");
            
            writeToUsb("\r\n", fp);
            writeToUsb(spsGen.getHeaderString(), fp);
                        
        }
        
    
        //kick / feed watchdog 
        wd.kick();
    
    }    
   
    return 0;    
}

//Thanks to MODSERIAL!
// Called everytime a new character goes into
// the RX buffer. Test that character for \n
// Note, rxGetLastChar() gets the last char that
// we received but it does NOT remove it from
// the RX buffer. 
void rxCallback(MODSERIAL_IRQ_INFO *q) {
    MODSERIAL *serial = q->serial;
    if (serial->rxGetLastChar() == '\n') {
        GPS_Data_Rdy = true;
    }
}

//Thanks to MODSERIAL!
// Called everytime a new character goes into
// the RX buffer. Test that character for \r and buffer char count
// Note, rxGetLastChar() gets the last char that
// we received but it does NOT remove it from
// the RX buffer. 
void bmagrxCallback(MODSERIAL_IRQ_INFO *q) {
    MODSERIAL *serial = q->serial;
    if ((serial->rxBufferGetCount() > 20) && (serial->rxGetLastChar() == '\r')) {
        BMAG_Data_Rdy = true;
    }
}

//Write to file
bool writeToUsb(string line, FILE * f){

    if (f != NULL) {
        
        fprintf(f, "\r\n");
        fprintf(f, line.c_str());  
              
    }
                 
    if(f == NULL){
        return false;
    }
    
    return true;      
}