Friday, May 14, 2021

Exploring Plug and Play GPS Options

 I have spent quite a bit of time exploring different options of "plug and play" GPS loggers, specifically for the GPS Team Challenge (GPSTC). This post is a summary of what I've learned so far about using several different loggers: the original Openlog; the Openlog Artemis from Sparkfun; the Adafruit Clue; and the M5Stack Basic.

1. Openlog and Beitian BN880

The two units on the left side of the picture above are my "old", GPSTC-approved prototypes that are based on Beitian GPS and Openlog chips. Here's a closer look at the lower one:

The Openlog is a little chip with an SD card that's widely used for logging GPS data from drones; it's on the right side in the image above. Openlogs are available for about $15 from Sparkfun, and about $5 on eBay (but beware - some of the cheap modules do not work as shipped!). I used it with a Beitian BN880 GPS chip (about $20 on Amazon) to create a prototype logger that has been approved for GPSTC postings. My prototype did not qualify as "plug and play", because it involved it required some soldering between the logger and the GPS chip, and to connect a battery (like the 400 mAh LiPo battery shown above) to power everything. Some of this soldering could be avoided by using a Sparkfun Openlog with headers, and a BN880 GPS chip that comes with cables. But you'd still need to connect everything to a battery, which would typically require soldering. 

A second issue with this approach is that you need to change the configuration of the GPS chip for GPSTC postings. By default, the GPS chips provide updates once per second (at 1 Hz), and in a text format (NMEA sentences). But the text format does not provide speed accuracy information that is required for GPSTC postings, and higher data rates give more accurate speeds. Therefore, the GPSTC requires that data are logged in a binary format (the UBX format in this case), and are recorded at 5 Hz or higher.

This is easy enough to change using the Windows program "U-center". But it requires hooking up the GPS chip to a computer using a serial-to-USB converter, which adds another level of complexity; and a bit of learning how to change the required settings in U-center.

If you know how to use a soldering iron, and don't mind spending a couple of hours to hook up everything and learn how to use U-center, this is a perfectly good option to create a GPS logger for about $50. But since soldering is required, it does not qualify as "plug and play".

2. Sparkfun Openlog Artemis and Sparkfun Quiic GPS 

A couple of newer products from Sparkfun offer a way to get around around the soldering requirement: the Openlog Artemis (OLA), and GPS chips that use the Quiic connector and a u-blox chip. In this setup, the logger and the GPS chip are connected using a cable. The OLA can be powered with a LiPo battery or a USB power pack, so no soldering is required. 

Bottom view of the OLA-M8 GPS, showing the OLA

Top view of the OLA-M8, showing the SAM-M8 GPS chip

 I have tested this setup with three different GPS chips: the SAM-M8Q ($40), the NEO-M9N with a chip antenna ($70), and the NEO-M9N with a U.FL connector ($65) and an external active antenna ($15). The chip antenna was to weak to give decent data, so I returned the chip right away, but the two other chips worked ok. For using the SAM-M8Q, I had to modify the OLA firmware, since the GNSS logging firmware from Sparkfun only supports the newer chips. However, installing new firmware on the OLA is very easy.

The one caveat with the OLA-Quiic GPS setup is that reliable communication requires a small change on the GPS chip: the "jumper" for the I2C communication needs to be scratched out. This is quite easy, takes just a minute or two, and there is a video tutorial on the Sparkfun site. Without this small modification, the data can be corrupted, which leads to lost data points due to checksum errors. 

The more expensive NEO-M9 GPS chips theoretically have several advantages over the older M8 GPS chips, which include the option to use 4 GNSS systems at the same time (vs. 3 for the M8), and faster data rates of up to 25 Hz. In reality, however, I discovered that the M9 chip reduces the maximum number of satellites used to 16 when logging at 10 Hz or above. This reduces the advantage of the extra GNSS system significantly, to a point where it is questionable that the data from the M9 chips is indeed "better" than data from M8 chips.

Compared to the first solution (Openlog and Beitian GPS), the OLA approach is significantly more expensive. If you include the cost for a battery (about $10), the total cost is about $100 with a M8 chip, and about $130 for the M9 chip. 

The green boards in the OLA setup are 4 cm x 8 cm, a size that fits into a waterproof housing for a GoPro 3 which is available for about $10 on Amazon, and can easily be attached to a windsurf helmet.

3. Adafruit Clue and Sparkfun Quiic GPS

While searching for other GPS chips that also use Sparkfun's Quiic cable system, I discovered the Adafruit Clue.  At $40, it's a bit cheaper than he Openlog Artemis. It does not have a built-in SD card for logging, but it does have a display that seems just large enough for reading speeds while windsurfing.  For initial tests, the Clue offers 2 MB of internal flash storage that can be used to store GPS data, but that's only enough for at most one hour at 5 Hz.

Another thing about the Clue that I found attractive is that it can be programmed using Python, a programming language that is much more modern (and popular) than the C / C++ language used for the OLA. After developing software in Java for the last couple of decades, going back to C / C++ is quite painful, so Adafruit's "CircuitPython" looked quite tempting.

The language change turned out not quite as easy as I had hoped. While there are plenty of things in Python that I love, I have gotten used to seeing any typing and syntax errors right away while I type, and to access the source code for any library classes with a single keystroke. That's not possible in Python, which assumes "if you type something I have not seen before, you probably mean it", and reveals errors much later, when the mistyped piece of code actually runs. Documentation is a very different thing, too. The first issue is that Python has changed a lot of time, so you often see "do this in Python < 3, but this in Python 3.0-3.5, and that in the newest versions". To this, we need to add that CircuitPython is a variation of MicroPython, which itself is a "dialect" of Python; and that error message you get during runtime are often quite misleading. All that means that little things that should have taken just 15 minutes often took many hours. But eventually, I had some Python scripts that received the data from the GPS, logged them, and showed speeds on he screen.

For windsurfing use, though, being able to log sessions longer than one hour is essential, and that's where things got difficult. Staying with the "plug and play" theme, I wanted to use a variation of the Openlog that has a Quiic connector, which is advertised as "the smarter and better looking cousin to the extremely popular OpenLog". Sounds fantastic! Well, I should have known better than to believe the marketing guys...

The first issue I encountered was that I2C communication, which the Quiic connectors use, is very different from serial communication. Think of serial communication as a TV that's alway on, blaring away in the background. The original Openlog is then a voice recorder that will record the noise from the TV as soon as it is turned on.

In contrast, I2C communication is more like Siri or Alexa: it will sit around, patiently waiting until you ask it a direct question. Without a direct question, it won't say a word - the "mute" button stays pressed. So instead of just connecting a few pins, the software on the Clue actually needs to tell the Quiic Openlog "now save these data, please".

That's not really hard, once you understand the difference, and I had the Quiic Openlog recording data from the GPS through the Adafruit Clue quickly. But reading these data was an entirely different issue: files always were a lot shorter than expected, and data were corrupted. A few hours of detective work traces the cause down to the firmware in the Quiic Openlog (QO). Whenever the QO got a "packet" of data, it would know the length of the data, but nevertheless determine the length of the data again, using the "good old" strlen function in C. Anyone who ever did a bit of programming in C know will know what the issue with logging binary data is: strlen searches for the first "0", which is used in C to mark the end of a string. But binary data often contain "0", which does not mean "end"! 

Fixing this in the QO firmware was a trivial thing, even for someone who has a strong dislike of C. But updating the firmware on the Quiic Openlog chip was a very different story, since that has to be done through a serial-to-USB converter connected to some holes on the QO. I still had one of those lying around, but all attempts to "burn" the firmware failed. Since I can be stubborn, I eventually succeeded, after soldering pins to the UART holes, and connecting the Quiic cable to supply power. After that, I was finally able to log GPS data to a file on the micro SD card.

But obviously, this is no longer a plug-and-play solution, so I looked for alternatives. The Adafruit Clue follows ideas from the micro:bit board, so theoretically, it allows making electric connections with screws. And windsurfers know how to screw, from plenty of training with fin, even before foils with their screw multitude became popular. 

In comes the gator:log: another version of the Openlog, this one with micro:bit-like holes. A quick look at the diagram seemed to indicate that the holes would like up, and a "Clue-gatorlog-screw" solution might be possible. Alas, that was too optimistic. In their wisdom, Adafruit decided that having vary the distance between the holes in the Clue, so that only 3 of the necessary 4 holes line up. Arrgghh! But it turned out that if you tweak things a bit, you can get everything screwed together. Here's a closer look:

Adafruit Clue - M9 - Gator:log

When I tested it, this setup worked .. mostly. About every 10-15 minutes, there would be a gap in the data, with 3-4 missing points (and that was after I fixed the code so that it would not just stop due to garbage collection issues - but that's a story for another time). Even worse, I sometimes got obscure errors in the I2C communication. It seems that the I2C bus sometimes requires pullup resistors to work well. The "sometimes" depends on factors like cable lengths, how the port on the chip is wired, and which other thingies are on the I2C bus. In the picture above, you may notice the black chip in the middle. That's an I2C switch, intended to turn off the GPS when not logging. But when I connected this switch, the I2C communication became really unreliable, to the point were it was definitely useless. Perhaps all this could be fixed by soldering in a couple of resistors - but that's not plug and play anymore.

After two close misses, it was time to look against something else. Ideally, something with a screen, an SD card slot, a battery, and USB and I2C cable connections. Surely, such a thing must already exist?

4. M5Stack

My countless hours of searching Amazon, Google, Sparkfun, and Adafruit for new gadgets seemed to come to fruition when I discovered the M5Stack: a 5 x 5 cm thingies with a powerful microprocessor, LED screen, SD card, I2C and USB cable connectors, and plenty of connection options - all for less than $40, and in little housing that almost looks like a Motion or GW-52 GPS. Too good to be true?

Perhaps. I certainly ran into quite a few problems. The first one was that the built-in battery did not work for more than a few minutes at first, and then gave up completely. Since the battery was very small, and one with 5x more capacity was available for less than $10, I ordered that one ... only to find out that it was not the battery, but rather the internal wiring that was broken. Bummer, but not a killer - everything works fine when hooking up a USB battery pack.

The only issue when hooking up USB was that the M5stack would issue a very annoying, high-pitched squeak. That's a known issue that M5 just never bothered to fix. Turning the amplifier down helped only a little, so I ended up simple removing the speaker.

The next issue was trying to get the Sparkfun I2C chips to work with the M5. In comparison, the Adafruit Clue was (a) easier and (b) better. Easier because the Python documentation for the M5stack is very poor (to phrase that as positively as I can ... don't ask me after I've had a few beers, or I will use very different words!). The Clue was better because I could at get hour-long and longer recordings that were mostly complete most of the time. With the M5stack, I'd get some communication between the GPS and the board sometimes

I had also ordered another "module" for the M5stack that promised to allow the use of USB peripherals. That would have been a very neat way to use a cheap M8-based USB GPS chip. Alas, once I got the module and spent a few hours looking for documentation, I realized that M5 provided absolutely no Python support for the module. Seems they are so busy coming up with multiple different versions in different sizes that they don't have time to provide decent software support (or even just organized documentation).

After quite a few frustrating hours, I finally remembered that I had some more Beitian BN880 GPS chips lying around, and matching cables that just might be useable with the pins that the M5stack has at the bottom. Finally, something worked! Here's a closeup:

No soldering, so it qualified as plug-and-play. Now, the lack of a working battery in the M5stack ended up not being a problem anymore, since I used a flat USB power pack and some velcro to put everything together (check the first picture in this post). 

I have tried the M5stack-BN880 and the OLA-M8 combo a few times on the water windsurfing and foiling, and the results were just as expected: very close to the results I get with my "approved" prototypes or Motion GPS units, all of which use very similar GPS chips. Here's a short section from a recent windsurfing session:

Speeds are very similar. The "noise" does not align well mostly because I had the Motion and the M5 on different arms, and the OLA on top of my helmet. When recording at 5 Hz or higher, we can actually see different movements of different body parts in the GPS tracks. The error estimates (lower panel) are slightly lower for the OLA-SAM M8, which reflects that the GPS on top of the helmet had the clearest view of the GPS satellites, without the signal distortions from head and body that the GPS units on the arms had. After several sessions with similar results, there is no doubt that the two "plug and play" GPS units based on the Openlog Artemis with the Sparkfun SAM-M8 GPS and the M5stack with the Beitian BN880 are suitable for competitions like the GPS Team Challenge, since the quality of the data they produce is at least comparable to the quality from other approved and currently commercially available units.