viernes, 1 de agosto de 2014

Escribir una librería para Arduino




Arduino Library Tutorial



Transcripción de la entrada localizada en la web de Arduino.cc

Escribir una librería para Arduino
Este documento explica cómo crear una librería para Arduino. Se inicia con un programa de código Morse y explica cómo convertir sus funciones en una librería. Esto permite que otras personas usen el código que has escrito y puedan actualizarlo facilmente a medida que mejora la librería.
Comenzamos con un programa de código Morse:
int pin = 13;
void setup() {
  pinMode(pin, OUTPUT);
}
void loop() {
  punto(); punto(); punto();
  raya(); raya(); raya();
  punto(); punto(); punto();
  delay(3000);
}
void punto() {
  digitalWrite(pin, HIGH);
  delay(250);
  digitalWrite(pin, LOW);
  delay(250);
}
void raya() {
  digitalWrite(pin, HIGH);
  delay(1000);
  digitalWrite(pin, LOW);
  delay(250);
}
Si ejecuta este programa, se representará el código de SOS (llamada de auxilio) en el pin 13.
El programa tiene unas pocas partes que tendremos que poner en nuestra librería. En primer lugar, tenemos las funciones punto() y raya() que hacen el parpadeo. En segundo lugar, tenemos la variable ledPin que indica el pin a utilizar. Por último, está la llamada a pinMod () que inicializa el pin como salida.
Vamos a empezar a convertir el programa en una librería!
Para una librería necesita al menos dos arcivos: un archivo de cabecera (w / con extensión. H) y el código fuente (w / extensión. cpp). El archivo de cabecera contiene definiciones para la librería: básicamente un listado de todo lo que hay dentro, mientras que el archivo del código fuente tiene el código real. Vamos a llamar a nuestra librería "Morse", por lo que nuestro archivo de cabecera será Morse.h. Echemos un vistazo a lo que contiene. Puede parecer un poco extraño al principio, pero tendrá más sentido una vez que vea el código fuente que lo acompaña.
El archivo de cabecera consiste básicamente en una clase con una línea para cada función de la librería, junto con las variables que se van a usar:
class Morse {
  public:
    Morse(int pin);
    void punto();
    void raya();
  private:
    int _pin;
};
Una clase es simplemente una colección de funciones y variables agrupadas en un mismo lugar. Estas funciones y variables pueden ser públicas, lo que significa que las podrán usar las personas que están utilizando la librería, o privada, lo que significa que sólo se puede acceder a ellas desde la propia clase. Cada clase tiene una función especial conocida como constructor, que se utiliza para crear una instancia de la clase (o sea, un objeto). El constructor tiene el mismo nombre que la clase, y no devuelve nada.
Se necesitan un par cosas más en el archivo de encabezado. Una de ellas es una instrucción # include que da acceso a los tipos estándar y las constantes del lenguaje Arduino (esto se agrega automáticamente a los programas normales, pero no a las librerías). Se parece a esto (y se coloca antes de la definición de la clase mostrada anteriormente):
  1. Include "WProgram.h"
Por último, es común añadir las siguientes lineas de código :
  1. Ifndef Morse_h
  2. Define Morse_h
// La declaración # include y el código van aquí ...
  1. endif
Básicamente, esto evita problemas si alguien accidentalmente usa dos veces el #include con la librería que estamos construyendo, evitando que se declaren las variables y funciones más de una vez.
Por último, se suele poner un comentario en la parte superior de la librería con su nombre, una breve descripción de lo que hace, quién lo escribió, la fecha y el tipo de licencia.
Echemos un vistazo a la cabecera completa:
/*
  Morse.h - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
  • /
  1. ifndef Morse_h
  2. define Morse_h
  3. include "WProgram.h"
class Morse {
  public:
    Morse(int pin);
    void punto();
    void raya();
  private:
    int _pin;
};
  1. endif
Vamos a repasar las distintas partes del código fuente de Morse.cpp.
Lo primero son un par de # include. Con esto el resto del código tendrá acceso a las funciones estándar de Arduino, y a las definiciones definidas en Morse.h:
  1. Include "WProgram.h"
  2. Include "Morse.h"
A continuación viene el constructor. Una vez más, en el constructor se establece lo que debe ocurrir cuando alguien crea una instancia de la clase. En este caso, el usuario especifica el pin que le gustaría utilizar. Configuramos el pin como salida en una variable privada para su uso en las otras funciones:
MORSE:: Morse (pin int) (   pinMode (pin, OUTPUT);   _pin = pin; )
Hay un par de cosas extrañas en este código. La primera es el Morse:: antes del nombre de la función. Esto indica que la función es parte de la clase Morse. Verás esto en otras funciones de la clase. Lo segundo es el subrayado en el nombre de nuestra variable privada, _pin. Esta variable puede tener cualquier nombre, siempre y cuando coincida con la definición que figura en el archivo de encabezado. Agregar un subrayado al inicio del nombre es una convención común para dejar claro que las variables son privadas, y también para diferenciarlas del argumento de la función (el pin en este caso).
Después viene el código del programa que estamos convirtiendo en una librería (¡por fin!). Se ve más o menos lo mismo, salvo Morse:: delante de los nombres de las funciones, y en lugar de _pin pin:
void Morse::punto() {
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}
void Morse::raya() {
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}
Por último, es típico incluir un comentario en la parte superior del código fuente. Vamos a ver el código:
/*
  Morse.cpp - Library for flashing Morse code.
  Created by David A. Mellis, November 2, 2007.
  Released into the public domain.
  • /
  1. include "WProgram.h"
  2. include "Morse.h"
Morse::Morse(int pin) {
  pinMode(pin, OUTPUT);
  _pin = pin;
}
void Morse::punto() {
  digitalWrite(_pin, HIGH);
  delay(250);
  digitalWrite(_pin, LOW);
  delay(250);  
}
void Morse::raya() {
  digitalWrite(_pin, HIGH);
  delay(1000);
  digitalWrite(_pin, LOW);
  delay(250);
}
Y eso es todo lo que necesita (hay algunas otras cosas opcionales, pero hablaremos de eso más adelante). Vamos a ver cómo usar la librería.
En primer lugar, hay que crear el directorio Morse dentro del subdirectorio de librerías . Copia o mueve los archivos Morse.h y Morse.cpp a ese directorio. Ahora ejecuta el IDE de Arduino. Si vas al menú Sketch > Import Library deberías ver el una opción Morse. La librería será compilada con los programas que la utilizan. Si no aparece la librería, asegúrate de que los nombres de los archivos terminan realmente ten .cpp y .h (y no en .pde o .txt, por ejemplo).
Vamos a ver cómo podemos modificar nuestro programa de SOS para hacer uso de la nueva librería:
  1. include <Morse.h>
Morse morse(13);
void setup() { }
void loop() {
  morse.punto(); morse.punto(); morse.punto();
  morse.raya(); morse.raya(); morse.raya();
  morse.punto(); morse.punto(); morse.punto();
  delay(3000);
}
Hay algunas diferencias con el programa original (aparte del hecho de que parte del código se ha trasladado a la librería).
En primer lugar, hemos añadido una declaración # include al principio del programa. Esto hace que la librería Morse esté disponible para el programa y que se envíe a la placa de Arduino. Cuando ya no necesite una librería en un programa, debe eliminar la sentencia # include para ahorrar espacio.
En segundo lugar, creamos una instancia de la clase Morse llamada morse:
Morse morse(13);
Cuando esta línea se ejecute ( esto sucede incluso antes de que se ejecute la función setup () ), se llamará al constructor de la clase Morse, y se le pasará un parámetro (en este caso, el valor 13).
Tenga en cuenta que nuestro setup() está vacío, esto se debe a que la llamada a pinMode () se produce dentro de la librería (cuando se construye la instancia).
Por último, para llamar a las funciones punto() y raya(), tenemos que precederlas del prefijo morse (que es el nombre de la instancia que hemos creado). Podríamos tener varias instancias de la clase Morse, cada una con su propio PIN almacenado en la variable privada _pin de esa instancia. Al llamar a una función se indica que instancia de la clase se debe utilizar. Es decir, si tuviéramos:
Morse morse (13); Morse morse2 (12);
la llamada a morse2.dot (), hace que la salida sea por el pin 12.
Si pruebas el nuevo programa, probablemente te darás cuenta de que el IDE de Arduino no reconoce las funciones de la librería y no resalta el código. Por desgracia, por ahora el software de Arduino no puede averiguar lo que hay definido en la librería (aunque sería una buena característica a tener en cuenta), así que tienes que ayudarle un poco. Para ello, crea un archivo llamado keywords.txt en el directorio de Morse.. Que debe tener este aspecto:
Morse KEYWORD1 raya KEYWORD2 punto KEYWORD2
Cada línea tiene el nombre de la palabra clave, seguido de un tabulador (no espacios), seguido por el tipo de palabra clave. Las clases deben ser del tipo KEYWORD1 y se muestran de color naranja; las funciones deben ser del tipo KEYWORD2 y serán de color marrón. Tendrá que reiniciar el entorno Arduino para conseguir que reconozca las nuevas palabras clave.
Es conveniente acompañar las librerías con algún programa de ejemplo que haga uso las mismas. Para ello, cree un directorio examples dentro del directorio Morse. A continuación, copie el directorio que contiene el programa de ejemplo que escribimos arriba (lo llamaremos SOS) en el directorio de ejemplos. (Puedes encontrar el programa de ejemplo con la opción Sketch > Show Sketch Folder) Si reinicias el entorno Arduino (esta es la última vez, lo prometo) – verás la opción Library-Morse dentro de File > Sketchbook > Examples que contiene su ejemplo. Es posible que quieras agregar algunos comentarios para explicar mejor cómo usar la librería.
Si quieres echa un vistazo a la librería completa (con palabras clave y el ejemplo), puede descargarlo: Morse.zip.
Eso es todo por ahora, pero probablemente voy a escribir una colección de tutoriales avanzados pronto. Mientras tanto, si tienes cualquier problema o sugerencia, por favor escribe en el foro de desarrollo de software.

Librerías en Arduino



¿Os acordais del personaje de Matrix, Neo cuando en una sesión de entrenamiento el ordenador le "enseña" kung fu, simplemente "transfiriendo" a su cerebro esa"habilidad"?



Pues bien, eso mismo es lo que hacemos cuando queremos que nuestro microcontrolador aprenda cosas de forma rápida. Para ello usamos las librerías.

Por ejemplo si tuviésemos ya diseñados un robot que sabe conducir solo y evitar obstáculos necesitaría aprender identificar las señales de tráfico y saber interpretarlas. Pues bien, podríamos enseñar a nuestro robot el Código de Circulación paso a paso, o bien, cargarle en su "cerebro", todas las señales como si fuera un diccionario. Parece bastante más sencillo que nos "carguen" la librería de kung fu,  en unos segundos, que dedicarle media vida a su aprendizaje, ¿no?


Pues bien, eso es simplemente una librería, un  código que se usan cuando se hace una llamada desde nuestro Sketch con la finalidad de que sepa realizar unas tareas concretas.

A medida que avancemos con sensores, actuadores y motorizaciones concretas, iremos familiarizando más y más con el uso de las librerías, y muchas veces veremos que aunque nos guste más un componente que otro, muchas veces elegiremos otro solo por la cantidad de código que ya hay disponible para sacarle partido al mismo. Por ejemplo para geolocalización,  para controlar motores, para controlar pantallas táctiles, etc.


Obviamente siempre podremos crear nuestras propias librerías, o bien adaptar alguna específica con nuevas funcionalidades  pero por economía lo suyo, sobre todo en las primeras fases de aprendizaje, es intentar usar todas aquellas que existen y otros usuarios ya han probado.


Y ¿cómo instalo una librería en mi código?

Pre-requisitos:
Se asume que ya sabemos cargar un programa al Arduino y ya tenemos una noción básico de cómo encender  un LED. Ver entrada (Encendido y Apagado de un LED).

Pasos:
  1. Comprobar que dentro de la carpeta "sketchbook" de nuestra carpeta personal existe un otra llamada "libraries". Si no es así hay que crearla.
  2. Descargar al escritorio la librería deseada, que normalmente estará comprimida y descomprimirla.
  3. Ahora para usar la librería en tu Sketch agrega en las primeras líneas del código agregando la línea
#include <nombre_de_la_libreria.h>


Nota: Al igual que nos pasa a nosotros aprender muchas cosas consume memoria, así que si no queremos quedarnos sin memoria en nuestro Arduino, lo suyo es invocar solo aquellas librerías que vayamos a usar, y no hacer llamadas a librerías de forma innecesaria.


Con todo esto hecho, ahora lo único que tendremos que hacer es importar la librería que queramos usar.   En la imagen a continuación vemos como al importar la librería para usar un motor paso a paso (Stepper Motor en inglés) , se nos incorpora al principio de nuestro programa una línea específica #include <Stepper.h>