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]