Arduino y el Nunchuk de la Wii

Objetivos

 

  • Presentar el Nunchuk.
  • Ver que dispositivos contiene.
  • Aprender a conectar y programar el Nunchuk.
  • Explicar qué es y cómo funciona un acelerómetro.
  •  

    Arduino y el modo Sleep

  • Buscamos extender el tiempo de uso de un Arduino Nano con baterías.
  • Para ello vamos a ver el modo Sleep.
  • Veremos un programa sencillo que nos permita reducir al máximo el consumo de nuestro circuito.
  •  

    Material requerido.

     

    Imagen de Arduino UNO

    Arduino Uno o compatible y con el firmware para S4A cargado.


    conexiones
     Unos  cables.
    Img_3_4 Una Protoboard
    Multimetro sencillo Un multímetro digital.

     

    Reduciendo el consumo de Arduino

     

    Como vimos en el capítulo previo, Arduino está diseñado más para ser fácil de usar que para consumir poco, sencillamente porque la eficiencia nunca entró en las especificaciones de diseño, hasta muy recientemente.

    En la última sesión apuntamos algunas ideas para reducir los consumos pero lo primero que vimos es que un Arduino UNO tiende a consumir uso 45 mA en vacío, mientras que un Nano apena llega a los 15 mA

    Ni que decir tiene que sería absurdo usar un Arduino UNO a baterías precisamente porque los circuitos internos de control del USB y especialmente del derrochador regulador de corriente que usa a su entrada, hacen que su consumo sea mucho mayor de lo que nos gustaría y por eso el Arduino Nano aparece como una opción clara para estas ocasiones.

    No he tenido ocasión de probar los Arduino Micro, que tiene fama de eficientes, pero espero recibir unos pocos en unos días y ya os daré un reporte sobre ellos (Ya tenían que haber llegado, pero el correo internacional está fatal)

    Así que de momento en esta sesión nos centraremos en otra forma de reducir sensiblemente el consumo de nuestro Arduino: El modo Sleep.

    El asunto es tan drástico como parece, porque no queremos tener encendido nuestro Duino como un árbol de navidad mientras no hace nada. Lo lógico es apagarlo, o por lo menos, hibernarlo, para que el consumo se reduzca al mínimo posible.

    No hemos inventado nada. Los osos y muchos otros animales como serpientes y anfibios suelen invernar en los climas fríos, entrando en un estado de animación suspendida que evita consumir una energía preciosa para llegar a la primavera, en un momento en el que no hay disponible alimento.

    Y eso es todo, creo que veréis que es más fácil de lo que parece.

     

    Arduino y el modo Sleep

     

    SI echáis una ojeada por internet con este tema encontrareis mucha información acerca del asunto y con mucha frecuencia, os hablaran de que hay que aprender a programar el chip interno de Arduino, el AVR, y os hablaran de no sé qué extravagancias que hay que hacer para ponerlo a dormir.

    La Liberia estándar de Arduino, por ahora no permite acceso a las funciones que hacen dormir al MCU (Micontrolador) y hay que usar la librería AVR directamente, pero para eso están las librerías, que almas generosas ponen a disposición de la comunidad.

    Recordad las reglas anti paletos. Hay que asustar a los nuevos y convencerles de que esto es muuuuy complicado y que hay que ser ingeniero para ello. Pero no. Es mucho más simple si usas la librería adecuada.

    Así que lo primero que os voy a recomendar es que si eres un usuario promedio y hasta justito no se te ocurra estudiar la librería AVR, es mucho más fácil usar una librería que nos haga el trabajo sucio.

    Y el caso del modo Sleep de Arduino no es una excepción. Usa la librería LowPower, es ligera y sencilla de usar,  y verás como ella se encarga.

    Una vez que descarguéis e instaléis la librería Low-Power-master, os propongo un sencillo ejemplo. Vamos a usar el mismo esquema de la sesión previa para medir el consumo de nuestro Arduino Nano:

    Esquema protoboard

     

    El programa de control

     

    Con el montaje descrito arriba vamos a hacer un programa, sencillo que muestre como dormir nuestro Arduino un tiempo, y después cuando despierte, encendemos dos segundos el LED incluido, y de ese modo que podamos hacer una lectura estable del consumo.

    Con un poco de suerte veremos que hay dos consumos diferentes. Cuando está dormido y cuando está despierto y de ese modo podremos comparar ambos.

    Lo primero es incluir la librería y definir el pin del LED

    #include "LowPower.h"
    int LED = 13 ;
    
    void setup()
    {    pinMode(13, OUTPUT);    }

    Después en el loop, dormimos el Nano un cierto tiempo, en este caso 8 segundos,  y cuando despierta, encendemos el led durante 2 segundos, al cabo de los cuales, volvemos a dormir nuestro Duino:

    void loop()
       { LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF); 
    
         digitalWrite(LED, HIGH);
         delay(1000);
         digitalWrite(LED, LOW);
       }

    La línea clave, por supuesto, es esta:

        LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);

    Como veis, simplemente pedimos a la librería que duerma a Arduino 8 segundos y mantenga apagados los convertidores analógico a digital, y el circuito BOD (O Brown Out Detection). Vamos con todo esto.

    Si no queréis complicaros más la vida, copiando esta línea, ya dispondréis de un buen ahorro de energía porque duerme a vuestro Arduino 8 segs y después hace lo que le pidamos al despertar.

    ¿Por qué 8 segundos? Bueno, una de las cosas más complicadas de dormir algo, es decidir cómo despertamos a la bella durmiente, y mucho cuidado aquí, porque si te equivocas puedes dejar tu Arduino por secula seculorum, así que mucho ojo con las pruebas.

  • Esto no puede ocurrir con la línea de arriba y por eso lo hacemos como primer ejemplo, así que tranquilos.
  • Si enredando con otros ejemplos no conseguís despertar a vuestro Arduino, hay que vaciarle la flash de programa y la forma más sencilla es reinstalar reprogramarlo con el blinking led o cualquier otro programa que no incluya instrucciones de dormirlo.[/fancy-ul] [/three-fourth]
  •  

    Hay tres maneras de despertar un Arduino del modo Sleep:

  • Interrupciones hardware
  • Timers y WDT que es un timer un tanto peculiar (Y del que ya hablaremos).
  • UART o puerta serie.[/fancy-ul] [/three-fourth]
  •  

    En este caso estamos usando el Watch Dog Timer y por ahora no quiero entrar detalles, pero nos basta con saber, que es una interrupción periódica que se dispara, si un cierto contador llega a 0.

    EL WatchDog Timer acepta diferentes periodos de disparo, de entre una tabla:

    SLEEP_15MS
    SLEEP_30MS
    SLEEP_60MS
    SLEEP_120MS
    SLEEP_250MS    
    SLEEP_500MS    
    SLEEP_1S 
    SLEEP_2S 
    SLEEP_4S 
    SLEEP_8S 
    SLEEP_FOREVER

    Como veis, 8 segundos es el máximo valor que podemos usar, pero nada nos impide hacer un bucle de digamos 15 periodos de 4 segundos para hacer un minuto:

    for (int i = 0 ;  i  <  16 ; i++)
                 LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);

    Esto genera un lapso de 4 x 15 segundos = 60, en los que el WDT despierta el micro lo justo para hacer un incremento de la variable i, y volver a dormirse. Y no hay ninguna razón para no hacer lo mismo 4 x 15 x 60 = 1 hora si es lo que queremos.

  • De nuevo, mucho cuidado con la opción SLEEP_FOREVER, porque ella solo se sale con una interrupción hardware o COMM y si la usáis alocadamente vais a tener un lío. Tu Arduino dormirá sin que seas capaz de despertarlo.
  • No uséis esto si no sabéis claramente lo que estáis haciendo..[/fancy-ul] [/three-fourth]
  •  

    Esta sencilla instrucción es la de menor consumo de energía, pero hay otros modos que pueden mantener encendidos ciertos circuitos del procesador interno del UNO y del Nano y si los necesitáis puede ser útiles:

    idle
    adcNoiseReduction   
    powerDown
    powerSave
    powerStandby   
    powerExtStandby
    standby

    Aquí os dejo la lista de modos y que hace cada uno, aunque tengo que reconocer que no veo claro muchas cosas, pero en fin quizás vosotros sí que lo veáis.

    descripcion de modulos

    Si no queréis complicaciones usad la línea de arriba, que es la de mayor ahorro  y listo.

    LowPower.powerDown(SLEEP_4S, ADC_OFF, BOD_OFF);

    Le pasamos dos parámetros más además del tiempo de despertar, que son:

  • ADC_OFF: Apaga los convertidores Analógico a digital (Aunque no se me ocurre para que podemos querer dejarlos encendidos si no tenemos procesador principal)
  • BOD_OFF: Apaga el circuito de Brown Out Detection, que es un circuito para detector niveles peligrosamente bajos de tensión.
  • Si no fuera por este detector BOD, cuando las pilas se fueran agotando la tensión podría descender de un cierto nivel y dañar los circuitos. Apagarlo ayuda a reducir consumo, pero ciertamente corres otros peligros. .[/fancy-ul] [/three-fourth]
  •  

    Vale ¿Y qué consumo podemos esperar de semejante apaño? De nuevo hay que medir para saberlo:

    No está mal, bajamos de 15 mA a 4.8 al activar el modo Sleep. Y Fíjate en que no he encontrado el modo de apagar el LED testigo de tensión en el Nano, que quieras que no, consume de continuo un par de mA de los 4.8 que consume el Nano dormido.

    Si no recuerdo mal, un LED típico tiene una caída de tensión unos 15 mV, que a 5V son 3mA de consumo. Así que si con una cuchilla os aseguráis de cortar una de las pistas que van al LED piloto, probablemente tendrás un consumo de unos 2 mA dormido, lo que no está nada mal.

  • Cuidado, este no es trabajo para manazas. Teneis que aseguraros de cortais solo una de las pistas del LED y nada mas.
  •  

    Si tu Arduino lee un par de sensores en digamos 1 segundo a 15 mA de consumo, y lo hace dos veces por hora, podemos esperar un consumo medio de poco más de 2 mAh, pon 3 mAh, Con una batería de 1200 mA, podrás alimentar tu circuito 1.200 / 3 = 400 horas que son 16 días a palmos.

     

    Pero elegir las baterías y sobre todo combinarlas de un modo eficiente, es un tema con su propia interés y por eso , en el la próxima sesión hablaremos como sacarlas el máximo partido, y por ahora vale la pena dejar el tema aquí.

     

    Resumen de la sesión

     

  • Presentamos los motivos por los que queremos maximizar la duracion de las baterias
  • Vimos como reducir al maximo el consumo de Arduino, mediante el modo Sleep.
  • Aprendimos entrar y salir del modo Sleep.
  •   

    Material requerido.

     

    Imagen de Arduino UNO

    Arduino Uno o similar. Arduino Uno o similar.

    conexiones

    Cables  de protoboard macho hembra.

    nunchuk wii Un Nunchuk con adaptador de pines.

     

    EL NUNCHUK

     

    En esta ocasión vamos a presentar un dispositivo que nos puede dar mucho juego a la hora de realizar proyectos con nuestro Arduino uno o Arduino mega, sobre todo en aquellos relacionados con la robótica.  Estamos hablando del Nunchuk de la Wii. El pequeño de los dos mandos que utiliza normalmente esta consola, el que no parece un mando de la tele.

    nunchuk wii

    Y es que este mando integra en poco espacio y con un diseño estupendo, un joystick, dos botones y  un acelerómetro (si no os suena no os preocupéis, ya hablaremos de este último). Tiene un precio muy razonable, de hecho los tenéis en la tienda de esta misma página por unos 11 euros, y además viene con un adaptador con una tira de pines para facilitar la conexión.

    El Nunchuck funciona mediante el bus I2C, así que solo vamos a necesitar un par de cables para controlarlo, además de los propios para la alimentación del mando. Sólo tenéis que tener en cuenta que en teoría funciona a 3.3V, y por lo demás el – va a tierra, d (data) a SDA y c (Clock) a SCL, que en el Arduino Uno corresponden a los pines A4 y A5.

  • La forma correcta de colocar el adaptador en la toma del Nunchuk es con los pines hacia el lado del adaptador que no tiene una hendidura.
  • De todas formas, siempre podéis hacerlo por prueba y error. Si al ejecutar el programa no funciona, le dais la vuelta y listo. 
  •  

    keyes nunchuk kduino

    Y como casi siempre, hay algunas librerías que nos van a facilitar mucho la programación. Hay varias aunque todas son bastante parecidas, pero nosotros hemos utilizado esta: WiiChuck. Esta vez tenemos que incluirla de una manera diferente a la que solemos hacerlo. Lo que tenéis que hacer es descomprimir el archivo que habéis descargado dentro de la carpeta «libraries» que está en el directorio en el que instalasteis el IDE.

     

    EL JOYSTICK Y LOS BOTONES

     

    Bueno, pues toca meternos en harina, y vamos a empezar por el joystick y los dos botones, que son los componentes del mando con los que más familiarizados estamos.

    Vamos a hacer un programa que nos permita ver en el monitor serie las medidas del joystick y si los botones están pulsados o no. Como veréis, la programación es muy sencilla gracias a la librería que estamos utilizando.

    #include "Wire.h" //Libreria I2C
    #include "WiiChuck.h" //Libreria WiiChuck
    
    WiiChuck chuck = WiiChuck(); //Creamos la instancia de WiiChuck
    
    
    void setup()
    { Serial.begin(115200); //Configuramos la velocidad del puerto serie
     chuck.begin(); //Iniciamos WiiChuck
    }
    void loop()
    { delay(20);
     chuck.update(); //Actualizamos los valores
     //Imprimimos los valores por pantalla
    
     Serial.print("Eje X: ");
     Serial.print(chuck.readJoyX()); //Eje X del Joystick
     Serial.print(" ");
     Serial.print("Eje Y: ");
     Serial.print(chuck.readJoyY()); //Eje X del Joystick
     Serial.print(" ");
    
     //Boton Z
     if (chuck.buttonZ)
     Serial.print("Z");
     else
     Serial.print("-");
     Serial.print(" ");
    
     //Boton C
     if (chuck.buttonC)
     Serial.println("C");
     else
     Serial.println("-");
    }

    Aquí podéis descargar el programa completo:

    nunchuk_joystick_botones.

    ¡Accede al contenido!

    Y si abrimos el monitor serie veremos algo como esto:

    nunchuk joy botones pantalla

     

    EL ACELERÓMETRO

     

    El otro componente que incluye este mando es un acelerómetro. Y, ¿qué es un acelerómetro? Pues un instrumento para medir aceleraciones (sí, no me he quedado calvo con esto…) , y quién más y quién menos lo usamos todos los días, porque nuestros preciados smartphones contienen uno. En nuestro caso, al igual que en los teléfonos, el acelerómetro del Nunchuk es capaz de medir aceleraciones en los 3 ejes: X, Y, Z.

    movimiento nunchuk arduino

    Estos dispositivos pueden tener muchas aplicaciones, por ejemplo, para hacer saltar un airbag de un coche en caso de que detecte una aceleración muy fuerte. Incluso creo que están intentando usarlo para desarrollar aplicaciones en los móviles, de forma que si tienes un accidente, por ejemplo una caída en moto, el móvil detecte ese cambio brusco en la aceleración y envíe un mensaje de socorro inmediato.

    Pero nosotros lo vamos a utilizar con otro fin, que es el de determinar la posición del mando a partir de las medidas de las aceleraciones. Y es q si recordamos nuestras clases de física, resulta que la fuerza de la gravedad provoca una aceleración en todos los cuerpos en la superficie de la Tierra de 9,8.

    Por lo tanto si tenemos el acelerómetro en posición horizontal, paralelo al suelo, deberíamos tener esa aceleración en el eje Z y una aceleración de 0  en los otros dos ejes. Pero si inclinamos el acelerómetro en cualquier dirección (ejes X o Y), estás medidas cambiarán. Pues a partir de estas tres medidas podemos calcular utilizando la trigonometría el ángulo de los ejes X e Y y determinar la posición del mando.

    ¿Y qué pasa con el eje Z? Pues que es imposible saber la posición en este eje con un acelerómetro, ya que la aceleración de la gravedad es paralela a este eje.

    yaw-pitch-roll

  • Normalmente los acelerómetros se combinan con giroscopios (ya hablaremos de ellos en otro momento) para tener medidas más exactas, pero en este caso nos bastará con el acelerómetro.
  • Para saber la posición en el eje Z necesitaríamos un magnetómetro que actúe a modo de brújula y nos indique la posición del Norte. 
  •  

    No vamos a entrar a explicar el cálculo de los ángulos a partir de las lecturas, porque no queremos aburrir a nadie; y además la librería lo va a hacer por nosotros.

    La programación va a ser igual de sencilla que en el apartado anterior, pero usando otras funciones de la librería. Además habrá que incluir la librería math.h, necesaria para el cálculo de los ángulos.

    #include <math.h>
    #include "Wire.h" //Libreria I2C
    #include "WiiChuck.h" //Libreria WiiChuck
    WiiChuck chuck = WiiChuck(); //Creamos la instancia de WiiChuck
    
    void setup()
    {
     Serial.begin(115200);
     chuck.begin();
    }
    
    void loop()
    {
     delay(20);
     chuck.update();
     Serial.print("Posicion: Eje X: ");
     Serial.print(chuck.readRoll()); //Posicición eje X
     Serial.print(" Eje Y: ");
     Serial.print(chuck.readPitch()); //Posición eje Y
     Serial.print(" *** ");
     Serial.print("Lecturas: ");
     Serial.print((int)chuck.readAccelX()); //Lectura eje X
     Serial.print(" ");
     Serial.print((int)chuck.readAccelY()); //Lectura eje Y
     Serial.print(" ");
     Serial.println((int)chuck.readAccelZ()); //Lectura eje Z
    }

    Aquí tenéis el programa completo: nunchuk_acelerometro,

    ¡Accede al contenido!

    Y el resultado en el monitor serie, en el que mostramos tanto las medidas del acelerómetro como la posición de los ejes X e Y. Si inclináis el mando en esos veréis como cambian las medidas y la posición en los ejes X e Y.

    monitor serie acelerómetro nunchuk

     

    Resumen de la sesión

     

    En esta sesión hemos aprendido varias cosas importantes: 

  • Hemos presentado el Nunchuk, un dispositivo que incluye elementos muy útiles por poco precio y siendo muy fácil de utilizar.
  • Hemos aprendido a programar el joystick y los botones del Nunchuk.
  • Sabemos lo que es un acelerómetro y cómo utilizarlo para obtener la posición del Nunchuk.
  •  

    Deja una respuesta