Arduino Communication with Processing

Updated: Oct 14

Want to make Arduino 'talk' with Processing? Read this post to see how Serial communication can be used to transfer data between them.

Serial communication between Arduino and Processing


Why do this?

While it's great that an Arduino can do a seemingly countless number of things on its own and disconnected from a computer, there are also many cases where it would be useful and even necessary to do so.


Processing

Processing is a powerful language based on Java that was created for hobbyists, hackers, educators, and artists. It has very extensive and powerful libraries for creating stunning visualizations without a lot of administrative overhead in your code. Pairing this language and development environment with the Arduino is to many a natural choice, especially since the Arduino IDE was even build based of the Processing IDE.


Serial Communication

Serial Communication was originally intended to reliably transmit data 1-bit at a time over long distances. It is a natural choice for communication between IC's, and due to simplicity it is the way that the Arduino prints out data to the monitor.


The link between Arduino and Processing

The Arduino and Processing IDE's each have the ability to print to something called the "Serial Monitor". In doing so, they can each indirectly communicate with each other by agreeing to send an receive data from the same place.


By the end of this short tutorial, you are going to make a Processing sketch that displays blue circles at random locations, which are provided by the Arduino over serial communication. The processing will detect mouse clicks and notify the Arduino over Serial communication to stop transmitting coordinates.





Arduino Example Code


Add this code below into the Arduino IDE and upload it to you board.


// Code snippet for Arduino to Processing

void setup() { 
   // Setup serial communication and specify Baud Rate
   Serial.begin(9600);   
}

// Send "i:j" via Serial
void loop() {
  for (int i = 1; i < 11; i++) {
      int j = 11 - i;          
      Serial.print(i);
      Serial.print(":");
      Serial.println(j);
      delay(1000); 
  }
}

Here is what's going on:

  • "Serial.begin(9600)" - We need to tell Arduino that we are going to be sending data over serial communication, and need to specify the Baude Rate, which specifies how fast data is sent over a serial line, in units of bits per second (bps). A rate of 9600 is pretty common for applications where time is not an overly critical specification. Other common baud rates are 1200, 2400, 4800, 19200, 38400, and 57600, just to name a few. While it's up to us to chose a Baud Rate that fits our requirements, it is critical that the other devices receiving the data on the serial line know what the is so that they are able to actually read the data.


  • "Serial.print(i); Serial.print(":"); Serial.println(j);" - This is how Arduino sends data over the serial line. The combination of these 3 print-statements sends the variable i and j in the format i:j. So in other words as the for loop iterates it will send '1:10', '2:9', '3:8', etc.

You can view the Serial output of the program by either going to Tools --> Serial Monitor, or by clicking on the magnifying glass icon in the top right corner of the Arduino IDE:



After loading the sketch to your Arduino Board the Serial monitor will look something like this. Notice that we need to select 9600 baud in the dropdown at the bottom of the monitor because that is the rate we chose with "Serial.begin(9600). If you don't then the monitor output will display cryptic garbage.



Processing Example Code


import processing.serial.*;

Serial myPort;
String data="";
int xCoordinate, yCoordinate;

void setup() {  
  String portName = Serial.list()[1]; 
  myPort = new Serial(this, portName, 9600);  
  myPort.bufferUntil('\n');
}

void draw() {
  print(xCoordinate);  
  print(":");
  print(yCoordinate);
  println();  
}

// Reads the data from the Serial Port
void serialEvent (Serial myPort) {  
  data = myPort.readStringUntil('\n');  
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, ':');  
      xCoordinate = int(items[0]);
      yCoordinate = int(items[1]);
  }
}

Things to note:

  • "import processing.serial.*;" - We need to import Processing's built-in library for handling Serial communcation.


  • "String items[] = split(data, ':')" - This is where we intake the data from the Serial line. The first value in the ":" delimited list gets assigned to xCoordinate and the second value gets assigned to yCoordinate.


  • "print(xCoordinate);" - These print statements are for display purposed only, so that we can see the values printed to the console. In the next steps we will modify this program to actually do something with these values.

Processing Output




Now update the Arduino code to the following:

int state = 0;

void setup() { 
   // Setup serial communication and specify Baud Rate
   Serial.begin(9600); 
   randomSeed(10); 
}

void loop() {
  if (state == 0) {
    // Send data over Serial line
    Serial.print(random(50, 910));
    Serial.print(":");
    Serial.println(random(50, 590));
    } 

   // Receive data over Serial line
   if (Serial.available() > 0) {
    state = Serial.parseInt();       
    }    
}

Things to note:

  • if (Serial.available() > 0) { state = Serial.parseInt(); }

This chunk of code is the piece that 'listens' to the Serial line to receive data being sent to the Processing sketch. We are assigned it to a variable named state, and then using this state to determine whether to pause sending random integers to the processing sketch. We've also update what we are sending to Processing, however the format int:int remains the same.


import processing.serial.*;

Serial myPort;
String data="";
int xCoordinate = width / 2, yCoordinate = height / 2;

void setup() {  
  String portName = Serial.list()[1]; 
  myPort = new Serial(this, portName, 9600);  
  myPort.bufferUntil('\n');
}

void draw() {
  fill(0, 0, 255); 
  ellipse(xCoordinate, yCoordinate, 50, 50);  
  if (mousePressed) {
    myPort.write(1);
    }
}

// Reads the data from the Serial Port
void serialEvent (Serial myPort) {  
  data = myPort.readStringUntil('\n');  
  if (data != null) {
    data = trim(data);
    // split the string at "/"
    String items[] = split(data, ':');  
      xCoordinate = int(items[0]);
      yCoordinate = int(items[1]);
  }
}

The main change here is the draw() function:


void draw() { fill(0, 0, 255); ellipse(xCoordinate, yCoordinate, 50, 50); if (mousePressed) { myPort.write(1); } }


With the statement myPort.write(), we are telling the sketch to send the value of '1' over the Serial line, which is then received by the Arduino. This function has also been added to draw ellipses anywhere on the screen as determined by the x and y coordinates passed to it from the Arduino random number generation.