For this recitation, we did many exercises to get familiar with the connection between Arduino and processing.
Exercise 1:
The first exercise is using Arduino to send two analog values to Processing via serial communication. I find this one the most confident one for me to do.
Below is the Arduino code:
void setup() { Serial.begin(9600); } void loop() { int sensor1 = analogRead(A0); int sensor2 = analogRead(A1); Serial.print(sensor1); Serial.print(","); // put comma between sensor values Serial.print(sensor2); Serial.println(); }
Processing:
import processing.serial.*; float x; float y; int NUM_OF_VALUES_FROM_ARDUINO = 2; /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ int sensorValues[]; /** this array stores values from Arduino **/ int sensorp[]; String myString = null; Serial myPort; void setup() { size(500, 500); setupSerial(); sensorp = new int[NUM_OF_VALUES_FROM_ARDUINO]; background(0); } void draw() { getSerialData(); printArray(sensorValues); x = map(sensorValues[0],0,1023,0,width); y = map(sensorValues[1],0,1023,0,width); stroke(255); line(sensorp[0], sensorp[1],x, y); sensorp[0]=int(x); sensorp[1]=int(y); } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[2], 9600); myPort.clear(); myString = myPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII myString = null; sensorValues = new int[NUM_OF_VALUES_FROM_ARDUINO]; } void getSerialData() { 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_FROM_ARDUINO) { for (int i=0; i<serialInArray.length; i++) { sensorValues[i] = int(serialInArray[i]); } } } } }
Video:
Exercise 2:
For this exercise, I found two codes for the bouncing circle. The first one is like this:
/** * Bounce. * * When the shape hits the edge of the window, it reverses its direction. */ int rad = 60; // Width of the shape float xpos, ypos; // Starting position of shape float xspeed = 2.8; // Speed of the shape float yspeed = 2.2; // Speed of the shape int xdirection = 1; // Left or Right int ydirection = 1; // Top to Bottom void setup() { fullScreen(); noStroke(); frameRate(30); ellipseMode(RADIUS); // Set the starting position of the shape xpos = width/2; ypos = height/2; } void draw() { background(102); // Update the position of the shape xpos = xpos + ( xspeed * xdirection ); ypos = ypos + ( yspeed * ydirection ); // Test to see if the shape exceeds the boundaries of the screen // If it does, reverse its direction by multiplying by -1 if (xpos > width-rad || xpos < rad) { xdirection *= -1; } ydirection *= 0; // Draw the shape ellipse(xpos, ypos, rad, rad); }
However, I found it really hard to use this code to communicate with processing, I tried several times but don’t know how to use “if statement” in this case. And later Tracy and I figured another way to code the bouncing circle. My servo isn’t working, so I did the coding part with Tracy and she filmed how the servo interacts with the bouncing circle.
Arduino code:
#define NUM_OF_VALUES_FROM_PROCESSING 1 /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ #include <Servo.h> /** DO NOT REMOVE THESE **/ int tempValue = 0; int valueIndex = 0; bool prevState = false; bool currentState = false; Servo myservo; int processing_values[NUM_OF_VALUES_FROM_PROCESSING]; void setup() { Serial.begin(9600); pinMode(12, OUTPUT); myservo.attach(10); } void loop() { getSerialData(); currentState = processing_values[0]; if (currentState != prevState && currentState == 1) { myservo.write(90); myservo.write(0); } else { myservo.write(0); } prevState = currentState; } //receive serial data from Processing void getSerialData() { while (Serial.available()) { char c = Serial.read(); switch (c) { case '0'...'9': tempValue = tempValue * 10 + c - '0'; break; case ',': processing_values[valueIndex] = tempValue; tempValue = 0; valueIndex++; break; case '\n': processing_values[valueIndex] = tempValue; tempValue = 0; valueIndex = 0; break; } } }
Processing:
import processing.serial.*; int NUM_OF_VALUES_FROM_PROCESSING = 1; /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ int processing_values[] = new int[NUM_OF_VALUES_FROM_PROCESSING]; /** this array stores values you might want to send to Arduino **/ Serial myPort; String myString; int x=30; int speedX = 5; void setup() { fullScreen(); background(0); setupSerial(); } void draw() { background(0); circle (x, 100, 100); x= x+speedX; if (x > width-40 || x < 0+30) { speedX = -speedX; } if (x > width-30) { processing_values[0] = 1; } else { processing_values[0] = 0; } sendSerialData(); } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[2], 9600); myPort.clear(); myString = myPort.readStringUntil( 10 ); // 10 = '\n' Linefeed in ASCII myString = null; } void sendSerialData() { String data = ""; for (int i=0; i<processing_values.length; i++) { data += processing_values[i]; //if i is less than the index number of the last element in the values array if (i < processing_values.length-1) { data += ","; // add splitter character "," between each values element } else { data += "\n"; // add the end of data character linefeed "\n" } } //write to Arduino myPort.write(data); print(data); // this prints to the console the values going to arduino }
Video:
Additional homework:
I found the communication quite confusing for there are many sections and it’s sometimes even impossible to figure out which part goes wrong. So I participated in the workshop and learnt more about the whole logic behind this.
Arduino code:
// IMA NYU Shanghai // Interaction Lab // For recitation 8 homework, controlling the display of two stars with two buttons void setup() { Serial.begin(9600); } void loop() { int button1 = digitalRead(9); int button2 = digitalRead(10); // keep this format Serial.print(button1); Serial.print(","); // put comma between values Serial.print(button2); Serial.println(); // add linefeed after sending the last value // too fast communication might cause some latency in Processing // this delay resolves the issue. delay(100); }
Processing:
// IMA NYU Shanghai // Interaction Lab // For recitation 8 homework, controlling the display of two stars with two buttons /* * 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[] buttonValues; /** this array stores values from Arduino **/ int prevButtonValue0 = 0; int prevButtonValue1 = 0; boolean star1Display = false; boolean star2Display = false; void setup() { size(600, 600); background(0); setupSerial(); } void draw() { updateSerial(); printArray(buttonValues); background(0); if (buttonValues[0]==1 && buttonValues[0]!= prevButtonValue0) { star1Display = !star1Display; } if (buttonValues[1]==1 && buttonValues[1]!= prevButtonValue1) { star2Display = !star2Display; } if (star1Display) { pushMatrix(); translate(width*0.3, height*0.3); rotate(frameCount / 200.0); star(0, 0, 30, 70, 5); popMatrix(); } if (star2Display) { pushMatrix(); translate(width*0.7, height*0.7); rotate(frameCount / 400.0); star(0, 0, 80, 100, 40); popMatrix(); } prevButtonValue0 = buttonValues[0]; prevButtonValue1 = buttonValues[1]; } void star(float x, float y, float radius1, float radius2, int npoints) { float angle = TWO_PI / npoints; float halfAngle = angle/2.0; beginShape(); for (float a = 0; a < TWO_PI; a += angle) { float sx = x + cos(a) * radius2; float sy = y + sin(a) * radius2; vertex(sx, sy); sx = x + cos(a+halfAngle) * radius1; sy = y + sin(a+halfAngle) * radius1; vertex(sx, sy); } endShape(CLOSE); } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[ 6 ], 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; buttonValues = 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++) { buttonValues[i] = int(serialInArray[i]); } } } } }
Video:
Research:
For the coming classes we will be learning how to manipulate image, video and sound. I’m really excited about this, I think it can add a lot more interesting effects to the interaction. It also is so relevant to the final project as well.
For our project, one of our ideas is to visualize the sound. Since originally, sound is a wave that comes from vibration. If it’s impossible for people with hearing problems to hear, it would be great for them to see the wave and feel the vibration, which are the two parts that builds the sound. By research we found that it’s possible to use processing to code wave or random shapes for different pitches, which I find really interesting.
Also, by searching for “processing image” on Google, I found that Processing currently works with GIF, JPEG, and PNG images. So it’s also possible to add actual pictures to the final result, which can also be very useful. I believe that using a GIF can have very funny effect.