Interacción Tangible | PEC02 – SIMON OPEN
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
El 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:
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;
}
}
}
Debatecontribution 0en Interacción Tangible | PEC02 – SIMON OPEN