Questions: TinyGPS on Teensy 4.0

OhioJim

Well-known member
This really isn't a bug problem. I just want to understand something about TinyGPS.

I have a GPS receiver connected to a hardware serial port on my T4.0.

This is a snippet of the code:
while (Serial2.available())
{
c = Serial2.read();

if(gps.encode(c))
{
gps.crack_datetime(&year,&month,&day,&hour,&minute,&second,&hundredths,&fix_age);
UTChours = hour+minute*1.66666666666666666666e-2+second*2.77777777777777777777e-4
+hundredths*2.77777777777777777777e-6; //UTC hour
getLST(UTChours,day, month, year, flong, LST);
getRaDec( LST, flat, RightAscension, Declination);
setDisplay(mode,UTChours,LST,RightAscension,Declination);

}
}

Everything is working as it should. I get the right numbers on the LCD display. And it updates every second.

Now, my question is about the first line and the "while (Serial2.available())". The GPS is sending a burst of data once a second. This takes only a small fraction of the second, and nothing else happens until the next burst.

I assume that the "while" statement falls through when there is no data on the serial port. Or am I wrong on this? If I move the lines of code shown in bold outside the "while", then the display is not updated every second.

At this point in the sketch all I need is the date and time. Previous to this is another "while" where I collect and average the latitude and longitude (variables flat and flong) (that would probably be best in the setup function) so I know that the "while" eventually drops through.

I want to be able to do other things during the time that the GPS is quiet, so why does it not update the display every second as the "while" drops through? This makes me wonder if things would get done properly if they are outside the "while".

Is there another GPS driver that would work better?

[Edit] I jut noticed that the display is NOT updating every second like I thought, but every so often it skips a second or two.
 
Last edited:
Its probably fine to change that while for an if - after all the characters are probably coming in at some fairly slow baud rate.

In general a while loop is a dangerous thing (although here its limited by the Serial rate so is unlikely to ever hog the processor.)

I would personally prefer the test to be an explicit comparison of the available count:
Code:
  if/while (Serial2.available () > 0)
As that make the return type of available() crystal clear, lest someone thing its bool.
 
Thanks, MarkT. I was wondering about why they used a "while" there, when I first looked at the provided examples. It made me wonder if it was supposed to be stuck there.

One thought though.

It seems to go like this: So long as there are characters coming in grab them off the serial port. "Encode" them, whatever that means. Then do what you want with the data. So does "encode" return false until a complete GPS sentence is received? In which case maybe it is a good idea to stay in the while loop? After all, you don't want to do any processing on partial or incomplete data.

If the "while" was changed to an "if" how do you tell when there is a complete GPS sentence, so you can do your thing with the data?

Remember that the GPS data is an indeterminate length. It is a character string that starts with a "$" and ends with a crlf. The number of characters depends on the current state and configuration of the GPS receiver.

I have programmed the GPS receiver to only send the bare minimum of information, so I will see how well that works.
 
I assume that the "while" statement falls through when there is no data on the serial port
Correct.

There's nothing wrong with the "while". If there are no characters in the Serial2 buffer then the while is bypassed. The if statement does two things. First, the "gps.encode(c)" passes the latest received character to the encoder. The encode function only returns non-zero (probably 1) if the latest character was the end of the whole NMEA message and the the gps library obtained a valid decode. So, if the character is not the last in the message, it returns zero (false) and the content of the if statement is not executed. The content of the 'if' statement is only executed when the encode function sees the end of message and decodes it correctly, at which point gps.crack_datetime is executed to extract the datetime from the message. This is why you see it print a message once a second. It only prints anything when a complete message has been received and decoded and that can only happen once a second. When you move those bolded statements outside the while, you extract the datetime from the message correctly inside the 'if' but do nothing with it. And the bolded statements outside the while will keep printing the same date and time to the display. You probably won't notice that happening because the display isn't changing.
If you want to do other things, you can do them before or after the 'while' as long as you don't slow it down so much that the while doesn't executed often enough to process the GPS message in a timely fashion.

Pete
 
Well the use of while is effectively declaring that that serial input has highest priority since it can in theory hog
the processor - the fact it doesn't hog the processor in practice means that it will behave the same as an if,
so why not make it an if and avoid a "while" in the code (remember whiles are red-flags when code-reviewing
a real-time piece of software!!)
 
This is all academic at this time anyway.

I have switched to using the NeoGPS library. It does the capture of the GPS sentences and extraction of the data fields for you, and stores them in a c++ structure. So all you have to do is query for the values you want. It is also easy to inquire if the values are valid. More intuitive and seems to run smoother, IMHO. It still has a while statement though.

I am running a Neo-8M, and using the UBlox utility I have programmed it to send the bare minimum of information. This should take, at the most, about 0.1 seconds leaving 0.9 seconds to do other things. But I may still try replacing the "while" with an "if" and see what it does.
 
Back
Top