Dan Matthews / Mbed 2 deprecated GPS_Incremental

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h" 
00002 
00003 //set up the message buffer to be filled by the GPS read process
00004 #define MODSERIAL_DEFAULT_RX_BUFFER_SIZE 256 
00005 
00006 #include "MODSERIAL.h"
00007 #include "SDFileSystem.h"      //imported using the import utility    
00008 //#include "rtos.h"
00009 #include "OEM615.h"
00010 
00011 #include "ADIS16488.h"
00012 #include <string>
00013 
00014 #define STATUS_MSG 0
00015 #define POSVEL_MSG 1
00016 #define STARTDATA_MSG 2
00017 #define STOPDATA_MSG 3
00018 #define STARTSTREAM_MSG 4
00019 #define STOPSTREAM_MSG 5
00020 #define STARTLOGINFO_MSG 6
00021 #define STOPLOGINFO_MSG 7
00022 #define DEGREES_TO_RADIANS (3.14519/180.0)
00023 
00024 //general items for this application
00025 //SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name);
00026 SDFileSystem sd(p11,p12,p13,p14,"sd");
00027 //Serial debug(USBTX, USBRX); // tx, rx  USB communication to the PC for debug purposes
00028 DigitalOut ppsled(LED1);
00029 DigitalOut trig1led(LED2);
00030 DigitalOut recordDataled(LED4);
00031 InterruptIn camera1Int(p30);
00032 DigitalOut camera2Pin(p29);
00033 //USB serial data stream back to the PC
00034 Serial toPC(USBTX, USBRX); //connect the GPS TX, RX to p9 and p10
00035 
00036 bool detectedGPS1PPS = false;
00037 bool recordData = false;
00038 int PPSCounter = 0;
00039 int byteCounter = 0;
00040 unsigned short perSecMessageCounter=0;
00041 bool lookingForMessages = true;
00042 bool messageDetected = false;
00043 int savedIMUClockCounter=0;
00044 int IMUClockCounter = 0;
00045 bool camera1EventDetected = false;
00046 double camera1Time;
00047 char serBuf[128];
00048 int serBufChars=0;
00049 bool sendPosVel=false;
00050 bool sendStatus=false;
00051 bool sendRecData=false;
00052 bool streamPos=false;
00053 bool sendStreamPos=false;
00054 bool logMsgInfo=false;
00055 bool sendLogMsgInfo=false;
00056 
00057 
00058 //ISR for detection of the GPS 1PPS
00059 void detect1PPSISR(void)
00060 {
00061     timeFromPPS.reset();
00062     savedIMUClockCounter = IMUClockCounter;
00063     IMUClockCounter = 0;
00064     GPS_COM1.rxBufferFlush();
00065     
00066     detectedGPS1PPS = true;
00067     lookingForMessages = true;
00068     PPSCounter++;
00069     PPSTimeOffset++;
00070     ppsled = !ppsled;
00071 };
00072 
00073 //ISR for detection of the hotshoe trigger 1
00074 void camera1ISR(void)
00075 {
00076     camera1Time = GPSTime + (double)PPSTimeOffset + timeFromPPS.read();
00077     trig1led = !trig1led;
00078     camera1EventDetected = true;
00079 };
00080 
00081 void readFromPC()
00082 {
00083     if (toPC.readable()) //read a PC serial byte and test it for a command
00084     {
00085         // Read in next character
00086         char inChar = toPC.getc();
00087         serBuf[serBufChars++] = inChar;
00088         // Append end of string character
00089         serBuf[serBufChars] = '\0';
00090         // Need to parse message to determine behavior
00091         // Need to clean this up 
00092         char msgList[8][32];
00093         sprintf(msgList[STATUS_MSG], "WMsg STATUS");
00094         sprintf(msgList[POSVEL_MSG], "WMsg POSVEL");
00095         sprintf(msgList[STARTDATA_MSG], "WMsg RECORDDATA Y");
00096         sprintf(msgList[STOPDATA_MSG], "WMsg RECORDDATA N");
00097         sprintf(msgList[STARTSTREAM_MSG], "WMsg POSSTREAM Y");
00098         sprintf(msgList[STOPSTREAM_MSG], "WMsg POSSTREAM N");
00099         sprintf(msgList[STARTLOGINFO_MSG], "WMsg LOGINFO Y");
00100         sprintf(msgList[STOPLOGINFO_MSG], "WMsg LOGINFO N");
00101         // assume an invalid message which needs to be reset
00102         bool validMessage = false;
00103         bool resetMessage = true;
00104         // Check for valid message
00105         for (int m = 0; m < 8 && !validMessage; m++)
00106         {
00107             if (strncmp(serBuf, msgList[m], serBufChars) == 0)
00108             {
00109                 validMessage = true;
00110                 // buffer length is same as message length
00111                 if (serBufChars == strlen(msgList[m]))
00112                 {
00113                     switch(m)
00114                     {
00115                         case STATUS_MSG:
00116                             sendStatus = true;
00117                         break;
00118                         case POSVEL_MSG:
00119                             sendPosVel = true;
00120                         break;
00121                         case STARTDATA_MSG:
00122                         case STOPDATA_MSG:
00123                             recordData = (m == STARTDATA_MSG);
00124                             sendRecData = true;
00125                         break;
00126                         case STARTSTREAM_MSG:
00127                         case STOPSTREAM_MSG:
00128                             streamPos = (m == STARTSTREAM_MSG);
00129                             sendStreamPos = true;
00130                         break;
00131                         case STARTLOGINFO_MSG:
00132                         case STOPLOGINFO_MSG:
00133                             logMsgInfo = (m == STARTLOGINFO_MSG);
00134                             sendLogMsgInfo = true;
00135                         break;
00136                         
00137                     }
00138                 }
00139                 // message is still in progress, do not reset
00140                 else
00141                 {
00142                     resetMessage = false;
00143                 }
00144             }
00145         }
00146         // if message should be reset
00147         if (resetMessage)
00148         {
00149             // reset serial buffer character count
00150             serBufChars = 0;
00151             // if invalid message and most recent character is 'W' (first message character),
00152             // possible message collision
00153             if ((!validMessage) && (inChar == 'W'))
00154             {
00155                 // start a new message
00156                 serBuf[serBufChars++] = inChar;
00157                 serBuf[serBufChars] == '\0';
00158             }
00159             // Append end of string character
00160             serBuf[serBufChars] = '\0';
00161         }
00162     }
00163 };
00164 
00165 void sendASCII(char* ASCI_message, int numChars)
00166 {
00167     //char ASCI_message[] = "unlogall COM1";
00168     int as = numChars - 1;
00169     unsigned char CR = 0x0d;  //ASCII Carriage Return
00170     unsigned char LF = 0x0a;  //ASCII Line Feed
00171     
00172     //printf("%s", ch);
00173     //printf("\n");
00174 
00175     for (int i=0; i<as; i++) GPS_COM1.putc(ASCI_message[i]); 
00176     GPS_COM1.putc(CR);   //carriage return at end
00177     GPS_COM1.putc(LF);   //line feed at end
00178 };
00179 
00180 //FILE* fp = NULL;
00181 void setupCOM(void)
00182 {
00183     //system starts with GPS in reset active
00184     //dis-engage the reset to get the GPS started
00185     GPS_Reset=1; wait_ms(1000); 
00186     
00187     //establish 1PPS ISR 
00188     PPSInt.rise(&detect1PPSISR);
00189     
00190     //set the USB serial data rate -- rate must be matched at the PC end
00191     //This the serial communication back to the the PC host
00192     //Launch the C++ serial port read program there to catch the ASCII characters
00193     //toPC.baud(9600); wait_ms(100);    
00194     toPC.baud(8*115200); wait_ms(100);
00195     //toPC.baud(1*115200); wait_ms(100);
00196     toPC.printf("\n\n released GPS from RESET and set to high baud rate \n\n");
00197     
00198     //just wait to lauinch the GPS receiver
00199     for (int i=0; i<5; i++) { toPC.printf(" to start: %3d \n", 4-i); wait(1); }
00200 
00201     
00202     mkdir("/sd/Data", 0777);
00203     
00204     /*
00205     fp = fopen("/sd/Data/IMUGPS.bin", "wb");
00206     if (fp == NULL)
00207     {
00208         toPC.printf(" cannot open the IMUGPS data file \n");
00209     }
00210     else
00211         toPC.printf(" opened the IMUGPS data file \n");
00212     */
00213       
00214     //this is the COM1 port from th GPS receiuver to the mbed
00215     //it should be always started at 9600 baud because thats the default for the GPS receiver 
00216     GPS_COM1.baud(9600); wait_ms(100);
00217    
00218     // this ASCII command sets up the serial data from the GPS receiver on its COM1
00219     char ch7[] = "serialconfig COM1 9600 n 8 1 n off";
00220     // this is a software reset and has the same effect as a hardware reset (why do it??) 
00221     char ch0[] = "RESET"; 
00222     //this command stops all communication from the GPS receiver on COM1
00223     //logs should still be presented on USB port so the CDU can be used in parallel
00224     char ch1[] = "unlogall COM1";
00225     //set the final baud rate that we will use from here  
00226     //allowable baud rate values: 9600 115200 230400 460800 921600
00227     char ch2[] = "serialconfig COM1 921600 n 8 1 n off";
00228     
00229     //the below commands request the POS, VEL, RANGE, and TIME messages
00230     char ch3[] = "log COM1 BESTPOSB ONTIME 1";   //messageID = 42 
00231     char ch4[] = "log COM1 BESTVelB ONTIME 1";   //messageID = 99
00232     char ch5[] = "log COM1 RANGEB ONTIME 1";     //messageID = 43
00233     char ch6[] = "log COM1 TIMEB ONTIME 1";      //messageID = 101
00234     
00235     //set up VARF to be 100Hz with 1X10^4 * 10^-8 = 10^-4 sec (10usec) pulse width
00236     char ch8[] = "FREQUENCYOUT enable 10000 1000000";
00237     
00238     toPC.printf("set serial config \n");
00239     sendASCII(ch7, sizeof(ch7)); wait_ms(500);
00240     //sendASCII(ch0, sizeof(ch0));  
00241     toPC.printf("unlog all messages \n");
00242     sendASCII(ch1, sizeof(ch1)); wait_ms(500);
00243     toPC.printf("log BESTPOSB on COM1 \n");
00244     sendASCII(ch3, sizeof(ch3)); wait_ms(500);
00245     toPC.printf("log BESTVELB on COM1\n");
00246     sendASCII(ch4, sizeof(ch4)); wait_ms(500);
00247     toPC.printf("log RANGEB on COM1\n");
00248     sendASCII(ch5, sizeof(ch5)); wait_ms(500);
00249     
00250     //toPC.printf("log TIMEB om COM1 \n");
00251     //sendASCII(ch6, sizeof(ch6)); wait_ms(100);
00252     
00253     toPC.printf(" set up th VARF signal \n"); 
00254     sendASCII(ch8, sizeof(ch8)); wait_ms(500);
00255        
00256     //set GPS output COM1 to the final high rate
00257     toPC.printf("set the COM ports to high rate\n");
00258     sendASCII(ch2, sizeof(ch2)); wait_ms(500);
00259     
00260     //set the mbed COM port to match the GPS transmit rate
00261     //the below baud rate must match the COM1 rate coming from the GPS receiver 
00262     GPS_COM1.baud(921600); wait_ms(500);  //without this wait -- the baud rate is not detected when using MODSERIAL     
00263 };
00264 
00265 void setupTriggers()
00266 {
00267     camera1Int.mode(PullUp);
00268     camera2Pin = 1;
00269     //establish Trigger ISR 
00270     camera1Int.rise(&camera1ISR);
00271     
00272 };
00273 
00274 int test = 0;
00275 unsigned short messageCounter = 0;
00276 unsigned short savedMessageCounter = 0;
00277 unsigned char msgBuffer[1536];
00278 unsigned short messageLocation[6] = {0};
00279 
00280 //see the mbed COOKBOOK for MODSERIAL
00281 //MODSERIAL is an easy to use library that extends Serial to add fully buffered input and output.
00282 void readSerialByte(MODSERIAL_IRQ_INFO *q)
00283 { 
00284     MODSERIAL *serial = q->serial;
00285     unsigned char synch0 = serial->getc();
00286     msgBuffer[byteCounter] = synch0;
00287 
00288     //we need to trap the GPS message header byte-string 0xAA44121C
00289     //generate a 4-byte sliding-window sequence from the input bytes
00290     //shift last 4-byte value left 8 bits & push recently read byte (synch0) into low-order byte
00291     test = (test<<8) | synch0;  //
00292    
00293     if (test == 0xAA44121C) //test for the Receiver message header signature
00294     {
00295         messageLocation[perSecMessageCounter] = byteCounter-3; //store the location of this message (with 4 synch words)
00296         perSecMessageCounter++;
00297         messageDetected = true;
00298      }   
00299      byteCounter++;     //total per-sec byte counter (reset to zero in main when 1PPS detected) 
00300 
00301 };
00302 
00303 int main() {
00304 
00305     //FILE *fpIMU = NULL;
00306     //FILE *fpGPS = NULL;
00307     FILE *fpNav = NULL;
00308     OEM615BESTPOS posMsg;
00309     OEM615BESTPOS curPos;
00310     OEM615BESTVEL velMsg;
00311     OEM615BESTVEL curVel;
00312     int msgLen;
00313     int msgEnd;
00314 
00315     //set up the GPS and mbed COM ports
00316     setupCOM(); 
00317     
00318     //set up the ADIS16488 
00319     setupADIS();
00320     
00321     //setup Hotshoe
00322     setupTriggers();
00323     //attempt to use the mbed RTOS library
00324     //Thread thread(writeThread);
00325     
00326     toPC.printf("completed setting up COM ports \n");
00327     
00328     //set up the interrupt to catch the serial byte availability
00329     GPS_COM1.attach(&readSerialByte, MODSERIAL::RxIrq);
00330     
00331     timeFromPPS.start();
00332 
00333     //while(PPSCounter < 1000)
00334     while(1)
00335     {        
00336         //read the USB serial data from the PC to check for commands
00337         readFromPC();
00338 
00339         if (sendPosVel)
00340         {
00341             sendPosVel=false;
00342             char solReady = 'N';
00343             if (posMsg.solStatus == 0)
00344             {
00345                 solReady = 'Y';
00346             }
00347             double nVel = velMsg.horizontalSpeed*cos(velMsg.heading*DEGREES_TO_RADIANS);
00348             double eVel = velMsg.horizontalSpeed*sin(velMsg.heading*DEGREES_TO_RADIANS);
00349             // For the 1 second deltas with which we are dealing
00350             //  this calculation should be close enough for now
00351             // approximately 1 nautical mile / minute latitude, 60 minutes/degree, 1852 meters/nautical mile
00352             double latMetersPerDeg = 60.0*1852.0;
00353             // longitude separation is approximately equal to latitude separation * cosine of latitude
00354             double lonMetersPerDeg = latMetersPerDeg*cos(posMsg.latitude*DEGREES_TO_RADIANS);
00355 
00356             // Elapsed time since last known GPS position
00357             double elTime = (double)PPSTimeOffset + timeFromPPS.read();
00358             // Position time
00359             double posTime = GPSTime + elTime;
00360 
00361             // Estimated position based on previous position and velocity
00362             double latPos = posMsg.latitude + (nVel/latMetersPerDeg)*elTime;
00363             double lonPos = posMsg.longitude + (eVel/lonMetersPerDeg)*elTime;
00364             double htPos = posMsg.height + velMsg.verticalSpeed/(60*1852)*elTime;
00365             toPC.printf("WMsg POSVEL %5.3lf %d %c %8.5lf %9.5lf %4.3lf %4.3lf %4.3lf %4.3lf\n", 
00366                          posTime, 
00367                          posMsg.numSolSV,
00368                          solReady,
00369                          latPos,
00370                          lonPos,
00371                          htPos,
00372                          nVel,
00373                          eVel,
00374                          velMsg.verticalSpeed
00375                          );
00376         }
00377         if (sendStatus)
00378         {
00379             sendStatus=false;
00380             char solReady = 'N';
00381             if (posMsg.solStatus == 0)
00382             {
00383                 solReady = 'Y';
00384             }
00385             toPC.printf("WMsg STATUS %5.3lf %c\n", 
00386                          GPSTime, 
00387                          solReady
00388                          );
00389         }
00390         if (sendRecData)
00391         {
00392             sendRecData=false;
00393             char recChar = 'N';
00394             if (recordData)
00395             {
00396                 if ((fpNav == NULL))
00397                 {
00398                     fpNav = fopen("/sd/Data/NAV.bin", "wb");
00399                 }
00400                 if (fpNav != NULL)
00401                 {
00402                     recChar = 'Y';
00403                 }
00404                 //recChar = 'Y';
00405             }
00406             else
00407             {
00408                 if (fpNav != NULL)
00409                 {
00410                     fclose(fpNav);
00411                     fpNav = NULL;
00412                 }
00413                 /*
00414                 if (fpIMU != NULL)
00415                 {
00416                     fclose(fpIMU);
00417                     fpIMU = NULL;
00418                 }
00419                 if (fpGPS != NULL)
00420                 {
00421                     fclose(fpGPS);
00422                     fpGPS = NULL;
00423                 }
00424                 */
00425             }
00426             toPC.printf("WMsg RECORDDATA %c\n", 
00427                          recChar
00428                          );
00429         }
00430         recordDataled = recordData;
00431         if (sendStreamPos)
00432         {
00433             sendStreamPos=false;
00434             char streamChar = 'N';
00435             if (streamPos)
00436             {
00437                 streamChar = 'Y';
00438             }
00439             toPC.printf("WMsg POSSTREAM %c\n", 
00440                          streamChar
00441                          );
00442         }
00443         if (sendLogMsgInfo)
00444         {
00445             sendLogMsgInfo=false;
00446             char logChar = 'N';
00447             if (logMsgInfo)
00448             {
00449                 logChar = 'Y';
00450             }
00451             toPC.printf("WMsg LOGINFO %c\n", 
00452                          logChar
00453                          );
00454         }
00455         if (IMUDataReady)
00456         {
00457             //write the IMU data
00458             //if (recordData && (fpIMU != NULL))
00459             if (recordData && (fpNav != NULL))
00460             {
00461                 fwrite(imuRec.dataWord, sizeof(IMUREC), 1, fpNav);
00462             }
00463             IMUDataReady = false;
00464         }
00465         //if (lookingForMessages && (timeFromPPS.read() > 0.100))  //it takes less than 20msec to receive all messages
00466         {
00467             
00468             //toPC.printf(" num messages = %3d time = %5d \n", perSecMessageCounter, timeFromPPS.read_us());
00469             for (int i=0; i<perSecMessageCounter; i++)
00470             {
00471                 // ensure at message header has arrived before processing
00472                 if (byteCounter < (messageLocation[i] + sizeof(MESSAGEHEADER)))
00473                 {
00474                     // Complete message header has not been received.
00475                     // Clear processed messages and break out of message processing loop
00476                     for (int j = 0; j < i; j++)
00477                     {
00478                         messageLocation[j] = messageLocation[i+j];
00479                         perSecMessageCounter--;
00480                     }
00481                     break;
00482                 }
00483                 msgHeader[i] = (MESSAGEHEADER*)&msgBuffer[messageLocation[i]];
00484                 // Ensure complete message has been received
00485                 // Message length is header length + message length + CRC
00486                 msgLen = 28;
00487                 switch (msgHeader[i]->messageID)
00488                 {
00489                     case 42:
00490                         msgLen = 104;
00491                     break;
00492                     case 99:
00493                         msgLen = 76;
00494                     break;
00495                     default:
00496                         msgLen = msgHeader[i]->headerLength + msgHeader[i]->messageLength + sizeof(unsigned long);
00497                     break;
00498                     
00499                 }
00500                 msgLen = msgHeader[i]->headerLength + msgHeader[i]->messageLength + sizeof(unsigned long);
00501                 // Find last byte position of message
00502                 msgEnd = messageLocation[i] + msgLen;
00503                 if (byteCounter < msgEnd)
00504                 {
00505                     // Complete message has not been received.
00506                     // Clear processed messages and break out of message processing loop
00507                     for (int j = 0; j < i; j++)
00508                     {
00509                         messageLocation[j] = messageLocation[i+j];
00510                         perSecMessageCounter--;
00511                     }
00512                     break;
00513                 }
00514                 else if ((i < (perSecMessageCounter-1)) &&
00515                          (messageLocation[i+i] < msgEnd)) // ignore CRC for now
00516                 {
00517                     // Next message was started before this mesage was completely received.
00518                     // Ignore and continue on to the next message
00519                     continue;
00520                 }
00521                 if (logMsgInfo)
00522                 {
00523                     toPC.printf("WMsg MESSAGEINFO %5d %5d %5d %5d %5d = %5d (%5d)\n", 
00524                                                     msgHeader[i]->messageID, 
00525                                                     messageLocation[i], 
00526                                                     msgHeader[i]->headerLength,
00527                                                     msgHeader[i]->messageLength,
00528                                                     sizeof(unsigned long),
00529                                                     msgEnd,
00530                                                     byteCounter);
00531                 }
00532                 //toPC.printf(" %5d ", msgHeader[i]->messageID);
00533                 if ((msgHeader[i]->messageID == 42) ||
00534                     (msgHeader[i]->messageID == 99))
00535                 {
00536                     if (msgHeader[i]->messageID == 42)
00537                     {
00538                         // Wait until velocity message has also been received before using as
00539                         // base position
00540                         //memcpy(&curPos, &msgBuffer[messageLocation[i]], sizeof(OEM615BESTPOS));
00541                         curPos = *((OEM615BESTPOS*)&msgBuffer[messageLocation[i]]);
00542                         if (streamPos)
00543                         {
00544                             toPC.printf("WMsg BESTPOS %d %d %d %8.5lf %9.5lf %5.3lf %5.3f %5.3f %5.3f %5.3f %5.3f %5.3f %d %d %d %d %d\n",
00545                                               curPos.msgHeader.GPSTime_msecs,
00546                                               curPos.solStatus,
00547                                               curPos.posType,
00548                                               curPos.latitude,
00549                                               curPos.longitude,
00550                                               curPos.height,
00551                                               curPos.undulation,
00552                                               curPos.latitudeSTD,
00553                                               curPos.longitudeSTD,
00554                                               curPos.heightSTD,
00555                                               curPos.diffAge,
00556                                               curPos.solutionAge,
00557                                               curPos.numSV,
00558                                               curPos.numSolSV,
00559                                               curPos.numGGL1,
00560                                               curPos.extSolStatus,
00561                                               curPos.sigMask);
00562                         }
00563                     }
00564                     else if (msgHeader[i]->messageID == 99)
00565                     {
00566                         // Wait until position message has also been received before using as
00567                         // base position
00568                         //memcpy(&curVel, &msgBuffer[messageLocation[i]], sizeof(OEM615BESTVEL));
00569                         curVel = *((OEM615BESTVEL*)&msgBuffer[messageLocation[i]]);
00570                     }
00571                     if ((curVel.msgHeader.GPSTime_msecs+250)/1000 == 
00572                         (curPos.msgHeader.GPSTime_msecs+250)/1000)
00573                     {
00574                         // update position and velocity used for calculation
00575                         GPSTimemsecs = curPos.msgHeader.GPSTime_msecs;
00576                         GPSTime = (double)GPSTimemsecs/1000.0;
00577                         velMsg = curVel;
00578                         posMsg = curPos;
00579                         PPSTimeOffset = 0;
00580                     }
00581                 }
00582                 if (i == (perSecMessageCounter-1))
00583                 {
00584                     if (recordData && (fpNav != NULL))
00585                     {
00586                         fwrite(msgBuffer, byteCounter, 1, fpNav);
00587                     }
00588                     byteCounter = 0;
00589                     perSecMessageCounter = 0;
00590                 }
00591             }  
00592             //toPC.printf(" %3d %8d \n", msgHeader[0]->timeStatus, GPSTimemsecs);
00593             //if (recordData && (fpGPS != NULL))
00594 
00595             /*
00596             if (recordData && (fpNav != NULL))
00597             {
00598                 fwrite(msgBuffer, byteCounter, 1, fpNav);
00599             }
00600             */
00601             //lookingForMessages = false;
00602         }
00603         if (messageDetected)
00604         {
00605             //toPC.printf(" msgTime = %4d \n", timeFromPPS.read_us());
00606             messageDetected = false;
00607         }
00608         if (camera1EventDetected)
00609         {
00610             toPC.printf("WMsg TRIGGERTIME %5.3lf\n", camera1Time);
00611             camera1EventDetected = false;
00612         }
00613         if (detectedGPS1PPS)
00614         {   
00615             //toPC.printf(" PPSCounter = %4d byteCounter = %10d num Messages Received = %3d IMUClock = %4d\n", 
00616             //                PPSCounter, byteCounter, perSecMessageCounter, savedIMUClockCounter);
00617             if (recordData && (fpNav != NULL) && (byteCounter > 0))
00618             {
00619                 fwrite(msgBuffer, byteCounter, 1, fpNav);
00620             }
00621             byteCounter = 0;
00622             perSecMessageCounter=0;
00623             detectedGPS1PPS = false;
00624         }
00625     }
00626     toPC.printf(" normal termination \n");
00627 }