Arduino and Raspberry Pi Serial Communication (USB & TX RX UART Guide)
| |

Arduino and Raspberry Pi Serial Communication (USB & TX RX UART Guide)

Learn how I connect Arduino and Raspberry Pi using USB and UART TX/RX pins with simple Python and Arduino code for beginners.

In this guide I explain how I connect Arduino and Raspberry Pi using serial communication. I start with the easiest USB method and then move to direct UART TX/RX wiring through header pins. I show working Arduino and Python code, explain baud rate, UART, and USB conversion, and demonstrate command-based communication where Raspberry Pi controls Arduino functions.

Project at a Glance

ParameterDetails
ProjectArduino ↔ Raspberry Pi Serial Communication
DifficultyBeginner
Estimated Time20–30 minutes
Cost$0 if you already own Arduino and Raspberry Pi
Communication MethodsUSB Serial and UART TX/RX Pins
Languages UsedArduino C++ and Python

Prefer watching instead of reading?

If you are too lazy to read through the entire article, don’t worry — I’ve got you covered.

I created a complete step-by-step video guide where I demonstrate everything explained in this tutorial. In the video, I show how to connect Arduino and Raspberry Pi using USB serial communication, how to send data between the two devices, and how to control Arduino functions directly from Raspberry Pi using Python.

I also walk through the TX and RX UART wiring method, explain common mistakes beginners make, and show the exact code running on both boards.

So if you prefer learning visually, you can simply follow along with the video below.

Why did I connect Arduino and Raspberry Pi together instead of using just one board?

When I started building robotics projects, I quickly realised that Arduino and Raspberry Pi serve completely different purposes. Arduino is excellent for interacting with hardware like sensors, motors, relays, and LEDs. Raspberry Pi on the other hand behaves like a small computer capable of running Linux, Python scripts, AI models, and networking applications.

Because of this difference, combining them gives me the best of both worlds. Arduino can handle low-level hardware control while Raspberry Pi handles complex processing and decision making. In many of my robotics tutorials on RootSaid, this combination appears again and again.

Once both boards are in the same project, they need a way to exchange information. The most common and easiest way to do that is through serial communication.

What exactly is serial communication and why is it used in embedded systems?

Serial communication is a method where data is transmitted one bit at a time between devices. Instead of sending multiple bits simultaneously like parallel communication, serial communication sends a continuous stream of bits in sequence.

This approach reduces the number of wires needed and improves reliability. That is why almost every microcontroller, including Arduino, supports serial communication through built-in hardware.

For example, when Arduino sends the sentence Hello Raspberry Pi, from Arduino, the message is actually transmitted as a stream of bits one after another. The receiving device reads those bits and reconstructs the original message.

Serial communication is simple, stable, and widely supported, which is why it is the preferred method for connecting microcontrollers and small computers.

What is UART and how does it enable devices to exchange data?

UART stands for Universal Asynchronous Receiver Transmitter. It is a hardware communication module built into microcontrollers that allows them to send and receive serial data.

UART communication typically uses two lines.

  • TX – Transmit data
  • RX – Receive data

When connecting two devices, the TX pin of one device must connect to the RX pin of the other device. This crossing ensures that transmitted data arrives at the receiving input.

UART communication is asynchronous, meaning the devices do not share a clock signal. Instead, both devices agree on a communication speed called the baud rate.

What is baud rate and why must both devices use the same value?

Baud rate represents the speed at which bits are transmitted over the serial line. For beginners, the most common value used is 9600 baud.

This means 9600 bits are transmitted every second. Both devices must use the exact same baud rate otherwise the data will appear corrupted or unreadable.

In my tutorials I usually start with 9600 because it is stable and beginner friendly. Higher speeds are possible but they introduce more complexity when learning.

How does USB serial communication between Arduino and Raspberry Pi actually work?

The easiest method I use when teaching beginners is USB communication. When I connect Arduino to Raspberry Pi using a USB cable, the Raspberry Pi detects the board as a serial device.

Internally, most Arduino boards contain a USB-to-serial converter chip. This chip converts USB signals into UART serial communication that the Arduino microcontroller understands.

So even though I am using a USB cable physically, the communication protocol underneath is still serial communication.

Step 1: How did I send data from Arduino to Raspberry Pi using USB?

First I upload a simple program to Arduino that repeatedly sends a message. This helps verify that the connection works immediatley.

void setup() {
Serial.begin(9600);
}void loop() {
Serial.println("Hello Raspberry Pi, from Arduino");
delay(2000);
}

This program initializes serial communication at 9600 baud and sends a message every two seconds. The delay helps avoid flooding the serial buffer too quickly.

Step 2: How did I read Arduino serial data using Python on Raspberry Pi?

Next I created a small Python script on the Raspberry Pi that listens to the serial port. The only thing I needed to check was the device name such as /dev/ttyACM0.

import serialser = serial.Serial('/dev/ttyACM0', 9600)print("Waiting for data from Arduino...")while True:
message = ser.readline().decode().strip()
print(message)

This script simply opens the serial connection and prints whatever Arduino sends. If everything is connected correctly, the message appears every two seconds in the terminal.

Before running the Python script, I install the serial library with this command.

pip3 install pyserial

How did I make Raspberry Pi send commands back to Arduino?

Once one-way communication worked, I expanded the project so Raspberry Pi could send commands to Arduino. This allowed me to trigger different functions based on incoming messages.

The concept is simple: Raspberry Pi sends a word and Arduino decides what action to run. This is one of the easiest ways to demonstrate two-way communication in a beginner robotics project.

Step 3: How did I create command-based functions in Arduino?

In this example Arduino waits for incoming text commands such as HAPPY, HEART, or TEST. Each command triggers a different function.

String command = "";void setup() {
Serial.begin(9600);
}void loop() { if (Serial.available() > 0) { command = Serial.readStringUntil('\n');
command.trim(); if (command == "HAPPY") {
happyFunction();
} else if (command == "HEART") {
heartFunction();
} else if (command == "TEST") {
testFunction();
} else {
Serial.println("Unknown Command");
} }}void happyFunction() {
Serial.println("Running HAPPY function");
}void heartFunction() {
Serial.println("Running HEART function");
}void testFunction() {
Serial.println("Running TEST function");
}

Here, the Arduino listens continuously for incoming serial data. When it receives a word followed by a newline, it checks the value and runs the matching function.

This is part of Jithin’s troubleshooting method as well. I always start with simple text-based commands before moving to real hardware actions like LEDs, motors, or sensors.

Step 4: How did I send commands from Raspberry Pi keyboard to Arduino?

To test the system interactively, I wrote a Python script that waits for keyboard input. When I press Enter, the command is sent to Arduino.

import serialser = serial.Serial('/dev/ttyACM0', 9600)print("Type a command and press ENTER")
print("Available commands: HAPPY, HEART, TEST")while True: command = input("Enter command: ") ser.write((command + "\n").encode()) response = ser.readline().decode().strip() print("Arduino:", response)

This simple method makes testing extremely easy. I often use this approach when debugging robotics systems because I can trigger commands manually.

The RootSaid Fix here is to always include the newline character when sending commands. Without that, the Arduino code waiting for a full line may never respond properly.

How can Arduino and Raspberry Pi communicate without USB using TX and RX pins?

After demonstrating USB communication, I usually explain the lower-level UART method. Instead of USB cables, the devices communicate directly through their header pins.

On Arduino Uno the UART pins are Pin 1 for TX and Pin 0 for RX. On Raspberry Pi the UART pins are GPIO14 for TX and GPIO15 for RX.

To connect them correctly, I cross the wiring. Arduino TX goes to Raspberry Pi RX, Arduino RX goes to Raspberry Pi TX, and Arduino GND goes to Raspberry Pi GND.

Why is voltage level conversion important when wiring UART pins?

This is one of the most critical details beginners often miss.

Raspberry Pi GPIO pins operate at 3.3 volts, while Arduino Uno typically uses 5 volts logic levels. If the Arduino TX line sends 5 volts directly into the Raspberry Pi RX pin, damage can occur.

The safest solution is to use a logic level converter or a simple resistor voltage divider. In several early experiments I skipped this and nothing bad happend, but it is still risky and I do not recommend it.

How do I enable UART on Raspberry Pi before using TX and RX pins?

Before UART communication works, the serial interface must be enabled in the Raspberry Pi configuration tool.

sudo raspi-config

Then I navigate to Interface Options and then Serial Port. I disable the login shell over serial but enable the serial hardware interface.

After rebooting, the UART device will usually appear as /dev/serial0.

sudo reboot

To verify it, I can check with:

ls /dev/serial0

Do the Arduino and Raspberry Pi codes change when switching from USB to TX RX?

Interestingly, the code remains almost identical. The Arduino program does not change at all because it still uses the same Serial interface.

The only modification occurs in the Raspberry Pi Python script. Instead of using /dev/ttyACM0, the serial device becomes /dev/serial0.

This small change is part of what I call the RootSaid Fix. Many beginners think they must rewrite the whole program, but in reality only the port name changes.

What code do I use on Arduino for TX RX communication?

On the Arduino side, I can keep using the same code I used earlier. That is because the Serial object still maps to the hardware UART pins.

For sending data from Arduino to Raspberry Pi, I can use this:

void setup() {
Serial.begin(9600);
}void loop() {
Serial.println("Hello Raspberry Pi, from Arduino");
delay(2000);
}

For command-based communication, I can use the same Arduino code from the earlier example.

String command = "";void setup() {
Serial.begin(9600);
}void loop() {
if (Serial.available() > 0) {
command = Serial.readStringUntil('\n');
command.trim(); if (command == "HAPPY") {
happyFunction();
}
else if (command == "HEART") {
heartFunction();
}
else if (command == "TEST") {
testFunction();
}
else {
Serial.println("Unknown Command");
}
}
}void happyFunction() {
Serial.println("Running HAPPY function");
}void heartFunction() {
Serial.println("Running HEART function");
}void testFunction() {
Serial.println("Running TEST function");
}

What code do I use on Raspberry Pi for TX RX communication?

For direct UART communication through header pins, I only change the serial port name on Raspberry Pi.

To read Arduino data through TX and RX pins, I use:

import serialser = serial.Serial('/dev/serial0', 9600)print("Waiting for data from Arduino...")while True:
message = ser.readline().decode().strip()
print(message)

To send commands from Raspberry Pi to Arduino through TX and RX pins, I use:

import serialser = serial.Serial('/dev/serial0', 9600)print("Type a command and press ENTER")
print("Available commands: HAPPY, HEART, TEST")while True:
command = input("Enter command: ")
ser.write((command + "\n").encode()) response = ser.readline().decode().strip()
print("Arduino:", response)

So the structure stays the same. Only the physical connection and the device name are different.

What is the difference between USB serial communication and UART header communication?

FeatureUSB SerialUART TX RX
DifficultyVery easyModerate
Extra wiringNoYes
Voltage riskNonePossible
Best for beginnersYesNo
Used in embedded systemsSometimesVery common

For beginners, I always recommend starting with USB. It is easier to test, safer for the hardware, and much faster to get working.

Once that is understood, moving to TX and RX pins becomes much easier because the underlying communication idea is the same.

What common mistakes occured when I first tested this setup?

When I first experimented with Arduino and Raspberry Pi communication, several small mistakes occured. The most common issue was selecting the wrong serial device on Raspberry Pi.

Another mistake was forgetting the newline character when sending commands from Python. Since the Arduino code reads data until a newline appears, the command must include that character.

Finally, beginners often forget the shared ground connection when using TX and RX wiring. Without a common ground reference, serial communication may behave unpredictably.

What is the most important concept beginners should remember?

The most important concept is that USB and UART are not different communication protocols in this context. USB simply acts as a bridge that converts signals into UART serial communication.

So whether I connect using a USB cable or direct TX/RX pins, the underlying idea is the same. The devices are simply sending text messages across a serial channel.

Once this concept clicks, building larger robotics systems becomes much easier.

Conclusion: What did I learn from connecting Arduino and Raspberry Pi?

In this tutorial I showed how I connect Arduino and Raspberry Pi using serial communication. I started with the beginner-friendly USB method and then explored direct UART communication through TX and RX header pins.

Along the way I covered UART fundamentals, baud rate, USB-to-serial conversion, and command-based communication between devices. These are the exact basics I want every beginner in RootSaid Robotics to understand before moving to advanced robotics projects.

Once you understand these principles, you can control motors, sensors, displays, and entire robots using Raspberry Pi as the intelligent controller and Arduino as the hardware interface.

Arduino handles the hardware. Raspberry Pi handles the intelligence. Serial communication is the bridge that lets them work together.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *