Recitation 8: Serial Communication by Tiana Lui

Etch a Sketch

For the first exercise, etch a sketch, I used Arduino to send two analog values to Processing via serial communication. During my makeup recitation I first went over the code example line by line with the help of Nick. After going through the code and understanding what each line/ variable/ function was used for, I went into the Arduino code and removed one sensor variable, because I only needed 2 sensors for the 2 potentiometers. Next I used the map function to map both sensor values to a range of 1-255, to keep my drawings within the size of the processing canvas. I also removed the Serial.print(“,”) and Serial.print(sensor3). I removed the comma, Serial.print(“,”), because processing reads in all the sensor values and commas into one string, stops reading once it reaches the linefeed character, then it splices the String by comma, turns each sensor value into an int, and stores the int values into an array. If there is an extra comma, splicing the string via commas will generate an extra empty value and store that empty value into the array.

In processing, I changed the NUM_OF_VALUES to 2, to make the array only store 2 values, because we were only receiving two sensor values from the 2 potentiometers. Under draw, I added a fill line and an ellipse line, with the x and y position set to sensorValues[0], and sensorValues[1], respectively to allow the potentiometer values control where the ellipse was drawn on the canvas. I then tested my code to check which port I was using for the arduino and set up the port in the setupSerial function.

The interaction involved in both circuits (etch a sketch and buzzer) was a classic example of input, processing, and output. In this circuit the user was manipulating and sending values from the potentiometer to the arduino, processing interpreting this information, and outputting a series of ellipses with positioning based on the potentiometer values received.

circuit schematic etch a sketch

Arduino Code

// IMA NYU Shanghai

// Interaction Lab

// For sending multiple values from Arduino to Processing

void setup() {

 Serial.begin(9600);

}

void loop() {

 int sensor1 = analogRead(A0);

 int sensor2 = analogRead(A1);

 sensor1=map(sensor1,1,1023,1,255);

 sensor2=map(sensor2,1,1023,1,255);

 //int sensor3 = analogRead(A2);

 // keep this format

 Serial.print(sensor1);

 Serial.print(“,”);  // put comma between sensor values

 Serial.print(sensor2);

 //Serial.print(“,”);

 //Serial.print(sensor3);

 Serial.println(); // add linefeed after sending the last sensor value

 // too fast communication might cause some latency in Processing

 // this delay resolves the issue.

 delay(100);

}

Processing Code

// IMA NYU Shanghai

// Interaction Lab

// For receiving multiple values from Arduino to Processing

/*

* Based on the readStringUntil() example by Tom Igoe

* https://processing.org/reference/libraries/serial/Serial_readStringUntil_.html

*/

import processing.serial.*;

String myString = null;

Serial myPort;

int NUM_OF_VALUES = 2;   /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/

int[] sensorValues;      /** this array stores values from Arduino **/

void setup() {

 size(500, 500);

 background(0);

 setupSerial();

}

void draw() {

 updateSerial();

 printArray(sensorValues);

 fill(255);

 ellipse(sensorValues[0],sensorValues[1],5,5);

 // use the values like this!

 // sensorValues[0]

 // add your code

 //

}

void setupSerial() {

 printArray(Serial.list());

 myPort = new Serial(this, Serial.list()[ 3 ], 9600);

 // WARNING!

 // You will definitely get an error here.

 // Change the PORT_INDEX to 0 and try running it again.

 // And then, check the list of the ports,

 // find the port “/dev/cu.usbmodem—-” or “/dev/tty.usbmodem—-”

 // and replace PORT_INDEX above with the index number of the port.

 myPort.clear();

 // Throw out the first reading,

 // in case we started reading in the middle of a string from the sender.

 myString = myPort.readStringUntil( 10 );  // 10 = ‘\n’ Linefeed in ASCII

 myString = null;

 sensorValues = new int[NUM_OF_VALUES];

}

void updateSerial() {

 while (myPort.available() > 0) {

   myString = myPort.readStringUntil( 10 ); // 10 = ‘\n’  Linefeed in ASCII

   if (myString != null) {

     String[] serialInArray = split(trim(myString), “,”);

     if (serialInArray.length == NUM_OF_VALUES) {

       for (int i=0; i<serialInArray.length; i++) {

         sensorValues[i] = int(serialInArray[i]);

       }

     }

   }

 }

}

Buzzer

For the buzzer, in arduino I defined the number of values as 2 again, and in the setup I set up one pinMode to pin 9. Under void loop, I used the tone function with one potentiometer value controlling the pitch, and the other potentiometer value controlling the duration. Ie. tone(9,values[0],values[1])

In processing, under void draw, I set the values[0] to mouseX, and values[1] to mouseY, so that my mouseX position controlled pitch, and mouseY controlled the duration of the pitch.

For the buzzer, instead of inputting turning/rotation of potentiometer, which was translated into integer numbers for the computer to read, the interaction took using computer mouse inputs, trackpad movements. And instead of processing outputting information, this time, arduino was used to output information.

buzzer

Arduino Code

// IMA NYU Shanghai

// Interaction Lab

/**

 This example is to send multiple values from Processing to Arduino.

 You can find the Processing example file in the same folder which works with this Arduino file.

 Please note that the echo case (when char c is ‘e’ in the getSerialData function below)

 checks if Arduino is receiving the correct bytes from the Processing sketch

 by sending the values array back to the Processing sketch.

**/

#define NUM_OF_VALUES 2    /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/

/** DO NOT REMOVE THESE **/

int tempValue = 0;

int valueIndex = 0;

/* This is the array of values storing the data from Processing. */

int values[NUM_OF_VALUES];

void setup() {

 Serial.begin(9600);

 //pinMode(13, OUTPUT);

 pinMode(9, OUTPUT);

}

void loop() {

 getSerialData();

 // add your code here

 // use elements in the values array

 // values[0]

 // values[1]

 tone(9, values[0], values[1]);

}

//receive serial data from Processing

void getSerialData() {

 if (Serial.available()) {

   char c = Serial.read();

   //switch – case checks the value of the variable in the switch function

   //in this case, the char c, then runs one of the cases that fit the value of the variable

   //for more information, visit the reference page: https://www.arduino.cc/en/Reference/SwitchCase

   switch (c) {

     //if the char c from Processing is a number between 0 and 9

     case ‘0’…’9′:

       //save the value of char c to tempValue

       //but simultaneously rearrange the existing values saved in tempValue

       //for the digits received through char c to remain coherent

       //if this does not make sense and would like to know more, send an email to me!

       tempValue = tempValue * 10 + c – ‘0’;

       break;

     //if the char c from Processing is a comma

     //indicating that the following values of char c is for the next element in the values array

     case ‘,’:

       values[valueIndex] = tempValue;

       //reset tempValue value

       tempValue = 0;

       //increment valuesIndex by 1

       valueIndex++;

       break;

     //if the char c from Processing is character ‘n’

     //which signals that it is the end of data

     case ‘n’:

       //save the tempValue

       //this will b the last element in the values array

       values[valueIndex] = tempValue;

       //reset tempValue and valueIndex values

       //to clear out the values array for the next round of readings from Processing

       tempValue = 0;

       valueIndex = 0;

       break;

     //if the char c from Processing is character ‘e’

     //it is signalling for the Arduino to send Processing the elements saved in the values array

     //this case is triggered and processed by the echoSerialData function in the Processing sketch

     case ‘e’: // to echo

       for (int i = 0; i < NUM_OF_VALUES; i++) {

         Serial.print(values[i]);

         if (i < NUM_OF_VALUES – 1) {

           Serial.print(‘,’);

         }

         else {

           Serial.println();

         }

       }

       break;

   }

 }

}

Processing Code

// IMA NYU Shanghai

// Interaction Lab

/**

* This example is to send multiple values from Processing to Arduino.

* You can find the arduino example file in the same folder which works with this Processing file.

* Please note that the echoSerialData function asks Arduino to send the data saved in the values array

* to check if it is receiving the correct bytes.

**/

import processing.serial.*;

int NUM_OF_VALUES = 2;  /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/

Serial myPort;

String myString;

// This is the array of values you might want to send to Arduino.

int values[] = new int[NUM_OF_VALUES];

void setup() {

 size(500, 500);

 background(0);

 printArray(Serial.list());

 myPort = new Serial(this, Serial.list()[ 3 ], 9600);

 // check the list of the ports,

 // find the port “/dev/cu.usbmodem—-” or “/dev/tty.usbmodem—-”

 // and replace PORT_INDEX above with the index of the port

 myPort.clear();

 // Throw out the first reading,

 // in case we started reading in the middle of a string from the sender.

 myString = myPort.readStringUntil( 10 );  // 10 = ‘\n’ Linefeed in ASCII

 myString = null;

}

void draw() {

 background(0);

 // changes the values

 values[0]=mouseX;

 values[1]=mouseY;

 // sends the values to Arduino.

 sendSerialData();

 // This causess the communication to become slow and unstable.

 // You might want to comment this out when everything is ready.

 // The parameter 200 is the frequency of echoing.

 // The higher this number, the slower the program will be

 // but the higher this number, the more stable it will be.

 echoSerialData(200);

}

void sendSerialData() {

 String data = “”;

 for (int i=0; i<values.length; i++) {

   data += values[i];

   //if i is less than the index number of the last element in the values array

   if (i < values.length-1) {

     data += “,”; // add splitter character “,” between each values element

   }

   //if it is the last element in the values array

   else {

     data += “n”; // add the end of data character “n”

   }

 }

 //write to Arduino

 myPort.write(data);

}

void echoSerialData(int frequency) {

 //write character ‘e’ at the given frequency

 //to request Arduino to send back the values array

 if (frameCount % frequency == 0) myPort.write(‘e’);

 String incomingBytes = “”;

 while (myPort.available() > 0) {

   //add on all the characters received from the Arduino to the incomingBytes string

   incomingBytes += char(myPort.read());

 }

 //print what Arduino sent back to Processing

 print( incomingBytes );

}

Leave a Reply