Recitation 8: Serial Communication——Leah Bian

Exercise 1: Make a Processing Etch A Sketch

Step 1: For this exercise, I needed to send two analog values from Arduino to Processing via serial communication. In Processing, I drew an ellipse, and its location was defined by the values from Arduino. I built a circuit with two potentiometers, controlling the ellipse’s x-axis and y-axis movement respectively. I used the A to P (multipleValues) code example and made some modifications. For example, I changed the number of the analog values in Processing, and used map function to limit the range. The interaction here is clear but quite simple, but it can be a single part of a bigger interactive process. 

exercise 1
exercise 1

Code (Processing):

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);
  setupSerial();
}

void draw() {
  background(0);
  updateSerial();
  float x = map(sensorValues[0],0,1023,0,500);
  float y = map(sensorValues[0],0,1023,0,500);
  printArray(sensorValues);
  fill(255);
  ellipse(x,y,100,100);
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[5], 9600);
  
  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]);
        }
      }
    }
  }
}

Code (Arduino):

void setup() {
Serial.begin(9600);
}

void loop() {
int sensor1 = analogRead(A0);
int sensor2 = analogRead(A1);

// keep this format
Serial.print(sensor1);
Serial.print(“,”); // put comma between sensor values
Serial.print(sensor2);
Serial.println ();
// too fast communication might cause some latency in Processing
// this delay resolves the issue.
delay(100);
}

Step 2: For step 2, I modified the code to draw a line. I needed to keep track of the previous x and y values to draw a line from there to the new x and y positions. Therefore, I used float() function for four times to define the variables, and then drew the line.

Code (Processing):

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() {
  float pX = map(sensorValues[0], 0, 1023, 0, width);
  float pY = map(sensorValues[1], 0, 1023, 0, width);
  updateSerial();
  float x = map(sensorValues[0], 0, 1023, 0, width);
  float y = map(sensorValues[1], 0, 1023, 0, height);
  printArray(sensorValues);
  stroke(255);
  line(pX,pY,x,y);
}

void setupSerial() {
  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[5], 9600);
  
  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]);
        }
      }
    }
  }
}

Code (Arduino):

void setup() {
Serial.begin(9600);
}

void loop() {
int sensor1 = analogRead(A0);
int sensor2 = analogRead(A1);

// keep this format
Serial.print(sensor1);
Serial.print(“,”); // put comma between sensor values
Serial.print(sensor2);
Serial.println ();
// too fast communication might cause some latency in Processing
// this delay resolves the issue.
delay(100);
}

Exercise 2:Make a musical instrument with Arduino

For this exercise, I wrote a Processing sketch that sends values to Arduino based on the mouse’s x and y positions. A hint was provided that we should use the tone() function, so I studied it first. The syntax of the function should be “tone(pin, frequency, duration)”, and the function can only be used with pin3 and pin11. Therefore, I put a buzzer on the breadboard and connected it to pin11 and the ground. The serial values from Processing are sent to Arduino and are translated into frequency and duration for a tone, which will be sounded by the buzzer. Besides, I drew an ellipse to make the location of the mouse’s x and y positions clearer. The interaction here is clear but simple, since only two variables are involved and what the user needs to do is just to move the mouse. However, this simple musical instrument could be a basis for further development and the idea can be an interesting inspiration.

0
exercise 2

Code (Processing):

import processing.serial.*;
int NUM_OF_VALUES = 2;  /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/
Serial myPort;
String myString;
int values[] = new int[NUM_OF_VALUES];

void setup() {
  size(500, 500);
  background(0);

  printArray(Serial.list());
  myPort = new Serial(this, Serial.list()[5], 9600);
 
  myPort.clear();
  myString = myPort.readStringUntil( 10 );  // 10 = '\n'  Linefeed in ASCII
  myString = null;
}

void draw() {
  background(0);
  values[0]=mouseX;
  values[1]=mouseY;
  circle(mouseX,mouseY,80);
  sendSerialData();
  echoSerialData(200);
}

void sendSerialData() {
  String data = "";
  for (int i=0; i<values.length; i++) {
    data += values[i];
    if (i < values.length-1) {
      data += ","; // add splitter character "," between each values element
    } 
    else {
      data += "n"; // add the end of data character "n"
    }
  }
  myPort.write(data);
}

void echoSerialData(int frequency) {
  if (frameCount % frequency == 0) myPort.write('e');

  String incomingBytes = "";
  while (myPort.available() > 0) {
    incomingBytes += char(myPort.read());
  }
  print( incomingBytes );
}

Code (Arduino):

#define NUM_OF_VALUES 2

int tempValue = 0;
int valueIndex = 0;
int values[NUM_OF_VALUES];

void setup() {
Serial.begin(9600);
pinMode(11, OUTPUT);
}

void loop() {
getSerialData();
tone(11,values[0],values[1]);

}

//recieve serial data from Processing
void getSerialData() {
if (Serial.available()) {
char c = Serial.read();
switch (c) {
case ‘0’…’9′:
tempValue = tempValue * 10 + c – ‘0’;
break;
case ‘,’:
values[valueIndex] = tempValue;
tempValue = 0;
valueIndex++;
break;
case ‘n’:
values[valueIndex] = tempValue;
tempValue = 0;
valueIndex = 0;
break;
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;
}
}
}

Leave a Reply