Serial UART connection RPI zero / Arduino

You can connect the RPI and Arduino is several ways, eg. Serial/UART, I2C or USB. With I2C you can connect several device on the same wire. 1:1 communication is now suffiecient so I will go for the Serial/UART connection.

The RPI operates at 3.3V and the arduino I have chosen on 5V. Therefor we should use a Logic Level Converter (LLC) for serial/UART communication. If you are going for I2C please use the I2C converter.


There are 12 total pins on the LLC – two parallel rows of six headers. One row contains all of the high voltage (e.g. 5V) inputs and outputs, the other row has all things low voltage (e.g. 3.3V).

The voltage supplied to the HV and GND inputs should be higher than that supplied to the LV side. For example, if you’re interfacing from 5V to 3.3V, the voltage on the HV pin should be 5V, and the voltage on LV sould be 3.3V.

There are four separate data channels on the BD-LLC, each capable of shifting data to and from high and low voltages. These pins are labeled HV1, LV1, HV2, LV2, HV3, LV3, HV4, and LV4. The number at the end of each label designates the channel of the pin, and the HV or LV prefix determines whether it’s on the high or low side of the channel.

A low-voltage signal sent in to LV1, for example, will be shifted up to the higher voltage and sent out HV1. Something sent in HV3 will be shifted down and sent out of LV3. Use as many of these channels as your project requires.

The RPI is the low level side and the Arduino on the high level side. Please note that for the GPIO the RPI uses 3.3V, but still it has pins to provide 5V. I use the RPI 5V pins to provide power to the Arduino Nano board. We can also use the other RPI 5V pin to provide the HV side for the Arduino. We also need to twist the TX/RX, check this cross on the LLC board (blue/yellow crossing).

RPI config
The RPI is not yet configured to use the serial for communication. Please perform the following steps:
You can use “raspi-config” utility to enable the UART:
1. sudo raspi-config
2. Under “Interfacing Options”, choose “Serial”.
3. Say “No” when it asks if you want a login shell over serial.
4. Say “Yes” when asked if you want the hardware enabled.
5. Finish, then accept the offer to reboot.

After this configuration change and the wiring you are ready to check if the serial communication is ready to use. First you can check if ttyS0 is available on the RPI side with the command ls -l /dev/ttyS0, you should see the following output: crw-rw—- 1 root dialout 4, 64 Mar 22 19:16 /dev/ttyS0

The fastest way to check the communication is to load the following program into your arduino:

int x = 0; // variable

void setup() {
Serial.begin(9600); // open the serial port at 9600 bps:

void loop() {
// print labels
Serial.print("NO FORMAT"); // prints a label
Serial.print("\t"); // prints a tab





for(x=0; x< 64; x++){ // only part of the ASCII chart, change to suit

// print it out in many formats:
Serial.print(x); // print as an ASCII-encoded decimal - same as "DEC"
Serial.print("\t"); // prints a tab

Serial.print(x, DEC); // print as an ASCII-encoded decimal
Serial.print("\t"); // prints a tab

Serial.print(x, HEX); // print as an ASCII-encoded hexadecimal
Serial.print("\t"); // prints a tab

Serial.print(x, OCT); // print as an ASCII-encoded octal
Serial.print("\t"); // prints a tab

Serial.println(x, BIN); // print as an ASCII-encoded binary
// then adds the carriage return with "println"
delay(200); // delay 200 milliseconds
Serial.println(""); // prints another carriage return

This arduino program will print out a list of dec, hex and binair numbers on the serial interface of the arduino.

Now enable the RPI side with:
sudo apt-get install minicom
sudo minicom -b 9600 -o -D /dev/ttyS0

To exit minicom: Hit enter, then ctrl-a then q then press “enter”

RPI installation without monitor, keyboard(Headless) and finalizing the config

I just bought a RPI zero and lacking a micro HDMI. Any way when installing a RPI2 or 3 I still do not want to connect a keyboard and monitor. Please perform below steps to make an installation without monitor and keyboard (headless). We will enable SSH login (disabled with newer raspbian images), configure the Wifi and finalize the installation. In the last steps I will expand the file system and add additional security measures, e.g. removing the PI user and setting up a firewall. So please download and write the raspbian image to your SD card.

Enabling Wifi and SSH access is done by writing a file to /boot/ of the SD card.

Enable Wifi: If a wpa_supplicant.conf file is placed into the /boot/ directory, this will be moved to the /etc/wpa_supplicant/ directory the next time the system is booted, overwriting the network settings.
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev


Location and filename: /boot/wpa_supplicant.conf

Replace your SSID, password and ISO-3166 in the config file. Your_ISO-3166-1_two-letter_country_code is your ISO Country Code (such as NL for Netherlands).

[Problem] Wifi not working with RPI3 B+: With the RPI zero above process worked, with the RPI3 B+ I run into problems with the wifi. I executed: sudo raspi-config, under localisation options selected change wifi country and then sudo rfkill unblock wifi. Now my wifi worked. [/Problem]

Enable SSH Raspbian will look for a file named ssh on the boot partition at startup and will enable sshd, which by default is disabled. So please create an empty file “ssh”

Location and filename: /boot/ssh

Expand file system We do this to make use of all the space present on the SD card as a full partition. All this does is, expand the OS to fit the whole space on the SD card which can then be used as the storage memory for the RPI.

sudo raspi-config
Option 7:Advanced options
A1: Expand file system

Update firmware It’s always good practice to run the latest version of the firmware which also included the latest bug fixes.

sudo rpi-update

Add user I do not want to continue to use the PI user for security reasons, that’s why we should create a new user with sudo rights.

sudo adduser --gecos "" replace_with_username
sudo usermod -aG sudo replace_with_username

–gecos: Set the gecos field for the new entry generated. Adduser will not ask for finger information if this option is given.

-aG add in group
Now it would be nice if only this user could login via SSH and that we disable root login:
sudo nano /etc/ssh/sshd_config
Add, edit, or append to the end of the file the following line, which contains the usernames you wish to allow to log in
AllowUsers add_with_username
PermitRootLogin no
After the change you will need to restart the sshd service using sudo systemctl restart ssh or reboot so the changes take effect.

Disable Pi user login Everybody knows that on a RPI the user PI is available, so for security reasons I would like to delete this PI user. Please login with your new created user.

sudo deluser pi
sudo passwd root

Change hostname You can change the hostname of the RPI (default: raspberry) by editing the hostname file:  sudo nano /etc/hostname

Firewall We still want to block access to the RPI on any ports that are not explicitly enabled.

apt-get install -y ufw
sudo ufw allow ssh
sudo ufw --force enable
sudo ufw status

Now your RPI is ready to rock!