JUSTIFICACIÓN

El presente documento se corresponde con la segunda Prueba de Evaluación Continua (PEC02) de la asignatura de Interacción Tangible del Grado en Técnicas de Interacción Digital y Multimedia de la UOC.

En esta prueba nos proponen crear un mini proyecto con Arduino en el que la acción de usuario actúe sobre, al menos, dos controles como iluminación, audio y/o imagen. Debemos trabajar el desarrollo del proyecto a través de las fases del design thinking (empatizar, definir, idear, prototipar, testear).

Se publica en Folio un extracto de la memoria, con la que podéis reproducir fácilmente el prototipo, junto con el video del funcionamiento.

HISTORIA

Imagen del Prototipo Simon OpenEl proyecto es un guiño al juego de SIMON SAY (Simón dice), ya que el funcionamiento de memorizar los colores o tonos es el mismo, aunque un poco más sencillo. La diferencia es que se trata de una única melodía con un número de notas predefinido. Cuando se logra reproducir correctamente podemos abrir la cerradura, por lo que he llamado al prototipo SIMON OPEN.

La cerradura bloquea una caja que contiene a Van Gogh pintando su autorretrato. El juego se trata de liberarlo reproduciendo la melodía aleatoria. ¡Si no eres capaz de memorizar un sencillo código sonoro-luminoso, no podrás salvarlo! ?.

 

DEFINICIÓN

El proyecto consiste en cuatro bombillas led de colores que se encienden al pulsar el botón correspondiente, cada uno de las cuales emite además un sonido característico.

El juego consiste en reproducir los sonidos/luces aleatorias que produce el Arduino en ese mismo orden, de manera que cuando se logra reproducir la melodía correcta (de 6 tonos en este caso, por hacerlo fácil), tenemos la posibilidad de abrir la cerradura de una caja tocando un sensor capacitivo.

PLANTEAMIENTO

Para resolver el problema planteado necesitaré generar números aleatorios (del 0 al 3) y almacenar la secuencia en un array de n posiciones. Comparando la secuencia pulsada por el usuario en los 4 pulsadores disponibles con la generada aleatoriamente podremos averiguar si es correcta y activar el sensor capacitivo para poder abrir la cerradura.

En el momento en que presionamos un botón equivocado, que difiere de la melodía generada, volvemos a empezar y se genera una nueva aleatoriamente.

Mapa conceptual

Enlace al video explicativo del funcionamiento

En el siguiente enlace está disponible una pequeña explicación del funcionamiento del prototipo, en el que se testea tanto el acierto como el fallo en la reproducción de la secuencia aleatoria:

PROTOTIPO

Para diseñar el prototipo he instalado la placa de interconexión y el Arduino sobre una antigua caja de diskettes, colocando la palanca del servomotor actuando como cerradura. Los componentes utilizados son los siguientes:

1x Arduino UNO
1x Piezoeléctrico
5x Resistencias 220 Ohms
2x Resistencias 10 kOhms
1x Resistencia 4,7 kOhms
4x Pulsadores
4x LED de color verde, amarillo, rojo y azul
1x Condensador de 0.1nF
1x Servomotor

Esquema y conexiones

He utilizado el pin analógico A0 del Arduino para recibir la tensión que llega de los pulsadores, que será diferente según se haya pulsado uno u otro botón debido al montaje en escalera de resistencias.

Los pines 2, 3, 4 y 5 los utilizo como salida digital para encender los LED, y el 8 servirá para enviar los datos al piezo.

El pin 9 lo utilizo en modo PWM para modificar el ángulo del brazo del servo.

El esquema del conexionado, implementado utilizando Fritzing:

Diseño esquemático

EL CÓDIGO

//Importamos las librerías para el servo y el sensor capacitivo y creamos las instancias

#include <Servo.h>

#include <CapacitiveSensor.h>

CapacitiveSensor capSensor = CapacitiveSensor (13,12);    //Defino los pines para activar el sensor

Servo myServo;

 

const int numNote = 6;      //Número de notas de la secuencia, que proporciona la dificultad al juego

int notes[] = {1915,1519,1275,956};   //array que guarda las 4 frecuencias

int sequence[numNote];   //array que guarda la secuencia inicial (random)

int userSequence[numNote];   //array que guarda la secuencia generada por el usuario

int position = 0; //posición en la que guardar la nota

 

boolean locked = true;  //Al inicio la puerta está bloqueada

int sensorValue;        //variable que almacena el valor del sensor capacitivo

 

void setup() {

Serial.begin(9600);   //iniciamos la comunicación en serie para poder utilizar el monitor serie

 

myServo.attach(9);     //Salida al servo

pinMode(2,OUTPUT);     //Salida a led verde

pinMode(3,OUTPUT);     //Salida a led amarillo

pinMode(4,OUTPUT);     //Salida a led rojo

pinMode(5,OUTPUT);     //Salida a led azul

 

//inicializamos los arrays

for (int i=0;i<numNote;i++){

userSequence[i] = 0;

sequence[i] = 0;

}

myServo.write(90);    //Colocamos el brazo del servo a 90 grados (bloqueo)

secuenciaInicio();    //Función que reproduce la secuencia de inicio del juego

 

}

 

void loop() {

//Leemos el sensor de contacto

sensorValue = capSensor.capacitiveSensor(30);

// Leemos el valor analógico y lo mostramos por el monitor del puerto serie

int keyVal = analogRead(A0);

Serial.println(keyVal);

Serial.print(sensorValue);

Serial.print(»    La secuencia es: «);

for (int i=0;i<position;i++) Serial.print(userSequence[i]);

//Dependiendo del valor que llegue tocamos una nota u otra, y encendemos el led correspondiente

if (keyVal == 1023){

tone(8, notes[3],500);

digitalWrite(5, HIGH);

delay(700);

grabarTono(3);

}

else if (keyVal >= 900 && keyVal <= 1022){

tone(8,notes[2],500);

digitalWrite(4, HIGH);

delay(700);

grabarTono(2);

}

else if (keyVal >= 650 && keyVal <= 710){

tone(8,notes[1],500);

digitalWrite(3, HIGH);

delay(700);

grabarTono(1);

}

else if (keyVal >= 500 && keyVal <= 550){

tone(8,notes[0],500);

digitalWrite(2, HIGH);

delay(700);

grabarTono(0);

}

else {            //Si no estamos pulsando mantenemos el silencio y los led apagados

noTone(8);

for (int i=2;i<6;i++) digitalWrite(i, LOW);

}

//Si tocamos la malla metálica y la caja no está bloqueada abrimos el brazo del servo y desbloqueamos la cerradura

if (sensorValue > 1000 & locked == false){

myServo.write(180);

}

}

 

/**************************************************************************************************************/

//FUNCIONES

//La secuencia de inicio reproduce la secuencia random muy rápidamente indicando que comienza el juego

void secuenciaInicio(){

for (int i=0;i<numNote;i++) sequence[i] = random(4); //generamos una secuencia aleatoria con números del 0 al 3 (Ej: {0,0,1,2,3,1,2,3,0,1})

for(int i=0;i<3;i++){

for (int j=0;j<numNote;j++){

tone(8,notes[sequence[j]],50);

digitalWrite(sequence[j]+2, HIGH);

delay(70);

noTone(8);

digitalWrite(sequence[j]+2, LOW);

delay(10);

}

}

delay(1000);

reproducirSecuencia();

}

//Función que reproduce la secuencia random pausadamente

//Aprovecho que los pines digitales coinciden con la posición de la frecuencia correspondiente +2

void reproducirSecuencia(){

for(int i=0;i<numNote;i++){

tone(8,notes[sequence[i]],500);

digitalWrite((sequence[i])+2, HIGH);

delay(700);

noTone(8);

digitalWrite((sequence[i])+2, LOW);

}

}

//En esta función se graba la secuencia pulsada en un array que se va comparando con la aleatoria

//La variable position

void grabarTono(int note){

userSequence[position] = note;

//Si el usuario se equivoca reiniciamos todo y bloqueamos

if (userSequence[position] != sequence[position]){

position = 0;

for (int i=2;i<6;i++) digitalWrite(i, LOW);

for (int i=0;i<numNote;i++){

userSequence[i] = 0;

sequence[i] = 0;

}

Serial.println(«FALLO»);

//close the door

myServo.write(90);

locked = true;

delay(500);

secuenciaInicio();

}

else{

position++;

//Si la variable position alcanza el valor definido activamos el sensor capacitivo para poder abrir la cerradura

if(position == numNote) {

for(int i=0;i<20;i++) {

Serial.println(«PRUEBA SUPERADA!!!»);

for (int j=2;j<6;j++) digitalWrite(j, HIGH);

delay(50);

for (int j=2;j<6;j++) digitalWrite(j, LOW);

delay(50);

}

//open the door

locked = false;

 

}

}

 

}