UART / Serial

After I2C and SPI, the third most popular "bus" protocol used is serial (also sometimes referred to as 'UART'). This is a non-shared two-wire protocol with an RX line, a TX line and a fixed baudrate. The most common devices that use UART are GPS units, MIDI interfaces, fingerprint sensors, thermal printers, and a scattering of sensors.

One thing you'll notice fast is that most Linux computers have minimal UARTs, often only 1 hardware port. And that hardware port may be shared with a console.

There are two ways to connect UART / Serial devices to your Jetson Nano. The easy way, and the hard way.

We'll demonstrate wiring up & using an Ultimate GPS with both methods.

Adafruit Ultimate GPS Breakout - 66 channel w/10 Hz updates

PRODUCT ID: 746
We carry a few different GPS modules here in the Adafruit shop, but none that satisfied our every desire - that's why we designed this little GPS breakout board. We believe this is...
$39.95
IN STOCK

The Easy Way - An External USB-Serial Converter

By far the easiest way to add a serial port is to use a USB to serial converter cable or breakout. They're not expensive, and you simply plug it into the USB port. On the other end are wires or pins that provide power, ground, RX, TX and maybe some other control pads or extras.

Here are some options, they have varying chipsets and physical designs but all will do the job. We'll list them in order of recommendation.

The first cable is easy to use and even has little plugs that you can arrange however you like, it contains a CP2102

USB to TTL Serial Cable - Debug / Console Cable for Raspberry Pi

PRODUCT ID: 954
The cable is easiest way ever to connect to your microcontroller/Raspberry Pi/WiFi router serial console port. Inside the big USB plug is a USB<->Serial conversion chip and at...
OUT OF STOCK

The CP2104 Friend is low cost, easy to use, but requires a little soldering, it has an '6-pin FTDI compatible' connector on the end, but all pins are broken out the sides.

Adafruit CP2104 Friend - USB to Serial Converter

PRODUCT ID: 3309
Long gone are the days of parallel ports and serial ports. Now the USB port reigns supreme! But USB is hard, and you just want to transfer your every-day serial data from a...
$5.95
IN STOCK

Both the FTDI friend and cable use classic FTDI chips, these are more expensive than the CP2104 or PL2303 but sometimes people like them!

FTDI Friend + extras

PRODUCT ID: 284
Note: These use genuine FTDI chips, either we purchase them or they are manufactured to our specifications with the requirement of genuine FTDI chips 10/22/14 -
$14.75
IN STOCK

FTDI Serial TTL-232 USB Cable

PRODUCT ID: 70
Just about all electronics use TTL serial for debugging, bootloading, programming, serial output, etc. But it's rare for a computer to have a serial port anymore. This is a USB to...
OUT OF STOCK

There is also a GPS module with integrated serial available which works like the GPS breakout connected to the USB to TTL Serial cable.

Adafruit Ultimate GPS with USB - 66 channel w/10 Hz updates

PRODUCT ID: 4279
The Ultimate GPS module you know and love has a glow-up to let it be easily used with any computer, not just microcontrollers! With the built in USB-to-Serial converter, you...
OUT OF STOCK

You can wire up the GPS by connecting the following

  • GPS Vin  to USB 5V or 3V (red wire on USB console cable)
  • GPS Ground to USB Ground (black wire)
  • GPS RX to USB TX (green wire)
  • GPS TX to USB RX (white wire)

Once the USB adapter is plugged in, you'll need to figure out what the serial port name is. You can figure it out by unplugging-replugging in the USB and then typing dmesg | tail -10 (or just dmesg) and looking for text like this:

At the bottom, you'll see the 'name' of the attached device, in this case its ttyUSB0, that means our serial port device is available at /dev/ttyUSB0

The Hard Way - Using Built-in UART

If you don't want to plug in external hardware to the Jetson Nano you can use the built in UART on the RX/TX pins. Unlike the Raspberry Pi, the Jetson Nano isn't using the RX/TX pins for a console, those are on a different UART peripheral, so you should be good to go!

You can use the built in UART via /dev/ttyTHS1

Wire the GPS as follows:

  • Connect the Jetson Nano +3.3V pin to the Vin pin on the GPS
  • Connect the Jetson Nano Ground pin to the GPS Ground pin
  • Connect the Jetson Nano UART TX (#8) to the GPS RX pin
  • Connect the Jetson Nano UART RX (#10) to the GPS TX pin

Install the CircuitPython GPS Library

OK onto the good stuff, you can now install the Adafruit GPS CircuitPython library.

As of this writing, not all libraries are up on PyPI so you may want to search before trying to install. Look for circuitpython and then the driver you want.

(If you don't see it you can open up a github issue on circuitpython to remind us!)

Once you know the name, install it with

sudo pip3 install pyserial adafruit-circuitpython-gps

You'll notice we also installed a dependancy called pyserial. This is a great thing about pip, if you have other required libraries they'll get installed too!

We also recommend an adafruit-blinka update in case we've fixed bugs:

sudo pip3 install --upgrade adafruit_blinka

Run that code!

The finish line is right up ahead. You can now run one of the (many in some cases) example scripts we've written for you.

Check out the examples for your library by visiting the repository for the library and looking in the example folder. In this case, it would be https://github.com/adafruit/Adafruit_CircuitPython_GPS/tree/master/examples

Lets start with the simplest, the echo example:

# Simple GPS module demonstration.
# Will print NMEA sentences received from the GPS, great for testing connection
# Uses the GPS only to send some commands, then reads directly from UART
import time
import board
import busio

import adafruit_gps


# Define RX and TX pins for the board's serial port connected to the GPS.
# These are the defaults you should use for the GPS FeatherWing.
# For other boards set RX = GPS module TX, and TX = GPS module RX pins.
RX = board.RX
TX = board.TX

# Create a serial connection for the GPS connection using default speed and
# a slightly higher timeout (GPS modules typically update once a second).
uart = busio.UART(TX, RX, baudrate=9600, timeout=30)

# for a computer, use the pyserial library for uart access
#import serial
#uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=3000)

# Create a GPS module instance.
gps = adafruit_gps.GPS(uart)

# Initialize the GPS module by changing what data it sends and at what rate.
# These are NMEA extensions for PMTK_314_SET_NMEA_OUTPUT and
# PMTK_220_SET_NMEA_UPDATERATE but you can send anything from here to adjust
# the GPS module behavior:
#   https://cdn-shop.adafruit.com/datasheets/PMTK_A11.pdf

# Turn on the basic GGA and RMC info (what you typically want)
gps.send_command(b'PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn on just minimum info (RMC only, location):
#gps.send_command(b'PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Turn off everything:
#gps.send_command(b'PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0')
# Tuen on everything (not all of it is parsed!)
#gps.send_command(b'PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0')

# Set update rate to once a second (1hz) which is what you typically want.
gps.send_command(b'PMTK220,1000')
# Or decrease to once every two seconds by doubling the millisecond value.
# Be sure to also increase your UART timeout above!
#gps.send_command(b'PMTK220,2000')
# You can also speed up the rate, but don't go too fast or else you can lose
# data during parsing.  This would be twice a second (2hz, 500ms delay):
#gps.send_command(b'PMTK220,500')

# Main loop runs forever printing data as it comes in
timestamp = time.monotonic()
while True:
    data = uart.read(32)  # read up to 32 bytes
    # print(data)  # this is a bytearray type

    if data is not None:
        # convert bytearray to string
        data_string = ''.join([chr(b) for b in data])
        print(data_string, end="")

    if time.monotonic() - timestamp > 5:
        # every 5 seconds...
        gps.send_command(b'PMTK605')  # request firmware version
        timestamp = time.monotonic()

We'll need to configure this code to work with our UART port name.

  • If you're using a USB-to-serial converter, the device name is probably /dev/ttyUSB0 - but check dmesg to make sure.
  • If you're using the built-in UART on the DragonBoard, the device name is /dev/ttyTHS1.

Comment out the lines that reference board.TX, board.RX and busio.uart and uncomment the lines that import serial and define the serial device, like so:

Download: file
# Define RX and TX pins for the board's serial port connected to the GPS.
# These are the defaults you should use for the GPS FeatherWing.
# For other boards set RX = GPS module TX, and TX = GPS module RX pins.
#RX = board.RX
#TX = board.TX

# Create a serial connection for the GPS connection using default speed and
# a slightly higher timeout (GPS modules typically update once a second).
#uart = busio.UART(TX, RX, baudrate=9600, timeout=3000)

# for a computer, use the pyserial library for uart access
import serial
uart = serial.Serial("/dev/ttyUSB0", baudrate=9600, timeout=3000)

And update the "/dev/ttyUSB0" device name if necessary to match your USB interface.

Whichever method you use, you should see output like this, with $GP "NMEA sentences" - there probably wont be actual location data because you haven't gotten a GPS fix. As long as you see those $GP strings sorta like the below, you've got it working!

This guide was first published on Sep 10, 2019. It was last updated on 2019-09-10 23:16:10 -0400. This page (UART / Serial) was last updated on Sep 16, 2019.