create new tag
view all tags

The Neo 6M GPS receiver

Most GPS receivers use a UART to communicate with their hosts and the Neo 6M is no exception. The ESP32 has 3 hardware UARTs with the following default connections:

UART number default Rx,Tx GPIO pins
0 3,1
1 9,10
2 16,17
On our system UART 0 is reserved for REPL, GPIO 9 and 10 are not pulled out to the connector and GPIO 16,17 are used by PSRAM. Fortunately the ESP32 allows to re-map UARTs to just about any GPIO pin using the GPIO matrix and the MicroPython driver supports the re-mapping. We can define a UART as follows: uart2=machine.UART(2, baudrate=9600, rx=21, tx=22, timeout=10000)

For more information about the ESP32 UART driver in MicroPython see


The card on which the Neo 6M GPS receiver is mounted has 4 connection pins (starting from the left):

Pin on Neo 6M Pin on ESP32 bus
Vcc 3.3V
Rx Rx: D1 = GPIO 22
Tx Tx: D2 = GPIO 21, only needed if you want to modify parameters on the Neo 6M
Gnd Gnd
Only Pin D2 or GPIO 21 is actually used and as you can tell from the instantiation of UART2 shown above the Neo 6M receiver communicates on 9600 baud.

Here is a photo of the device:


Reading NMEA sentences with the ESP32

Once the connection is made and the UART instantiated all you need is an endless loop to read the UART line by line. This is what you will see if you print the result:


These are sentences of the NMEA protocol. You will need a parser that extracts the relevant information from these messages. It is not too difficult to write such a parser yourself but why do you want to do it if the job has already be done for you? In fact Peter Hinch has a github repository with gps drivers containing all you need:


He uses the NMEA parser from https://github.com/inmcm/micropyGPS but adapted it to his asynchronous driver.

Connecting the GPS receiver to your PC

In order to read out the GPS receiver from the PC we need a USB to serial converter:

usb2serial.png As can be seen on the photo the connections must be made as follows (pin 1 is the leftmost pin)

Pin no on the USB to serial converter Label Connection on GPS receiver
1 DTR nc
2 RX Tx
3 TX Rx
4 VCC 3.3V
5 CTS nc
If you now communicate with the USB to serial adapter on /dev/ttyUSB0 with a terminal emulator like minicom or gtkterm running on 9600 baud you should see NMEA messages sent be the GPS receiver.


ublox u-center

ublox provides a Windows application for its GPS receivers named u-center which you can download from https://www.u-blox.com/en/product/u-center. Its user guide can be found at https://www.u-blox.com/sites/default/files/u-center_Userguide_%28UBX-13005250%29.pdf. It is possible to run this application on Linux using the Windows emulator wine. u-center allows you to connect to a Windows com port in order to communicate with the receiver. When running the u-center installation you will get the executable in
~/.wine/drive_c/Program Files (x86)/u-blox/u-center_v20.06.01

Finally we must figure out to which Windows com port our USB to serial adapter corresponds to. Looking at ~/.wine/dosdevices shows that /dev/ttyUSB0 is mapped to com33.


ublox GPS receivers use 2 different protocols

  • the NMEA protocol
  • a proprietary binary protocol, which not only transmits GPS data but also allows to configure the receiver
As mentioned above, the standard baud rate on the ublox neo 6M is 9600 baud, which is very slow. It takes ~ 600 ms to transmit the batch of NMEA sentences the receiver sends every second. When trying to parse the sentences as they come in real time I see many CRC errors, which may come from the fact that there is simply not enough time left for the data treatment before the next batch comes in.

u-center allows you to change the baud rate (I selected 115200 baud, which I also use to communicate with the ESP32) and to save this change in battery backed up RAM such that it can be recovered when the receiver is restarted after a power down.

Here is a screen dump of the running u-center application:



While u-center is a Windows application and can only be run on Linux through Windows emulation, there is also a GPS suite that runs natively on Linux named gpsd.

The GPS daemon gpsd connects to a GPS receiver and provides its data to clients over a TCP connection.You can find it on https://gpsd.gitlab.io/gpsd/index.html.

Check the gpsd documentation and in particular INSTALL.adoc and build.adoc in the source repository for information on how to build and install gpsd.

Once installed we first make sure that the daemon is not already running:
systemctl stop gpsd
systemctl stop gpsd.socket 

To check that the GPS receiver is sending data we can check with gpscat:

gpscat -s 115200 /dev/ttyUSB0


Then we can run gpsd as a foreground process (-N), specify the baud rate (-s 115200) and the serial port to which the neo 6M is connected (/dev/ttyUSB0):

gpsd -N -s 115200 /dev/ttyUSB0

Once the daemon is running we use gpspipe to see the NMEA sentences on the console: gpspipe -r

This time the NMEA sentences are not picked up from the USB to serial converted but from the TCP/IP port 2947 where gpsd provides information to its clients.


Now that we know that gpsd is working normally we can start gspmon which extracts basic GPS information like latitude, longitude, altitude and time and some information about the satellites seen.


Finally we run xgps to give us a graphical representation of the satellites in the sky.


More programs are part of gpsd but I will let you discover those yourself.

Showing GPS position information on a map

There is a nice tutorial from the Linux journal describing how to use gpsd when taking GPS information from a mobile phone:

What we will try to do is taking the data from the ublox neo 6M connected to the PC through the USB to serial connection instead of using the mobile phone.

The strategy will be this:

  • Get the GPS data from the neo 6M connected through a USB to serial adapter to the PC and send the information to gpsd
  • Run gpspipe or gpsmon to verify that the data are seen.
  • Send the data to OpenStreetView and display them in marble. This is done with the map.qml file described in the second part of the tutorial
Following the tutorial step by step here is a screen dump of the result:


Getting NMEA information for gpsd from the ESP32

gpsd does not only allow reading GPS information from the serial line but it can also get this information from a TCP of UDP socket. It should therefore be possible to keep the ublox neo M6 connected to the ESP32 and write a simple TCP server (named ser2tcpServer.py. I use port 29998 for this server) which listens to a connection request from gpsd and then reads NMEA sentences from the ESP32 UART and transfers them to gpsd over the TCP socket. To get things to work we must:

  • start the ser2tcpServer.py (on the ESP32)
  • start gpsd with tcp://IP_OF_ESP32:29998
Now you can run gpspipe -r to see the NMEA messages transferred or gpsmon to get them decoded.
Finally you pipe the messages from gpsd back into a socket with

gpspipe -r | nc -l 29999

from where they are picked up by map.qml. The result will be the same map as shown above but the GPS source has been shifted from the PC serial port to the ESP32.

-- Uli Raich - 2020-07-01


Topic attachments
I Attachment History Action Size Date Who Comment
PNGpng dosdevices.png r1 manage 91.0 K 2020-08-23 - 10:17 UliRaich  
PNGpng gps.png r1 manage 169.9 K 2020-07-01 - 09:03 UliRaich  
PNGpng gpscat.png r1 manage 91.2 K 2020-08-24 - 18:40 UliRaich  
PNGpng gpsdata.png r1 manage 89.8 K 2020-07-31 - 13:04 UliRaich  
PNGpng gpsmap.png r1 manage 182.2 K 2020-08-24 - 18:39 UliRaich  
PNGpng gpsmon.png r1 manage 92.8 K 2020-08-24 - 18:39 UliRaich  
PNGpng gpspipe.png r1 manage 106.9 K 2020-08-24 - 18:45 UliRaich  
PNGpng nmeaPC.png r1 manage 107.5 K 2020-08-23 - 10:17 UliRaich  
PNGpng u-center.png r1 manage 186.0 K 2020-08-23 - 10:17 UliRaich  
PNGpng usb2serial.png r1 manage 268.7 K 2020-08-23 - 10:17 UliRaich  
PNGpng xgps.png r1 manage 140.0 K 2020-08-24 - 18:45 UliRaich  
Edit | Attach | Watch | Print version | History: r8 < r7 < r6 < r5 < r4 | Backlinks | Raw View | Raw edit | More topic actions
Topic revision: r8 - 2020-08-28 - UliRaich
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2008-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback