Serial Duplex

For this lab, I learned how to read input from multiple sensors and translate the serial data via two different methods. The first one is called the Punctuation method. Each time the data is read, it is punctuated with a newline and a carriage return to indicate the end of a reading (i.e. when all the sensors have been read once through).

I translated the data from two FSRs into x and y coordinates for an ellipse in Processing.

The Punctuation method code that I used in Arduino differs slightly from the example code in the lab, but it works equally well.

[code lang="c"]
//Punctuation Method - Arduino
const int switchPin = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT);
  }

void loop()
{
  int sensorValue = 0;
  
  for(int sensor = 0; sensor < 3; sensor++)
  {
    if (sensor < 2)
    {
      sensorValue = analogRead(sensor);
      Serial.print(sensorValue);
      Serial.print(",");
    }
    else
    {
      sensorValue = digitalRead(switchPin);
      Serial.println(sensorValue);
    }
  }
}[/code]

Processing code:

[code lang="java"]
//Punctuation Method - Processing

import processing.serial.*;
Serial myPort;

float bgcolor;               // Background color
float fgcolor;               // Fill color
float xpos, ypos;
boolean firstContact = false;

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

void draw()
{
  background(bgcolor);
  smooth();
  fill(fgcolor);
  ellipse(xpos, ypos, 20, 20);
}

void serialEvent(Serial myPort) {
  // read the serial buffer:
  String myString = myPort.readStringUntil('n');

  if (myString != null) 
  {
    myString = trim(myString);

    // split the string at commas & convert sections into ints
    int sensors[] = int(split(myString, ','));
    
    xpos = map(sensors[0], 430, 580, 0, width);
    ypos = map(sensors[1], 430, 580, 0, height);

    for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) 
    {
      print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "t");
    }
    // add a linefeed after all the sensor values are printed:
    println();
    
    if (sensors.length > 1) 
    {
      xpos = sensors[0];
      ypos = sensors[1];
      fgcolor = sensors[2] * 255;
    }
  }
}[/code]

The second method I used is called the Call and Response or Handshaking method. Instead of punctuating the data to indicate the end of a set, it just sends one set of data at a time, and it waits for a response before sending it. The serial output looks something like this:

This is the result:

Here is the Arduino code:

[code lang="c"]//Handshake method
const int switchPin = 2;

void setup()
{
  Serial.begin(9600);
  pinMode(switchPin, INPUT);
  establishContact();
}

void loop()
{
  int sensorValue = 0;
  
  if(Serial.available() > 0)
  {
    int inByte = Serial.read();
    
    for(int sensor = 0; sensor < 3; sensor++)
    {
      if (sensor < 2)
      {
        sensorValue = analogRead(sensor);
        Serial.print(sensorValue, DEC);
        Serial.print(",");
      }
      else
      {
        sensorValue = digitalRead(switchPin);
        Serial.println(sensorValue, DEC);
      }
    }
  }
}

void establishContact()
{
  while (Serial.available() <= 0) 
  {
      Serial.println("hello");   // send a starting message
      delay(300);
  }
}[/code]

Here is the Processing code:

[code lang="java"]//Handshake method
import processing.serial.*;
Serial myPort;

float bgcolor;               // Background color
float fgcolor;               // Fill color
float xpos, ypos;
boolean firstContact = false;

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

void draw()
{
  background(bgcolor);
  smooth();
  fill(fgcolor);
  ellipse(xpos, ypos, 20, 20);
}
void serialEvent(Serial myPort) {
  // read the serial buffer:
  String myString = myPort.readStringUntil('n');
  // if you got any bytes other than the linefeed:
  if (myString != null) {

    myString = trim(myString);

    // if you haven't heard from the microncontroller yet, listen:
    if (firstContact == false) {
      if (myString.equals("hello")) {
        myPort.clear();          // clear the serial port buffer
        firstContact = true;     // you've had first contact from the microcontroller
        myPort.write('A');       // ask for more
      }
    }
    // if you have heard from the microcontroller, proceed:
    else {
      // split the string at the commas
      // and convert the sections into integers:
      int sensors[] = int(split(myString, ','));

      // print out the values you got:
      for (int sensorNum = 0; sensorNum < sensors.length; sensorNum++) {
        print("Sensor " + sensorNum + ": " + sensors[sensorNum] + "t");
      }
      // add a linefeed after all the sensor values are printed:
      println();
      if (sensors.length > 1) {
        xpos = map(sensors[0], 0,1000,0,width);
        ypos = map(sensors[1], 0,1000,0,height);
        fgcolor = sensors[2] * 255;
      }
    }
    // when you've parsed the data you have, ask for more:
    myPort.write("A");
  }
}[/code]