I used the NeoSWSerial Library that you wrote, and it works like a charm.
Thanks, and thanks to jboyton who created it! I adopted it and posted it up on github.
I don't really need too much of information from GPS except its location.
One of the features I put in NeoGPS is configurability. You can actually disable all the code that parses GPS fields and messages you don't use. In your case, you could turn off everything except parsing the location from a $GPRMC sentence. The final program size would be very small. If your program ever gets too big or slow, NeoGPS could save a few K of FLASH, up to 1k of RAM, and a few milliseconds of CPU time per GPS update. But it sounds like your sketch works fine for now.
When I was trying the UKHAS example to configure my GPS, I found the checksum loop be quite annoying. It usually ran four or five times before it could return a correct checksum.
Yes, it is not written like a real embedded communications program. Matching configuration requests (CFG_xxx from the Arduino) to acknowledgments (ACK/NAK from the Neo-6M), and keeping track of timeouts and retries, definitely requires more sophisticated programming techniques. Every other sketch that sends UBX binary commands does not properly wait, or does not even try to wait. Usually, they just send the binary commands once and hope that it gets to the Neo-6M and is processed.
I assume the checksum should work as an indicator to tell us whether the receiver has correctly received the information. But is [the CS] really necessary?
There are two things going on here: a checksum in every message; and ACK/NAK messages to configuration requests.
The checksum is used to verify that a received message is valid and can be parsed. It is detects errors in transmission and receipt. The Neo-6M will ignore UBX messages (CFG or otherwise) that do not have a good CS (I have verified this). You have to send the correct CS.
Similarly, the Arduino should ignore UBX messages that do not have a good CS. ACKs to configuration requests and position reports all have a CS, and they should be ignored if the CS does not match. (NeoGPS calculates the CS as each frame is being sent/received, so it is guaranteed to be calculated only once.)
In contrast to the CS, the ACK message (with its own CS) tells the Arduino that the Neo-6M received the CFG request correctly (the CS passed) and also performed the request. However, if the Neo-6M receives the request correctly and does not perform the request, it will reply with a NAK message (again, with its own CS). If neither an ACK nor a NAK is received "in time" (i.e., before the timeout expires), the Arduino can assume there was a CS failure. It will usually send the message again (a "retry").
I also found that the ACK/NAK timeout had to accommodate the serial "pipeline". If the Neo-6M happened to be sending a position report back to the Arduino, the Arduino had to wait until the Neo-6M was done sending data before the timeout would expire. This could add several hundred milliseconds to the timeout. Very subtle behavior!
If the UKHAS library was failing when you were still using SoftwareSerial
, I'm not at all surprised. Losing just one character will cause the CS to fail. But there are lots of ways it could have failed.
BTW, you can use u-center to send the configuration commands that you want, then look at the log for what bytes to send. Just do that in your sketch in setup
... like so many others. You can also use u-center to store that configuration permanently in the Neo-6M's non-volatile memory. This is a little more reliable, IMO. It also takes the code out of your sketch.
I do not recommend switching to the UBX binary protocol until every other time- or space-saving technique has been tried with the NMEA text protocol. Sometimes, sending a UBX binary message is the only way to configure the Neo-6M, but receiving ACK/NAK messages, and handling timeouts, retries and UBX binary position reports is much more complicated!
Cheers,
/dev