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
