Etch A Sketch
For this, I started off adding two potentiometers to my breadboard, which connected to my Arduino to change the ellipses x and y values. On the computer, the Arduino’s code would connect to Processing to draw the ellipses there.
The circuit looked like this:
The code for the Arduino was:
void setup() { Serial.begin(9600); } void loop() { int sensor1 = analogRead(A0); int sensor2 = analogRead(A1); sensor1 = map(sensor1, 0 ,1023, 0, 500); sensor2 = map(sensor2, 0, 1023, 0, 500); // 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); }
And the code for Processing (first part because the second part is all the same in example):
import processing.serial.*; String myString = null; Serial myPort; int NUM_OF_VALUES = 2; int[] sensorValues; void setup() { size(500, 500); background(0); rectMode(CENTER); setupSerial(); } void draw() { updateSerial(); printArray(sensorValues); // use the values like this! // sensorValues[0] // add your code fill(255,255,255); ellipse(width/2,height/2,sensorValues [0], sensorValues [1]); // }
Here is a video of the it working on Processing:
After completing this, I went to create an Etch A Sketch by changing the ellipse code on Processing to:
// 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 **/ float prevX; float prevY; void setup() { size(500, 500); background(0); setupSerial(); } void draw() { updateSerial(); printArray(sensorValues); // use the values like this! // sensorValues[0] // add your code float posX = sensorValues[0]; float posY = sensorValues[1]; stroke(255); line(prevX, prevY, posX, posY); prevX = posX; prevY = posY; } void setupSerial() { printArray(Serial.list()); myPort = new Serial(this, Serial.list()[ 4 ], 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]); } } } } }
Here is a video of it:
Musical Instrument
For this code, the multiple values Processing to Arduino example was used and then modified, since in the example it said to send Serial Values from Processing to Arduino.
I tried to create a musical instrument that would create a different sound when the mouse was pressed, and when it was at a different spot in terms of width and length.
The circuit looked like this:
The code for Arduino was:
#define NUM_OF_VALUES 2 int tempValue = 0; int valueIndex = 0; int values[NUM_OF_VALUES]; void setup() { Serial.begin(9600); pinMode(7, OUTPUT); } void loop() { getSerialData(); tone(7, values[1], values[0]); // add your code here // use elements in the values array // values[0] // values[1] } //recieve 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; } } }
The code for Processing was:
import processing.serial.*; int NUM_OF_VALUES = 2; 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()[ 4 ], 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); if(mousePressed) { 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 ); }
My Arduino had issues connecting to the computer so I borrowed an Arduino yesterday and it did not work. It could upload, but any code I tried got stuck at “Uploading…”. I am pretty sure it is not my computer’s problem.
Edit 2019-11-22 14:02:38: Tristan is looking at that borrowed Arduino that had issues, I borrowed another one and it is working. Uploading video for Musical Instrument and changing code for all examples to look better.