How to send multiple variables from Processing to Arduino

Categories Interaction, Programming

I wanted to be able to send a set of 4 integers to an Arduino from a Processing application that I am working on, I also wanted to be able to prefix the set with a tag, so that I could deal with different sets of integers in specific ways, for specific purposes.

For instance, I have an LCD screen and some LED’s connected to my Arduino, or maybe I have a servo motor and a speaker that I want to control based on events happening in software running via Processing.

I modified* the code below from the code shown here (Arduino Cookbook @ inkling.com)

*I simply expanded the amount of variables being sent per packet.

Processing Code:

// Processing Sketch

/* SendingBinaryToArduino
 * Language: Processing
 */
import processing.serial.*;

Serial myPort;  // Create object from Serial class
public static final char HEADER    = 'H';
public static final char A_TAG = 'M';
public static final char B_TAG = 'X';

void setup()
{
  size(512, 512);
  String portName = Serial.list()[1];
  myPort = new Serial(this, portName, 9600);
}

void draw(){
}

void serialEvent(Serial p) {
  // handle incoming serial data
  String inString = myPort.readStringUntil('\n');
  if(inString != null) {     
    print( inString );   // echo text string from Arduino
  }
}

void mousePressed() {
  sendMessage(A_TAG, 8,5,20,33);
}

void sendMessage(char tag, int a, int b, int c, int d){
  // send the given index and value to the serial port
  myPort.write(HEADER);
  myPort.write(tag);
  myPort.write((char)(a / 256)); // msb
  myPort.write(a & 0xff);  //lsb
  myPort.write((char)(b / 256)); // msb
  myPort.write(b & 0xff);  //lsb
  myPort.write((char)(c / 256)); // msb
  myPort.write(c & 0xff);  //lsb
  myPort.write((char)(d / 256)); // msb
  myPort.write(d & 0xff);  //lsb
}

You can see in the void sendMessage function that each integer is being split into two bytes, but both the header and tag are sent as a single byte – this means we are sending 10 bytes all up (we will need to reference this in the Arduino code in TOTAL_BYTES).

Arduino Code:

// BinaryDataFromProcessing
// These defines must mirror the sending program:
const char HEADER       = 'H';
const char A_TAG    = 'M';
const char B_TAG    = 'X';
const int  TOTAL_BYTES  = 10  ; // the total bytes in a message

void setup()
{
  Serial.begin(9600);
}

void loop(){
  if ( Serial.available() >= TOTAL_BYTES)
  {
     if( Serial.read() == HEADER)
    {
      char tag = Serial.read();
      if(tag == A_TAG)
      {
        //Collect integers
        int a = Serial.read() * 256; 
        a = a + Serial.read();
        int b = Serial.read() * 256;
        b = b + Serial.read();
        int c = Serial.read() * 256;
        c = c + Serial.read();
        int d = Serial.read() * 256;
        d = d + Serial.read();
        Serial.print("Received integers | a:");
        Serial.print(a);
        Serial.print(", b:");
        Serial.println(b);
        Serial.print(", c:");
        Serial.println(c);
        Serial.print(", d:");
        Serial.println(d);
      }
      else {
        Serial.print("got message with unknown tag ");
        Serial.write(tag);
      }
    }
  }
}

You can see under Serial.available() after the comment “//Collect integers” that each byte is being stored in a variable (multiplied by 256 to reverse the division on the Processing side) and then the second byte is added to that (thus reversing the rejoining the split that took place on the Processing side) – in this way we are reassembling the data that we sent into a useable format to be used.

From here you can do whatever you like with the data, use it for conditionals or set it to analog outputs. The applications are nearly endless.