Projecte per realitzar una interface física i gràfica generant una proposta gràfica interactiva amb Processing.
La premisa principal és establir una relació conceptual, física i gràfica. Al voltant de la interacció.
Objectius
- Conceptualitzar els processos d'interacció.
- Desenvolupar una interface gràfica i física.
- Establir una connexió conceptual entre la interface i la interacció.
- Gestionar un projecte personal interactiu.
Continguts
- Fonaments de programació bàsica amb Processing.
- Fonaments de programació física amb Arduino.
- Disseny multimèdia.
Procés
- Conceptualitzar el procés d'interacció: Establint un discurs físic i gràfic. Relacionat amb una relació gràfica entre la interacció i la gràfica digital.
- Generar la gràfica que vindrà donada per el concepte a desenvolupar. Definint els elements dinàmics interactius. I la relació en quins paràmetres s'estableix.
- Definir la interface física: comunicant amb els gràfics digitals. Comunicar Arduino i Processing.
- Desenvolupar el prototip final.
Pràctiques
Procés per instalar la llibreria d'Arduino en Processing i que els dos programes es comuniquen Com instalar la llibreria d'Arduino en Processing
- Comunicar: Potenciòmetre (Arduino) a Processing
- Enviar missatge d'Arduino a Processing
- Arduino meets Processing
- Send multiple signals from Arduino to Processing
Trabajo en grupo: Modesto Valero, Alexis Fuentes, Joel Contreras, Cristina Mena.
Objetivos
- Creación de una interfaz que cree una metafora con un elemento físico y una programación digital.
Explicación
- Hemos creado una "pecera" que esta conectada a un sensor de proximidad, la metafora es que los peces de un acuario al acercarse mucho alguien huyen, se van, y esto lo hemos querido representar con una pecera en la pantalla, donde los peces estan a su libre albedrio, pero en el momento que el sensor detecta que se acerca algo huyen. El primer pez huye a las 15 pulgadas de cercania, el segundo a las 10 pulgadas de cercania y el tercero a las 5 pulgadas. Se van del centro de la pantalla y cuando se aleja, vuelven a su ritmo habitual.
- Hemos utilizado el programa procesing 2.1.1 de 32bits, ya que el de 64bits no funciona con el sensor de proximidad.
Proceso
- El primer paso fue limpiar la placa para prevenir posibles errores.:
* * EEPROM Clear * * Sets all of the bytes of the EEPROM to 0. * This example code is in the public domain. */ #include <EEPROM.h> void setup() { // write a 0 to all 512 bytes of the EEPROM for (int i = 0; i < 512; i++) EEPROM.write(i, 0); // turn the LED on when we're done digitalWrite(13, HIGH); } void loop() { }
- En segundo lugar programamos la placa para que recoja los datos del sensor de proximidad:
/* Ping))) Sensor This sketch reads a PING))) ultrasonic rangefinder and returns the distance to the closest object in range. To do this, it sends a pulse to the sensor to initiate a reading, then listens for a pulse to return. The length of the returning pulse is proportional to the distance of the object from the sensor. The circuit: * +V connection of the PING))) attached to +5V * GND connection of the PING))) attached to ground * SIG connection of the PING))) attached to digital pin 7 http://www.arduino.cc/en/Tutorial/Ping created 3 Nov 2008 by David A. Mellis modified 30 Aug 2011 by Tom Igoe This example code is in the public domain. */ // this constant won't change. It's the pin number // of the sensor's output: const int pingPin = 7; void setup() { // initialize serial communication: Serial.begin(9600); } void loop() { // establish variables for duration of the ping, // and the distance result in inches and centimeters: long duration, inches, cm; // The PING))) is triggered by a HIGH pulse of 2 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: pinMode(pingPin, OUTPUT); digitalWrite(pingPin, LOW); delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(5); digitalWrite(pingPin, LOW); // The same pin is used to read the signal from the PING))): a HIGH // pulse whose duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(pingPin, INPUT); duration = pulseIn(pingPin, HIGH); // convert the time into a distance inches = microsecondsToInches(duration); cm = microsecondsToCentimeters(duration); Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); delay(100); } long microsecondsToInches(long microseconds) { // According to Parallax's datasheet for the PING))), there are // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per // second). This gives the distance travelled by the ping, outbound // and return, so we divide by 2 to get the distance of the obstacle. // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf return microseconds / 74 / 2; } long microsecondsToCentimeters(long microseconds) { // The speed of sound is 340 m/s or 29 microseconds per centimeter. // The ping travels out and back, so to find the distance of the // object we take half of the distance travelled. return microseconds / 29 / 2; }
- Por último introducimos el cógigo en el procesing:
import processing.serial.*; Serial myPort; // The serial port: /* OpenProcessing Tweak of *@*http://www.openprocessing.org/sketch/28644*@* */ /* !do not delete the line above, required for linking your tweak if you upload again */ PImage ocean; PImage [] nemo; float x = 0; float x2 = 0; float x3 = 0; float x4 = 0; float x5 = 0; float x6 = 0; float y = 250; float y2 = 150; float y3 = 100; float y4 = 450; float y5 = 50; float y6 = 300; int frame = 0; int frame2 = 2; int frame3 = 3; int frame4 = 1; int frame5 = 4; int frame6 = 5; int W = 100; int H = 75; int A = 3; float B = 3.5; int C = 4; float D = 4.5; int E = 1; float F = 1.5; int counter=0; int cont=0; int distancia=0; int limite=1; String portname = "/dev/cu.usbserial-3B1"; // find the name of your serial port in your system setup! int baudrate = 9600; // set baudrate here int value; // variables used to store value from serial port String buf=""; // String buffer to store serial values int value1; // value1 is the read value void setup() { frameRate(30); size(640, 480); println(Serial.list()); nemo = new PImage[3]; for (int i = 0; i< nemo.length; i ++) { nemo[i] = loadImage("nemo" + (i+1) + ".png"); } ocean = loadImage("oceanfloor1.jpg"); myPort = new Serial(this, Serial.list()[0], 9600); // myPort = new Serial(this, portname,baudrate); myPort.bufferUntil('\n'); } void draw() { while(myPort.available() > 0){ //value =myPort.read(); // println(value); serialEvent(myPort); } limite=distancia; println(limite); cont++; if (frame > 2) frame = 0; //fish 1 if (frame2 >2) frame2 = 0; //fish 2 if (frame3 > 2) frame3 = 0; // fish 3 if (frame4 >2) frame4 = 0; //fish 4 if (frame5 >2) frame5 = 0; //fish 5 if (frame6 >2) frame6 = 0; //fish 6 image(ocean, 0, 0, 800, 600); ////////////////////////////////////////////////////////////// pushMatrix();//fish 1 if (distancia<=10) { // A *= -1; //B *= -1; translate(0, 0); //translate(x, y); } else { translate(x+100, y+100); } image(nemo[frame], -50, -37.5, W, H); popMatrix(); x += A; y += B; if (counter%15==0) { frame++; } if (x>500 || x<=0) { A *= -1; } if (y>480 || y<=0) { B *= -1; } ///////////////////////////////////////////////////////// pushMatrix();//fish 2 if (distancia<=5) { // C *= -1; // D *= -1; translate(640, 0); //translate(x, y); } else { translate(x2, y2); } image(nemo[frame2], -30, -37, 100, 75); popMatrix(); x2 += C; y2 += D; if (counter%5==0) { frame2++; } if (x2>640 || x2<=0) { C *= -1; } if (y2>480 || y2<=0) { D *= -1; } /////////////////////////////////////////////////////// pushMatrix();//fish 3 if (distancia<=15) { //E *= -1; //F *= -1; translate(0, 480); //translate(x, y); } else { translate(x3, y3); } image(nemo[frame3], -30, -37, 100, 75); popMatrix(); x3 += E; y3 += F; if (counter%10==0) { frame3++; } if (x2>640 || x2<=0) { E *= -1; } if (y3>480 || y3<=0) { F *= -1; } counter++; } void keyPressed() { if (key == '1') { ocean = loadImage("oceanfloor1.jpg"); } if (key == '2') { ocean = loadImage("oceanfloor2.jpg"); } if (key == '3') { ocean = loadImage("oceanfloor3.jpg"); } if (key == 'b') { H++; W++; } } void serialEvent(Serial myPort) { String myString = myPort.readStringUntil('\n'); if (myString != null) { print("Serialized data: "); println(myString); int[] nums = int(split(myString, 'i' )); distancia=nums[0]; println("distancia:",distancia); // limpio el buffer para que no se sature myPort.clear(); } /*if(serial!=10) { buf += char(serial); } else { //extract the value from the string 'buf' buf = buf.substring(1,buf.length()); //cast the value to an integer value1 = int(buf); buf=""; println(value1); }*/ // distancia = int( map(tempDiameter, 0, 1023, 30, 250) ); }
Imagenes y video:
- Imagenes:
1. http://imageshack.com/a/img842/3240/z85i.jpg
2. http://imageshack.com/a/img571/9391/m9bt.jpg
3. http://imageshack.com/a/img829/6261/rbr0.jpg
4. http://imageshack.com/a/img40/3033/src.JPG
- Videos:
Trabajo Ping Pong Invader
Integrantes del grupo: Miriam Berbegal, Sonia Conde, Laura Sanchez, Paloma Valero y Pablo Albero.
Objetivos
- Como objetivos principales se nos encomienda realizar un diseño con el que interactuar físicamente. Para ello hemos empleado dos programas, el Processing, para el diseño y el Arduino, para que éste diseño interactue con el espectador mediante un sensor (potenciometro) que permite el movimiento.
Explicación
- Para este proyecto interactivo, hemos querido hacer un pequeño guiño al popular juego Pong de los '70, pero usando solo una pala o raqueta, y modificando el diseño incorporando otro guiño aun juego también muy famoso (Space Invaders).
- Queríamos crear una interacción divertida, y que a pesar de ser sencilla, pudieras pasarte unos minutos con ella. Un juego era la mejor opción para nosotros.
- Al igual que los otros compañeros de clase, hemos tenido que usar la versión 2.1 de 32 bits de Processing, ya que se producia un error a la hora de trabajar con el potenciometro. Para poder hacer uso del potenciometro, enviamos unos valores a la placa Arduino, puerto de la conexión, velocidad de transmision, etc:
int potPin=0; void setup(){
Serial.begin(19200); }
void loop(){
int val=analogRead(potPin); val=val/4; Serial.write(val); delay(75);
}
- Y al igual que añadimos en Arduino, en Processing también añadimos unos comandos para poder lograr esa interacción y junto al resto de codigo, es el siguiente:
import processing.serial.*;
String portname = "COM9"; Serial port;
//invader float invader_x; float invader_y; float invader_dir = 1; float invader_size = 5; // Radio float dy = 0; // Dirección
// Raqueta int paddle_width = 5; int paddle_height = 30; int paddle_pos; // nueva posición int paddle_ppos; // última posición int dist_wall = 15;
PImage invader1,raqueta,Espacio;
void setup() {
size(280 , 280); rectMode(CENTER); ellipseMode(CENTER); noStroke(); smooth(); invader_y = height/2; invader_x = 1; invader1= loadImage("invader2.png"); raqueta=loadImage("raqueta.png"); Espacio= loadImage("Espacio.jpg"); port = new Serial(this, portname, 19200);
}
void draw() {
background(Espacio); imageMode(CENTER); image(invader1,invader_x, invader_y); invader_x += invader_dir * 2.0; invader_y += dy; if(invader_x > width+invader_size) { invader_x = -width/2 - invader_size; invader_y = random(0, height); dy = 0; } if (port.available() > 0) { paddle_ppos = paddle_pos; // guarda la ultima posición paddle_pos = port.read(); // lee y almacena la nueva posición } // Desplazamiento de la raqueta float paddle_y = constrain(paddle_pos, paddle_height, height-paddle_height); // Reacción pelota con la raqueta float py = width-dist_wall-paddle_width-invader_size; if(invader_x == py && invader_y > paddle_y - paddle_height - invader_size && invader_y < paddle_y + paddle_height + invader_size) { invader_dir *= -1; if(paddle_pos != paddle_ppos) { dy = (paddle_pos - paddle_ppos)/2.0; if(dy > 5) { dy = 5; } if(dy < -5) { dy = -5; } } } // Cambio de la dirección invader if(invader_x < invader_size && invader_dir == -1) { invader_dir *= -1; } // Superior o inferior del borde if(invader_y > height-invader_size) { dy = dy * -1; } if(invader_y < invader_size) { dy = dy * -1; } // Pelota del invader noFill(); ellipse(invader_x, invader_y, 8, 8); // Raqueta noFill(); image(raqueta,260, paddle_y); rect(width-dist_wall, paddle_y, paddle_width, paddle_height);
}
Imagen y video:
- Imagen:
1. https://www.dropbox.com/s/o0dx2z0vme0th3f/IMG_20140202_112421.jpg?m=
- Video final de la interaccíon:
1. https://www.facebook.com/photo.php?v=737871326232466
Trabajo en grupo: Jose Antonio Gabaldón, Jose Antonio Sanchez y Pilar Cuadrado.
Objetivos
- Creación de una interfaz que cree una metafora con un elemento físico y una programación digital.
Explicación
- Pensamos en crear una ironía jugando con la pantalla y el espectador. El concepto es que la palabra tímida que aparece en la pantalla cuando te alejas aparece en gran tamaño y cuando te aproximas a la pantalla disminuye viéndose solo una pequeña mancha.
- Hemos utilizado el programa procesing 2.1.1 de 32bits, ya que el de 64bits no funciona con el sensor de proximidad.
Proceso
- El primer paso fue crear el código de la palabra en processing:
PFont fuente; String message="tímida"; float x=0; int sensor;
void setup() {
size(950, 700); fuente=loadFont("Elephant-Italic-48.vlw"); int num=message.length(); //text(message,width/2,height/2); println(num);
} void draw() {
background(100); fill(255); sensor=mouseX; float m= map(sensor,0,width,5,90); textFont(fuente, m); textAlign(CENTER, CENTER); text(message, width/2, height/2);
}
- En segundo lugar programamos la placa para que recoja los datos del sensor de proximidad:
[@ /* Ping))) Sensor
This sketch reads a PING))) ultrasonic rangefinder and returns the distance to the closest object in range. To do this, it sends a pulse to the sensor to initiate a reading, then listens for a pulse to return. The length of the returning pulse is proportional to the distance of the object from the sensor. The circuit: * +V connection of the PING))) attached to +5V * GND connection of the PING))) attached to ground * SIG connection of the PING))) attached to digital pin 7 http://www.arduino.cc/en/Tutorial/Ping created 3 Nov 2008 by David A. Mellis modified 30 Aug 2011 by Tom Igoe This example code is in the public domain. */
// this constant won't change. It's the pin number // of the sensor's output: const int pingPin = 7;
void setup() {
// initialize serial communication: Serial.begin(9600);
}
void loop() {
// establish variables for duration of the ping, // and the distance result in inches and centimeters: long duration, inches, cm; // The PING))) is triggered by a HIGH pulse of 2 or more microseconds. // Give a short LOW pulse beforehand to ensure a clean HIGH pulse: pinMode(pingPin, OUTPUT); digitalWrite(pingPin, LOW); delayMicroseconds(2); digitalWrite(pingPin, HIGH); delayMicroseconds(5); digitalWrite(pingPin, LOW); // The same pin is used to read the signal from the PING))): a HIGH // pulse whose duration is the time (in microseconds) from the sending // of the ping to the reception of its echo off of an object. pinMode(pingPin, INPUT); duration = pulseIn(pingPin, HIGH); // convert the time into a distance inches = microsecondsToInches(duration); cm = microsecondsToCentimeters(duration); Serial.print(inches); Serial.print("in, "); Serial.print(cm); Serial.print("cm"); Serial.println(); delay(100);
}
long microsecondsToInches(long microseconds) {
// According to Parallax's datasheet for the PING))), there are // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per // second). This gives the distance travelled by the ping, outbound // and return, so we divide by 2 to get the distance of the obstacle. // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf return microseconds / 74 / 2;
}
long microsecondsToCentimeters(long microseconds) {
// The speed of sound is 340 m/s or 29 microseconds per centimeter. // The ping travels out and back, so to find the distance of the // object we take half of the distance travelled. return microseconds / 29 / 2;
}
- Por último creamos la unión entre procesing y arduino y ajustamos los parámetros del sensor.
import processing.serial.*; Serial myPort; int distancia; PFont fuente; String message="Tímida"; float x=0; int sensor; int dato;
void setup() {
size(950, 700); fuente=loadFont("Elephant-Italic-48.vlw"); myPort = new Serial(this, Serial. list()[0], 9600); myPort.bufferUntil('\n'); int num=message.length(); //text(message,width/2,height/2); println(num);
} void draw() {
dato= distancia; while (myPort.available()>0){ serialEvent(myPort); } background(#f79797); fill(255); sensor=distancia; float m= map(dato, 0, width/20, 5, 90); textFont(fuente, m); textAlign(CENTER, CENTER); text(message, width/2, height/2);
}
void serialEvent(Serial myPort) {
String myString = myPort.readStringUntil('\n'); if (myString != null) { int[]nums = int (split(myString, 'i')); distancia=nums[0]; }
}
Imagen y video:
- Imagen: http://www.flickr.com/photos/115875465@N06/sets/
- Video final de la interaccíon:http://www.youtube.com/watch?v=O-kzzqLMRx0&feature=youtu.be