Bmag incl gps rettelse

Dependencies:   mbed WDT MODSERIAL BME280

main.cpp

Committer:
gert_lauritsen
Date:
2019-06-20
Revision:
56:df9052e3808c
Parent:
26:68277a308839

File content as of revision 56:df9052e3808c:

#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] = "09999";
int barcodeint;

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

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

//global system variables
bool run = true;
bool toggler = true;
bool dispFlag = false;
bool checkStateFlag = false;
int togglecount = 0;
ErrorState prevState = NONE;
ErrorState presentState = NONE;



//global BMAG variables
bool BMAG_Data_Rdy = false;
bool magTimeSetManually = false;
bool magStringsReceived = 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);

//dispflag func
void setDispFlag(void){
    dispFlag = true;        
}

//set check state flag func
void setCheckStateFlag(void){
    checkStateFlag = true;    
}

void GetSerialNumber() {
   LocalFileSystem local("local");
   FILE *fp = fopen("/local/Serial.txt", "r");
   if (fp!=NULL) { //Hvis filen er der læs den,
        fscanf(fp,"%d",&barcodeint);
        fclose(fp);
        sprintf(BARCODE,"%06d",barcodeint);
        dbg.printf("New Barcode %s\r\n",BARCODE);
   }
   else dbg.printf("NO Barcode. make file serial.txt\r\n");      
}    

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
    GetSerialNumber();
    //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);
    dispTxtHandler.setErrorState(NONE);
    
    //init of display timer
    Ticker dispTicker;
    dispTicker.attach(&setDispFlag, 1.01);
    
    //init of state ticker
    Ticker stateTicker;
    stateTicker.attach(&setCheckStateFlag, 1.0);
    
      
    //infinite loop running after initialization
    while(run) {
        
        //display txt on disp
        if(dispFlag){
            //get state to be displayed
            presentState = dispTxtHandler.getErrorState();
            //ensure that display is only cleared if the state to be displayed has changed.
            //this ensures that a minimum time duration is used to clear the display.
            if(presentState != prevState){
                display.clear_display();    
            }
            //Ensure that next check will have the current state as previous state, as expected.
            prevState = presentState;
            
            //write text to display
            display.write_lines(dispTxtHandler.getLine1(), dispTxtHandler.getLine2());
            
            //clear display flag
            dispFlag = false;    
        }
        
        //check state / set state
        if(checkStateFlag){
            
            //missingGpsConnectionCounter gets cleared at every received gps string
            if(!GPS_Override_Active && missingGpsConnectionCounter < 10){
                
                missingGpsConnectionCounter += 1;
            }
            
            if(gpsOverridePushButtonCounter > 3){
                GPS_Override_Active = true;        
            }
            
                                        
            //pushbutton check gpsOverridePushButtonCounter
            if(!timeSetManuallyButton){
                gpsOverridePushButtonCounter += 1;        
            }
            
            if(missingGpsConnectionCounter > 30 && !GPS_Override_Active){
                dispTxtHandler.setErrorState(GPS_OVERRIDE_NEEDED);
                
                redLed = 1;
                greenLed = 0; 
                                
            }
            
            if((toggler && magStringsReceived &&(missingGpsCnt < GPSACQTIMELIMITINSECONDS)) || (toggler && dispTxtHandler.getMagTimePromtStatus()) && magStringsReceived) {
                //show battery voltage and gps fix status for 10 seconds
                dispTxtHandler.setErrorState(DISPLAY_VBAT_FIX);
    
                togglecount += 1;
                if(togglecount >= 10) {
                    toggler = false;
                    togglecount = 0;
                }
    
            }
    
            if((!toggler && (missingGpsCnt < GPSACQTIMELIMITINSECONDS) && magStringsReceived) || (!toggler && dispTxtHandler.getMagTimePromtStatus()) && magStringsReceived) {
                //show magnT reading for 10 seconds
                dispTxtHandler.setErrorState(DISPLAY_MAG_MEASUREMENT);
    
                togglecount += 1;
                if(togglecount >= 10) {
                    toggler = true;
                    togglecount = 0;
                }
            }
            
            
            //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 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 10 mag reading cycles
            if((magCntWithoutGpsData > 10) && !magTimeSetManually) {
                //show error indication of gps data missing
                dispTxtHandler.setErrorState(NO_GPS);

                //set led error status
                redLed = 1;
                greenLed = 0;
                
                GGA_Fix_Present = false;
                
                //knaptryk check 
                if(!timeSetManuallyButton){
                    timeSetManuallyCount += 1;        
                }
                
                if(timeSetManuallyCount > 3){
                    magTimeSetManually = true;         
                }
                     
            }                        
            
                
            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;                    
                }     
            }    
                        
            checkStateFlag = false;    
        }
        
        //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 bmag data string is available
        if(BMAG_Data_Rdy) {
            
            //change magStringsReceived flag to true when mag data is available
            if(magStringsReceived == false){
                magStringsReceived = true;    
            }
            
            //if gps override is active reset magCntWithoutGpsData
            if(GPS_Override_Active){
                magCntWithoutGpsData = 0;    
            }
            
            //if mag data is present but gps data is not and gps override is not active
            if(magCntWithoutGpsData < 100 && !GPS_Override_Active) {
                magCntWithoutGpsData += 1;
            }
            
            //move bmag data from rxbuffer to temporary array
            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;
                
                spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
                //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);

            //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) {
                    spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
                    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) {
                    spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
                    writeToUsb(spsGen.getHeaderString(), fp);
                    firstLineWritten = true;
                }

                if(firstErrsWritten){
                    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;
                }
            }


            BMAG_Data_Rdy = false;
        }
     
        
        if(GPS_Data_Rdy){
            
            missingGpsConnectionCounter = 0;
            
            if(gpsStringsReceived == false){
                gpsStringsReceived = true;    
            }
            
            //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);
            
            //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 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;      
}