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
sudo apt-get dist-upgrade
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
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.
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
enable_uart=1
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
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
You also need to remove the console from the cmdline.txt. If you edit this with:
sudo nano /boot/cmdline.txt
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
To Enable the Serial Console edit the file using:
sudo nano /boot/cmdline.txt
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
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
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