viernes, 30 de diciembre de 2011

Detector de mentiras conArduinoNunchuk y servo

Este proyecto sirve para probar el manejo del Nunchuk de la Wii. Según se gire en el aire el Nunchukse le envía al servo la orden de giro.

La chorradita del cartel de Mentira y Verdad ha sido para divertir a mi hija pequeña y a una amiga suya.

Estuve sopesando algunas librerías para manejar el Nunchuk y al final me he decantado por http://www.gabrielbianconi.com/projects/arduinonunchuk/

Como adaptador para conectar el nunchuk a Arduino he usado el WiiChuck http://todbot.com/blog/2008/02/18/wiichuck-wii-nunchuck-adapter-available/



Código fuente:

/*
 * Detector de mentiras conArduinoNunchuk y servo
 *
 * Copyleft 2011 Antonio Garcia Figueras
 *
 * Usando libreria de Gabriel Bianconi, http://www.gabrielbianconi.com/
 *
 * Project URL: http://www.gabrielbianconi.com/projects/arduinonunchuk/
 *
 */

#include <Wire.h>
#include "ArduinoNunchuk.h"
#include <Servo.h>

#define BAUDRATE 19200

ArduinoNunchuk nunchuk = ArduinoNunchuk();

Servo myservo;

 int minX;
 int maxX;
 int minY;
 int maxY;
 int minZ;
 int maxZ;
 int contador;
 float razonX;
 int posXServo;

void setup() {
  Serial.begin(BAUDRATE);
  myservo.attach(9);  // attaches the servo on pin 9 to the servo object
  myservo.write(90);  // lo colocamos centrado
  Serial.println("Inicio incializacion");
  nunchuk.init();
  Serial.println("Final incializacion");
  calibraAccel();
 
//Calculo de la razon para calcular el valor del servo (0-180)
//en funcion del movimiento del nunchucku
  razonX = (float)180/(maxX - minX);
  Serial.print("Razon:");
  Serial.println(razonX, DEC);
}

void loop() {
     nunchuk.update();
   
     // Al multiplicar la posicion del nunckuk por la razon
     // lo convertimos a valores entre cero y 180 para el servo
     posXServo = (int)(nunchuk.accelX - (maxX - minX)) * razonX;
     Serial.print("accelX:");
     Serial.println(nunchuk.accelX, DEC);
   
     Serial.print("posXServo:");
     Serial.println(posXServo, DEC);
     if (posXServo > 180) posXServo=180; //por si por los decimales da un valor superior
     if (posXServo < 0) posXServo=0;
   
     myservo.write(posXServo);
   
     delay(10); //Para dar tiempo a que se coloque el servo
 
 
 
//  nunchuk.update();
//
//  Serial.print(nunchuk.analogX, DEC);
//  Serial.print(' ');
//  Serial.print(nunchuk.analogY, DEC);
//  Serial.print(' ');
//  Serial.print(nunchuk.accelX, DEC);
//  Serial.print(' ');
//  Serial.print(nunchuk.accelY, DEC);
//  Serial.print(' ');
//  Serial.print(nunchuk.accelZ, DEC);
//  Serial.print(' ');
//  Serial.print(nunchuk.zButton, DEC);
//  Serial.print(' ');
//  Serial.println(nunchuk.cButton, DEC);
}


// Calibra todos los acelerometros para saber sus
// valores minimos y maximos
void calibraAccel()  {
 nunchuk.update();
 minX = nunchuk.accelX;
 maxX = nunchuk.accelX;
 minY = nunchuk.accelY;
 maxY = nunchuk.accelY;
 minZ = nunchuk.accelZ;
 maxZ = nunchuk.accelZ;
 contador=0;

 Serial.println("Inicio calibracion");

 while (contador<=200){
     Serial.print("Paso=");
     Serial.println(contador);
     nunchuk.update();
     if (nunchuk.accelX < minX){
       minX=nunchuk.accelX;
     }
     if (nunchuk.accelX > maxX){
       maxX=nunchuk.accelX;
     }
   
     if (nunchuk.accelY < minY){
       minY=nunchuk.accelY;
     }
     if (nunchuk.accelY > maxY){
       maxY=nunchuk.accelY;
     }

     if (nunchuk.accelZ < minZ){
       minX=nunchuk.accelZ;
     }
     if (nunchuk.accelZ > maxZ){
       maxZ=nunchuk.accelZ;
     }   
     delay(10);
     contador++;
 }
 Serial.print("Resultado calibracion X. MinX=");
 Serial.print(minX, DEC);
 Serial.print(" MaxX=");
 Serial.print(maxX, DEC);
 Serial.print(" Diferencia=");
 Serial.println(maxX - minX);

 Serial.print("Resultado calibracion Y. MinY=");
 Serial.print(minY, DEC);
 Serial.print(" MaxY=");
 Serial.print(maxY, DEC);
 Serial.print(" Diferencia=");
 Serial.println(maxY - minY);

 Serial.print("Resultado calibracion Z. MinZ=");
 Serial.print(minZ, DEC);
 Serial.print(" MaxZ=");
 Serial.print(maxZ, DEC);
 Serial.print(" Diferencia=");
 Serial.println(maxZ - minZ);
}

lunes, 19 de diciembre de 2011

Felicitador navideño

Mediante un relé conecto Arduino a una tarjeta de felicitación navideña de las que empiezan a sonar con musiquita navideña y encienden un led.
Uso la cámara de vídeo como sensor de movimiento (no tomo ni grabo la foto) y entonces cierra el relé durante 30 segundos con lo que empieza a sonar el circuito de la tarjeta de felicitación. Pasado ese tiempo lo inactivo durante 5 minutos para que no esté sonando continuamente.


Vídeo primera parte:




Vídeo segunda parte:



Código fuente FelicitadorNavidadV1:

// Mediante un relé conecto Arduino a una tarjeta de felicitación navideña de las que empiezan a sonar
// con musiquita navideña y encienden un led.
// Uso la cámara de vídeo como sensor de movimiento (no tomo ni grabo la foto) y entonces cierra el relé durante 30 segundos con
// lo que empieza a sonar el circuito de la tarjeta de felicitación. Pasado ese tiempo lo inactivo durante
// 5 minutos para que no esté sonando continuamente.

#include <VC0706.h>
#include <SD.h>
#if ARDUINO >= 100
 #include <SoftwareSerial.h>
#else
 #include <NewSoftSerial.h>
#endif

// This is the SD card chip select line, 10 is common
#define chipSelect 10
// This is the camera pin connection. Connect the camera TX
// to pin 2, camera RX to pin 3
#if ARDUINO >= 100
SoftwareSerial cameraconnection = SoftwareSerial(2, 3);
#else
NewSoftSerial cameraconnection = NewSoftSerial(2, 3);
#endif
// pass the serial connection to the camera object
VC0706 cam = VC0706(&cameraconnection);


void setup() {
  Serial.begin(9600);
 
  // Try to locate the camera
  if (cam.begin()) {
    Serial.println("Camera Found:");
  } else {
    Serial.println("No camera found?");
    return;
  }
  // Print out the camera version information
  char *reply = cam.getVersion();
  if (reply == 0) {
    Serial.print("Failed to get version");
  } else {
    Serial.println("-----------------");
    Serial.print(reply);
    Serial.println("-----------------");
  }

  // Set the picture size - you can choose one of 640x480, 320x240 or 160x120
  // Remember that bigger pictures take longer to transmit!
 
  //cam.setImageSize(VC0706_640x480);        // biggest
  cam.setImageSize(VC0706_320x240);        // medium
  //cam.setImageSize(VC0706_160x120);          // small

  // You can read the size back from the camera (optional, but maybe useful?)
  uint8_t imgsize = cam.getImageSize();
  Serial.print("Image size: ");
  if (imgsize == VC0706_640x480) Serial.println("640x480");
  if (imgsize == VC0706_320x240) Serial.println("320x240");
  if (imgsize == VC0706_160x120) Serial.println("160x120");


  //  Motion detection system can alert you when the camera 'sees' motion!
  cam.setMotionDetect(true);           // turn it on
  //cam.setMotionDetect(false);        // turn it off   (default)

  // You can also verify whether motion detection is active!
  Serial.print("Motion detection is ");
  if (cam.getMotionDetect())
    Serial.println("ON");
  else
    Serial.println("OFF");
   
   
    pinMode(6, OUTPUT); // Controla el relay
}




void loop() {
 if (cam.motionDetected()) {
   Serial.println("Motion!");  
   cam.setMotionDetect(false);
   Serial.println("Activamos el relay!");
   digitalWrite(6, HIGH); // Activamos el relay
   delay(30000); // Mantenemos activo 30 seg
   Serial.println("Desctivamos el relay!");
   digitalWrite(6, LOW); // Desactivamos el relay
  
  Serial.println("...Done!");
  delay(300000); // Pausamos 5 min para que no vuelva a activarse demasiado pronto
  cam.resumeVideo();
  cam.setMotionDetect(true);
 }
}