Introduction: Interface Python and Arduino With PySerial
Over the last few months I have learned how to program with Python. With one of the upcoming projects that I am working on it would be nice to have a computer’s display to view the data collected by a rover in real-time as well as crunch numbers while the rover completes its mission. The rover will have an Arduino as a brain. What I found after some searching was pySerial. This is a really neat piece of software that allows Python to send and receive data much like the Serial Monitor does.
pySerial is available to download at
Step 1: Installation
Once you download it open up Terminal and type in:tar xfvz /Users/*Account*/Downloads/pyserial-2.6.tar.gz
cd pyserial-2.6
sudo python setup.py install
To make sure that everything installed correctly open up Idle and type in 'Import Serial'. If no errors appears then everything is good to go.
You can check the available ports with the linels /dev/tty.*
Step 2: Program the Arduino
Now to test it out, upload the below sketch to your Arduino. I do not know how this will or will not work on Arduino clones.void setup() {
Serial.begin(9600); // set the baud rate
Serial.println("Ready"); // print "Ready" once
}
void loop() {
char inByte = ' ';
if(Serial.available()){ // only send data back if data has been sent
char inByte = Serial.read(); // read the incoming data
Serial.println(inByte); // send the data back in a new line so that it is not all one long line
}
delay(100); // delay for 1/10 of a second
}
Step 3: Program Idle
Next in Idle create a new window and create the below program.from time import sleep
import serial
ser = serial.Serial('/dev/tty.usbmodem1d11', 9600) # Establish the connection on a specific port
counter = 32 # Below 32 everything in ASCII is gibberish
while True:
counter +=1
ser.write(str(chr(counter))) # Convert the decimal number to ASCII then send it to the Arduino
print ser.readline() # Read the newest output from the Arduino
sleep(.1) # Delay for one tenth of a second
if counter == 255:
counter = 32
Two things to keep in mind. To determine what serial port your Arduino is connected to look at the bottom right corner of your Arduino sketch. Whatever that is should be what is in quotes in line 3 of the Python program.
You can also change the baud rate in line 3 of the Python program and line 2 of the Arduino program as long as they stay the same.
Once you run the program it will print out the majority of ASCII characters. By first sending them to the Arduino, which will in turn send it back to the computer that Python then prints out.

Participated in the
Instructables Design Competition
21 Comments
3 years ago
Tip 3 years ago
It's much easier to use dedicated libraries for Python <--> Arduino communication. For example, https://github.com/PowerBroker2/pySerialTransfer and https://github.com/PowerBroker2/SerialTransfer. SerialTransfer.h is installable via the Arduino IDE Libraries Manager and pySerialTransfer is pip-installable. With these libraries, you can easily and reliably transfer ***bytes, ints, floats, and even structs***!!
5 years ago
This is great. I would like to have a certain digital output from my Arduino be the determining factor for my Tkinter/Python button to work. this program seems to be almost what I need. I have it set up so my Arduino Mega 2560 digital output #51 goes high or low if a relay latches or unlatches. I would like that high low information to tell the Tkinter/python button label to either change state.
any ideas?
6 years ago
how to use that data , for example control the servo
6 years ago
This helped me a lot! However, there are a couple of pitfalls in the python script that could cause a major headache if not noticed:
1) You should always remember to close the serial port when you're done using ser.close()
2) There should be some way to exit out of the infinite while loop. The program is not very useful if it doesn't have a way to end. I ended my loop once count reached 255, but some other approach would work as well, perhaps watching for an end signal from the Arduino?
7 years ago
Hi there! Nice tutorial! I was wondering whether this could be used to interface between the Raspberry Pi and Arduino? I mean I want my RPi to trigger my Arduino to run its sketch depending upon some conditions, so I could simply check for those conditions on the RPi's python script and then send a variable to Arduino and it runs the script. Can this happen?
8 years ago on Introduction
Where on python does this get printed? I am running the python script and also opened up the serial monitor on Arduino. It reads "Ready" and that's about it. Nothing else seems to happen. Is there a serial monitor-type thing I need to open on IDLE? Please help me. I need to figure this out for my project ASAP.
Reply 7 years ago
It's displayed in the python terminal
7 years ago
OK, what is Idle?
Reply 7 years ago
Idle is a python IDE. Basically, what you write your python script in.
Reply 7 years ago
Thanks urshur.
7 years ago
I love the combination of Python and the Arduino. So I have created a collection about it. I have added your instructable, you can see the collection at: >> https://www.instructables.com/id/Arduino-and-Pytho...
7 years ago
Note for Unix you might want to add this to the top of the code.
#!/usr/bin/python
7 years ago on Introduction
Got me going!
8 years ago on Introduction
Where on python does this get printed? I am running the python script and also opened up the serial monitor on Arduino. It reads "Ready" and that's about it. Nothing else seems to happen. Is there a serial monitor-type thing I need to open on IDLE? Please help me. I need to figure this out for my project ASAP.
8 years ago on Introduction
Easy enough!
8 years ago
Thank you for the tutorial, it is really useful. Just one question: Is
it possible to reuse somehow Arduino libraries to interface Arduino
shields (gsm.h) from Python?
Reply 8 years ago on Introduction
oh yes :D
8 years ago on Step 3
Excellent tutorial, just what I needed to start reading data from my 'Barometric Differentiation Engine'
Thanks
8 years ago on Introduction
Nice! it work for me, the only change I made was instead of
('/dev/tty.usbmodem1d11', 9600) I used (2) what is the COM3 port.
Thanks