How to setup the UART on Raspberry Pi 3

How to setup UART on the Raspberry Pi 3 GPIO

Introduction to the UART setup

In this article we will try to setup the UART on the Raspberry Pi 3 and Raspberry Pi Zero W running the latest debian “Jessy” release of the kernel. This used to be pretty easy on the previous versions of the Raspberry Pi models but on the Raspberry Pi 3 model it is a little bit different.
The BCM2837 on the Raspberry Pi3 has 2 UARTs (as did its predecessors), however to support the Bluetooth functionality the fully featured PL011 UART was moved from the header pins to the Bluetooth chip and the mini UART made available on header pins 8 and 10. Hence, the miniUART is now available on /dev/ttyS0.
Now the bluetooth module occupies the UART channel /dev/ttyAMA0 which on previous models was used as the primary serial GPIO UART interface.
So on the Raspberry Pi 3, the UART hardware interface used for the Bluetooth is named /dev/ttyAMA0 and the new UART connected to pins 8 and 10 on the GPIO connector J8 is named /dev/ttyS0.

Unfortunately there are a number of other consequences:

The mini UART is a secondary low throughput UART intended to be used as a console.
The mini UART has the following features:

  • 8 symbols deep FIFOs for receive and transmit.
  • 7 or 8 bit operation.
  • 1 start and 1 stop bit.
  • No parities.
  • Break generation.
  • SW controlled RTS, SW readable CTS.
  • Auto flow control with programmable FIFO level.
  • Baudrate derived from system clock.

There is no support for parity and the throughput is limited, but the latter should not affect most uses.

Before beginning, there is usually wise to update your installation to the latest version of the debian “jessy”:
First, update your system’s package list by entering the following command:

sudo apt-get update
Next, upgrade all your installed packages to their latest versions with the command:
sudo apt-get dist-upgrade
Generally speaking, doing this regularly will keep your installation up to date.
Also be aware that downloaded package files (.deb files) are kept in /var/cache/apt/archives. You can remove these in order to free up space with sudo apt-get clean.

To find the kernel version and distribution version, run:
Kernel version:

uname -a
Distribution version:
cat /etc/os-release

Some issues:
There is an issue with some of the releases of jessy which makes the UART work not as intended in some situations:
See post on raspi org here.
And follow up post on git here.

Some issues
There is an issue with some of the releases of jessy which makes the UART work not as intended in some situations:
See post on raspi org here.
And follow up post on git here.

Setup UART on the raspi 3 GPIO

For some strange reason the default for Pi3 using the latest 4.4.9 kernel is to DISABLE UART. To enable it you need to change enable_uart=1 in /boot/config.txt. (There is no longer necessary to add core_freq=250 to fix the core frequency to get stable baudrate.)
If you don’t use Bluetooth (or have undemanding uses) it is possible to swap the ports back in the Device Tree. There is a pi3-miniuart-bt and pi3-disable-bt module which are described in /boot/overlays/README here. See end of this article on how to do this.

As mentioned, by default the new GPIO UART is not enabled so the first thing to do is to edit the config.txt file to enable the serial UART:

sudo nano /boot/config.txt
and add the line (at the bottom):
enable_uart=1
Edit the file using nano
Fig.1. Edit the /boot/config.txt file with nano
You have to reboot for the changes to take effect.

To check where your serial ports are pointing you can use the list command with the long “-l” listing format:

ls -l /dev
Listing files in the /dev directory
Fig. 2. The /dev directory listing

In the long listing you will find:
serial0 -> ttyS0
serial1 -> ttyAMA0

Thus on a Raspberry Pi 3 and Raspberry Pi Zero W, serial0 will point to GPIO J8 pins 8 and 10 and use the /dev/ttyS0. On other Raspberry Pi’s it will point to /dev/ttyAMA0.

So where possible refer to the serial port via it’s alias of “serial0” and your code should work on both Raspberry Pi 3 and other Raspberry Pi’s.

Disabling the Console (if required)

By default the Raspberry Pi uses the serial port for the “console” login and via a software service called “getty”.
If you are using the serial port for anything other than the console you need to disable it. This will be slightly different depending on whether you are running a Raspberry Pi 3 or not.
For non Raspberry Pi 3 machines, remember it’s /dev/ttyAMA0 that is linked to the getty (console) service.

For Raspberry Pi 3’s the command is referencing /dev/ttyS0:

sudo systemctl stop serial-getty@ttyS0.service
sudo systemctl disable serial-getty@ttyS0.service
The “disable” will stop it loading at reboots.

You also need to remove the console from the cmdline.txt. If you edit this with:

sudo nano /boot/cmdline.txt
……you will see something like this:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes root wait

remove the line: console=serial0,115200 and save and reboot for changes to take effect:

reboot
Or anything involving console= that isn’t console=tty1, remove it. Make sure not to accidentally add a line break to that file, it should remain all one line with spaces between the options, but no spaces around any =.
To Enable the Serial Console edit the file using:
sudo nano /boot/cmdline.txt
Change the file to the following:

dwc_otg.lpm_enable=0 console=tty1 console=serial0(or ttyAMA0),115200 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait

Exit and save your changes.
Reboot for the changes to take effect.

reboot
Test your UART with Python and a terminal emulator
sudo apt-get install python-serial

Now, on the Raspberry Pi, type the following code into a text editor, taking care to get the indentation correct:



import serial

serialport = serial.Serial("serial0", baudrate=9600, timeout=3.0)

while True:
    serialport.write("rnSay something:")
    rcv = port.read(10)
    serialport.write("rnYou sent:" + repr(rcv))

Save the result as file serialtest.py, and then run it with:

sudo python serialtest.py

If all is working, you should see the following lines appearing repeatedly, one every 3 seconds, on the terminal emulator:

Say something:
You sent:”
Try typing some characters in the terminal emulator window. You will not see the characters you type appear straight away – instead you will see something like this:

Say something:
You sent:’abcabc’

Swapping the Serial Ports on Raspberry Pi 3

If you don’t want to use the Bluetooth and you want that high performance /dev/ttyAMA0 back on the GPIO, you can do this via a device overlay called “pi3-miniuart-bt” i.e. use the mini-uart (/dev/ttyS0) for Bluetooth.

To use add the following line to the /boot/config.txt

sudo nano /boot/config.txt
and add (at the end of the file):

dtoverlay=pi3-miniuart-bt

Save and reboot for changes to take effect.

sudo reboot

You can check that it has worked by:

ls -l /dev
and you’ll see something like this:

Swapped Raspberry PI 3 serial port aliases

Another options:

If you want to disable the bluetooth all together, another overlay is available:

dtoverlay=pi3-disable-bt

END

arrow