Arduino PPT

En esta ocasión voy a mostrar una aplicación de Arduino para facilitar las presentaciones en Power Point mediante el uso del accesorio “Nunchuck” de la Nintendo Wii.

Se trata de un sistema compuesto de 2 componentes, uno que gobierna el control del Arduino, y otro corriendo en el lado del PC que se encarga de la comunicación con el puerto USB y el envío de comandos al Power Point.

La aplicación que se ejecuta en el microcontroldador del Arduino,  básicamente se ocupa de leer el estado del acelerómetro del eje X del mando “Nunchuck” y lo envía por el puerto USB cada 100 milisegundos.
Por otro lado,  la aplicación de PC está constantemente leyendo el buffer de datos asociado al puerto, de manera que si detecta que el mando se ha movido a la derecha (o el Joystick), envía a PowerPoint el comando de “Diapositiva siguiente”, mientras que si detecta que el mando se ha movido hacia atrás, envía el comando “Diapositiva anterior”. Esta misma funcionalidad la he implementado pulsando uno de los botones del Nunchuck por si es más cómodo utilizar el “Joystick” para desplazar las diapositivas.

Puede verse un video del proyecto en funcionamiento :

El código fuente de la parte del “Wii-chuck” está basdo en uno de los tantos publicados, y es el siguiente, aunque puede descargarse directamente de aqui :

/*
    Luis Alberto Aldea (Skynet) 2011
    
    Libreria para la lectura del Nunchuck.
    Acelerómetro eje X – Analógico eje X
    Acelerómetro eje Z – Analógico eje Z
    
    twi.h definido a 1000000L para tension de 3.3V
*/

    #include <Wire.h>
    #include <string.h>

    #undef int
    #include <stdio.h>

    #define UMBRAL_JOY_X_L 70
    #define UMBRAL_JOY_X_R 95    
    #define UMBRAL_JOY_Y_D 145
    #define UMBRAL_JOY_Y_U 95    
    #define UMBRAL_CHUCK_X_L 95    
    #define UMBRAL_CHUCK_X_R 125
    #define UMBRAL_CHUCK_Y_D 160    
    #define UMBRAL_CHUCK_Y_U 125
    #define UMBRAL_CHUCK_Z_F 160
    #define UMBRAL_CHUCK_Z_B 155
    #define BOTON_C_PULS 1
    #define BOTON_Z_PULS 2
    
    uint8_t chuckOut[6];                                            // Almacén de dato de 6 bytes devuelto por el Wii Nunchuck
    int pivote = 0;
    int ledPin = 13;
    int wiiChuckPinVcc = A3;
    int wiiChuckPinGnd = A2;
    
    byte byte0 = 0x00;
    byte byte1 = 0x00;

    void setup ()
    {
        Serial.begin(19200);
        //delay(1000);
        wiiChuck_Vcc ();                    // Puesta en tension de PIN A2 a 3.3V y PIN A3 a 0V
        Wire.begin ();                       // Conexion al bus I2C
        wiiChuck_Init ();                     // Envio del handshake para inicializar el Nunchuck
    }

    void loop ()
    {
      Wire.requestFrom (0x52, 6);                                   // Pido un dato de 6 bytes al Nunchuck en la direccion 0x52
      while (Wire.available ())
      {
        digitalWrite (ledPin, HIGH);                                // Encciendo el led de transmitiendo byte
        chuckOut[pivote] = traduce_nunchu_byte (Wire.receive ());   // Recepcion y traduccion de 1 nunchubyte
        digitalWrite (ledPin, LOW);                                 // Apago el led de transmitiendo byte
        pivote++;
      }

      if (pivote >= 5)                                              // Si llegan como poco 6 bytes, los imprimo
      {
        manda_Serie();
      }

      pivote = 0;                                                   // Reseteo de pivote bytes
      envio_FinTx ();                                               // Mando el fin de transmision para recibir nuevos
      delay (100);
    }
    
    void wiiChuck_Init ()
    {
        Wire.beginTransmission (0x52);            // Inicializacion de transmision en la 0×52
        Wire.send (0x40);                        // Envio de la direccion de memoria (0x40)
        Wire.send (0x00);                        // Envio de ‘fin de transmision’ (0x00)
        Wire.endTransmission ();                // Fin de la transmision
    }
    
    void wiiChuck_Vcc ()
    {
                int nunchuck_Vcc = 675;                               // Tension del Wii Nunchuck a 3.3V
                nunchuck_Vcc = map(nunchuck_Vcc, 0, 1023, 0, 255);  
                analogWrite(wiiChuckPinVcc, nunchuck_Vcc);            // Seteo con 3.3V el PIN A2
                analogWrite(wiiChuckPinGnd, 0);                       // Seteo con 0V   el PIN A3
    }

    void envio_FinTx ()
    {
        Wire.beginTransmission (0x52);                // Inicializacion de transmision en la 0×52
        Wire.send (0x00);                            // Envio de ‘fin de transmision’ (0x00)
        Wire.endTransmission ();                    // Fin de la transmision
    }

    // Codifica el byte argumentado al formato reconocible por
    // la mayoria de los drivers wiimote
    char traduce_nunchu_byte (char x)
    {
        //x = (x ^ 0x17) + 0x17;  Comentado solo para testeo de char
        return x;
    }

void manda_Serie ()
    {
      
        int joy_abscisas      = chuckOut[0];
        int joy_ordenadas     = chuckOut[1];
        int accel_abscisas    = chuckOut[2];
        int accel_ordenadas   = chuckOut[3];
        int accel_eje_z       = chuckOut[4];
        int botones           = chuckOut[5];
                
        // Voy a despreciar los LSB del byte 5 ya que solo voy a mandar la posicin del chuck en cuanto que pase el umbral
        byte0 = 0x00;
        byte1 = 0x00;
                        
        if (joy_abscisas < UMBRAL_JOY_X_L)           // El joystick esta hacia la izquierda
            byte0 = byte0 && 0x02;      
        else if (joy_abscisas > UMBRAL_JOY_X_R)      // El joystick esta hacia la derecha
            byte0 = byte0 && 0x01;      
        else                                         // El joystick esta en el centro
            byte0 = 0x00;               
        if (joy_ordenadas > UMBRAL_JOY_Y_D)          // El joystick esta hacia abajo
            byte0 = byte0 + 0x08;       
        else if (joy_ordenadas < UMBRAL_JOY_Y_U)     // El joystick esta hacia arriba
            byte0 = byte0 + 0x04;
        if (accel_abscisas < UMBRAL_CHUCK_X_L)       // El nunchuck esta hacia la izquierda
            byte0 = byte0 + 0x10;
        else if (accel_abscisas > UMBRAL_CHUCK_X_R)  // El nunchuck esta hacia la derecha
            byte0 = byte0 + 0x10;
        if (accel_ordenadas > UMBRAL_CHUCK_Y_D)      // El nunchuck esta hacia abajo
            byte0 = byte0 + 0x80;
        else if (accel_ordenadas < UMBRAL_CHUCK_Y_U) // El nunchuck esta hacia arriba
            byte0 = byte0 + 0x40;
        if (accel_eje_z > UMBRAL_CHUCK_Z_F)          // El nunchuck esta hacia adelante
            byte1 = byte1 &&  0x02;
        else if (accel_eje_z < UMBRAL_CHUCK_Z_B)     // El nunchuck esta hacia atras
            byte1 = byte1 && 0x01;
        if (botones == BOTON_Z_PULS)                 // El boton Z esta pulsado
            byte1 = byte1 && 0x04;
        else if (botones == BOTON_C_PULS)            // El boton C esta pulsado
            byte1 = byte1 && 0x08;
        // Envio del paquete de 4 bytes por serie
                  
        Serial.print(0x69, DEC);
        Serial.print(byte0, DEC);
        Serial.print(byte1, DEC);
        Serial.print(0x66, DEC);
    }
El snipplet de la pieza de PC que trata los datos enviados por el WiiChuck puede implementarse en cualquier lenguaje de programación, en VB sería el siguiente :

Private Sub TratarDato(dato As String)
 
    chuckIn = Decodificar(dato)
   
        ‘Si esta pulsado el boton C hacemos caso al mando
        If (chuckIn.btn_C) Then
            If Not datoEnviado Then
                If (chuckIn.joy_X < UMBRAL_ACC_IZD) Then
                    SendKeys “{BS}”
                    datoEnviado = True
                    btn_C.FillColor = vbGreen
                ElseIf (chuckIn.joy_X > UMBRAL_ACC_DCHA) Then
                    SendKeys “{ENTER}”
                    datoEnviado = True
                    btn_C.FillColor = vbGreen
                End If
            End If
        End If
        ‘Si esta pulsado el boton Z hacemos caso al acelerómetro
        If (chuckIn.btn_Z) Then
            If Not datoEnviado Then
                If (chuckIn.acc_X < UMBRAL_ACC_IZD) Then
                    SendKeys “{BS}”
                    datoEnviado = True
                    btn_Z.FillColor = vbGreen
                ElseIf (chuckIn.acc_X > UMBRAL_ACC_DCHA) Then
                    SendKeys “{ENTER}”
                    datoEnviado = True
                    btn_Z.FillColor = vbGreen
                End If
            End If
        End If
     
End Sub

Aqui dejo un enlace compilado y linkado para el interesado…

WiiChuck_PC

Para más información estoy disponible en info@skynetronic.es

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: