Arduino Python Communication Via USB

199,972

75

21

Introduction: Arduino Python Communication Via USB

Sometimes when working on an Ardunio project, it is necessary to send data back and forth between a computer. Now, you could use something like the arduino ethernet shield, which would send data over a network, but if you want something easy and free the simplest solution is USB communication.

There are several ways to approach Ardunio USB communication, but in this case we will be using Python on the computer side to send and receive information. As such, this instructable expects that you have some prior knowledge of Ardunio, and of Python (or other similar scripting language).

Why Python?

Python is a versatile, easy to learn, and easy to use scripting language. Its power, and huge library of user-created modules (everything from keyboard emulation to game programming) makes it an ideal language for a wide verity of computer side tasks. You could easy parse network information and make an Arduino visualizer, create a game controller, or make a keypad computer login system. Arduino with Python opens up a word of possibilities.

Step 1: The Computer Environment

On the Computer side of things, we will be using a Python module called PySerial. PySerial, coincidentally, allows for the use of serial connections with Python. Installing PySerial on Windows is a pretty simple process. Note: this 'ible assumes you have Python 2.* installed! If you do not, PySerial will still work, but you may need to change the code slightly to fit with the new standards.

To install on Windows, simply visit PySerial's Download Page, download the Windows binary, and run it (at the time of writing, it's pyserial-2.7.win32.exe). Afterwards, test your installation by opening up a new instance of the Python interpreter, and running:

import serial

Step 2: Initial Connection

To initiate a connection with the Arduino from Python, we first have to figure out which COM Port the Arduino is on. This task is luckily made simple by the Ardunio programming environment.

Simply look in the bottom right corner of your Arduino IDE, and you will see some text containing the COM Port number. We will use this to initiate our Python serial connection, like so:

arduino = serial.Serial('COM1', 115200, timeout=.1)

The above code will create a new serial object called "ardunio" on "COM1" with a "115200" baud-rate and a .1 second timeout. It is extremely important that you keep the chosen baud-rate on hand, as it must match exactly with the baud-rate on the Ardiuno side of things.

Step 3: Ardiuno to Python Communication

Communicating between the Ardunio and Python is somewhat easier than the other way around. First, we will want a bit of code that will initiate the Ardunio's serial connection, and pass a message along. We can do this with Arduino's Serial.write() function, like so:

void setup() {
	Serial.begin(115200); // use the same baud-rate as the python side
}
void loop() {
	Serial.println("Hello world from Ardunio!"); // write a string
	delay(1000);
}

This code will write a "Hello world from Ardunio!" line to the serial connection once every second. We will now build a Python script capable for receiving these messages, and doing with them as we wish. First, we must initiate the connection as we did on the previous page, and then we will create a loop that grabs the current information from the stream, and prints it to the console.

import serial
arduino = serial.Serial('COM1', 115200, timeout=.1)
while True:
data = arduino.readline()[:-2] #the last bit gets rid of the new-line chars
if data:
print data

Note that in this case, readline() is blocking, so it will wait until a new line is passed entirely through the serial buffer. Quite often, readline() will grab a blank line, so I threw in an if statement to check that data actually contained anything. If you wanted more precise non-blocking data grabbing, you could use read(), and use Serial.write() (for bytes) or Serial.print() (for ASCII chars) on the Arduino side, but you would need to parse character by character.

Step 4: Python to Arduino Communication

This step is a tad harder, as it requires us to parse the data on the Arduino side of things. To help speed things up, I've gone ahead and written a simple loop that grabs the current data from the Serial buffer, and creates a null-terminated string (C string), which it then passes back to the Serial connection. You can use this technique to write an actual parser by designating your own packet prefix and suffix, and scanning the serial buffer for those, creating strings accordingly.

void setup() {
	Serial.begin();
}
void loop() {
	if(Serial.available() > 0) {
		char data = Serial.read();
		char str[2];
str[0] = data;
str[1] = '\0'; Serial.print(str); } }

Now we can write a simple script that sends data from Python to the Arduino, and then prints out what it gets back.

import serial, time
arduino = serial.Serial('COM1', 115200, timeout=.1)
time.sleep(1) #give the connection a second to settle
arduino.write("Hello from Python!")
while True:
data = arduino.readline()
if data: print data.rstrip('\n') #strip out the new lines for now
# (better to do .read() in the long run for this reason

It's easy to see how this method can be extended further to allow for complex communication between the two devices. I will be covering an example of this communication in a future 'ible, where I will make a game-pad device capable of working on any kind of PC game!

1 Person Made This Project!

Recommendations

  • Make it Glow Contest

    Make it Glow Contest
  • First Time Author Contest

    First Time Author Contest
  • PCB Challenge

    PCB Challenge

21 Discussions

Traceback (most recent call last):
File "C:\Users\Antek\Documents\#python prijects\serial test.py", line 2, in <module>
arduino = serial.Serial('COM9', 115200, timeout=.1)
AttributeError: module 'serial' has no attribute 'Serial'
[Finished in 0.5s]


please help
0
wouyang1
wouyang1

2 months ago

thank you so much! it solved my problem

1
GokhanTekir
GokhanTekir

Question 11 months ago

i am getting permission denied error. Help please

0
cele1993
cele1993

Answer 7 months ago

the reasons can be:
-close the serial monitor of arduino IDE
-close python idle (if you launch a module whit serial.Serial instructions, IDLE keeps the COM port busy, even you stop the program with ctrl+c)

0
RashikS
RashikS

Answer 7 months ago

Same, did you solve it?

0
arslan.1985
arslan.1985

1 year ago

ı took " port busy" or access denied com 8 error. do you know how solve th problem??

0
EmreA48
EmreA48

Reply 1 year ago

Maybe you opened a connection but did not close it. So it remained open. Before you end the program, you should close the connection with "arduino.close()"
Or maybe your arduino serial screen is open, so serial port is busy. You should close that serial screen before you run the python script

0
aida_manzano
aida_manzano

Question 1 year ago

Hi, was wondering if you did end up making the game pad, and if so, if you have a link to a tutorial?
Thanks :)

0
SanjayR58
SanjayR58

Question 2 years ago on Step 2

What does the timeout value signify

0
aida_manzano
aida_manzano

Answer 1 year ago

timeout I believe is the time required to receive a reply from port after transmitting a query

0
shoravsuriyal
shoravsuriyal

3 years ago

please help me out

0
shoravsuriyal
shoravsuriyal

3 years ago

i am getting error when i am running the python script...

Error: AttributeError: 'module' object has no attribute 'Serial'

I already installed the pyserial library

0
liaohuiooooo
liaohuiooooo

3 years ago

Thank you.But,Python.3 cannot downward compatibility.That's a little pity.

0
RunAndGo
RunAndGo

Reply 3 years ago

Hi.

I used Python 3 for this project, and it worked fine.

All I had to do was add parenthesis to the print statement on line 6.

0
damiaotechie
damiaotechie

4 years ago

It uses USB for serial connection that is viewed by the host computer as a "COMx" port.

0
IanB82
IanB82

4 years ago

Why is this called communication via USB when it does not use USB?

Cheers

Ian

0
piratemonkey
piratemonkey

5 years ago on Introduction

Great! Note that you can remove trailing whitespace from the input line with:

data = arduino.readline().strip()

which saves having to guess at the length of the string ;)