Bmag incl gps rettelse

Dependencies:   mbed WDT MODSERIAL BME280

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "main.h"
00002 
00003 //please note that mbed library should be of revision 137 or before.
00004 
00005 //change GPSACQTIMELIMITINSECONDS to change the duration in seconds, allowed for the gps to get gps fix. 
00006 //After this duration, an error indication will occur if fix is not present.
00007 #define GPSACQTIMELIMITINSECONDS 120 
00008 
00009 //to change battery low indication change this value
00010 #define BATTERYLOWLIMIT 10.5 
00011 
00012 //change BARCODE string inside double quotes to barcode of BMAG equipment
00013 char BARCODE[6] = "05020";
00014 int barcodeint; 
00015 
00016 //Global GPS variables
00017 Timer t;
00018 bool ppsTick = false;
00019 
00020 char tmpHour[5];
00021 char tmpMinute[5];
00022 char tmpSecond[5];
00023 char time_buffer[32];
00024 char bytesInBuffer[4];
00025 bool RTC_set = false;
00026 bool GPS_Data_Rdy = false;
00027 bool GPS_Data_Valid = false;
00028 bool GPS_Override_Active = false;
00029 bool GGA_Fix_Present = false;
00030 bool firstLineWritten = false;
00031 bool fileNameUpdated = false;
00032 bool lastErrStatus = true;
00033 bool firstErrsWritten = false;
00034 bool gpsStringsReceived = false;
00035 bool dateChanged = true;
00036 char tmpGpsRxString[128];
00037 char timer_ms[5];
00038 int secCount = 0;
00039 int missingGpsCnt = 0;
00040 int GpsCntWithoutMagData = 0;
00041 int magCntWithoutGpsData = 0;
00042 char missingGpsConnectionCounter = 0;
00043 char gpsOverridePushButtonCounter = 0;
00044 int seconds;
00045 int minutes;
00046 int hours;
00047 char timeArr[10]; 
00048 string timeStr;
00049 string dateBeforeChange = "";
00050 
00051 string INTERPRETERID = "";
00052 char interpreterTmpID[10];
00053 
00054 //global system variables
00055 bool detachMag = false;
00056 bool tickerUpdated = false;
00057 bool gpsRunning = false;
00058 bool gpsCheckedAfter10Sec = false;
00059 bool run = true;
00060 bool toggler = true;
00061 bool dispFlag = false;
00062 bool checkStateFlag = false;
00063 char flushStr[200];
00064 int togglecount = 0;
00065 int fixPresentCnt = 0;
00066 ErrorState prevState = NONE;
00067 ErrorState presentState = NONE;
00068 
00069 //global BMAG variables
00070 string lastUTCTimestamp;
00071 bool BMAG_Data_Rdy = false;
00072 bool magTimeSetManually = false;
00073 bool magStringsReceived = false;
00074 char tmpBMAGRxString[128];
00075 char magnTarr[15];
00076 int magTimePromptCount = 0;
00077 int timeSetManuallyCount = 0;
00078 int tmpTime = 0;
00079 char tmpChar1[5];
00080 char tmpChar2[5];
00081 int lastGPRMC_CNT = 0;
00082 int timeDiffInt = 0;
00083 int timeDiffStrLen = 0;
00084 
00085 //PTH vars
00086 void getPthValues();
00087 bool PTHValuesReadyFlag = false;
00088 bool PTHSensorActive = false;
00089 float PTH_Preassure = 0;
00090 float PTH_Temperature = 0;
00091 float PTH_Humidity = 0;
00092 char PreassureArr[10] = "";
00093 char TemperatureArr[10] = "";
00094 char HumidityArr[10] = "";
00095 
00096 //batteryvoltage
00097 char batteryvoltagearr[5];
00098 string batteryvoltage;
00099 
00100 //time
00101 time_t t_of_day;
00102 
00103 //Write to file prototype
00104 bool writeToUsb(string line, FILE * f);
00105 
00106 //Gps available check prototype
00107 void gpsAvailCheck(void);
00108 
00109 
00110 //epoch time conversion
00111 time_t setMbedTime(string GPRMCDate, string GPRMCUtc, Serial * debug){
00112     
00113     char tmpYear[6];
00114     char tmpMonth[5];
00115     char tmpDay[5];
00116     char tmpHour[5];
00117     char tmpMinute[5];
00118     char tmpSecond[5];
00119     
00120     struct tm str_time;
00121     
00122     memset(tmpYear,'\0',6);
00123     memset(tmpMonth,'\0',5);
00124     memset(tmpDay,'\0',5);
00125     memset(tmpHour,'\0',5);
00126     memset(tmpMinute,'\0',5);
00127     memset(tmpSecond,'\0',5);    
00128     
00129     snprintf(tmpYear, 6, "%s", GPRMCDate.substr(0, 4));
00130     snprintf(tmpMonth, 5, "%s", GPRMCDate.substr(5, 2));
00131     snprintf(tmpDay, 5, "%s", GPRMCDate.substr(8, 2));
00132     
00133     snprintf(tmpHour, 5, "%s", GPRMCUtc.substr(0, 2));
00134     snprintf(tmpMinute, 5, "%s", GPRMCUtc.substr(3, 2));
00135     snprintf(tmpSecond, 5, "%s", GPRMCUtc.substr(6, 2));
00136 
00137     str_time.tm_year = atoi(tmpYear) - 1900;
00138     str_time.tm_mon = atoi(tmpMonth) - 1;           // Month, 0 - jan
00139     str_time.tm_mday = atoi(tmpDay);          // Day of the month
00140     str_time.tm_hour = atoi(tmpHour);
00141     str_time.tm_min = atoi(tmpMinute);
00142     str_time.tm_sec = atoi(tmpSecond)+2;
00143     str_time.tm_isdst = 0;        // Is DST on? 1 = yes, 0 = no, -1 = unknown
00144     t_of_day = mktime(&str_time);
00145     
00146     debug->printf("-------------------------------\r\n");
00147     debug->printf("Setting time as seen below:\r\n");
00148     debug->printf("Year: %s\r\n", tmpYear);
00149     debug->printf("Month: %s\r\n", tmpMonth);
00150     debug->printf("Day: %s\r\n", tmpDay);
00151     debug->printf("Hour: %s\r\n", tmpHour);
00152     debug->printf("Minute: %s\r\n", tmpMinute);
00153     debug->printf("Second: %s\r\n", tmpSecond);
00154     debug->printf("-------------------------------\r\n");
00155     debug->printf("time since epoch in seconds:");
00156     debug->printf("%d", (unsigned long)t_of_day);
00157     debug->printf("\r\n");
00158     debug->printf("-------------------------------\r\n");
00159     
00160     set_time((unsigned long)t_of_day);
00161 
00162     RTC_set = true;
00163     
00164     
00165     return t_of_day;        
00166 }
00167 
00168 
00169 //dispflag func
00170 void setDispFlag(void){
00171     dispFlag = true;        
00172 }
00173 
00174 //set check state flag func
00175 void setCheckStateFlag(void){
00176     checkStateFlag = true;    
00177 }
00178 
00179 //set time variables
00180 void setTime(int s, int m, int h){
00181     seconds = s;
00182     minutes = m;
00183     hours = h;    
00184 }
00185 
00186 //get time
00187 string getTime(void){
00188     memset(timeArr, '\0', 10);
00189     snprintf(timeArr, 10, "%.2d:%.2d:%.2d", hours, minutes, seconds);
00190     timeStr = timeArr;
00191     return timeStr;    
00192 }
00193 
00194 //pps tick
00195 void pps_Tick(){
00196     seconds += 1;
00197     if(seconds == 60){
00198         minutes += 1;
00199         seconds = 0;    
00200     }
00201     if(minutes == 60){
00202         hours += 1;
00203         minutes = 0; 
00204     }
00205     if(hours == 24){
00206         hours = 0;
00207     }
00208     
00209     //ensure date change in sps file at midnight
00210     if(hours == 00 && minutes == 00 && seconds == 00){
00211         dateChanged = false;    
00212     }
00213 } 
00214 
00215 //timer reset // clock update
00216 void resetTimer(void){
00217     t.reset();  
00218     pps_Tick();
00219 }
00220 
00221 //test without mag data
00222 void testMagWithoutMag(void){
00223     ///used for test of date change
00224     BMAG_Data_Rdy = true;
00225      ///    
00226 }
00227 
00228 //bmag interrupt enable
00229 void bmagSerialInterruptEnable(void){        
00230     //BMAG communication init
00231     bmag.baud(115200);
00232     bmag.attach(&bmagrxCallback, MODSERIAL::RxIrq);
00233     detachMag = true;       
00234 }
00235 
00236 void GetSerialNumber() {
00237    LocalFileSystem local("local");
00238    FILE *fp = fopen("/local/Serial.txt", "r");
00239    if (fp!=NULL) { //Hvis filen er der læs den,
00240         fscanf(fp,"%d",&barcodeint);
00241         fclose(fp);
00242         sprintf(BARCODE,"%05d",barcodeint);
00243         dbg.printf("New Barcode %s\r\n",BARCODE);
00244    }
00245    else dbg.printf("NO Barcode. make file serial.txt\r\n");      
00246 }
00247 
00248 int main(void){
00249     //init pps timing variables
00250     seconds = 0;
00251     minutes = 0;
00252     hours = 0;
00253     memset(timeArr, '\0', 10);
00254     memset(flushStr,'\0',200);
00255     
00256     //init pth char arrays
00257     memset(PreassureArr,'\0',10);
00258     memset(TemperatureArr,'\0',10);
00259     memset(HumidityArr,'\0',10);
00260     memset(timer_ms,'\0',5);
00261     memset(time_buffer,'\0',32);    
00262     
00263     t.start();
00264     
00265     EA_OLED();
00266     
00267     //initializing watchdog, timeout 5 seconds
00268     Watchdog wd;
00269     wd.init(5.0);
00270     
00271     //PPS
00272     InterruptIn PPS(p12);  
00273     PPS.rise(&resetTimer);
00274       
00275     //Led outputs
00276     DigitalOut redLed(p25);
00277     DigitalOut greenLed(p23);
00278     
00279     //MagTime manually set by user input
00280     DigitalIn timeSetManuallyButton(p30);
00281     timeSetManuallyButton.mode(PullUp);
00282     
00283     redLed = 0;
00284     greenLed = 0; 
00285     
00286     //init of battery string
00287     memset(batteryvoltagearr,'\0',5);
00288     batteryvoltage = "";   
00289     
00290     //Analog battery reading
00291     AnalogIn battery(A5);  
00292 
00293     string currentFilename, nextFilename; 
00294     
00295     currentFilename = "/usb/tempFile.sps";
00296     
00297     //Initializing string buffer for GPS data
00298     string GPS_String_Buff;
00299     GPS_String_Buff.resize(128);
00300     memset(tmpGpsRxString,'\0',128);
00301     
00302     //Initializing string buffer for BMAG data
00303     string BMAG_String_Buff;
00304     BMAG_String_Buff.resize(128);
00305     memset(tmpBMAGRxString,'\0',128);
00306     
00307     //debug comm setup
00308     dbg.baud(115200);
00309     dbg.printf("Init...\r\n");
00310 
00311     //bme pth sensor init 
00312     if(!BME.init(BME280_i2c, 0x77)){
00313         dbg.printf("BME280 init failed!\r\n");
00314             
00315     }
00316     if(!BME.start()){
00317         dbg.printf("BME280 start failed!\r\n"); 
00318     }
00319     
00320     if(BME.is_ok()){
00321         PTHSensorActive = true;    
00322     }
00323 
00324     //setting up USB device
00325     USBHostMSD msd("usb");
00326     
00327     clear_display_waiting(); 
00328     
00329     //USB message
00330     l1 = "Mounting";
00331     l2 = "USB pen";
00332     thr_writelines.start(write_lines);    
00333     wait_ms(1000);    
00334     
00335     while(!msd.connect()){
00336         dbg.printf("Trying to connect to usb flash disk\r\n");
00337         wait_ms(500);      
00338     }
00339     
00340     //Opening a file on usb disk
00341     FILE * fp;
00342     FILE * e_fp;
00343     fp = fopen(currentFilename.c_str(), "a");
00344     e_fp = fopen("Errorlog.txt", "a");
00345     wait_ms(100);
00346     
00347     //initializing SPS generation 
00348     SPS spsGen;
00349     
00350     //GPS communication init
00351     gps.baud(9600);
00352     gps.attach(&rxCallback, MODSERIAL::RxIrq);
00353         
00354     clear_display_waiting();
00355     
00356     //GPS message
00357     l1 = "GPS";
00358     l2 = "Startup";    
00359     thr_writelines.start(write_lines);
00360     wait_ms(1000); 
00361     
00362     dbg.printf("Init.... Done!\r\n");
00363  
00364     //init interpreterid
00365     GetSerialNumber();
00366     memset(interpreterTmpID,'\0',10);
00367     sprintf(interpreterTmpID,"%4x", barcodeint);
00368     INTERPRETERID.assign(interpreterTmpID); 
00369     
00370     //Init Done!
00371     clear_display_waiting();
00372     l1 = "Init";
00373     l2 = "Done";  
00374     thr_writelines.start(write_lines);
00375     wait_ms(1000);
00376     
00377     //Init errorhandler
00378     ErrorHandler dispTxtHandler(&batteryvoltage, &GGA_Fix_Present, &magParser, &gpsNMEA);
00379     dispTxtHandler.setErrorState(NONE);
00380     
00381     //init of display timer
00382     Ticker dispTicker;
00383     dispTicker.attach(&setDispFlag, 1.0);
00384     
00385     //init of state ticker
00386     Ticker stateTicker;
00387     stateTicker.attach(&setCheckStateFlag, 1.0);
00388     
00389     //init ticker for bmag interrupt enable timing
00390     Ticker magTicker;
00391     magTicker.attach(&bmagSerialInterruptEnable, 30.0);
00392     
00393     //BME280 pth ticker
00394     Ticker PTHTicker;
00395     PTHTicker.attach(&getPthValues, 11.0);
00396     
00397     //gps available ticker
00398     Ticker gpsAvailableTicker;
00399     gpsAvailableTicker.attach(gpsAvailCheck, 10.0);
00400     
00401     //test ticker emulating mag data 1Hz
00402     Ticker TestMagTicker;
00403     
00404     
00405     //clock freqency info
00406     dbg.printf("SystemCoreClock = %d Hz\r\n", SystemCoreClock);
00407       
00408     snprintf(PreassureArr, 10, "%s", "NaN");
00409     snprintf(TemperatureArr, 10, "%s", "NaN");
00410     snprintf(HumidityArr, 10, "%s", "NaN");
00411       
00412     //infinite loop running after initialization
00413     while(run) {
00414         
00415         //disable continuous magtick detach
00416         if(detachMag){
00417             magTicker.detach();
00418             detachMag = false;           
00419             //for test without mag data
00420             //TestMagTicker.attach(testMagWithoutMag, 1.0); //remember to comment this line when using a mag
00421                 
00422         }
00423         
00424         //display txt on disp
00425         if(dispFlag){
00426             
00427             //get state to be displayed
00428             presentState = dispTxtHandler.getErrorState();
00429             //ensure that display is only cleared if the state to be displayed has changed.
00430             //this ensures that a minimum time duration is used to clear the display.
00431             
00432             //thr_writelines.start(clear_display);                    
00433             
00434 
00435             //update display text
00436             l1 = dispTxtHandler.getLine1();
00437             l2 = dispTxtHandler.getLine2(); 
00438             
00439             
00440             thr_writelines.start(write_lines);
00441             
00442                         
00443             //Ensure that next check will have the current state as previous state, as expected.
00444             prevState = presentState;
00445             
00446             //clear display flag
00447             dispFlag = false;    
00448         }
00449         
00450         //check state / set state
00451         if(checkStateFlag){
00452             
00453             
00454             //inform of missing GPS
00455             if(gpsCheckedAfter10Sec && !gpsRunning){
00456                 dispTxtHandler.setErrorState(NO_GPS);            
00457             }
00458             
00459             if(gpsCheckedAfter10Sec){
00460                 
00461                 if(gpsRunning){
00462                     gpsAvailableTicker.detach();
00463                 }
00464                 
00465                 if(!PTHSensorActive){
00466                     //bme pth sensor init 
00467                     if(!BME.init(BME280_i2c, 0x77)){
00468                         dbg.printf("BME280 init failed!\r\n");       
00469                     }
00470                     if(!BME.start()){
00471                         dbg.printf("BME280 start failed!\r\n"); 
00472                     }
00473                     
00474                     if(BME.is_ok()){
00475                         PTHSensorActive = true;    
00476                     }
00477                 }
00478                                 
00479                 gpsCheckedAfter10Sec = false;                  
00480             }
00481             
00482             //missingGpsConnectionCounter gets cleared at every received gps string
00483             if(!GPS_Override_Active && missingGpsConnectionCounter < 10){
00484                 
00485                 missingGpsConnectionCounter += 1;
00486             }
00487             
00488             if(gpsOverridePushButtonCounter > 1){
00489                 GPS_Override_Active = true;        
00490             }
00491             
00492                                         
00493             //pushbutton check gpsOverridePushButtonCounter
00494             if(!timeSetManuallyButton){
00495                 gpsOverridePushButtonCounter += 1;        
00496             }
00497             
00498             if(missingGpsConnectionCounter > 30 && !GPS_Override_Active){
00499                 dispTxtHandler.setErrorState(GPS_OVERRIDE_NEEDED);
00500                 
00501                 redLed = 1;
00502                 greenLed = 0; 
00503                                 
00504             }
00505             
00506             if((toggler && magStringsReceived &&(missingGpsCnt < GPSACQTIMELIMITINSECONDS)) || (toggler && dispTxtHandler.getMagTimePromtStatus()) && magStringsReceived) {
00507                 //show battery voltage and gps fix status for 10 seconds
00508                 dispTxtHandler.setErrorState(DISPLAY_VBAT_FIX);
00509                 
00510                 if(!tickerUpdated){
00511                     dispTicker.detach();
00512                     dispTicker.attach(&setDispFlag, 10.0);
00513                     tickerUpdated = true;
00514                             
00515                 }
00516                 
00517                 togglecount += 1;
00518                 if(togglecount >= 2) {
00519                     toggler = false;
00520                     togglecount = 0;
00521                 }
00522     
00523             }
00524     
00525             if((!toggler && (missingGpsCnt < GPSACQTIMELIMITINSECONDS) && magStringsReceived) || (!toggler && dispTxtHandler.getMagTimePromtStatus()) && magStringsReceived) {
00526                 //show mag working for 20 seconds
00527                 dispTxtHandler.setErrorState(DISPLAY_MAG_MEASUREMENT);
00528     
00529                 togglecount += 1;
00530                 if(togglecount >= 2) {
00531                     toggler = true;
00532                     togglecount = 0;
00533                 }
00534             }
00535             
00536             
00537             //if battery voltage is below BATTERYLOW limit, initiate battery low error state
00538             if((0.00036621652)*battery.read_u16() < BATTERYLOWLIMIT){
00539                 dispTxtHandler.setErrorState(BATTERY_LOW);
00540                 redLed = 1;
00541                 greenLed = 0;    
00542             }
00543             
00544             //if gga fix is not present for a prolonged period of time, prompt user
00545             if((missingGpsCnt > GPSACQTIMELIMITINSECONDS) && !dispTxtHandler.getMagTimePromtStatus()) {
00546 
00547                 //Prompt user to set mag time manually
00548                 dispTxtHandler.setErrorState(NO_FIX);
00549             }            
00550             
00551             //if gps data is missing for more than 10 mag reading cycles
00552             if((magCntWithoutGpsData > 10) && !magTimeSetManually) {
00553                 //show error indication of gps data missing
00554                 dispTxtHandler.setErrorState(NO_GPS);
00555 
00556                 //set led error status
00557                 redLed = 1;
00558                 greenLed = 0;
00559                 
00560                 GGA_Fix_Present = false;
00561                 
00562                 //knaptryk check 
00563                 if(!timeSetManuallyButton){
00564                     timeSetManuallyCount += 1;        
00565                 }
00566                 
00567                 if(timeSetManuallyCount > 3){
00568                     magTimeSetManually = true;         
00569                 }
00570                      
00571             }                        
00572             
00573                 
00574             if(!GGA_Fix_Present && GpsCntWithoutMagData < 20){
00575                 //Missing GGA fix LED indicator
00576                 greenLed = 0;
00577                 redLed = 1;
00578             }
00579             
00580             if(GpsCntWithoutMagData > 20){
00581                 //Missing MAG data prompt
00582                 dispTxtHandler.setErrorState(NO_MAG_DATA);
00583                 greenLed = 0;
00584                 redLed = 1;
00585             }
00586                     
00587             if((GGA_Fix_Present && GpsCntWithoutMagData < 20) || (magTimeSetManually && GpsCntWithoutMagData < 20)){
00588                 //GGA fix LED indicator / time set manually unless battery is low
00589                 if(dispTxtHandler.getErrorState() != BATTERY_LOW){
00590                     greenLed = 1;
00591                     redLed = 0;                    
00592                 }     
00593             }    
00594                         
00595             checkStateFlag = false;    
00596         }
00597         
00598         //if the gps rx buffer is full, get info to error file.
00599         if(gps.rxBufferFull()){
00600             gps.rxBufferFlush();
00601             dbg.printf("GPS rxBuffer flushed\r\n"); 
00602         }
00603         
00604         //if the bmag rx buffer is full, flush the buffer.
00605         if(bmag.rxBufferFull()){
00606             dbg.printf("BMAG rxBuffer flushed\r\n");
00607             bmag.rxBufferFlush(); 
00608         }
00609         
00610         //if bmag data string is available
00611         if(BMAG_Data_Rdy) {
00612             
00613             //reset last read ms val
00614             memset(timer_ms,'\0',5);
00615             
00616             //read time since pps interrupt
00617             tmpTime = t.read_ms();
00618             snprintf (timer_ms, 5, "%d",tmpTime);    
00619                          
00620             if(RTC_set){
00621                 
00622                 string tmpTime = getTime();
00623              
00624                 //HH
00625                 gpsNMEA.currentUTCFromGPRMC[0] = tmpTime[0];
00626                 gpsNMEA.currentUTCFromGPRMC[1] = tmpTime[1];
00627              
00628                 //MM
00629                 gpsNMEA.currentUTCFromGPRMC[3] = tmpTime[3];
00630                 gpsNMEA.currentUTCFromGPRMC[4] = tmpTime[4];
00631              
00632                 //SS
00633                 gpsNMEA.currentUTCFromGPRMC[6] = tmpTime[6];
00634                 gpsNMEA.currentUTCFromGPRMC[7] = tmpTime[7];                   
00635             }
00636             
00637             
00638             if(strlen(timer_ms) == 1){
00639                 gpsNMEA.currentUTCFromGPRMC[9] = '0';
00640                 gpsNMEA.currentUTCFromGPRMC[10] = '0';
00641                 gpsNMEA.currentUTCFromGPRMC[11] = timer_ms[0];                  
00642             }
00643             
00644             if(strlen(timer_ms) == 2){
00645                 gpsNMEA.currentUTCFromGPRMC[9] = '0';
00646                 gpsNMEA.currentUTCFromGPRMC[10] = timer_ms[0];
00647                 gpsNMEA.currentUTCFromGPRMC[11] = timer_ms[1];    
00648             }
00649             
00650             if(strlen(timer_ms) == 3){
00651                 gpsNMEA.currentUTCFromGPRMC[9] = timer_ms[0];
00652                 gpsNMEA.currentUTCFromGPRMC[10] = timer_ms[1];
00653                 gpsNMEA.currentUTCFromGPRMC[11] = timer_ms[2];       
00654             }
00655             
00656             if(strlen(timer_ms) > 3 || strlen(timer_ms) == 0){
00657                 gpsNMEA.currentUTCFromGPRMC[9] = '0';
00658                 gpsNMEA.currentUTCFromGPRMC[10] = '0';
00659                 gpsNMEA.currentUTCFromGPRMC[11] = '0';                       
00660             }
00661             
00662                        
00663             //change magStringsReceived flag to true when mag data is available
00664             if(magStringsReceived == false){
00665                 magStringsReceived = true;    
00666             }
00667             
00668             //if gps override is active reset magCntWithoutGpsData
00669             if(GPS_Override_Active){
00670                 magCntWithoutGpsData = 0;    
00671             }
00672             
00673             //if mag data is present but gps data is not and gps override is not active
00674             if(magCntWithoutGpsData < 100 && !GPS_Override_Active) {
00675                 magCntWithoutGpsData += 1;
00676             }
00677             
00678             //move bmag data from rxbuffer to temporary array
00679             bmag.move(tmpBMAGRxString, bmag.rxBufferGetCount());
00680             
00681             //copy c_string to string
00682             BMAG_String_Buff.assign(tmpBMAGRxString);
00683             
00684             //clear tmpRxBuffer
00685             memset(tmpBMAGRxString,'\0',128);
00686 
00687             //parse bmag string
00688             magParser.parseBMAGString(BMAG_String_Buff);
00689             
00690             //reset counter containing gps string count without mag data
00691             GpsCntWithoutMagData = 0;
00692 
00693             //update filename when date is available with gga fix
00694             if(!fileNameUpdated && GGA_Fix_Present) {
00695                 spsGen.generateSpsFilename(gpsNMEA.currentDATEFromGPRMC, BARCODE, gpsNMEA.currentUTCFromGPRMC);
00696                 nextFilename.assign(spsGen.getSpsFileName());
00697                 fclose(fp);
00698                 currentFilename.assign(nextFilename);
00699                 nextFilename = "";
00700 
00701                 fp = fopen(currentFilename.c_str(), "a");
00702 
00703                 fileNameUpdated = true;
00704                 
00705                 spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
00706                 //add header to top of file
00707                 writeToUsb(spsGen.getHeaderString(), fp);
00708             }
00709             
00710             //read battery voltage
00711             sprintf(batteryvoltagearr, "%0.1f",(0.00036621652)*battery.read_u16());
00712             batteryvoltage.assign(batteryvoltagearr);
00713 
00714             //generate default sps string
00715             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, PreassureArr, TemperatureArr, HumidityArr, gpsNMEA.currentAltitude ,magParser.getMagTimeStr(), magParser.getMagNTStr(), magParser.getMagSq(), &dbg);
00716 
00717             //write data strings to sps file if GGA fix is present, and date has changed, or gps override is activated
00718             if(GGA_Fix_Present && (dateChanged || GPS_Override_Active)) {
00719 
00720                 missingGpsCnt = 0;
00721                 
00722                 if(firstLineWritten){        
00723                     writeToUsb(spsGen.getCurrentString(), fp);             
00724                 }
00725                 
00726                 if(!firstLineWritten) {
00727                     spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
00728                     writeToUsb(spsGen.getHeaderString(), fp);
00729                     firstLineWritten = true;
00730                 }
00731 
00732                 
00733 
00734                 if(!lastErrStatus && firstErrsWritten) {
00735                     //force clock resync
00736                     RTC_set = false;  
00737                     
00738                     //error end string
00739                     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);
00740                     writeToUsb(spsGen.getCurrentErrString(), fp);
00741                     lastErrStatus = true;
00742                     firstErrsWritten = false;
00743                     firstLineWritten = false;
00744                 }
00745             }
00746 
00747             //write data strings to sps file, with error messages as defined in *.sps definition if date has changed, or gps override is activated
00748             if(!GGA_Fix_Present && (dateChanged || GPS_Override_Active)) {
00749 
00750                 if(missingGpsCnt <=  GPSACQTIMELIMITINSECONDS) {
00751                     missingGpsCnt += 1;
00752                 }
00753 
00754                 if(!firstLineWritten) {
00755                     spsGen.UpdateHeaderString(BARCODE, IDENTIFIERID, GROUP, TIMEZONE, ENCODING,SOURCEIDENTIFICATION, INTERPRETERID, DATALINEVERSION, FWSRCVERSION, FWIVERSION);
00756                     writeToUsb(spsGen.getHeaderString(), fp);
00757                     firstLineWritten = true;
00758                 }
00759 
00760                 if(firstErrsWritten){
00761                     writeToUsb(spsGen.getCurrentString(), fp);
00762                 }
00763 
00764                 if(lastErrStatus && !firstErrsWritten) {
00765                     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);
00766                     writeToUsb(spsGen.getCurrentErrString(), fp);
00767                     lastErrStatus = false;
00768                     firstErrsWritten = true;
00769                 }
00770 
00771             }
00772 
00773             //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.
00774             if(!timeSetManuallyButton && dispTxtHandler.getMagTimePromtStatus()) {
00775                 timeSetManuallyCount += 1;
00776 
00777                 if(timeSetManuallyCount > 3) {
00778                     magTimeSetManually = true;
00779                 }
00780             }
00781 
00782             BMAG_Data_Rdy = false;
00783         }
00784      
00785         
00786         if(GPS_Data_Rdy){
00787                  
00788             gpsRunning = true;      
00789             
00790             missingGpsConnectionCounter = 0;
00791             
00792             if(gpsStringsReceived == false){
00793                 gpsStringsReceived = true;    
00794             }
00795             
00796             //clear mag data string counter, counting mag data received since last gps string received
00797             magCntWithoutGpsData = 0;
00798             
00799             //if gps data has been received without mag data since last gps string, increment counter.
00800             if(GpsCntWithoutMagData < 200){
00801                 
00802                 GpsCntWithoutMagData += 1;
00803                 
00804             }
00805                           
00806             gps.scanf("%s", &tmpGpsRxString);              
00807             
00808                         
00809             //copy c_string to string
00810             GPS_String_Buff.assign(tmpGpsRxString);
00811             
00812             //Debug gps output
00813             //dbg.printf(tmpGpsRxString);
00814             //dbg.printf("\r\n");
00815             
00816             //clear tmpRxBuffer
00817             memset(tmpGpsRxString,'\0',128);
00818             
00819             //Validate CRC
00820             GPS_Data_Valid = gpsNMEA.ValidateData(GPS_String_Buff);
00821          
00822             //store valid string, either gga or rmc
00823             if(GPS_Data_Valid){
00824                  gpsNMEA.StoreString(GPS_String_Buff/*, &dbg*/);   
00825             }
00826             
00827             //Get gga fix flag
00828             GGA_Fix_Present = gpsNMEA.GGAFixVerification();
00829             
00830             //Assign value to error flag
00831             spsGen.setErrStatus(GGA_Fix_Present);  
00832             
00833             //Clearing RX buffer.
00834             GPS_String_Buff = "";
00835             GPS_String_Buff.resize(128);
00836             
00837             //parse current date 
00838             gpsNMEA.ParseCurrentDateFromGPRMC();
00839             
00840             //ensure that date changes after midnight
00841             if(dateChanged){
00842                 dateBeforeChange = gpsNMEA.currentDATEFromGPRMC;                
00843             }
00844             
00845             if(!dateChanged && (dateBeforeChange != gpsNMEA.currentDATEFromGPRMC)){
00846                 dateChanged = true;
00847             }            
00848             
00849             //parse current time
00850             gpsNMEA.ParseCurrentUTCFromGPRMC();
00851             
00852             //parse gps coordinates
00853             gpsNMEA.ParseCurrentLatitudeFromGPRMC();
00854             gpsNMEA.ParseCurrentLongitudeFromGPRMC();
00855             gpsNMEA.ParseCurrentAltitudeFromGGA(); 
00856             //clearing flags
00857             GPS_Data_Valid = false;
00858             GPS_Data_Rdy = false;
00859             
00860             if(GGA_Fix_Present && !RTC_set){
00861                 fixPresentCnt += 1;    
00862             }
00863             
00864             if(GGA_Fix_Present && (!RTC_set && (fixPresentCnt > 5))){
00865                 
00866                     setMbedTime(gpsNMEA.currentDATEFromGPRMC, gpsNMEA.currentUTCFromGPRMC, &dbg);
00867                     
00868                                  
00869                     memset(tmpHour, '\0', 5);
00870                     memset(tmpMinute, '\0', 5);
00871                     memset(tmpSecond, '\0', 5);
00872                     
00873                     snprintf(tmpHour, 5, "%s", gpsNMEA.currentUTCFromGPRMC.substr(0, 2));
00874                     snprintf(tmpMinute, 5, "%s", gpsNMEA.currentUTCFromGPRMC.substr(3, 2));
00875                     snprintf(tmpSecond, 5, "%s", gpsNMEA.currentUTCFromGPRMC.substr(6, 2));
00876                     
00877                     int hours = atoi(tmpHour);
00878                     int minutes = atoi(tmpMinute);
00879                     int seconds = atoi(tmpSecond);                 
00880                     setTime(seconds, minutes, hours);
00881                     
00882                     RTC_set = true;
00883                     fixPresentCnt = 0;                          
00884             }
00885                 
00886         }
00887         
00888         //if pth data is due, convert pth values to char arrays
00889         if(PTHValuesReadyFlag){
00890             memset(TemperatureArr,'\0',10);
00891             memset(HumidityArr,'\0',10);
00892             
00893             //assign last measured preassure to char array, and ensure correct zero padding
00894             memset(PreassureArr,'\0',10);
00895             snprintf(PreassureArr, 10, "%04.f", PTH_Preassure);                 
00896             
00897             //ensure correct  temperature operator (+ or -) to show if temperature is positive or negative
00898             //assign last measured temperature to char array with zero padding if needed
00899                 
00900             if((PTH_Temperature > -10) && (PTH_Temperature < 10)){
00901                     
00902                 if(PTH_Temperature < 0){
00903                     snprintf(TemperatureArr, 10, "%03.0f", PTH_Temperature);
00904                 }
00905                     
00906                 if(PTH_Temperature >= 0){
00907                     snprintf(TemperatureArr, 10, "+%02.0f", PTH_Temperature);    
00908                 }                
00909             }
00910                 
00911             if(PTH_Temperature <= -10){
00912                 snprintf(TemperatureArr, 10, "%03.0f", PTH_Temperature);        
00913             }
00914                 
00915             if(PTH_Temperature >= 10){
00916                 snprintf(TemperatureArr, 10, "+%02.0f", PTH_Temperature);        
00917             } 
00918      
00919             //assign last measured relative humidity to char array            
00920             snprintf(HumidityArr, 10, "%03.0f", PTH_Humidity);                                            
00921 
00922             //dbg.printf("P = %s, T = %s, H = %s\r\n",PreassureArr,TemperatureArr, HumidityArr);     
00923             
00924             PTHValuesReadyFlag = false;
00925                                    
00926         }
00927         
00928         //If the pth sensor is inactive write NaN in the data columns normally containing PTH values
00929         if(!PTHSensorActive){
00930             memset(PreassureArr,'\0',10);
00931             memset(TemperatureArr,'\0',10);
00932             memset(HumidityArr,'\0',10);
00933             snprintf(PreassureArr, 10, "%s", "NaN");
00934             snprintf(TemperatureArr, 10, "%s", "NaN"); 
00935             snprintf(HumidityArr, 10, "%s", "NaN");             
00936         }  
00937 
00938         //If connection to USB flash disk is lost, reconnect to the flash disk
00939         if(!msd.connected()){
00940             
00941             //USB message
00942             clear_display_waiting();            
00943             l1 = "USB pen";
00944             l2 = "Missing!"; 
00945             thr_writelines.start(write_lines);
00946             
00947             //reestablish usb connection
00948             while(!msd.connect()){
00949                 dbg.printf("Trying to reconnect to usb flash disk\r\n");
00950                 wait_ms(200);
00951                 msd.connect();
00952             }
00953             
00954             thr_writelines.terminate();
00955                 
00956             //Reopening a file on usb disk
00957             fp = fopen(currentFilename.c_str(), "a");
00958             
00959             writeToUsb("\r\n", fp);
00960             writeToUsb(spsGen.getHeaderString(), fp);
00961                         
00962         }
00963         
00964         //kick / feed watchdog 
00965         wd.kick();
00966         
00967         Thread::yield();
00968     }    
00969    
00970     return 0;    
00971 }
00972 
00973 //Thanks to MODSERIAL!
00974 // Called everytime a new character goes into
00975 // the RX buffer. Test that character for \n
00976 // Note, rxGetLastChar() gets the last char that
00977 // we received but it does NOT remove it from
00978 // the RX buffer. 
00979 void rxCallback(MODSERIAL_IRQ_INFO *q) {
00980     MODSERIAL *serial = q->serial;
00981     if (serial->rxGetLastChar() == '\n') {
00982         GPS_Data_Rdy = true;
00983     }
00984 }
00985 
00986 //Thanks to MODSERIAL!
00987 // Called everytime a new character goes into
00988 // the RX buffer. Test that character for \r and buffer char count
00989 // Note, rxGetLastChar() gets the last char that
00990 // we received but it does NOT remove it from
00991 // the RX buffer. 
00992 void bmagrxCallback(MODSERIAL_IRQ_INFO *q) {
00993     MODSERIAL *serial = q->serial;
00994     if ((serial->rxBufferGetCount() > 20) && (serial->rxGetLastChar() == '\r')) {
00995         BMAG_Data_Rdy = true;
00996     }
00997 }
00998 
00999 //Write to file
01000 bool writeToUsb(string line, FILE * f){
01001 
01002     if (f != NULL) {
01003         fprintf(f, "\r\n");
01004         fprintf(f, line.c_str());  
01005               
01006     }
01007                  
01008     if(f == NULL){
01009         return false;
01010     }
01011 
01012     return true;      
01013 }
01014 
01015 
01016 void getPthValues(){
01017     if(BME.get(PTH_Temperature, PTH_Preassure, PTH_Humidity)){
01018          PTHValuesReadyFlag = true;   
01019     }
01020 };
01021 
01022 
01023 void gpsAvailCheck(void){
01024     gpsCheckedAfter10Sec = true;
01025 };