NOT SLEEPING HAT

DESCRIPCIÓN

En esta aplicación se muestra el uso de la tarjeta LilyPad de Arduino para la creación de un dispositivo estilo wearable computing, específicamente, la construcción de una gorra que permite mantener despierto a un usuario. El tutorial describe como se usa la tarjeta LilyPad y el manejo de algunos dispositivos (acelerómetro, salida serial a través del USB, led, buzzer, parlante) conectados a ella.

OBJETIVOS

  • Modificar una gorra comercial agregándole una tarjeta Lilypad y algunos dispositivos para crear una gorra que mantenga despierto a quien la use
  • Crear un programa en el entorno de Arduino que permita leer y procesar los datos del acelerómetro de 3 ejes (x,y,z) para obtener la orientación del sensor, con esta información tomar decisiones que permitan generar acciones para mantener despierto al usuario de la gorra.

COMPONENTES NECESARIOS

  • Software Arduino 10.0 o superior
  • Acelerómetro de 3 ejes (en este tutorial se usó: ADXL 335)
  • Tarjeta Lilypad de Arduino
  • Hilo conductor
  • Led
  • Buzzer
  • Speaker
  • Gorra

DESARROLLO

Un buen lugar para comenzar a explorar el uso de la tarjeta LilyPad de Arduino, es el sitio de Leah Buechley: http://web.media.mit.edu/~leah/LilyPad/index.html. Este sitio provee información útil como: forma de conectar la tarjeta al computador, instrucciones de seguridad para uso de la tarjeta en la creación de prototipos, uso de leds, speakers y sensores. Si buscas un lugar para comprar los dispositivos de LilyPad usados en este tutorial, la siguiente página puede ser de utilidad: http://www.sparkfun.com/categories/135

Instalación del entorno de desarrollo (Windows 7)

Antes de comenzar con este tutorial, es necesario tener el entorno de desarrollo de Arduino instalado, para ello se debe bajar el software desde: http://arduino.cc/en/Main/Software . LilyPad solo funciona en la versión 10.0 o una versión superior. Después de descargado el instalador, se debe descomprimirlo en alguna carpeta del sistema. En aquella carpeta se debe ejecutar el archivo arduino.exe que muestra el entorno de programación el cual debe lucir similar al mostrado a continuación:

Al conectar por primera vez la tarjeta LilyPad al computador, se debe esperar a que el sistema realice la instalación del dispositivo (Windows 7). El sitio de Leah Buechley, contiene instrucciones de instalación para Windows XP y Mac OS X.

Antes de empezar a programar, es necesario seleccionar la board adecuada en el entorno de desarrollo, eso se hace como se muestra en la siguiente gráfica:

Al momento de escribir este tutorial, existen dos tipos de tarjeta LilyPad, para asegurarte de seleccionar la versión adecuada puedes mirar el chip principal de tu tarjeta y de acuerdo con ello seleccionar la versión adecuada en la interfaz (ATmega328 o ATmega168).

Construcción del demo

Si se piensa construir la aplicación como prototipo usando caimanes, es buena idea construir un elemento de protección para evitar que los caimanes se resbalen, para ello puedes seguir las instrucciones de: http://web.media.mit.edu/~leah/LilyPad/coaster.html

La distribución de los puertos de la tarjeta para esta aplicación se muestra a continuación:

Las siguientes gráficas indican donde se debe conectar los conectores de los dispositivos:

Si se desea construir el demo sobre una gorra, este es el momento en el cual se deben coser los dispositivos como se indica en las imágenes anteriores, si se desea hacer un prototipo las uniones se pueden realizar mediante la utilización de caimanes para las conexiones.

Código de la aplicación

Configuración de los pines: Se deben definir algunas variables que se van a utilizar para poder configurar los pines. En el método setup(), se debe inicializar los puertos de LilyPad que se van a utilizar en el proyecto. En este caso inicializamos los puertos para el led externo, el led interno, el speaker y los buzzer.

// DEFINICION DE PINES
const int xPin = 2; //acelerometro en X
const int yPin = 3; //acelerometro en Y
const int zPin = 5; //acelerometro en Z
const int ledPin = 13; //pin del led (board)
const int ledPinExt = 6; //pin del led externo
const int speakerPin = 9; //pin del speaker
const int buzzerPin = 10; //pin del buzzer
const int buzzerPin1 = 11; //pin del buzzer

//Configuración de la board
void setup(){
  pinMode(ledPin, OUTPUT); //configurar el pin para el led como salida
  pinMode(ledPinExt, OUTPUT); //configurar el pin para el led como salida
  pinMode(speakerPin, OUTPUT); //configurar el pin para el speaker como salida
  pinMode(buzzerPin, OUTPUT); //configurar el pin para el buzzer como salida
  pinMode(buzzerPin1, OUTPUT); //configurar el pin para el buzzer como salida
  Serial.begin(9600); //configurar la salida del puerto serial a 9600bps
}

Generación de sonidos y vibración: El LilyPad speaker funciona de la misma manera que cualquier parlante, cuando se le da un voltaje alto el speaker se ubica en una posición, y cuando se le da un voltaje bajo en una posición diferente. Para producir sonido, es necesario crear vibraciones en el aire a frecuencias determinadas. La función desarrollada permite generar sonido a través del speakerPin, a la frecuencia dada (frecuencyInHertz), durante el tiempo determinado (timeInMilliseconds).

void beep (unsigned char speakerPin, int frequencyInHertz, long timeInMilliseconds) {
  int x1;
  long delayAmount = (long)(1000000/frequencyInHertz);
  long loopTime = (long)((timeInMilliseconds*1000)/(delayAmount*2));
  for (x1=0;x1<loopTime;x1++){
      digitalWrite(speakerPin,HIGH);
      digitalWrite(buzzerPin,HIGH);
      delayMicroseconds(delayAmount);
      digitalWrite(speakerPin,LOW);
      digitalWrite(buzzerPin,LOW);
      delayMicroseconds(delayAmount);
  }
}

Lectura del acelerómetro: El acelerómetro provee una medida análoga a través de sus pines que representa la fuerza a la que esta sometida el objeto. Para información más detallada sobre acelerómetros y gyros consulte http://arduino.cc/forum/index.php/topic,58048.0.html, http://bildr.org/2011/04/sensing-orientation-with-the-adxl335-arduino/.

Para reducir el ruido de las lecturas obtenidas del acelerómetro, se utiliza un filtro pasabajo mediante una media móvil de longitud 50.

//FILTRO LECTURAS
const int filterSize = 50;
int xFilter[filterSize];
int yFilter[filterSize];
int zFilter[filterSize];
boolean filterInitialized = false;

//LECTURAS DEL ACELEROMETRO
void leerAcelerometro() {
  int xRead = analogRead(xPin);
  int yRead = analogRead(yPin);
  int zRead = analogRead(zPin);  
  if(filterInitialized == false) {
    for(int i = 0; i < filterSize; i++) {
      xFilter[i] = xRead;
      yFilter[i] = yRead;
      zFilter[i] = zRead;
    }
  }else{
    int xtmp;
    int ytmp;
    int ztmp;
    for(int i = 0; i < filterSize; i++) {
      int tmp1;
      if(i==0) {
        //xread....
        xtmp = xFilter[0];
        xFilter[0] = xRead;
        //yread....
        ytmp = yFilter[0];
        yFilter[0] = yRead;
        //zread...
        ztmp = zFilter[0];
        zFilter[0] = zRead;
      }else{
        //xread...
        tmp1 = xFilter[i];
        xFilter[i]=xtmp;
        xtmp = tmp1;
        //yread...
        tmp1 = yFilter[i];
        yFilter[i]=ytmp;
        ytmp = tmp1;
        //zread...
        tmp1 = zFilter[i];
        zFilter[i]=ztmp;
        ztmp = tmp1;
      }
    }
  }
}

int leerX() {
  int suma = 0;
  for(int i = 0; i < filterSize; i++) {
    suma += xFilter[i];
  }
  return suma / filterSize;
}

int leerY() {
  int suma = 0;
  for(int i = 0; i < filterSize; i++) {
    suma += yFilter[i];
  }
  return suma / filterSize;
}

int leerZ() {
  int suma = 0;
  for(int i = 0; i < filterSize; i++) {
    suma += zFilter[i];
  }
  return suma / filterSize;
}

El código cíclico a ejecutar en el microcontrolador: El código que se ejecuta constantemente en la aplicación permite realizar las siguientes acciones:

//Ciclo que se ejecuta constantemente
void loop(){
  //leer los valores analogos de los sensores
  leerAcelerometro();  
  int xRead = leerX();
  int yRead = leerY();
  int zRead = leerZ();
  //Convertir los valores para que puedan ser calculados en el atan2
  int xAng = map(xRead, minVal, maxVal, -90, 90);
  int yAng = map(yRead, minVal, maxVal, -90, 90);
  int zAng = map(zRead, minVal, maxVal, -90, 90);
  //Calcula la orientación a 360°
  x = RAD_TO_DEG * (atan2(-yAng, -zAng) + PI);
  y = RAD_TO_DEG * (atan2(-xAng, -zAng) + PI);
  z = RAD_TO_DEG * (atan2(-yAng, -xAng) + PI);
  //Enviar la orientación por puerto serial
  Serial.print("Ang;");
  Serial.print(x);
  Serial.print(";");
  Serial.print(y);
  Serial.print(";");
  Serial.println(z);
  //Evaluar la orientación de la cabeza para ver si está despistado....
  if( (x>340 || x < 20) && (y>340 || y < 20) ) { 
    digitalWrite(ledPin, LOW); //apagar el pin
    digitalWrite(ledPinExt, LOW); //apagar el pin
    contSleep = 0;
  } else {
    if(contSleep > limLed) {
      digitalWrite(ledPin, HIGH); //encender el pin
      digitalWrite(ledPinExt, HIGH); //encender el pin
    }    
    if(contSleep > limSleep) { // si lleva más de determinado tiempo reproducir sonido...
      beep(speakerPin,3520,100); //Do durante 100ms 
    } else {
      contSleep ++;
    }
  }
}

VIDEO DE DEMOSTRACIÓN

En el siguiente link se encuentra el vídeo demostrativo de la aplicación:

http://www.youtube.com/watch?v=j3RxAxeGoEA&feature=youtu.be

El código completo de la aplicación de Arduino y la interfaz hecha en Unity se pueden descargar aquí: proyecto.zip

not_sleeping_hat.txt · Última modificación: 2012/05/06 22:27 por jj.martinez60
Departamento de Ingeniería de Sistemas y Computación - Facultad de Ingeniería - Universidad de los Andes
CC Attribution-Noncommercial-Share Alike 3.0 Unported
Valid CSS Driven by DokuWiki Recent changes RSS feed Valid XHTML 1.0