Timing of "while" loop

I am parsing GPS data and this is working great.
However, I would like to time the parsing of GPS data for a given period.
Once this period has expired and no valid data has been received, I must send “No Fix” message.
If I comment out:

//    while (time_now < (start_time + (1 * 60000UL)))// default 2 minutes
//    {

AND

//      time_now = millis(); // reset time_now
//    }  // END: while (time_now < (start_time + (1 * 60000UL)))

My sketch works great, but I cannot get it to work in the while loop.
My Code:

void parseGPS() {

  Serial.println("Got To parseGPS");

  unsigned long start_time;
  unsigned long time_now;
  time_now = millis();
  start_time = time_now;

//    while (time_now < (start_time + (1 * 60000UL)))// default 2 minutes
//    {
  boolean newGPS = false;
  char * strtokIndx; // this is used by strtok() as an index

  strtokIndx = strtok(tempGPS, ",");     // get the first part - the string
  strcpy(gpsHeader, strtokIndx); // copy it to gpsTime

  strtokIndx = strtok(NULL, ",");     // get the first part - the string
  strncpy(gpsTime, strtokIndx, 6); // copy it to gpsTime

  strtokIndx = strtok(NULL, ",");     // get the first part - the string
  strcpy(gpsValid, strtokIndx); // copy it to gpsValid

  if (gpsValid[0] == 'A') {

    GPSvalid++;
    Serial.print("GOT VALID: ");
    Serial.println(GPSvalid);


    // START LATITUDE STUFF
    strtokIndx = strtok(NULL, ",");
    strncpy(gpsLat, strtokIndx, 9);
    strncpy(DegLat, gpsLat, 2);
    DegLat[2] = 0;
    int LatDeg = DegLat[0];
    strncpy(MinLat, &gpsLat[2], 7);
    MinLat[7] = 0;

    float numLat = atof(MinLat);
    numLat = (numLat * 10000);
    numLat = (numLat / 60);
    numLat = round(numLat);

    String LatitudeDec = (String)DegLat +  (String)(numLat);
    int LatPosition = LatitudeDec.indexOf('.');
    LatitudeDec = LatitudeDec.substring(0, LatPosition);
    unsigned long myLat = (LatitudeDec.toInt());
    LatHEX = String(myLat, HEX);
    if (LatHEX.length() == 5)
    {
      LatHEX = "0" + LatHEX;
    }
    strtokIndx = strtok(NULL, ",");     // get the first part - the string
    strcpy(gpsNS, strtokIndx); // copy it to gpsData

    if (gpsNS[0] == 'S') {
      NS = "53";
    }
    if (gpsNS[0] == 'N') {
      NS = "4E";
    }
    // END LATITUDE STUFF


    // START LONGITUDE STUFF
    strtokIndx = strtok(NULL, ",");
    strncpy(gpsLon, strtokIndx, 10);
    strncpy(DegLon, gpsLon, 3);
    DegLon[3] = 0;
    int LonDeg = DegLon[0];
    strncpy(MinLon, &gpsLon[3], 9);
    MinLon[8] = 0;

    float numLon = atof(MinLon);
    numLon = (numLon * 10000);
    numLon = (numLon / 60);
    numLon = round(numLon);

    String LongitudeDec = (String)DegLon +  (String)(numLon);
    int LonPosition = LongitudeDec.indexOf('.');
    LongitudeDec = LongitudeDec.substring(0, LonPosition);
    unsigned long myLon = (LongitudeDec.toInt());
    LonHEX = String(myLon, HEX);
    if (LonHEX.length() == 5)
    {
      LonHEX = "0" + LonHEX;
    }
    strtokIndx = strtok(NULL, ",");     // get the first part - the string
    strcpy(gpsEW, strtokIndx); // copy it to gpsData

    if (gpsEW[0] == 'E') {
      EW = "45";
    }
    if (gpsEW[0] == 'W') {
      EW = "57";
    }
    // END LONGITUDE STUFF

    // START SPEED STUFF
    strtokIndx = strtok(NULL, ",");
    gpsKnots = atof(strtokIndx);     // convert this part to a float
    unsigned int myKph = (gpsKnots);
    myKph = (myKph * 1.852);
    KphHEX = String(myKph, HEX);
    if (KphHEX.length() == 1)
    {
      KphHEX = "0" + KphHEX;
    }
    // END SPEED STUFF

    if (GPSvalid == 3) {
     GPSvalid = 0;
      msgTX = LatHEX + NS + LonHEX + EW + KphHEX;
      Serial.print("Tx Message: ");
      Serial.println(msgTX);
      digitalWrite(GPS_PIN, LOW);//GPS OFF
    }

  }// END if (gpsValid[0] == 'A')
//      time_now = millis(); // reset time_now
//    }  // END: while (time_now < (start_time + (1 * 60000UL)))
//    Serial.println("GPS TIMEOUT");
 //  NOW I MUST SEND "NO FIX" MESSAGE
//   msgTX = "000000000000000000";
}

Try posting the whole sketch rather than just the routine you believe is the cause of the problem. Very often there is a cause beyond the location that appears to be wrong, such as a memory write over an array bound scribbling on a variable relied on.

What does or does not happen when you say "I can not get it to work in the while loop."?

//    while (time_now < (start_time + (1 * 60000UL)))// default 2 minutes

Not relevant for the question but this comment looks wrong. I wonder what else is wrong.

What are you actually trying to achieve by reparsing the GPS data repeatedly without, as far as I can see, updating it?
I notice you do a digitalWrite to turn the GPS Off near the end of the loop, which is not really anything to do with parsing the GPS data, should this be in the loop, or possibly in a different function?

You can't run strtok() on the same buffer twice. The first time, all of the commas get turned into nulls.

Parsing the same message repeatedly for 1 minute (or two) WON'T tell you how many valid fixes arrived in that minute since you aren't reading any messages while parsing.

Did you want an alarm when there has not been a valid fix for two minutes?

  if (gpsValid[0] == 'A') {
    TimeOffLastValidFix = millis();  // Add this line to set a global variable
  // In the part of the code waiting for input, put:
  if (millis() - TimeOffLastValidFix >= (2ul * 60ul * 1000ul))
  {
    // It has been two minutes since the last time a valid fix was parsed.  Raise the alarm here.
  }

Try using a timeObj?

STEP (1)
#incllude <timeObj.h> // Include it.

STEP (2)
timeObj toTimer(2.0 * 60.0 * 1000.0); // Create a global, set it up as two minute timer.

STEP (3a)
each time you get a valid fix call…

toTimer.start(); // To reset the timer.

STEP (3b)
check the timer during loop to see if it has expired…

if (toTimer.ding()) {
Serial.println(“NO FIX!”);
}

That’s it!

Available in LC_baseTools form you handy IDE library manager.

Good luck!

-jim lee

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.