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!