Bmag incl gps rettelse

Dependencies:   mbed WDT MODSERIAL BME280

main.cpp

Committer:
MAA
Date:
2017-05-15
Revision:
22:9f5955f051f5
Parent:
21:325cb82f1838
Child:
23:2e914b705b99

File content as of revision 22:9f5955f051f5:

#include "main.h"

//please note that mbed library should be of revision 137 or before.

//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 120 

//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] = "06655";


//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;


//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, &gpsNMEA);
            
    //infinite loop running after initialization
    while(run) {
        
        //if the gps rx buffer is full, flush the buffer
        if(gps.rxBufferFull()){
            gps.rxBufferFlush();    
        }
        
        //if the bmag rx buffer is full, flush the buffer
        if(bmag.rxBufferFull()){
            bmag.rxBufferFlush();    
        }
        
        //if battery voltage is below BATTERYLOW limit, initiate battery low error state
        if((0.00036621652)*battery.read_u16() < BATTERYLOWLIMIT){
            dispTxtHandler.setErrorState(BATTERY_LOW);
            redLed = 1;
            greenLed = 0;    
        }
        
        //if bmag data string is available
        if(BMAG_Data_Rdy) {
            
            dbg.printf("GGA_Fix_Present val: %d\r\n", GGA_Fix_Present);
            
            //if mag data is present but gps data is not
            if(magCntWithoutGpsData < 100) {
                magCntWithoutGpsData += 1;
            }

            bmag.move(tmpBMAGRxString, bmag.rxBufferGetCount());

            //copy c_string to string
            BMAG_String_Buff.assign(tmpBMAGRxString);

            //clear tmpRxBuffer
            memset(tmpBMAGRxString,'\0',128);

            //parse bmag string
            magParser.parseBMAGString(BMAG_String_Buff);


            //reset counter containing gps string count without mag data
            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;
                }
            }

            //write data strings to sps file, with error messages as defined in *.sps definition
            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(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;
                
                display.clear_display(); 
                display.write_lines(dispTxtHandler.getLine1(), dispTxtHandler.getLine2());
                
            }
            
                                 
            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();
            
                 
                
            if(!GGA_Fix_Present && GpsCntWithoutMagData < 20){
                //Missing GGA fix LED indicator
                greenLed = 0;
                redLed = 1;
            }
            
            if(GpsCntWithoutMagData > 20){
                //Missing MAG data prompt
                dispTxtHandler.setErrorState(NO_MAG_DATA);
                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(dispTxtHandler.getErrorState() != BATTERY_LOW){
                    greenLed = 1;
                    redLed = 0;                    
                }     
            }                        
            
            
            //clearing flags
            GPS_Data_Valid = false;
            GPS_Data_Rdy = false;
                
        }
  

        //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;      
}