By Jeff Gray, Apr 2008

Much like the call and response example taken from the intro to p-comp class here at ITP, this example allows you to send a human readable version, which you can then string parse in processing. The can be useful if you want to be able to read the values in a serial terminal, or if you'd like to easily send values that are bigger than a byte or are not numerical (ie: messages and other status states).

Arduino Code

int firstSensor = 0;    // first analog sensor
int secondSensor = 0;   // second analog sensor
int thirdSensor = 0;    // digital sensor
int inByte = 0;         // incoming serial byte

void setup()
{
  // start serial port at 9600 bps:
  Serial.begin(9600);
  pinMode(2, INPUT);   // digital sensor is on digital pin 2
  establishContact();  // send a byte to establish contact until Processing responds 
}

void loop()
{
  // if we get a valid byte, read analog ins:
  if (Serial.available() > 0) {
    // get incoming byte:
    inByte = Serial.read();
    // read first analog input, no dividing necessary:
    firstSensor = analogRead(0);
    // delay 10ms to let the ADC recover:
    delay(10);
    // read second analog input, no dividing necessary:
    secondSensor = analogRead(1);
    // read  switch, multiply by 255
    // so that you're sending 100 or 255:
    thirdSensor = 100 + (155 * digitalRead(2));
    // send sensor values:
    Serial.print("X,");
    Serial.print(firstSensor, DEC);
    Serial.print(",Y,");
    Serial.print(secondSensor, DEC);
    Serial.print(",Z,");
    Serial.print(thirdSensor, DEC);   
    Serial.print("\n");    
  }
}

void establishContact() {
 while (Serial.available() <= 0) {
      Serial.print('A', BYTE);   // send a capital A
      delay(300);
  }
}

Processing Code

import processing.serial.*;

int bgcolor;			     // Background color
int fgcolor;			     // Fill color
Serial port;                         // The serial port

String serialInString = "";          // Where we'll put what we receive

int xpos, ypos;		             // Starting position of the ball
boolean firstContact = false;        // Whether we've heard from the microcontroller

void setup() {
  size(800,800);  // Stage size
  noStroke();      // No border on the next thing drawn

  // Set the starting position of the ball (middle of the stage)
  xpos = width/2;
  ypos = height/2;

  // Print a list of the serial ports, for debugging purposes:
  println(Serial.list());

  // I know that the first port in the serial list on my mac
  // is always my  Keyspan adaptor, so I open Serial.list()[0].
  // On Windows machines, this generally opens COM1.
  // Open whatever port is the one you're using.
  port = new Serial(this, Serial.list()[0], 9600);
}

void draw() {
  background(bgcolor);
  fill(fgcolor);
  // Draw the shape
  ellipse(xpos, ypos, 20, 20);
}

void serialEvent(Serial port) {
  // read a byte from the serial port:
  int inByte = port.read();
  // if this is the first byte received, 
  // take note of that fact. Otherwise, add it to the array:
  if (firstContact == false) {
    if (inByte == 'A') { 
      port.clear();          // clear the serial port buffer
      firstContact = true;
      port.write('A');
    } 
  // if firstContact has been made, check to see if a full string has come in
  } else {
    if(inByte == '\n'){
      // split the serialInString into pieces of data
      String[] pieces = serialInString.split(",");

      // grab strings from array, and convert into ints
      xpos = Integer.parseInt(pieces[1]);
      ypos = Integer.parseInt(pieces[3]);
      fgcolor = Integer.parseInt(pieces[5]);

      // print the values (for debugging purposes only):
      println(xpos + "\t" + ypos + "\t" + fgcolor);

      // Send a capital A to request new sensor readings:
      port.write('A');
      // Reset serialInString
      serialInString = "";
    } else {
      serialInString += (char)inByte;
    }
  }
}