Usar el nunchuk en tus proyectos con Arduino

Una de las mejores cosas que tiene la electrónica es que puedes usar aparatos que se fabrican en serie con unas características increibles a precios muy bajos. En esta ocasión voy a explicar cómo usar el nunchuk de la wii para poder adaptarlo a vuestros proyectos electrónicos. En este artículo me centraré en la plataforma Arduino.

No es necesario tener la wii para adquirir un nunchuk, de hecho ni siquiera tiene por qué ser el oficial, un clónico puede llegar a costar 7 €. Por otra parte es necesario tener el wiichuck, que es un adaptador para el nunchuk con una tira de pines y hace más manejable el uso de este (no supera los 4€).

El nunchuk trabaja con una tensión de 3,3 v., pero también puede hacerlo a 5 v. (Limitando su vida útil, pero por 7€ …). Funciona mediante el bus I2C en su variante Fast (400Kb/s) y lo que podemos leer son los datos del acelerómetro XYZ, del joystick y de los dos botones que contiene. Lo que haré en este artículo es recuperar esa información y mostrarla por el puerto serie.

Para empezar hay que inicializar el nunchuk de la siguiente forma:

  • Enviar a la dirección 0x52 los bytes 0xF0 y 0x55.
  • Enviar a la dirección 0x52 los bytes 0xFB y 0x00.

A partir de entonces cada vez que queramos leer los datos tenemos que:

  • Enviar a la dirección 0x52 el byte 0x00.
  • Leer de la dirección 0x52 seis bytes.

Los 6 bytes que hemos leido contienen la información del acelerómetro, del joystick y de los botones, pero vienen formateados:

  • Primer byte: La posición X del joystick (0-255)
  • Segundo byte: La posición Y del joystick (0-255)
  • Tercer byte: Los 8 bits de mayor peso del eje X del acelerómetro (Finalmente tendrá un valor entre 0 y 1023)
  • Cuarto byte: Los 8 bits de mayor peso del eje Y del acelerómetro (Finalmente tendrá un valor entre 0 y 1023)
  • Quinto byte: Los 8 bits de mayor peso del eje Z del acelerómetro (Finalmente tendrá un valor entre 0 y 1023)
  • Sexto byte: que contiene
    • los dos bits de menor peso del eje Z del acelerómetro
    • los dos bits de menor peso del eje Y del acelerómetro
    • los dos bits de menor peso del eje X del acelerómetro
    • Un bit indicando el estado del botón C (0 si pulsado, 1 si no lo está)
    • Un bit indicando el estado del botón Z (0 si pulsado, 1 si no lo está)

Tomaremos los 3,3 v. y la masa que ofrece arduino, conectaremos el pin de data del wiichuck al pin analógico 4 y el pin de clock al pin analógico 5. No son necesarias las resistencias pull-up típicas del bus I2C ya que los pines analógicos 4 y 5 ya las tienen implementadas internamente y son activadas al inicializar la librería wire:

El código fuente simplificado al máximo:

Y así es como se ven los datos de una de las pruebas que he hecho:

Si os ha gustado me plantearé hacer otro artículo donde explico cómo hacer lo mismo para microcontroladores AVR y PIC.

12 comentarios en “Usar el nunchuk en tus proyectos con Arduino

  1. pelayator

    Menudo crack. Gracias por la información!!
    En una tienda de chinos de Vallecas me vendían el mando «no oficial» de la wii entero creo recordar por 10 euros, para la mano izqda y drcha, enterito. El wiichuck donde se puede comprar¿? Un saludete

    Responder
  2. David

    esta genial esta guia, pero para cuando un post sobre cómo programarlo en AVR sin librerias (seria para mi robby, ya le conoces, y el micro el atmegau16 de jorge), ya que tengo pensado mover la pinza y el robby en general con el nunchuck, ya tengo todo comprado (Estan en el avion jeje)

    saludos

    Responder
  3. Green

    hice exactamente lo que dijiste (en lo de las conexiones y todo) y me da

    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0
    JX:0 JY:0 AX:0 AY:0 AZ:0 C:0 Z:0

    infinitamente, tengo el wiichuck de sparkfun, y el control es un original con cable.. que podrá ser???

    Saludos.-

    Responder
  4. Omnimusha

    HOla monstruo!!.pude finalmente hacerlo funcionar.gracias asu code.
    del autor no me funcionaba, me faltaba agregar en utilitytwi.h
    TWBR = ((CPU_FREQ / 400000L) – 16) / 2
    yo no cambie la velocidad a 400Kb/s osea aqui:
    #define TWI_FREQ 100000L
    funciona bien!!

    aqui, me modesto codigo para processing.donde emboza la idea de como
    interpetar los datos q nos envia via el purto seri el del nunchuk.
    del codigo del autor suprimos JX, JY…etc por una coma «,».es decir:

    Serial.print(buffer[0], DEC);

    Serial.print(«,»);
    Serial.print(buffer[1], DEC);

    Serial.print(«,»);
    Serial.print((buffer[2] <> 2));

    Serial.print(«,»);
    Serial.print((buffer[3] <> 4));

    Serial.print(«,»);
    Serial.print((buffer[4] <> 6));

    Serial.print(«,»);
    Serial.print((buffer[5] >> 1) & 1);

    Serial.print(«,»);
    Serial.println(buffer[5] & 1);
    ====================
    bueno aqui mi code:

    import processing.serial.*;
    Serial myport;

    char delim= ‘,’;
    float joyX,joyY;
    int sensorcount =7;

    void setup()
    {
    size(255, 255); smooth();noStroke();

    myport = new Serial(this,Serial.list()[1],4800);
    myport.clear();
    }

    float[] sensorValues = new float[sensorcount];
    void serialEvent(Serial myport){
    String serialString = myport.readStringUntil(‘n’);

    if (serialString != null){
    String[] numbers = split(serialString, delim);

    if ( numbers.length == sensorcount){
    for(int i=0;i< numbers.length;i++){
    if(i <= sensorcount){
    numbers[i] = trim(numbers[i]);
    sensorValues[i]= float(numbers[i]);
    }
    }
    }
    }
    }

    //==============================0

    void draw()
    {
    background( 51 );
    float val=0 ;

    val= (sensorValues[2]/(1023+2));
    ellipse(val*200, sensorValues[1], 33, 33);println(val );// para aclerometroX y joyY
    }

    //==============================

    Responder
    1. Oscar

      En radianes:
      atan2(AX, AZ) para el cabeceo
      atan2(AY, AZ) para el alabeo

      En grados:
      atan2(AX, AZ) * 180 / PI para el cabeceo
      atan2(AX, AZ) * 180 / PI para el alabeo

      Responder
  5. Omnimusha

    hola, me encontre con esto.con su formula no me concide en en la posicion q se encuentra el sensor.

    Rx=528
    Ry=516
    Rz=744

    normalize vector (convert to a vector with same direction and with length 1)

    R = sqrt(square(Rx) + square(Ry) + square(Rz)); //teotema pitagoras
    R=1048.129

    Rx =Rx/ R; = 0.503

    Axr = arccos (Rx / R) =89.97 //precen q esta en grados

    —-
    segun esto el vector esta parallelo al eje z(fucionado),donde esta formando en cada eje un angulo de 90º–


    CRE QUE ESTO ESTA CORRECTO, USTED QUE DICE ?

    http://www.starlino.com/imu_kalman_arduino.html

    Responder

Responder a Omnimusha Cancelar la respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *