Serial Call-and-Response (Processing)

This example for Processing shows how to take in a multi-byte string of serial data and process it byte by byte. In this example, the computer sends an “A” to the microcontroller, and the microcontroller sends three bytes in response. Each byte represents a sensor value.

After sending the “A”, the computer reads each byte in, adding it to a string until it has three bytes in the string. It then parses each byte of the string out into an int, and assigns values to three variables from those bytes.

This example is written for Processing,by Casey Reas and Ben Fry. It was last updated for beta version 115.

Processing code:

/*
  Serial call-and-response for v.85 and beyond
 by Tom Igoe

 Sends a byte out the serial port, and reads 3 bytes in.
 Sets foregound color, xpos, and ypos of a circle onstage
 using the values returned from the serial port.
 Thanks to Daniel Shiffman for the improvements.
 Thanks to Casey Reas for reminding me to use SerialEvent() properly.

 Updated 30 May 2006
 */

import processing.serial.*;

int bgcolor;			     // Background color
int fgcolor;			     // Fill color
Serial port;                         // The serial port
int[] serialInArray = new int[3];    // Where we'll put what we receive
int serialCount = 0;                 // A count of how many bytes we receive
int xpos, ypos;		     // Starting position of the ball
boolean firstContact = false;        // Whether we've heard from the microcontroller

void setup() {
  size(256, 256);  // 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);
  port.write(65);    // Send a capital A to start the microcontroller sending
}

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

  // If no serial data has beeen received, send again until we get some.
  // (in case you tend to start Processing before you start your
  // external device):
  if (firstContact == false) {
    delay(300);
    port.write(65);
  }
}

void serialEvent(Serial port) {
  // if this is the first byte received,
  // take note of that fact:
  if (firstContact == false) {
    firstContact = true;
  }
  // Add the latest byte from the serial port to array:
  serialInArray[serialCount] = port.read();
  serialCount++;

  // If we have 3 bytes:
  if (serialCount > 2 ) {
    xpos = serialInArray[0];
    ypos = serialInArray[1];
    fgcolor = serialInArray[2];

    // print the values (for debugging purposes only):
    println(xpos + "t" + ypos + "t" + fgcolor);
    // Send a capital A to request new sensor readings:
    port.write(65);
    // Reset serialCount:
    serialCount = 0;
  }
}

The microprocessor is reading its sensors, then listening for a byte of data from the Director program. If it gets a byte, it sends out its five sensor readings. If it doesn’t, it goes about its other business. Examples for for PicBasic Pro, the BX-24, and Wiring/Arduino can be found at this link as well.

These methods won’t work in every situation, and they will need to be modified to fit most situations, but they are a starting point.