Today I realized that the Raspberry Pi version 4 has 6 hardware serial ports! This is really interesting for robotics use, because we can interface lots of hardware without the need for multiplexing the ports. Unfortunately, the raspi-config tool only allows us to use one serial port and only works on Raspberry Pi OS. This blog post shows you how to use all the serial ports in Ubuntu and Raspberry Pi OS.
About the Serial Port Hardware
The Raspberry Pi 4 is based on the BCM2711 ARM processor. This means that we theoretically can use up to 6 hardware serial ports. The default use of the serial ports is as follows:
Raspberry Pi OS: By default, the first port (UART0) is used for Bluetooth communication and all other ports are disabled.
Ubuntu: Ubuntu for the Raspberry pi ships with the U-Boot bootloader. The bootloader by default listens on the first hardware serial port with a baud rate of 115200 and interrupts the boot process, if it detects any input. So if you want to use the serial port for a sensor which streams data (e.g. GPS), you will need to disable this feature.
The above screenshot shows the serial output for a Raspberry Pi 4 booting Ubuntu without any special configuration. Note that U-Boot will stop autoboot if any key press is detected.
After U-Boot is done running, the default Linux Shell is accessible on the serial-port. If you want to use this serial port, you need to disable both features.
Disable U-Boot (Ubuntu Only)
There are multiple ways to disable the serial port in U-Boot. In my opinion, the simplest one is by connecting to the Raspberry Pi with an USB to serial adapter. This way you can directly configure U-Boot and see the remaining serial messages. If you want to follow this guide, connect the serial adapter to your Raspberry Pi like this:
You can then access the U-Boot terminal by first opening a serial connection with a baud rate of 115200 and then powering up your Raspberry Pi. As soon as the “Hit any key to stop autoboot” message appears, hit any key to enter the U-Boot terminal.
You can then simply disable the boot interruption by typing the following commands:
After the saveenv command has finished, you can power cycle your Raspberry Pi to boot into Ubuntu. Note that you cannot access U-Boot anymore after the change.
Disable Serial Console and Bluetooth
In order to use UART0 on the GPIO pins, we also need to disable Bluetooth as well as the serial console. This can be accomplished by logging into our Raspberry Pi via SSH and editing the following file:
sudo nano /boot/firmware/config.txt
In this file, you need to add the following line at the very end to disable Bluetooth and thereby freeing UART0:
Save the file and exit nano (CTRL+O -> Enter, CTRL+X).
The next file we need to edit is:
sudo nano /boot/firmware/cmdline.txt
In this file we need to remove the serial console part. After editing the file, it should look like this:
net.ifnames=0 dwc_otg.lpm_enable=0 console=tty1 root=LABEL=writable rootfstype=ext4 elevator=deadline rootwait fixrtc
You also need to save the file and exit nano just like before.
Now you can reboot your Pi (sudo reboot) and should see the following result on the serial port:
Note that U-Boot still prints some data to the port but as soon as the kernel boots, no more data is sent. We can now use the serial port!
Enabling the other serial ports
Since all other serial ports are disabled by default, we just need to enable them to use them. This is done by appending the following lines to /boot/firmware/config.txt:
dtoverlay=uart2 dtoverlay=uart3 dtoverlay=uart4 dtoverlay=uart5
There is no need to enable uart0, it is enabled by default. UART1 would map to the same pins as UART0 and is therefore not enabled.
After rebooting the Raspberry Pi, you can use all five hardware serial ports as you’d expect:
But doesn’t the Raspberry Pi 4 have 6 serial ports?
Yes, but only five of those ports can be mapped to GPIO ports simultaneously. The remaining port can be used for Bluetooth communication.
In order to connect to the five serial ports, you need to connect the following pins:
|UART||Linux tty||TX Pin||RX Pin|
|UART0||/dev/ttyAMA0||GPIO 14||GPIO 15|
|UART2||/dev/ttyAMA1||GPIO 0||GPIO 1|
|UART3||/dev/ttyAMA2||GPIO 4||GPIO 5|
|UART4||/dev/ttyAMA3||GPIO 8||GPIO 9|
|UART5||/dev/ttyAMA4||GPIO 12||GPIO 13|