Recitation 10 Documentation– Blog 13
Part 1: From Arduino to Processing
Video:
For this exercise, I am trying to use buttons to control whether an image should go up or go down. I think the most difficult thing is that the button cannot change the electricity of the circuit accurately. The figure shown on the screen is jumping between 0 and 1 and it cannot be a stable number. So the picture will move by itself sometimes. Since I am going to use this circuit in my final project, I am going to find a more accurate and more sensitive sensor that can also create this “TRUE” or “FALSE” effect.
Code for Arduino:
// IMA NYU Shanghai // Interaction Lab // For sending multiple values from Arduino to Processing void setup() { Serial.begin(9600); } void loop() { int sensor1 = digitalRead(4); int sensor2 = digitalRead(8); // keep this format Serial.print(sensor1); Serial.print(","); // put comma between sensor values Serial.print(sensor2); 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); }
Code for processing:
//PImage photo; //void setup() { // size(550, 880); // photo = loadImage("sad guy.jpeg"); //} //void draw() { // image(photo, 0, 0, 550, 880); //} import processing.serial.*; PImage photo; 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 **/ float sensorvalue1=0; float sensorvalue2=0; float photoX=width/2; float photoY=0; float spd = 5; void setup() { size(600, 1200); background(0); setupSerial(); photo = loadImage("sad guy.jpeg"); } void draw() { updateSerial(); printArray(sensorValues); background(0); if (sensorvalue1 == 1) { photoY -= 10; } if (sensorvalue2 == 1) { photoY += 10 ; } image(photo, photoX, photoY, 200, 440); sensorvalue1= sensorValues[0]; sensorvalue2= sensorValues[1]; } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[3], 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]); } } } } }
Part 2: From Processing to Arduino
video:
For this exercise, I think the most difficult part is how to transfer the volume of my microphone to figures that can be sent to Arduino. Also, at first, I don’t know how to let the servo spin around according to the volume of the sound played by my microphone. However, by trying different ways such as for loop and if functions, I finally find out that the most simple code can achieve my goal.
Code for Arduino:
// 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. **/ #define NUM_OF_VALUES 1 #define NUM_OF_VALUES_FROM_PROCESSING 1 /** YOU MUST CHANGE THIS ACCORDING TO YOUR PROJECT **/ #include <Servo.h> Servo myservo; /** DO NOT REMOVE THESE **/ int tempValue = 0; int valueIndex = 0; //int pos = 0; int values[NUM_OF_VALUES]; /* This is the array of values storing the data from Processing. */ int processing_values[NUM_OF_VALUES_FROM_PROCESSING]; void setup() { Serial.begin(9600); //pinMode(9, OUTPUT); myservo.attach(9); } void loop() { getSerialData(); myservo.write(processing_values[0]); delay(2); } //receive serial data from Processing void getSerialData() { while (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 ',': processing_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 processing_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; } } }
Code for Processing:
// 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. **/ import processing.serial.*; import processing.sound.*; AudioIn microphone; Amplitude analysis; //FFT freqAnalysis; //int frequencies = 256; 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 **/ //float[] spectrum = new float[frequencies]; Serial myPort; String myString; void setup() { size(500, 500); background(0); microphone = new AudioIn(this, 0); microphone.start(); analysis = new Amplitude(this); analysis.input(microphone); // freqAnalysis = new FFT(this, frequencies); // freqAnalysis.input(microphone); setupSerial(); } void draw() { // freqAnalysis.analyze(spectrum); background(0); float volume = analysis.analyze(); println(analysis.analyze()); processing_values[0] = round(map(volume, 0, 1, 0, 360)); // send the values to Arduino. sendSerialData(); } 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; } 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 } //if it is the last element in the values array 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 }
Questions for readings:
Through reading the article “Computer Vision for Artist and Designers“, I found that the way I used to create serial communication between Arduino, which can create physical movement, and Processing, which can make the interaction more visible and easier to recognize. In the article, author emphasizes that by using computers, interactive projects can easily capture people’s figures and then react to it. There are many examples that can represent this concept. Interactive designers are willing to capture people’s movements and use projection to show how people’s movement will lead to certain interesting results. This concept is a great example of connecting Arduino and Porcessing. In the exercise that I did this week, I first create two buttons that can control whether an image should go up or go down. This is a very simple expression of explaining how people’s body movements or motion are reflected on the screen. As for the second exercise, the concept is definitely the same. But this time, I used Processing to record people’s motion and use Arduino to control servos that can create a physical vision of the interaction. Also, in the article the author talk about the technology that can detect people’s movements through vision. In my two exercise projects, however, I didn’t use images and camera to record the motion. But I am still impressed by the “frame differencing”, “background subtraction” and “brightness thresholding” that are used in detecting movements.