ZOE GPS proto board / ZOE setup with examples


  • Full Member
  • ***
    • Posts: 27
    • View Profile
In this post it is described how to change the configuration of an u-blox M8 GNSS receiver using UART communication. Focus is on the u-blox ZOE-M8B. Most examples are configuration changes necessary for model rocket applications.

Ben Rose  gave me the opportunity to test and evaluate a ZOE GPS prototype board, see the posts “GPS TinyShield does not provide actual altitude” and “ZOE GPS proto board in 35 mm model rocket application / Introduction” on the forum.

The ZOE GPS prototype board that I received is a bit bigger board, about TinyScreen+ size, with u-blox ZOE-M8B GNSS, Bosch BME280 (combined humidity and pressure sensor), ST LSM9DS1 (3D accelerometer, 3D gyroscope and 3D magnetometer) and microSD slot.

I connected the ZOE proto board with a TinyZero using the TinyShield expansion bus. Because of components on both ZOE proto board and TinyZero it is necessary to put another board in between. In my 35 mm model rocket application I finally used a Barometric pressure TinyShield between ZOE proto and TinyZero, but another board like the standard TinyShield proto board with both top and bottom bus expansion also works fine.

By default u-blox M8 GNSS receivers give 6 NMEA (GGA, GLL, GSA, GSV, RMC and VTG) messages at 1 Hz at 9600 baud rate and take into account  a “portable” platform model e.g. assuming low acceleration and a maximum vertical velocity of 50 m/s.

The ZOE-M8B has a bit different firmware (SPG 3.51) than most other u-blox M8 receivers optimizing a very low power consumption. It has “Aggressive with 1 Hz” as default power mode setup (PMS) related to its  “Super-E mode”.  With static tests I found that the ZOE, which I had given a 5Hz update rate, changed this automatically to 1 Hz after about 5 minutes presumably to reduce power consumption.

I also found that SBAS (Satellite-based augmentation system) is not enabled by default in the ZOE in contrast with e.g. the SAM-M8Q GNSS receiver, so if this is not changed, the ZOE will never provide a Differential GPS fix taking into account some provided corrections. In the ZOE-M8B datasheet, see [1],  it is stated “Tracking SBAS satellites uses power and requires a long decoding time. It is recommended to disable SBAS for Super-E mode.”

For many applications it will be necessary to modify the configuration of the ZOE-M8B (or another M8 GNSS receiver). In this post I will elaborate how to change the ZOE configuration in the setup part of the TinyZero code and how to gather the related evidence.

The I2C pins of the u-blox ZOE-M8B GNSS on the ZOE GPS prototype board  are not connected, so it is not possible to use I2C for control. The backup voltage pin is not connected either, so all commands (following the UBX protocol) to modify the default ZOE setup have to be given through the UART1 which is connected to IO0, IO1 and ground, so available at the TinyZero under the HW UART “Serial”.


For my 35 mm model rocket application I made the following changes:

-   Disable all NMEA messages (6 x UBX-CFG-MSG) in order to ease catching the ZOE responses (acknowledge, results of polling) after other UBX commands
-   Change the dynamic platform model (UBX-CFG-NAV5) to 8 (Airborne <4g)
-   Change power mode setup (PMS) to "balanced" (UBX-MSG-PMS)
-   Change the NMEA message rate to 5 Hz (200 ms) (UBX-MSG-RATE)
-   Change the baud rate to 57600 (UBX-MSG-PRT)
-   Enable NMEA messages GGA, GSA and VTG again (UART1 only) (3x UBX-CFG-MSG)

Additionally, I will also show how to enable SBAS by UBX-CFG-GNSS, because after this command the ZOE will reset and provide both acknowledge (in UBX format) and TXT strings (in NMEA format).

When enabling SBAS it is also important to check and perhaps change the SBAS satellite PRN masks to enable the right satellites depending on the area you are in. For Europe the right ones are already in the default configuration but it is advised to make the selection as small as possible. I have experimented myself with enabling EGNOS satellites PRN 123 and PRN136 only by UBX-CFG-SBAS.

In order to see if SBAS satellites are received by the ZOE I have included NMEA GSV messages and left the data rate at 1 Hz in the example code.

Connect with u-blox u-center

The u-blox M8 receiver description including protocol specification, see [2], provides a good overview and  a solid description of the M8 GNSS receiver family, NMEA protocol messages and UBX protocol messages.

However, it is not that easy to compose the UBX messages based on the document only. This holds especially for the long and more complicated commands like UBX-CFG-NAV5 and UBX-MSG-GNSS, but also for the shorter commands it is simpler and safer to use examples that can be derived from outputs from the u-blox program u-center, GNSS evaluation software for Windows [3].

To interface with u-center I used a simple passthrough code on the TinyZero (“SerialPassthrough_a.ino”, see first attachment) which is directly derived from the code from the examples in the Arduino program (tab File, Examples,  04.Communication, SerialPassthrough). Main adaptation is that Serial1 has been replaced by SerialUSB. The attached code can be used by the Arduino program for verification and upload to the TinyZero.

In this way all UART communication from ZOE to TinyZero is translated to communication from TinyZero to PC and vice versa. The u-center program has to be connected to the actual COM port, which should be the same as used to upload the TinyZero.

In u-center you can see the NMEA strings passing by on the Text console, but also the detailed configuration in the Configuration View. The configuration can be changed in a very user friendly way and checked by polling. These changes will be lost after switching off the ZOE, because local saving is not possible in case of the ZOE GPS prototype board.

However, you can save the actual configuration in a .txt file (Tools, Receiver Configuration, Configuration file (provide name) and Save configuration (push button Transfer GNSS -> File)) for reference.

The default configuration file of the ZOE-M8B that I saved can be found in the 2nd attachment.

The configuration file includes many UBX command kernels. By comparing the configuration file  after a change in u-center with the default one you can detect the difference(s).

Nearly all configuration changes can be worked out this way and even tested. An exception is changing the baud rate, which works fine in a direct connection with an u-blox M8 receiver, but does not in an indirect one with passthrough. In u-center it is possible to change the power mode setup (PMS), but this is not one-to-one reflected in a kernel of the UBX-CFG-PMS message, because that one is not in the list.

Compose a UBX command / example to disable NMEA GGA strings

Let us first disable the NMEA GGA message in u-center. In u-center we go to tab View, Configuration View, MSG(Messages), look for message F0-00 NMEA GxGGA and disable all ports (I2C, UART1, etc).

Then we push the Send button and check if all ports remain enabled by pushing the Poll button. When we save the configuration to file under another name, we can find in this file a line with text:

CFG-MSG - 06 01 08 00 F0 00 00 00 00 00 00 00
While the same line in the default configuration shows as:

CFG-MSG - 06 01 08 00 F0 00 01 01 00 01 01 00

In these lines stands “06 01” for CFG-MSG, “08 00” for the length (8 bytes) of the “payload” part of the UBX message and “F0” for GxGGA. The meaning of all bytes is described in [2], par.

We now have the kernel of the UBX message to disable the transmission of NMEA GGA over all ports:  06 01 08 00 F0 00 00 00 00 00 00 00 (all hexadecimal bytes 0x06 etc.)
We just need to add the UBX header with  “B5 62” in front of the kernel and to add the 2 byte standard UBX checksum, see [2], par. 32.2 and 32.4.

It is possible to calculate the checksum in the TinyZero code, but I have chosen to do it in a simple semi-manual excel file, see 3rd attachment for better understanding how it works.

The checksum is important. If the checksum is not correct, the ZOE does not react at all.

The total code for this message is (all (hexadecimal) bytes):
B5 62 06 01 08 00 F0 00 00 00 00 00 00 00 FF 23

In the setup code the char bufferMSG[16] is filled with this sequence and send to the ZOE with a “serial. write”, see for complete code, “GPS_Monitor_ZOE_a.ino”,  in the  4th attachment.

The composition of the other messages is done in the same way, so the code to enable NMEA GGA again for UART1 only is e.g.:
B5 62 06 01 08 00 F0 00 00 01 00 00 00 00 00 28

In some cases it also helps if the default configuration of another u-blox M8 GNSS receiver, e.g. SAM-M8Q is available for comparison.

Catching ZOE responses

After receiving a command the ZOE will react with an acknowledge message, also in UBX format. This can be an “ack-ack” or an “ack-nack”, depending on whether or not the message was processed correctly by the ZOE. See [2], par. 32.5.1.

The “ack-ack” of all CFG-MSG commands is the same:

B5 62 05 01 02 00 06 01 0F 38

So it is important to group commands in a logical way. The 4th byte 0x01 means that it is an “ack-ack”, 0x06 0x01 indicates CFG-MSG.

In the code (see attachment 4)  I have included a number of while loops to gather the response of the ZOE after a group of commands.

Most responses are in UBX format, so a series of bytes (hexadecimal), but in some cases there are still some NMEA strings coming (series of char), so it is important to try to distinguish between both formats. This is done in a oversimplified non-exhaustive way, just to ease the interpretation of the data. NMEA strings should start with $ (= 0x24), while UBX strings start with 0xB5. 0xB5 is not part of an NMEA string, but 0x24 can be part of an UBX message.

Furthermore, I have chosen to display UBX messages with commas between the bytes (and omitting leading zeros) to improve the readability and to simplify pasting e.g. in an excel file for comparison.

So “ack-ack” of CFG-MSG is transformed to:


After the UBX-CFG-GNSS command to enable SBAS (with bufferGNSS[68]), the ZOE does not react only with an “ack-ack” but also resets GNSS and gives 3 NMEA TXT messages:

$GNTXT,01,01,02,Resetting GNSS*3B

In some important cases I asked for confirmation of the execution of the command with more detail.
This is done by sending a polling message, e.g. to check if the dynamic platform model has been changed (in this case to 8), the polling message for CFG-NAV5, only 8 bytes, is sent:

B5 62  06 24  00 00 2A  84

The ZOE will react with the complete CFG-NAV5 and the related “ack-ack”(commas are added):


Example code for monitoring and logging ZOE output (setup and after)

As already mentioned, attachment 4 contains an example code “GPS_Monitor_ZOE_a.ino” for changing the ZOE code (in setup) and monitoring the results on PC or logging these on microSD or both at the same time.

The code includes many lines in void setup() and just a few in void loop ().

After first definitions and declarations Void setup() starts with lines to secure ZOE GPS SAFEBOOT_N and RESET_N pins in high state to avoid problems.

A string buffer (buffer1) is used to overcome waiting problems with writing the microSD card.

For the bulk logging process writing is only done in blocks of 512 bytes. The size of buffer1 is rather big, 2k Bytes, but the TinyZero can handle bigger data memories.

After opening the .txt logging file with an updated 3 digit number file name, the ZOE configuration is modified:

-   suppress all default NMEA strings (GGA, GLL, GSA, GSV, RMC and VTG) to be sure that acknowledge and polling messages are clearly received
-   Gather ZOE response (6x “ack-ack”), (with some NMEA strings in the pipeline)
-   Adaptation of CFG-GNSS to include SBAS (leading to reset GNSS)
-   Gather ZOE response (“ack-ack” and  3 $GNTXT strings),
-   Adaptation of dynamic platform model (->8 = Airborne <4g) using NAV5
-   Prepared for alternative PMS: Adaptation of power mode setup (PMS) to “full power”
-   Adaptation of power mode setup (PMS) to "balanced"
-   Gather ZOE response (2x “ack-ack”)
-   Polling NAV5 in order to check the correct adaptation of the dynamic platform model
-   Polling PMS in order to check the adaptation of the power mode setup
-   Polling GNSS in order to check the adaptation of the configuration to include SBAS
-   Prepared for: RATE -> 5 Hz (200ms) / Note: Prepared for, because of additional enabling of NMEA GSV will can result in many NMEA strings
-   Gather ZOE response (results of polling NAV5, PMS and GNSS plus 3x “ack-ack”)
-   Modification of baudrate to E1 (225) x 256 = 57600 using PRT
-   Enable NMEA strings GGA, GSA, GSV and VTG on UART1 only
-   Gather ZOE response (4x “ack-ack”), followed by first NMEA strings

Void loop() writes incoming char in buffer1. Buffer1 has overload protection. In case of overload some incoming char will not be written. Such an event will be visible in the output by some blank lines.

When the contents of buffer1 has reached 512 bytes it is checked if the microSD is available for write, and if so, a block is written.

A 5th attachment containing the first part of a logging on microSD will follow as example of an output file.

Final remark

If there are questions or errors found, please let me know.

[1] ZOE-M8B datasheet (ZOE-M8B_DataSheet_(UBX-17035164).pdf): https://www.u-blox.com/en/docs/UBX-17035164
[2] u-blox8-M8_ReceiverDescrProtSpec_(UBX-13003221).pdf): https://www.u-blox.com/en/docs/UBX-13003221
[3] u-blox program u-center: https://www.u-blox.com/en/product/u-center



  • Full Member
  • ***
    • Posts: 27
    • View Profile
Herewith the  5th attachment containing the first part of a logging on microSD as example of an output file.


Ben Rose

  • Administrator
  • Hero Member
  • *****
    • Posts: 357
    • View Profile
Hi Willem,

I've just had time to fully read the post. This is great work and thanks for posting it. I've only skimmed the code, but it looks very helpful- I seem to recall finding very little Arduino example code to interface with the uBlox module, although maybe I just missed it. Like you say, the documentation is all 'there', but it's not easy to get started creating the commands. The method of listening to the u-center commands is a good workaround.

Somewhat unfortunately we decided to do a quick test with the ZOE-M8Q, which is only a minor hardware difference, before producing hardware. I'll update here with progress on that.



  • Full Member
  • ***
    • Posts: 27
    • View Profile
Hi Ben,

with respect to existing examples of Arduino code to interface with u-blox modules I would like to mention the “Sparkfun Ublox Arduino Library”. This large code package is much more focused on the I2C interface than the UART, but it can provide some learning experience with the u-blox GNSS receivers.

If you plan to use the ZOE-M8Q instead of the ZOE-M8B, it means that the “normal” SPG 3.01 firmware version is applicable, so some peculiar default settings related to the “Super-E mode” of the ZOE-M8B have gone. This means that adaptation of power mode setup (PMS) and change of CFG-GNSS to include SBAS can be skipped.

If I am right, it also means 3.3 V supply instead of 1.8 V, so perhaps the level shifter could be left out.
If you include the ZOE-M8Q, is it perhaps possible to provide access to the I2C pins?
With my model rocket application with UART only I have shown that it is not strictly necessary to have access to the I2C, but access to both UART and I2C will certainly increase the attractiveness of the new board.



  • Sr. Member
  • ****
    • Posts: 50
    • View Profile
WillemH said...

"With my model rocket application with UART only I have shown that it is not strictly necessary to have access to the I2C, ]but access to both UART and I2C will certainly increase the attractiveness of the new board"

I concur...john

Ben Rose

  • Administrator
  • Hero Member
  • *****
    • Posts: 357
    • View Profile
Thanks for the feedback, really appreciate it. Based on this and some review here, I think we will try to make this a 20x20mm TinyShield compatible with all processor boards, and use the ZOE-M8Q with UART as well as I2C if I can route it. The origins of the TinyScreen+ format board were a pretty specific use case. I'll update here, we'll build a few extra prototypes.


  • Sr. Member
  • ****
    • Posts: 50
    • View Profile

How can one charge the battery if the UART (USB port, I assume) is being used for this board? Let me know if I'm off base on this.

BTW, a 20mm x 20mm board would be fantastic!



SMF spam blocked by CleanTalk