Serial communication with Arduino and Processing: simple examples and an Arduino based gamepad interfacing with Processing

Last updated on Mon, 2010-07-26 13:42. Originally submitted by fabio on 2010-07-24 18:46.

In this blog post, I'll describe Arduino serial communication capabilities. I'll provide simple examples of Arduino programs which use the serial interface to communicate with other devices, mostly a PC. I'll show you how to read and write data on a Serial interface and we'll also interface Arduino with a simple Processing program, a super simple video game.

Arduino and Serial communication

Arduino, as we have seen in the past blog posts, offers a lot of possibilities to interact with sensors, actuators, motors, etc.. But this is somehow limited by the simple capabilities of Arduino itself. We certainly can't run a Full HD LDC monitor running an OpenGL videogame with Arduino.

Fortunately, it's pretty simple to interface Arduino with more complex devices like a PC or another Arduino board. This can be achieved using the integrated Serial interface of Arduino.

As we saw on an older post, Arduino connects to the PC using an USB port. Anyway, that USB connection is actually used like a Serial (RS232) connection (remember the old 56K external modems? most of them where connected using a Serial interface). The Arduino IDE uses it to upload our programs to the board but the serial connection can also be used for any other kind of communication.

Arduino also has digital pins 0 (RX) and 1 (TX) which can be used to directly connect Serial interfaced wires into Arduino. They deliver the same signals sent on the USB Serial interface.

NOTE: Always remember that, when the serial communication is in use, it's impossible to use digital pins 0 and 1 for anything else then serial communication. They are delivering serial signals (even if you don't plug them and you are using USB) so you can't use them for anything else.

Arduino Serial programming

The Arduino programming language comes with a really simple Serial API. It's all contained into the Serial library/package which contains the following functions:

  • begin(): sets the datarate in bits per second (baud) for serial data transmission.
  • end(): disable serial communication
  • available(): gets the number of bytes (characters) available for reading over the serial port.
  • read(): reads the first byte of incoming serial data available.
  • flush(): flushes the buffer of incoming serial data.
  • print(): prints data to the serial port.
  • println(): prints data to the serial port, followed by a carriage return character(ASCII 13, or '\r') and a newline character (ASCII 10, or '\n')
  • write(): writes binary data to the serial port.

A complete description of these function is out of scope here. For more informations and all the details of the Arduino Serial APIs you should refer to the official Arduino documentation.

Writing data to the Serial interface with Arduino: reading the state of one button

Let's start practicing with Arduino serial API by writing a simple program which reads the state of one button and, if pressed, lights on an LED and send the button state over the serial interface.

For doing so we'll start from the digitalRead() example we saw some time ago. The circuit will be almost the same: the only difference will be that we'll use a pull-up resistor rather than a pull-down one. This decision will make sense in the next examples.

Note that a pull-up connected pin will read HIGH when the button is not pressed while it will read LOW when the button is pressed.

The circuit will looks like:

Scheme of a simple Arduino based circuit to read the state of one button and communicate its status via serial interface

Once assembled on the Arduino board, the circuit will looks like:

Picture of a simple Arduino based circuit to read the state of one button and communicate its status via serial interface

Arduino program to write one button status to the Serial Interface

We can use the following program to read the state of the button from the Digital In pin and then switch off the LED when the button is pressed and communicate the button state over the Serial interface.

/**
* Read the state of the button from the Digital In pin and 
* then switch off the LED when the button is pressed and communicate 
* the button state over the Serial interface
*/

#define LEDPIN 13
#define INPIN 2

int state = LOW;

void setup() {
  Serial.begin(9600); // setup serial connection speed
  pinMode(LEDPIN, OUTPUT);
  pinMode(INPIN, INPUT);
}

void loop() {
  delay(10); // debounces switch
  int sensorValue = digitalRead(INPIN);
  if(state != sensorValue) {
    state = sensorValue; 
    digitalWrite(LEDPIN, sensorValue); // turns the LED on or off
    Serial.println(sensorValue, DEC);
  }
}

The above program is pretty simple. In the setup() routine we initialize the Serial interface and set its speed to 9600 bauds. In loop() we debounce the switch then we read the button status with digitalRead(). We keep track of the current state of the button. By doing this we are able to only communicate state changes in the button.

I think that it's pretty important to keep low on the amount of informations flowing trough the Serial interface. It seems that most of the how-tos and examples I've found online each loop they print to the serial interface. I think this is pretty useless as we are only interested in state changes, we do know that between two state changes the button hasn't changed its status.

So, only if we detect a state change, we use digitalWrite() to turn on or off our LED and then print the value as decimal using Serial.println.

Arduino IDE Serial Monitor

Once we'll create the circuit and we'll upload the program above to Arduino, we'll be able to use the Arduino IDE Serial Monitor to show everything passes on the serial connection.

The Arduino IDE serial monitor

The Serial Monitor is a pretty cool feature of the Arduino IDE. It basically let you see everything your Arduino prints to the Serial interface and you are also able to send strings to the Arduino.

NOTE: most operating systems limit to one the number of the applications capable of reading from a Serial interface. This means that we won't be able to have two applications reading on the serial interface: eg the serial monitor and a Processing program, see examples below.

Following a video demonstrating how the above circuit and program works.

Reading the state of two buttons with Arduino and communicate their state via Serial interface

We now try to make the above example a little bit more complex by reading two buttons instead of one. We'll now need two pull-up resistors and another LED. Remember that pin 13 has a 1k Ohm resistor connected in series, so it's safe to directly connect the LED to it. If we want to add another LED, for example on Digital pin 12, we'll have to use a series 1k Ohm to avoid damages to the LED.

Our circuit will then looks like:

Scheme of a simple Arduino based circuit to read the state of two button and communicate their status via serial interface

Once plugged on the Arduino board, the circuit will looks like:

Picture of a simple Arduino based circuit to read the state of two button and communicate their status via serial interface

Arduino program to write two button status to the Serial Interface

Starting from the code of the one button example we can write the following program:

/**
* Read the state of two buttons from the Digital In pins and 
* then switch off the LEDs associated to each button when the button is pressed and communicate 
* the buttons states over the Serial interface
*/

#define LEDPIN1 13
#define LEDPIN2 12
#define INPIN1 2
#define INPIN2 3

int state1 = HIGH;
int state2 = HIGH;

void setup() {
  Serial.begin(9600);
  pinMode(LEDPIN1, OUTPUT);
  pinMode(LEDPIN2, OUTPUT);
  pinMode(INPIN1, INPUT);
  pinMode(INPIN2, INPUT);
}

void loop() {
  delay(10); // debounces switches
  int val1 = digitalRead(INPIN1);
  int val2 = digitalRead(INPIN2);
  if(state1 != val1 || state2 != val2) {
    state1 = val1; 
    state2 = val2;
    digitalWrite(LEDPIN1, val1); // turns the LED on or off
    digitalWrite(LEDPIN2, val2); // turns the LED on or off
    Serial.print(val1, DEC);
    Serial.println(val2, DEC);
  }
}

Nothing really new here. We use the same logic of the first program for two buttons. Note however that we use Serial.print for the first print rather than Serial.println so that the two values are printed side by side.

The program and circuit above, once deployed on the Arduino board, will produce the result shown in this video:

Arduino Digital Input internal pull-up resistors

Unfortunately, as we can see from the picture above, connecting two buttons requires 4 resistors and quite a lot of wires. This is somehow unpratical: if we would need to connect a large number of buttons, the circuit would be really complex.

Fortunately, Arduino (actually its internal ATmega chip) provides internal 20K pull-up resistors on any digital input pin. This feature can be enabled by software with this two calls:

pinMode(pin, INPUT);           // set pin to input
digitalWrite(pin, HIGH);       // turn on pullup resistors

By writing HIGH on a digital input pin previously set as INPUT we enable the 20K internal pull-up resistors. Doing so we no more need to connect the pull-up resistors to the internal pull-up enabled digital input pins and we can simply connect the button to the pin and ground. Really more simple.

Using internal pull-up resistors out circuit can became:

Scheme of a simple 2 buttons input circuit using 20K internal pullup on Arduino board

Once assembled on the board, the circuit will looks like:

Picture of a simple 2 buttons input circuit using 20K internal pullup on Arduino board

As you can see the circuit is really more simple than the external pullup version we seen earlier. Internal pullup really are cool!

Arduino program to write two button status to the Serial Interface using internal pull-up resistors

Now, if we want to use the two instructions and the circuit presented above to do exactly what we did earlier, we just need this:

/**
* Uses internal pullups to read 2 pushbutton states,
* Comunicate the state of the button using serial interface and
* lights on/off 2 LEDs associated with the buttons
*/

#define LEDPIN1 13
#define LEDPIN2 12
#define INPIN1 2
#define INPIN2 3

int state1 = HIGH;
int state2 = HIGH;

void setup() {
  Serial.begin(9600);
  pinMode(LEDPIN1, OUTPUT);
  pinMode(LEDPIN2, OUTPUT);
  
  pinMode(INPIN1, INPUT);
  digitalWrite(INPIN1, HIGH); // enable pullup resitor
  
  pinMode(INPIN2, INPUT);
  digitalWrite(INPIN2, HIGH); // enable pullup resitor
}

void loop() {
  delay(10); // debounces switches
  int val1 = digitalRead(INPIN1);
  int val2 = digitalRead(INPIN2);
  if(state1 != val1 || state2 != val2) {
    state1 = val1; 
    state2 = val2;
    digitalWrite(LEDPIN1, val1); // turns the LED on or off
    digitalWrite(LEDPIN2, val2); // turns the LED on or off
    Serial.print(val1, DEC);
    Serial.println(val2, DEC);
  }
}

The program is exactly the same of the external pullup version. We just added the two instructions to enable the internal pullup resitors.

The behaviour of the circuit and program is this:

Two-way communication with Arduino

In the examples above we used serial communication only to print something to the Serial interface from the Arduino board. However, Arduino can also read from the serial interface.

Now, we will try to implement a little program which could leverage two ways communication capabilities of the Arduino board: we'll plug only one LED to pin 13 and we'll try to light on or off using a command coming from the serial interface.

Driving an LED on/off using command coming from the Serial communication with Arduino

In the programs above we used Serial.print() and Serial.println() to print data to the Arduino serial interface. In order to implement a simple two-way communication we also have to be able to read from the serial interface. The Serial.read() function does exactly that.

The following program reads from the Serial connection, if it read a 1 it turns on the LED, if it read 0 it turn off the LED.

/**
* Reads commands coming from serial interface to drive an LED on/off
* Also prints led status back
*/

#define LEDPIN 13

int state = LOW;
char incomingByte = 0;

void setup() {
  Serial.begin(9600);
  pinMode(LEDPIN, OUTPUT);
}

void loop() {
  
  // send data only when you receive data:
  if (Serial.available() > 0) {
     // we receive a char representing an integer. let's converto to int
    int incomingState = (Serial.read() == '1');
    
    // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingState, DEC);
    
    if(incomingState != state) {
      state = incomingState;
      digitalWrite(LEDPIN, state); // turns the LED on or off
      Serial.print("Setting LED as: ");
      Serial.println(state);
    }
    else {
      Serial.print("Doing nothing. LED already: ");
      Serial.println(state);
    }
  }
}

The above program is demonstrated in the video below:

Interfacing Arduino with a program running on a PC: Arduino and Processing to implement a simple gamepad and videogame

As you can imagine, the great power of serial communication cames out when we are able to use it to connect to an intelligent divice and let Arduino interact with it. One of the simplest possibilities is to use Serial communication to let Arduino interacts with a program running on a PC.

Almost every complete programming language supports Serial communication providing APIs for using it. Personally, in a Robotics university course I attended while I was Erasmus student at the ULPGC, I already used Python to interact with a didactical robot using serial communication.

Processing

Python APIs for serial communication are great and I really like Python, anyway it seems that the Arduino is usually interfaced with the Processing programming language which is a very simple graphics oriented programming language.

Processing is an open source programming language and integrated development environment (IDE) built for the electronic arts and visual design communities with the purpose of teaching the basics of computer programming in a visual context, and to serve as the foundation for electronic sketchbooks.

The Arduino programming language is modelled after Processing, so these two languages share lot of things. A complete introduction to processing is out of scope here, but we'll see how simple and immediate is that programming language. For a complete documentation on Processing you should have a look at the official documentation.

Ok, what we want to do is implement a super simple game controller (or gamepad) with Arduino and a simple video game with Processing both communicating via .

Building a gamepad with Arduino

First, we have to create our gamepad on the breadboard. We'll use 4 buttons for directions (right, up, left, down) and another one for fire. We'll connect them to Arduino and ground directly, without any pullup or pulldown resistors: we'll enable the internal pull-up resistors from the program. Using the internal pullup resitors will make our circuit a lot simpler.

Our circuit will looks like:

Circuit scheme of a simple gamepad with Arduino

Once connected on the Arduino board, the circuit will looks like:

Circuit picture of a simple gamepad with Arduino

Arduino Program to read the gamepad circuit and communicate with Serial

We have the circuit, we need a program. Basically, we use the same ideas already used in the past examples, just for a bigger number of buttons.

/**
* Uses internal pullups to read 4 pushbutton states,
* Comunicate the state of the buttons using serial interface
*/

#define IN1 2  // fire 
#define IN2 3  // right
#define IN3 4  // up
#define IN4 5  // left
#define IN5 6  // down

int state1 = HIGH;
int state2 = HIGH;
int state3 = HIGH;
int state4 = HIGH;
int state5 = HIGH;

void setup() {
  Serial.begin(9600);
  
  pinMode(IN1, INPUT);
  digitalWrite(IN1, HIGH); // enable pullup resitor
  
  pinMode(IN2, INPUT);
  digitalWrite(IN2, HIGH); // enable pullup resitor
  
  pinMode(IN3, INPUT);
  digitalWrite(IN3, HIGH); // enable pullup resitor
  
  pinMode(IN4, INPUT);
  digitalWrite(IN4, HIGH); // enable pullup resitor
  
  pinMode(IN5, INPUT);
  digitalWrite(IN5, HIGH); // enable pullup resitor
}

void loop() {
  delay(10); // debounces switches
  
  int val1 = digitalRead(IN1);
  int val2 = digitalRead(IN2);
  int val3 = digitalRead(IN3);
  int val4 = digitalRead(IN4);
  int val5 = digitalRead(IN5);
  
  // check if we had a change in state
  if(state1 != val1 || state2 != val2 || state3 != val3 || state4 != val4 || state5 != val5) { 
    state1 = val1; 
    state2 = val2;
    state3 = val3; 
    state4 = val4;
    state5 = val5;
    
    /* 
    we create a 8 bit word (1 byte) whose 5 right bit represent
    from right to left buttons fire, right, up, left, down status: 
    0 if pressed, 1 if not pressed
    remaining bits are unused
    
    I'm not that expert in bit operations, there's probably a
    better way (faster) to do the following.
    */
    unsigned int state = (val5 << 4) | (val4 << 3) | (val3 << 2) | (val2 << 1) | val1 ;
    
    Serial.print(state, BYTE);
  }
}

The program above is still pretty simple. We already saw all of the communication logic here. The only new thing is that I try to limit the amout of data travelling on the serial wire. That's why I set that state variable using some bitwise operations. It constructs an 8 bit word, whose 5 right bits are set to 1 if the associated button isn't pressed or to 0 if it is pressed.

The Processing video game

Above we created a program which is capable of sending our gamepad state trough the Serial wire to the PC. We now need something on the PC side which will read those data and react accordlying to its values.

We will create a simple program which draws a square box on a window. Using your controller you will be able to move the box around the screen. When you press fire, the box will change it's color.

Our processing code will be:

import processing.serial.*;

Serial myPort;  // Create object from Serial class

int state = 31;

int fire = 1;
int right = 1;
int up = 1;
int left = 1;
int down = 1;

int x = 275;
int y = 275;
int c = 0;

void setup() 
{
  size(600, 600);
  myPort = new Serial(this, "/dev/ttyUSB5", 9600);
}

void draw() {
  if(myPort.available() > 0) {
    state = myPort.read();
    println(state);
    println(binary(state));
    
    fire = state & 1;
    right = (state & 2) >> 1;
    up = (state & 4) >> 2;
    left = (state & 8) >> 3;
    down = (state & 16) >> 4;
    
    print(fire);
    print(right);
    print(up);
    print(left);
    println(down);
  }
    
  c = (fire == 0) ? 250 : 0;
  
  if(right == 0 && left == 1) {
    x = x + 2;
  }
  if(up == 0 && down == 1) { 
    y = y - 2; 
  }
  if(left == 0 && right == 1) {
    x = x - 2;
  }
  if(down == 0 && up == 1) {
    y = y + 2;
  }
  
  background(255, 255, 150);
  fill(c);
  rect(x, y, 50, 50);
}

Well, also this code looks quite simple. After importing the needed packages and definging some global variables, it initializes the Serial connection to the Arduino board. I used /dev/ttyUSB0 because that's the name of the serial device Arduino it's connected to on my system. On your system it will probably be different: you can understand the correct device name by looking under Tools -> Serial Port of your Arduino IDE.

Note how Processing is similar to Arduino programming language: it also uses setup() while it has a draw() which does exactly the same of the Arduino loop().

The code in draw() just reads from the serial interface and sets some state variables. It uses the state variables to change the position of the square, if the fire button is pressed it changes its color.

Putting all togheter!

Following a demonstration of the Arduino controller and the Processing program:

Conclusions

As we saw, Arduino communication capabilities are really powerful while still being easy to use. Also Processing looks like a really cool tool to know. Let's see if we can make good use of them.

References

Arduino Serial APIs documentation at arduino.cc
Processing programming language

Posted in:

Helpful, informative tutorial!

Submitted by ScottInc (not verified) on Thu, 2013-08-08 04:52.

Even with a good bit of programming knowledge, I found your thorough tutorial to be quite helpful in understanding how to use Processing with an Arduino's serial communications. Thank you for sharing this!

Good stuff!

Submitted by Don (not verified) on Sat, 2013-03-16 09:49.

Thanks for a comprehensive article. Perfect for a newbie like me.
For the first time I know that I can safely dispense with external resistors.
Now to learn a bit more about Processing!

online social media marketing

Submitted by online social media marketing (not verified) on Sat, 2013-02-16 06:42.

This is very educational content and written well for a change. It's nice to see that some people still understand how to write a quality post!

doubt

Submitted by vijay (not verified) on Mon, 2013-01-21 13:42.

will you please tell about how to actuate the cylinder using serial communication?

actuate the cylinder?

Submitted by Dan Zeman (not verified) on Mon, 2014-03-24 20:05.

Vijay, actuate what cylinder? It sounds like you are trying to use serial communication to turn on/off a pneumatic cylinder maybe?

This would work and im so close but...

Submitted by FRosty (not verified) on Mon, 2012-10-08 17:26.

The BYTE keyword is no longer supported, how do i get round this issue? The debug suggest's to use the serial.write keyword but that is not right.

Try using an "unsigned char",

Submitted by David C. (not verified) on Thu, 2012-12-20 08:35.

Try using an "unsigned char", to replace the BYTE variable type.

Thanks for the tutorial!

Submitted by Anonymous (not verified) on Wed, 2011-12-07 23:38.

I Am researching Arduino duplex serial communication for home automation - Eg, Posting a temp sensor reading from the Arduino on serial to a PC then after PC does the logic sending a trigger command from the PC back to Arduino to actuate a solid state relay (switches on the boiler). After reading this article I came up with the idea of using the PC to Poll the Arduino temperature then sending back the Trigger command if required (a much more efficient way of doing it as Arduino can just run a serial read loop and only post the temp on request!) Once I have it tested I'll post something up on the arduino forums!

Thanks for taking the time to write the article!

You have written a very good

Submitted by Abhimanyu Singh Udawat (not verified) on Mon, 2011-07-18 11:07.

You have written a very good tutorial and above all, the starting steps as well. Like, you could have gone with showing only the Arduino+Processing game in the end but you showed the steps from reading a single byte and moving over to complex programs. Thats the way to do it. Thanks.

Post new comment

The content of this field is kept private and will not be shown publicly.
If you have a personal or company website insert its address in the form http://www.example.com/ .
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <pre> <small> <del> <img> <h2> <h3> <h4> <b> <video> <sub> <sup>
  • Lines and paragraphs break automatically.
  • Images can be added to this post.
  • You may use [inline:xx] tags to display uploaded files or images inline.
  • You may insert videos with [video:URL]
  • Each email address will be obfuscated in a human readable fashion or (if JavaScript is enabled) replaced with a spamproof clickable link.

More information about formatting options