Raspberry Pi and Arduino Connected Over Serial GPIO

by Oscar

One way to connect the Raspberry Pi and Arduino is by connecting the GPIO on the Raspberry Pi and the Serial Pins on the Arduino.

Some of the links on this page are affiliate links. I receive a commission (at no extra cost to you) if you make a purchase after clicking on one of these affiliate links. This helps support the free content for the community on this website. Please read our Affiliate Link Policy for more information.

Because there is a voltage difference between the two device on these interface, a voltage divider or logic level converter would be required.

Check my article about connecting the two using I2C if you haven’t already seen it. Before we start, we need to set up the Raspberry Pi so it’s ready for serial communication.

Raspberry Pi Serial GPIO Configuration

0. if you have not seen my article on how to remote access your Raspberry Pi, take a look here:

https://oscarliang.com/setup-raspberry-pi-for-remote-access/

1. In order to use the Raspberry Pi’s serial port, we need to disable getty (the program that displays login screen) by find this line in file /etc/inittab

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

And comment it out by adding # in front of it

#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

2. To prevents the Raspberry Pi from sending out data to the serial ports when it boots, go to file /boot/cmdline.txt and find the line and remove it

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

3. reboot the Raspberry Pi using this command: sudo reboot

4. Now, Install minicom

sudo apt-get install minicom

And that’s the end of the software configuration.

Connect Serial Pins and GPIO with a Voltage Level Converter

Load this program on your Arduino first:

[sourcecode language=”cpp”]
byte number = 0;

void setup(){
Serial.begin(9600);
}

void loop(){
if (Serial.available()) {
number = Serial.read();
Serial.print(“character recieved: “);
Serial.println(number, DEC);
}
}
[/sourcecode]

Then connect your Arduino, Raspberry Pi and Logic Level Converter like this:

arduino-raspberry-pi-serial-gpio-connect-schematics

This is how the wires are connected.

arduino-raspberry-pi-serial-gpio-connect-wiring

And this is the GPIO pins on the Raspberry Pi. Make sure you connect the correct pin otherwise you might damage your Pi.

GPIOs

A Simple Example with Minicom

Now to connect to the Arduino via serial port using this command in putty or terminal

minicom -b 9600 -o -D /dev/ttyAMA0

When you type a character into the console, it will received by the Arduino, and it will send the corresponding ASCII code back. Check here for ASCII Table. And there it is, the Raspberry Pi is talking to the Arduino over GPIO serial port.

arduino-raspberry-pi-serial-gpio-connect-minicom

To exit, press CTRL + A release then press Q

Example with Python Program

Using Python programming language, you can make Raspberry Pi do many fascinating stuff with the Arduino when they are connected. Install Py-Serial first:

sudo apt-get install python-serial

Here’s a simple application that sends the string ‘testing’ over the GPIO serial interface

[sourcecode language=”python”]

import serial
ser = serial.Serial(‘/dev/ttyAMA0’, 9600, timeout=1)
ser.open()

ser.write(“testing”)
try:
while 1:
response = ser.readline()
print response
except KeyboardInterrupt:
ser.close()

[/sourcecode]

Raspberry Pi and Arduino Connected Over Serial GPIO python-serial-program-output

To exit, press CTRL + C

Connect Raspberry Pi and Arduino with a Voltage Divider

Apart from replacing the Login Level Converter with a voltage divider, the way it works is the same as above. Anyway, I will show you a different example to demonstrate this. A voltage divider is basically just two resistors.

There is something you should be aware of before we continue. The RX pin on the Arduino is held at 5 Volts even when it is not initialized. The reason could be that the Arduino is flashed from the Arduino IDE through these pins when you program it, and there are weak external pull-ups to keep the lines to 5 Volts at other times. So this method might be risky. I recommend using a proper level converter, if you insist on doing it this way, try adding a resistor in series to the RX pin, and never connect the Raspberry Pi to Arduino RX pin before you flash the program to Arduino, otherwise you may end up with a damaged Pi!

arduino-raspberry-pi-serial-gpio-connect-schematics

The Arduino serial pin is held at 5 volts and Raspberry Pi’s at 3.3 volts. Therefore a voltage divider would be required, it’s basically just two resistors.

arduino-raspberry-pi-serial-connect-schematics

Here is the program you need to write to the Arduino board.

[sourcecode language=”cpp”]

void setup() {
Serial.begin(9600);
}

void loop() {
if (Serial.available() > 0) {
int incoming = Serial.read();
Serial.print(“character recieved: “)
Serial.print(incoming, DEC);
}
}
[/sourcecode]

Now you can connect directly from your computer to the Raspberry Pi on the tty-device of the Arduino, just like we described above. (type below into your putty)

minicom -b 9600 -o -D /dev/ttyAMA0

And as you type in characters in the console, you should see something like this:

arduino-raspberry-pi-serial-gpio-connect-minicom

And that’s the end of this Raspberry Pi and Arduino article. There are other ways of connecting, if you don’t already know, you can also use a Micro USB cable. Check out this post: https://oscarliang.com/connect-raspberry-pi-and-arduino-usb-cable/

Leave a Comment

By using this form, you agree with the storage and handling of your data by this website. Note that all comments are held for moderation before appearing.

48 comments

Muhammad Osama Shamim 1st July 2023 - 10:07 am

Hello I want to make 4 different gpio pins of raspberry pi4 model b high when a certain object is detected in my python code. Then I want the arduino to read which pin is high and make actions accordingly. Which approach should I take and what are the safety measures I need to take. Please help.

Reply
sad 12th October 2021 - 8:44 am

100 new members a month is three a day, and it would be very hard to get one person to sign up to what is obviously an MLM program. As is usually the case with MLM programs, the products are far more expensive than they would be in a regular business. It makes no sense to pay $500 for an air cleaner when a good one can be had for a fraction of that. If Nikken is selling good products, they should have just set up a regular online store to sell the products and not bothered with the MLM program.

Reply
patio storage 9th October 2021 - 12:03 pm

No te rindas, Roope. Cuantas más horas pongas, más rápido empezarás a ganar. Dirigir y construir un sitio web rentable es un trabajo MUY duro!

Reply
Amit Nikhade 20th October 2020 - 11:22 am

Is the arduino and raspberrypi using separate power sources

Reply
Siva Sankar 26th July 2018 - 10:28 am

Hello ,

I used the same wiring method and the data exchange is good.

However it is not reliable, when i run a ping pong data exchange simultaneously for thousands and millions of time in a loop, and at the same time performing some motor controls from arduino (Motors are known to draw current up to 0.8 A), the data is getting corrupted.

The data corruption happens when the setup demands more current (for controlling motors).

Measures taken by me to solve this problem,

> i have added shield to the wires Tx and Rx.
> grounding is verified properly.

Still i dont know how when the setup draws more current, the data on Tx and Rx is corrupted.

Any help will be appreciated

Reply
Mars 30th June 2017 - 12:21 am

Have you an article on connecting a bluno nano from dfrobot with an hm10 on a raspberry pi 2 by any chance? Im having trouble getting it to work. I can send from bluno-arduino to raspberry but not the other way around for some reason.

Reply
roger 29th June 2017 - 8:26 pm

Hello,

I have a similar situation. I’d like to connect an Arduino Uno to a 3.3v sensor through RX/TX…
Now I understand Arduino-TX -> sensor-RX needs a voltage divider ( so the 5V of the arduino doesn’t break the sensor).
Now I’d expect the 3.3V from the sensor TX to Arduino-RX to be “safe”, however you mention in some situations the Arduino-RX can be at 5V, which would then go to the sensor and might break it…

So question ( assuming not using a level-divider)
– why not have 2 voltage dividers ? ( for both TX-RX and RX-TX connections)
– could we put a schottky diode between the “Arduino-RX” to “sensor-TX”, to make sure there can only be a flow from the sensor to the Arduino, and and the diode blocks the other way around ( note: n00b here, so I might be completely misunderstanding it ).

Regards

Reply
Ralf S 20th March 2017 - 11:03 pm

Hey Oscar!
I just found your (super) instructions, and wanted to go through it.
Funny, I already fail on the very beginning. On my Raspi3 the /etc/inittab file doesn’t exist.
It seems it’s gone nowadays, see
raspberrypi.org/forums/viewtopic.php?f=66&t=123081

But also when I follow the steps in the linked doc to deactivate getty, I don’t get your tutorial to work.
Hooking an oszilloscope to the Tx output of the raspi I don’t see anying coming there, so the minicom remains dead silent.
Any hints on how to get this going with a new setup?
Thanks,
Ralf

Reply
Ralf 21st March 2017 - 8:51 pm

ok, reason found.
On Raspi3 the AMA0 points to bluetooth.
Serial nuw is on ttyS0.
Thanks anyway….

Reply
Mario 21st June 2018 - 5:24 pm

Finally. You gave me the hint. Working for me in /dev/serial0

Thank you

Reply
Rodrigo 6th February 2016 - 6:42 pm

Hey, Oscar:
I just dropped by to say thank you.
I’m an educator trying to get fit with Arduino and RPi before using them for teaching STEM to the kids.
Your blog is really a source of inspiration.

Cheers,
Rod

Reply
Rod 28th February 2016 - 1:00 pm

Just a minor thing, I ran into the following error when running the python code:

File “gpio_serial.py”, line 4, in
myserial.open()
File “/usr/lib/python2.7/dist-packages/serial/serialposix.py”, line 271, in open
raise SerialException(“Port is already open.”)
serial.serialutil.SerialException: Port is already open.

It seems that the Serial constructor already opens the port, I had to comment out the following line of code:
ser.open()

Reply
Jeremy 11th December 2015 - 11:22 pm

Hi Oscar,

A thought about the RX pin voltage issue if using the voltage divider TX – put a schottkey diode to clamp the Rpi TX to the +3.3V, will prevent problems from the weak pull-up.

Reply
Werner 21st July 2015 - 1:33 pm

Hi dear………
I needed an easy way to transmit information to the Arduino to have the light convey meaningful information

Reply
Jamil 13th July 2015 - 6:43 am

Hi Oscar, is it uart or usart? and is it possible using this method to connect multiple arduinos with one raspy?

Reply
Oscar 13th July 2015 - 10:23 am

to connect multiple arduino to 1 Pi, I2C is a better option.

Reply
lcsbngg 7th June 2015 - 4:25 pm

Hello,

I have a question and i can not find the answer so maybe you can help me.

I have a raspberry pi with a python program (Tweet monitor learn.sparkfun.com/tutorials/raspberry-pi-twitter-monitor)

When a tweet is found with the term i want it turn on a led (GPIO 22 HIGH)

And i have a other program (a clock with 18 7-segment display) on a arduino mega, when a button is push (Pin 7 HIGH) the clock decrease one second.

I wanted to know if it’s possible to plug the GPIO 22 (rpi) to the Pin 7 (arudino) and the GND to GND.

I was afraid to kill the raspberry (because raspberry 3.3V and arduino 5V apparently) but in my situation it’s from the raspberry to arduino and only this way not the other.

Thanks
and sorry about my english.. ;)

Reply
Oscar 8th June 2015 - 1:13 pm

use i2C, you don’t need any conversion, and you can connect them directly.

Reply
Lcsbngg 8th June 2015 - 1:33 pm

Thanks for your answer

I will look your tutorial on i2c

And what about connect directly RPi GPIO 22 to arduino 7 and gnd to gnd without conversion ?

Reply
Oscar 8th June 2015 - 1:53 pm

i don’t see there is any problem with that, if you set your Pin7 on Arduino as read only.
but it’s a good idea to measure the voltage on that pin, make sure it’s safe before connection.

Reply
Sven 1st February 2015 - 2:32 pm

Hi Oscar,

We developed an addon board for raspberry Pi called CoPiino ( CoPiino.cc ). It communicates directly with Raspberry Pi and on the other and has connectors which are Arduino compatible.

Please let us know if you are interested to check it out.

Best
– Sven

Reply
Oscar 1st February 2015 - 5:56 pm

Hi Sven,
not sure if you are the same person, i replied to Tswaehn earlier.
https://oscarliang.com/raspberry-pi-face-recognition-opencv/comment-page-6/#comment-6653

cheers
Oscar

Reply
Corbin Haugen 15th October 2014 - 4:07 am

Thanks for the info. I know this is fairly old but when connecting to an Arduino Nano, I had to swap Tx and Rx between the arduino and the LLC so that it goes Tx to Tx and Rx to Rx.

I was beating my head against the wall trying different things and finally said screw it and swapped them. No sparks, no smoke, no flames… just a happy RPi that is casually talking to the Nano… thanks for the post. Great info!

Reply
Jerkson 26th April 2015 - 3:04 am

I too had the same problem. My TX and RX from the Arduino went into TX and RX respectively (not swapped as shown above) on the level converter.

Reply
Isaac 21st August 2014 - 10:10 pm

First congratulations by your work that was very usefull.

I have this problem:
I want communicate arduino and raspberry using xbee

I’ve tryed use this code:

import serial
ser = serial.Serial(‘/dev/ttyAMA0’, 9600)
ser.open()
string = “Hello from Raspberry pi”
print(‘Sending “%s” ‘ %string)
ser.write(‘%s’ %string)

while True:
incoming = ser.readline().strip()
print(‘Received %s’ %incoming)
ser.write(‘RPi RECEIVED: %S’ %incoming)

And this error appears:
Import error: No module named serial.

I’ve tested and the minicom works. I see the information sent from arduíno, but just using minicom because the code doesn’t work. Can you help about this problem?

Thank you and one more time congratulations

Reply
Isaac 21st August 2014 - 10:13 pm

Ps:
I’ve alrady installed this:
sudo apt-get install python-serial

and all is update.

Reply
Oscar 22nd August 2014 - 11:36 am

There might be two version of python on your pi (python2 and python3), and you only installed serial on python2, and you are using python3 to compile the code, that might be why you are getting this error.

I didn’t have this issue for some reason, but try what is suggested here:
http://stackoverflow.com/questions/20559457/python-no-module-named-serial

Reply
Oscar 22nd August 2014 - 11:27 am

have you installed python-serial?

Reply
RIVO 5th August 2014 - 5:02 pm

I connect arduino Mega serial pins and raspberry type B GPIO with a adafruit voltage level converter
I copied and pasted your code (python for Raspberry). Unfortunately when I type 103 in the arduino serial monitor, the raspbian terminal displays:
character recieved: 1
character recieved: 0
character recieved: 3

and like that for all numbers (111, 100, 32 …). I can not see all numbers, but one by one …. It is as python can not handle the characters ‘ n’ and ‘ r’ even if I remove the code with
if response == ‘ n’ or response ==” or response == ‘ r’

thank you for your site he taught me a lot.

Reply
Lasonya 8th July 2014 - 3:28 am

We are a bunch of volunteers and opening a new scheme
in our community. Your web site offered us with useful info to work on. You have performed an impressive activity and our whole community will likely be grateful to you.

Reply
Oscar 9th July 2014 - 3:56 pm

that’s great! :)

Reply
Thomas 3rd April 2014 - 1:00 pm

Hi Oscar!

It seems you are using a BSS138 vor level shifting. I’m currently trying to send and receive data to a multiwii which is Arduine mega 2560 based. My Baud rate is 115200, is that too fast for that shifter? Do I need to use 9600?

Thanks for any comments on this as I can’t proceed currently.

Reply
Franklyn 1st April 2014 - 7:09 am

Very good info. Lucky me I ran across your blog by chance (stumbleupon).
I have book marked it for later!

Reply
Rutger 14th March 2014 - 12:49 pm

Hi Oscar,

Is it possible to connect multiple Arduino’s to one RPi via GPIO?

Thanks,
Rutger

Reply
Oscar 14th March 2014 - 1:12 pm

by using i2c, yes! (up to 128 connections)

Reply
Ouroborus 2nd August 2014 - 4:03 am

Why not use i2c to begin with? It seems like then you wouldn’t need to disable the various console outputs, can drop the level converter, and get expandability as a bonus.

Reply
Oscar 22nd August 2014 - 11:37 am

I am just exploring the possibility here, how to use, what to use, is up to the readers.

Reply
Andrew 29th January 2014 - 5:49 pm

I have mine hooked up in a similar way, but it isn’t working for me. My multimeter shows that the high level on the logic board is at 5v, and the low level is at 3.3v. The TX from the Pi goes in the A3 pin on the logic converter, and the B3 pin then connects to the RX pin on the Arduino.

I’m curious… when using the logic converter, does it matter where the 3.3v and 5v come from? The only difference with my setup is that the Arduino 5v output is also powering the Pi.

So yeah, I’m not sure why mine isn’t working. Reading the serial RX pin on the Arduino always shows a value of -1.

Reply
Oscar 31st January 2014 - 11:47 am

you should use seperate external 5V to power the PI. have you tried using potential divider? just to rule out the possibility that your logic converter is bad.

Reply
Bill Thomson 15th January 2014 - 11:57 pm

Hello,

The caution note at the top of the article says the Arduino RX pin is held at 5V,
yet the pictorial diagram show the voltage divider on the Arduino TX pin.

Regards,

Bill Thomson

Reply
Oscar 16th January 2014 - 9:50 am

No. the RX is only held at 5V when it’s not initialized and that could be a problem. (but I haven’t had any issue because of this so far)
And you only need to use voltage divider on the Arduino TX as the voltage could changes between 0V and 5V on this pin connection.
The Arduino RX voltage should be safe for the PI connected directly, because only the PI is driving the voltage on this connection (0V to 3.3V).

Reply
Lucas 25th June 2015 - 8:04 pm

Then why not to put 2 voltage dividers, one from TX (Arduino) to GPIO8(RPi) and the other between RX (Arduino) and GPIO 10(RPi), so make sure RX won’t break the RPi ??

Reply
Leslee 12th January 2014 - 3:46 pm

Wonderful beat ! I wish to apprentice while you amend your site, how could i subscribe for a blog web site?

The account helped me a acceptable deal. I had been a little bit acquainted of this your broadcast provided bright
clear concept

Reply
Carroll 12th January 2014 - 2:49 pm

An impressive share! I’ve just forwarded this onto a coworker who has been conducting a little homework on this.
And he actually ordered me lunch simply because I found it for him…

lol. So allow me to reword this…. Thanks for the
meal!! But yeah, thanks for spending time to talk about this subject
here on your blog.

Reply
Leonida 12th January 2014 - 8:55 am

This is very interesting, You’re a very skilled blogger.
I have joined your rss feed and look forward to seeking more of your great post.

Also, I’ve shared your web site in my social networks!

Reply
capitalstars04 5th February 2014 - 9:19 am

Nice Article!!!!!!!!!!

Reply
Miralay 11th July 2013 - 8:33 am

Hi,

we have one problem for about Rs232

example I want give or take 1 data Pi to PC, I can send to PC no problem but I cant take Pc to Pi any data… if I send 30 times or 40 times after I can send PC to Pi… then it be normaly… but if I push caracter from keyboard after lock serial com… after I send again 30 or 40 times data then open again… after normaly…

I tried resister then I use max3232 but no change… only I have problem for Pi to PC send wire…

example some example I have from internet “Pi serial com. to ardiuno” but this not work…

I will wait your helps …

thanks a lot…

Reply
Oscar 12th July 2013 - 4:03 pm

Hi Miralay, sorry I don’t think I can help with your problem, because I don’t own a RS232 so I can’t test it and I have never used that type of cable before either.

have you tried google that problem? hope you can find an answer.

Reply