Arduino Python Communication Via USB

216,391

77

29

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

  • Jewelry Challenge

    Jewelry Challenge
  • Raspberry Pi Contest

    Raspberry Pi Contest
  • Anything Goes Contest 2021

    Anything Goes Contest 2021

29 Comments

0
IanB82
IanB82

5 years ago

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

Cheers

Ian

0
xXSystem-HackedXx
xXSystem-HackedXx

Reply 5 months ago

It uses USB. The Arduino uses type B USB (mostly)

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
DrSQL
DrSQL

Reply 12 months ago

Did you install pyserial or did you just install serial.

0
xXSystem-HackedXx
xXSystem-HackedXx

Reply 5 months ago

Both work. To make sure, just install pyserial using CMD pip install pyserial

0
xXSystem-HackedXx
xXSystem-HackedXx

Reply 5 months ago

I have the same problem. I installed:
pip3 install pyserial
and
pip3 install serial

both didn't work :(
Any help??

EDIT:
just type instead:
arduino = serial.Serial('COM4', 115200, timeout=.1)

0
dnbarriosr
dnbarriosr

10 months ago on Step 1

the link to pyserial is broken.

0
xXSystem-HackedXx
xXSystem-HackedXx

Reply 5 months ago

Open CMD (command prompt) > type in CMD: pip install pyserial > you're done!

0
xXSystem-HackedXx
xXSystem-HackedXx

Tip 5 months ago

Troubleshooting:
1- serial has no attribute serial
If anyone is getting "serial has no attribute serial"

Just make sure that serial.Serial is capitalized like that:
arduino = serial.Serial('COM4', 115200, timeout=.1)

(You can copy-paste code)

It's easy as that lol

2- Port busy or Access denied
Stop executing Python code (You can close the editor) and try again.

That's because python is getting info while Arduino IDE is trying to send so it gets busy.

3- "COM1": FileNotFoundError(2, 'The system cannot find the file specified:

Change the port to your port number (usually 3 or 4)

If you have any troubles, reply to me, I can help you.

0
wouyang1
wouyang1

1 year ago

thank you so much! it solved my problem

0
GokhanTekir
GokhanTekir

Question 1 year ago

i am getting permission denied error. Help please

0
cele1993
cele1993

Answer 1 year 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 1 year ago

Same, did you solve it?

0
arslan.1985
arslan.1985

2 years ago

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

0
EmreA48
EmreA48

Reply 2 years 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 2 years 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 3 years ago on Step 2

What does the timeout value signify

0
aida_manzano
aida_manzano

Answer 2 years ago

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