Arduino - Primeros Pasos Con Arduino PDF
Arduino - Primeros Pasos Con Arduino PDF
INTRODUCCIÓN A ARDUINO
¿QUÉ ES ARDUINO?
Arduino es una herramienta para hacer que las computadoras puedan sentir y controlar el mundo
físico a través de tu computadora personal. Es una plataforma de desarrollo de computación física
(physical computing) de código abierto, basada en una placa con un sencillo microcontrolador y un
entorno de desarrollo para crear software (programas) para la placa.
Puedes usar Arduino para crear objetos interactivos, leyendo datos de una gran variedad de
interruptores y sensores y controlar multitud de tipos de luces, motores y otros actuadores físicos.
Los proyectos de Arduino pueden ser autónomos o comunicarse con un programa (software) que
se ejecute en tu computadora (ej. Flash, Processing, MaxMSP). La placa puedes montarla tú mismo
o comprarla ya lista para usar, y el software de desarrollo es abierto y lo puedes descargar gratis.
Asequible - Las placas Arduino son más asequibles comparadas con otras plataformas de
microcontroladores.
Software ampliable y de código abierto- El software Arduino está publicado bajo una
licencia libre y preparado para ser ampliado por programadores experimentados. El
lenguaje puede ampliarse a través de librerías de C.
P á g i n a 1 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
http://arduino.cc/en/main/software
Y bajamos la versión más reciente del IDE (Entorno de desarrollo de Arduino) Que a la fecha de
escribir esto es la beta 1.6.2 es suficientemente estable para usarla en condiciones normales.
Una vez finalizado, ejecuta el fichero descargado, e ir respondiendo a las opciones de instalación.
Al cabo de unos minutos finalizara la instalación, y en el área de trabajo del equipo aparecerá el
icono de Arduino
COMPROBACIÓN DE LA INSTALACIÓN
Una vez instalado el IDE, vamos a comprobar que reconoce nuestro Arduino correctamente y que
podemos programarlo. Para ello, Conecta tu Arduino a tu computadora mediante el USB
Al hacerlo nuestro PC debe detectar el nuevo dispositivo USB y montar el driver adecuado.
P á g i n a 2 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Y finalmente:
Atención, el puerto serie en que se instala puede variar del indicado en la imagen, dependiendo de
las características del equipo.
Ahora, ya podemos hacer click en el icono de Arduino del escritorio de trabajo y configurar el
modelo de Arduino y confirmar el puerto serie al que se conecta. En [Menú]\Herramientas\Placa
Elegir el modelo exacto de nuestro Arduino. En nuestro caso elegimos un Arduino Nano:
P á g i n a 3 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
P á g i n a 4 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Este mensaje en color blanco indica que hemos cargado correctamente el programa y ya
deberíamos ver una luz que parpadea en nuestra placa.
ARDUINO NANO
En este curso usaremos la versión Nano de la placa arduino. A continuación se hará una pequeña
reseña de este dispositivo.
DESCRIPCIÓN GENERAL
El Arduino Nano es una pequeña y completa placa basada en el ATmega328 (Arduino Nano 3.0que
se usa conectándola a una protoboard. Tiene más o menos la misma funcionalidad que el Arduino
UNO, pero con una presentación diferente. No posee conector para alimentación externa, y
funciona con un cable USB Mini-B en vez del cable estándar.
ESPECIFICACIONES:
P á g i n a 5 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
REPRESENTACIÓN GRAFICA
ENERGÍA
El Arduino Nano posee selección automática de la fuente de alimentación y puede ser alimentado
a través de:
ENTRADA Y SALIDA
Cada uno de los 14 pines digitales del Nano puede ser usado como entrada o salida, usando las
funciones pinMode(), digitalWrite(), y digitalRead(). Operan a 5 voltios. Cada pin puede proveer o
recibir un máximo de 40mA y poseen una resistencia de pull-up (desconectada por defecto) de 20
a 50 kOhms. Además algunos pines poseen funciones especializadas:
Serial: 0 (RX) y 1 (TX). (RX) usado para recibir y (TX) usado para transmitir datos TTL vía
serie.
P á g i n a 6 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Interrupciones Externas: pines 2 y 3. Estos pines pueden ser configurados para activar una
interrupción por paso a nivel bajo, por flanco de bajada o flanco de subida, o por un
cambio de valor.
PWM: pines 3, 5, 6, 9, 10, y 11. Proveen de una salida PWM de 8-bits cuando se usa la
función analogWrite().
SPI: pines 10 (SS), 11 (MOSI), 12 (MISO), 13 (SCK). Estos pines soportan la comunicación
SPI, la cual, a pesar de poseer el hardware, no está actualmente soportada en el lenguaje
Arduino.
LED: Pin 13. Existe un LED conectado al pin digital 13. Cuando el pin se encuentra en nivel
alto, el LED está encendido, cuando el pin está a nivel bajo, el LED estará apagado.
El Nano posee 8 entradas analógicas, cada una de ellas provee de 10 bits de resolución (1024
valores diferentes). Por defecto miden entre 5 voltios y masa, sin embargo es posible cambiar el
rango superior usando la función analogReference(). También, algunos de estos pines poseen
funciones especiales:
I2C: Pines 4 (SDA) y 5 (SCL). Soporta comunicación I2C (TWI) usando la librería Wire.
AREF: Tensión de referencia por las entradas analógicas. Se configura con la función
analogReference().
OBJETIVOS
P á g i n a 7 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Mientras que las personas somos razonablemente buenas interpretando las instrucciones,
generalmente vagas, de una receta de cocina, cuando programamos quien debe entendernos es
una computadora que espera instrucciones precisas respecto a lo que debe hacer y que además
carece por completo de la imaginación o capacidad de improvisación humana.
Por ello se desarrollan los lenguajes de computadora, para dar instrucciones a una máquina de
forma:
El IDE de Arduino se programa en una variante de C, que es un lenguaje muy extendido por sus
características, aunque no es un lenguaje muy sencillo. Un programa es una serie de instrucciones
que se ejecutan en secuencia (salvo que indiquemos expresamente condiciones precisas en las
que esta secuencia se altera).
Cuando el comprobador acepta nuestro programa, invoca otro programa que traduce lo que
hemos escrito a instrucciones comprensibles para el procesador de nuestro Arduino. A este nuevo
programa se le llama compilador.
P á g i n a 8 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El lenguaje con el que se programan nuestras placas Arduino es un derivado del lenguaje de
programación Wiring. Su estructura y su sintaxis es igual que la de C. De hecho todas las librerías
de C y algunas de C++ se pueden utilizar con Arduino.
Así la primera parte de un Sketch será la declaración de variables, donde definiremos las variables
globales del Sketch declarando su tipo y, si queremos, su valor inicial. Estas variables serán
accesibles desde cualquier parte de nuestro Sketch al contrario que las variables locales, que son
las que se declaran dentro de una función o dentro de una estructura de control (por ejemplo un
bucle For).
int pin; // crea la variable de tipo entero pin
int numero = 1; // crea la variable de tipo entero numero y le asigna el
// valor 1
La segunda parte de un Sketch es una parte que solo se ejecuta una vez tras el arranque de la
placa Arduino, el Setup.
Void Setup()
{
...
...
...
}
Suele utilizarse para definir los pines que vamos a utilizar y declararlos como entradas o como
salidas, sobre todo en los ejemplos que encontraremos en la web y en los ejercicios que haremos
en este curso, y esto suele inducirnos a algunos errores como creer que un pin solo se puede
utilizar como entrada o como salida en un sketch, lo cual no es cierto, se puede cambiar durante la
ejecución del Sketch.
El Setup () debe considerarse como lo que es: un conjunto de código que solo se ejecuta una vez
cuando Arduino arranca. Esto nos dará una increíble flexibilidad a la hora de programar.
Siguiente parte importante de un Sketch: el Loop. Es la parte principal de nuestro programa pues
en el tendremos que poner el código para que el microcontrolador lo ejecute de manera recursiva,
es decir, esta parte del Sketch se repetirá una y otra vez mientras la placa Arduino tenga energía.
Void Loop()
{
...
...
...
}
P á g i n a 9 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
No todo el código tiene que estar en el Loop, ciertas partes pueden ser escritas fuera de este
bucle: las funciones. Las funciones son fragmentos de código separado al que se puede llamar
desde el Setup o desde el Loop, pero eso lo veremos más adelante.
Los Sketches generados desde el Arduino IDE se guardan en archivos con la extensión .ino.
Cuando abrimos el IDE de Arduino (o hacemos [Menú]\Archivo\nuevo) él nos escribe ya estas dos
funciones:
Nótese que el principio de cada función es indicado por la apertura de llave “{” y el fin de la misma
corresponde al símbolo de cerrar llaves “}”.
De hecho el conjunto de instrucciones contenidas entre una apertura y cierre de llaves se llama
bloque y es de suma importancia a la hora de que nuestro Arduino interprete de una u otra
manera las instrucciones que le damos.
Es de suma importancia que a cada apertura de una llave corresponda un cierre de llave.
Por ahora resaltar las líneas que aparecen dentro de los bloques principales:
Cualquier cosa que escribamos precedido por “//” son comentarios, y serán ignorados. Es decir
podemos dejarnos mensajes dentro del código (que de otro modo darían errores). El compilador
ignorará cualquier cosa entre // y el fin de línea.
Pediremos a Arduino que active su pin 13 como salida digital y después encenderemos y
apagaremos esta señal lo que hará que el LED que tiene conectado de serie se encienda o apague
al ritmo que marquemos.
P á g i n a 10 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Para indicar al sistema que deseamos usar el pin 13 como salida digital utilizamos la instrucción:
pinMode( 13, OUTPUT ) ;
El primer parámetro indica el pin a usar y “OUTPUT” es para usarlo como salida, y también podría
usarse el valor “INPUT” para indicar que vamos a leer de este pin.
Estas definiciones se harán solo una vez al principio, en la función setup(). La nuestra quedará, con
una única instrucción que declara que vamos a usar el pin 13 como salida digital:
void setup()
{
// initialize the digital pin as an output
pinMode( 13, OUTPUT) ;
}
El 13 indica el pin a utilizar y HIGH, LOW indican el valor que deseamos poner en esa salida, que en
Arduino corresponden a 5V para HIGH y 0V para LOW.
Si en la función loop() escribiéramos estas dos instrucciones seguidas, Arduino cambiaría estos
valores tan deprisa que no percibiríamos cambios, así que necesitamos frenarle un poco para que
podamos percibir el cambio.
delay(): Pausa el programa por un tiempo determinado (en milisegundos) especificado por un
parámetro. Hay 1000 milisegundos en un segundo.
Por tanto para programar una luz que se enciende y se apaga, tendríamos que generar una
secuencia de órdenes (Como en una receta de cocina) que hicieran:
1. Informar a Arduino de que vamos a utilizar el pin13 para escribir valores (en el Setup).
3. Esperar un segundo.
Si omitiéramos este segundo retraso, apagaría la luz y volvería a empezar encontrándose la orden
de volver a encender. No apreciaríamos que se había apagado.
P á g i n a 11 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El primer concepto que hay que fijar, es que las computadoras procesan las órdenes en secuencia,
una instrucción después de otra y en el orden en que se la dan. Nuestro programa instruye al
ordenador para que ejecute esas instrucciones y fija el orden en el que se ejecutan.
La forma de escribir un programa en Arduino que haga lo anteriormente descrito es algo parecido
a esto:
void setup()
{
pinMode( 13 , OUTPUT); // Usaremos el pin 13 como salida
}
void loop()
{
digitalWrite(13 , HIGH); // Enciende el LED
delay(1000); // Esperar un segundo
digitalWrite(13 , LOW); // Apagar el LED
delay(1000); // Esperar otro segundo
}
Solo nos falta ya, comprobar si hay errores y para ello pulsamos el icono en amarillo:
Si todo va bien (si no hay errores en rojo) podemos compilar y volcar con la siguiente flecha, En
caso contrario habrá que revisar los posibles errores y corregirlos.
La flecha en amarillo cargara nuestro programa al Arduino y podremos comprobar que la luz del
pin 13 parpadea con un retraso de un segundo entre encendido y apagado.
Nota: Esto no funcionara con ningún otro Pin del Arduino Nano, porque solo el 13 tiene un LED
conectado.
En el ejercicio anterior vimos el ejemplo de Sketch más sencillo que se puede hacer con Arduino,
que un LED parpadee controlando los intervalos de tiempo con la función delay().
P á g i n a 12 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
La función delay() es un retardo, la placa Arduino no hace otra cosa que contar los milisegundos
que le especifiquemos entre los paréntesis. En un Sketch sencillo como el del ejercicio 1 no hay
problema en tener al microcontrolador ocupado en la tarea de contar milisegundos, pero en
general serán pocas las veces que podamos permitirnos ese lujo. Lo más normal será que además
de controlar el tiempo nuestra Arduino tenga que ocuparse de otras tareas.
Por ese motivo vamos a ver cómo puede Arduino controlar el tiempo que está encendido el LED
sin recurrir a la función delay() y mientras tanto queda el microcontrolador libre para hacer otras
cosas.
Blink WithOut Delay utiliza la función millis() para controlar el tiempo. Esta función devuelve el
número de milisegundos que han transcurrido desde que se ha encendido por última vez.
// variables que cambiarán de valor.
int ledState = LOW; // ledState se usará para establecer el estado del LED
void setup()
{
pinMode(ledPin, OUTPUT); // establece el pin digital como salida
}
void loop()
{
// Se comprobará si es el momento de parpadear el LED, esto es, si la
// diferencia entre el tiempo transcurrido y el tiempo en que parpadeó
// por última vez el LED es mayor que el intervalo que establecimos en
// la declaración de variables.
P á g i n a 13 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Una resistencia de 330 Ohmios.
6. Algunos cables de Protoboard.
Cuando dejamos fluir agua de un sitio alto a otro más bajo, el agua corre libremente mientras no
se lo impidamos, y siempre de arriba abajo. Decimos que las diferentes alturas suponen una
diferencia de potencial entre ambos puntos que puede ser transformada en trabajo útil.
Cuando existe una diferencia de tensión eléctrica (o diferencia de potencial) entre dos puntos con
conexión, la electricidad fluye del positivo (o de más carga) hacia el negativo o menos, y también
podemos obtener trabajo útil de este principio.
Aunque la física detrás de estos dos ejemplos es diferente, conceptualmente son bastante
parecidos y por ello hablamos de:
P á g i n a 14 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
La idea es que la corriente eléctrica fluye del positivo al negativo porque hay una diferencia de
tensión (que medimos en Voltios de símbolo V) pero esto no es una medida absoluta sino la
diferencia que hay entre los puntos en que lo medimos.
Hay componentes que se oponen a la libre circulación de la corriente. Los llamamos resistencias,
su valor se mide en Ohmios y su símbolo es Ω.
V=RxI
Donde:
V es la tensión en voltios.
R la resistencia.
En el mundo de Arduino la tensión es casi siempre 5V, que es la tensión a que funciona y la que es
capaz de poner en sus salidas digitales.
Antes de meternos de lleno en el montaje de nuestro primer circuito primero hay que presentar
un elemento muy útil a la hora de armar circuitos electrónicos y este es la Protoboard.
Construir un circuito, desde luego, es una forma de probar si funciona. Pero esto no es práctico a
la hora de hacer ensayos: Hay que quitar y poner componentes para hacer diferentes pruebas, y el
hecho de estar soldándolos hacer perder tiempo, además de acortar la vida de esos componentes.
Una alternativa a soldar los componentes es usar una protoboard, donde los componentes no se
sueldan, sino que se "insertan". Un protoboard tiene una serie de orificios con un conexionado
interno, lo que permite montar rápidamente un circuito y también desmontarlo, así como hacer
numerosas pruebas.
La distancia entre orificios no es caprichosa. Igual que los componentes tienen unas medidas
normalizadas, especialmente en lo que se refiere a distancia entre terminales, la distancia entre
orificios también está normalizada, de modo que los componentes "entran" bien en ellos.
P á g i n a 15 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
DISTINTOS TAMAÑOS
Hay disponibles varios tamaños de protoboard, desde uno que es prácticamente una hilera, hasta
otros que son grandes tableros donde podemos hacer grandes proyectos.
Si uno de ellos no es suficiente para acomodar nuestro circuito, podemos agrupar varios de ellos
sin límite, con lo que, en teoría, podemos montar cualquier circuito, por grande que sea.
CONEXIONADO INTERNO
Es de suma importancia conocer como están dispuestos los contactos internos del protoboard no
sólo para poder hacer bien los circuitos, sino para no dañar los componentes o incluso las fuentes
de alimentación o dispositivos que conectemos.
Líneas de alimentación
P á g i n a 16 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En la imagen sobre estas líneas vemos arriba del protoboard un par de hileras de orificios.
También en la parte mas baja vemos otras dos líneas de orificios iguales.
Estas líneas se utilizan típicamente para aplicar la tensión de alimentación que puede ser continua
o alterna, o de cualquier otra naturaleza, por ejemplo, impulsos eléctricos o incluso señales
digitales. A menudo hacen falta dos líneas: Positivo y negativo si es continua, o dos polos si es
alterna.
Zona de componentes
Es la parte central del protoboard, y consta de una o más filas constituidas por cinco columnas de
pines. Estos cinco pines están unidos entre sí verticalmente, pero no horizontalmente. Si
conectamos por ejemplo, un terminal de una resistencia, a uno de estos pines, los otros cuatro
pines estarán conectados a ese terminal. Así, podemos conectar otros componentes a ese
terminal de la resistencia usando cualquier de los cuatro pines de esa columna.
Hay un caso especial: Los circuitos integrados: Deben conectarse sobre el "canal" que separa a
esos grupos de cinco filas.
P á g i n a 17 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En la sección anterior programamos el LED conectado al pin 13 de nuestro Arduino. Hoy vamos a
duplicar este circuito en el exterior montándolo desde el principio con componentes discretos. Su
esquema eléctrico sería:
Vemos a la izquierda el símbolo del LED que es emisor de luz y por eso tiene esas flechitas
salientes para indicarlo (LED viene del inglés Light Emitting Diode, o diodo emisor de luz).
La resistencia se representa por ese segundo símbolo indicando un nombre R1 y su valor 330Ω.
A su vez vemos a la izquierda las letras GND para indicar que es el negativo. Tiene muchos
nombres: Masa, El símbolo –, Tierra (aunque no es lo mismo), Ground, Negativo, cátodo.
Por último a la derecha el símbolo de +5V indica el extremo de tensión positiva o positivo y a veces
se representa como Vcc. Las líneas rectas y negras indican conexión eléctrica mediante cables
conductores.
P á g i n a 18 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
1. Un diodo, es un componente electrónico que solo permite pasar la corriente en una dirección. En la
dirección del positivo al negativo (la parte ancha del triángulo) al negativo, la punta del triángulo
(que indica la dirección).
2. Para indicar cuál de las patas de un diodo LED es el positivo, éste suele ser de mayor longitud.
Es importante entender los esquemas electrónicos porque permiten comprender con rapidez
cualquier circuito. Vale la pena dedicarle un poco de esfuerzo porque son el lenguaje de la
electrónica.
Una vez comprendido el esquema eléctrico del circuito, veamos la conexión en la Protoboard:
Este esquema sigue una pauta de marcar los cables que van a positivo en rojo y los que van a GND
en negro. Recomendamos encarecidamente se siga esta norma en la práctica porque ayuda a
identificar posibles problemas y evita errores.
3. Usamos el raíl positivo (los pines de la línea roja) para conectar a la resistencia.
4. El otro extremo de la resistencia se conecta al positivo del LED porque están en la misma
vertical de la Protoboard (y esta los conecta eléctricamente).
P á g i n a 19 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
5. Nótese que el positivo del LED está claramente marcado como de mayor longitud
mediante un pequeño ángulo cerca de la base.
6. Un diodo LED casi no presenta resistencia propia, por lo que siempre debe usarse una
resistencia adicional que limite el paso de corriente, y evite que se queme. (Una
resistencia entre 220 y 3300 Ω suele ser adecuada).
7. El circuito se cierra con un cable desde el negativo del LED al raíl de GND.
8. Cuando nuestro programa ponga un valor de HIGH (5V) en el pin 1,3 permitirá el flujo de
corriente por el circuito iluminando el LED. Con LOW sencillamente el circuito estará
apagado, sin tensión.
Podemos ahora cargar el ejemplo Blink, y veremos cómo ésta vez, además del LED propio de
Arduino, nuestro LED exterior parpadea siguiendo el mismo ciclo de encendido y apagado.
OBJETIVOS
Un operador: Negación.
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Una resistencia de 330 Ohmios.
6. Un pulsador.
7. Algunos cables de Protoboard.
ENTRADAS DIGITALES
Con frecuencia en electrónica necesitamos saber si una luz está encendida o apagada, si alguien ha
pulsado un botón o si una puerta ha quedado abierta o está cerrada.
P á g i n a 20 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
A este tipo de señales todo / nada, SI / NO, TRUE /FALSE, 0/1 se les llama digitales, y podemos
manejarlas con los pines de 0 al 13 de Arduino y por eso hablamos de pines digitales.
Muchos de los sensores y actuadores que vemos en el mundo real son digitales:
Como actuadores digitales, tenemos luces, alarmas, sirenas, desbloqueo de puertas, etc.
Hemos visto que Arduino pueden usar los pines digitales como salidas todo o nada para encender
un LED. De la misma manera podemos leer valores, todo o nada, del mundo exterior.
En esta sección veremos que los pines digitales de Arduino pueden ser usados tanto de entrada
como de salida. Vamos a leer un botón o pulsador externo y vamos a encender o apagar un LED en
función de que el botón se pulse o no.
Montaremos un circuito con un diodo LED y resistencia conectado al pin digital 10 de Arduino, tal
y como vimos en las secciones previas y además un segundo circuito con un pulsador S1
conectado al pin 6 con una resistencia como se muestra en el diagrama siguiente.
P á g i n a 21 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
1. A esta resistencia que fuerza el valor alto en vacío se le conoce como pullup Si la
conectáramos a masa para forzar una lectura a Ground se le llamaría pulldown resistor.
2. Esta resistencia es clave para que las lecturas del pulsador sean consistentes. El circuito,
simplemente, no funcionará bien si se omite (volveremos sobre esto).
En este esquema hemos seguido la práctica habitual de usar cables negros para conectar a
masa y cables rojos para conectar a tensión (5V).
Obsérvese que el pulsador S1 tiene cuatro pines (el que está sobre la resistencia horizontal).
Esto es porque cada entrada del interruptor tiene dos pines conectados. En nuestro circuito
simplemente ignoramos los pines secundarios.
P á g i n a 22 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Empecemos haciendo un programa que haga que el LED se encienda cuando pulsamos el botón y
se apague cuando lo soltamos. Para ello pediremos a Arduino que configure el pin digital 10 (D10)
como salida para manejar el LED, y el pin digital 6 (D6) como entrada para leer el botón.
Normalmente en programas sencillos basta con poner el número de pin en las instrucciones. Pero
a medida que el programa se complica esto tiende a provocar errores difíciles de detectar.
Por eso es costumbre definir variables con los números de pin que usamos, de forma que
podamos modificarlos tocando en un solo lugar (y no teniendo que buscar a lo largo del
programa). Vamos a escribir esto un poco más elegantemente:
int LED = 10 ;
int boton = 6;
void setup()
{
pinMode( LED, OUTPUT) ; // LED como salida
pinMode( boton , INPUT) ; //botón como entrada
}
Atención: C diferencia entre mayúsculas y minúsculas y por tanto LED, Led y led no son lo
mismo en absoluto. Del mismo modo, pinMode es correcto y en cambio pinmode generará
un error de compilador fulminante.
Vimos que para encender el LED bastaba usar digitalWrite(LED, HIGH). Para leer un botón se hace
algo similar: digitalRead(botón). Veamos cómo podría ser nuestro loop:
void loop()
{
int valor = digitalRead(boton); //leemos el valor de boton
digitalWrite( LED, valor) ;
}
Fácil no? Aunque el LED está encendido hasta que pulsamos el botón y se apaga al pulsar.
¿Cómo podríamos hacer lo contrario, que el LED se encienda al pulsar y se apague si no? Bastaría
con escribir en LED lo contrario de lo que leamos en el botón.
Existe un operador que hace eso exactamente el operador negación “!”. Si una valor dado x es
HIGH, entonces !x es LOW y viceversa.
P á g i n a 23 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Un operador es un símbolo que relaciona varios valores entre sí, o que modifica el valor de
una variable de un modo previsible.
Ejemplos de operadores en C son los matemáticos como +,-,*, /; y hay otros como la
negación ! o el cambio de signo de una variable : – x. Iremos viendo más.
De hecho este tipo de operaciones son tan frecuentes que C incorpora un tipo llamado bool o
booleano que solo acepta dos valores TRUE (cierto) y FALSE y son completamente equivalentes al
1 / 0, y al HIGH / LOW
CONDICIONALES Y BOTONES
OBJETIVOS
Debouncing.
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Una resistencia de 330 Ohmios.
6. Un pulsador.
7. Algunos cables de Protoboard.
P á g i n a 24 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En la sección anterior presentamos el tipo de variable bool destacando que solo puede tomar dos
valores: True o False. Aunque para quienes no estén acostumbrados al algebra booleana o binaria
puede parecer excesivo dedicar un tipo a algo tan simple, en la práctica buena parte de las
instrucciones de programación se apoyan o dependen de este tipo de variables.
La razón práctica es que con frecuencia hay que tomar decisiones para seguir un camino u otro en
función de que se cumpla una condición dada; Esta condición se debe evaluar necesariamente, a
True o False para tomar una decisión sin duda posible.
Existen otras muchas instrucciones que se apoyan en los valores booleanos, (como los
condicionales if que veremos en esta sección) pero en un modo muy explícito toda la
computación actual se basa en la lógica digital de solo dos valores que solemos llamar 1 y 0, pero
que con todo derecho podemos llamar a estos valores True y False.
Los ordenadores modernos funcionan mediante la aplicación del algebra de bool a variables
booleanas y con un juego completo de operadores lógicos como la negación, que vimos en la
sección anterior, más operadores lógicos como AND, OR, + y –.
LA INSTRUCCIÓN IF
En este capítulo vamos a presentar unas instrucciones nuevas de C, que nos permitan tomar
decisiones para hacer una cosa u otra.
La instrucción if es muy sencilla de usar, basta con pasarle entre paréntesis una variable o
condición que se evalúe a true o false. Si el resultado es true se hace el bloque que viene a
continuación y en caso contrario se ejecuta el bloque que hay detrás del else si existe.
Si no existe la cláusula del else, entonces el bloque que sigue al if, se ejecuta o no, en función de la
condición y luego sigue con la secuencia de instrucciones a continuación.
if ( condición)
{
instrucción 1 ;
instrucción 2 ;
................
}
else
{
instruccion20 ;
instruccion21 ;
..............
}
P á g i n a 25 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Leemos primero el botón a una variable bool y después decidimos si encender o apagar el LED
dependiendo de qué su valor sea True o False.
Se puede utilizar una instrucción if omitiendo la cláusula de else si se desea, pues esta es
opcional.
Vamos con un programa diferente. Queremos que el botón actúe como un interruptor, que al
pulsarlo una vez se encienda, y la próxima vez lo apague. Podríamos plantear algo así y les
recomiendo que lo prueben en su Arduino:
int LED = 10 ; int boton = 6 ;
bool estado = false ;
void setup()
{
pinMode( LED, OUTPUT) ;
pinMode( boton , INPUT_PULLUP) ;
digitalWrite(LED , LOW) ; // Apagamos el LED al empezar
}
void loop()
{
bool valor = digitalRead(boton) ; //leemos el botón
if ( valor == false ) // esto es que han pulsado el botón
{
estado = ! estado ; // cambiamos el estado
digitalWrite(LED, estado) ; // escribimos el valor
}
}
La idea es definir una variable llamada estado al principio para guardar la situación del LED. El loop
comprueba si se ha pulsado el botón, y de ser así invierte su estado, y después escribe el valor de
estado en el LED. Si estaba encendido lo apaga. Si estaba apagado se enciende.
P á g i n a 26 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Por eso, si lee un número par de veces dejara el LED como estaba y si lo lee un número impar de
veces lo invertirá. En la práctica la situación del LED se torna aleatoria, y si pulsáis repetidamente
el botón veréis que el resultado es impredecible.
Otra fuente de problemas es que en el mundo real un interruptor no cambia de un estado a otro
de forma perfecta, sino que suele rebotar y causar varios conexiones y desconexiones muy rápidas
antes de quedar en un valor estable. A esto se le llaman rebotes (bouncing) y al procedimiento
para eliminar estos rebotes se le llama debouncing en la jerga electrónica.
El debouncing se puede hacer por hardware con un conjunto de resistencia y condensador, o por
software, mucho más frecuentemente (por más barato) y para esto una solución es nuevamente
frenar a Arduino y hacerle esperar un tiempo entre 50 y 250 mili-segundos una vez que detecta
que se ha pulsado el botón, de modo que nos dé tiempo a liberar el pulsador:
void loop()
{
bool valor = digitalRead(boton) ; //leemos el botón
Muy importante: Nótese que la condición es (valor == false), con doble =. En C la comparación de
dos valores usa ==, la asignación de valor a una variable solo uno. Esto es fuente de errores
frecuentes al principio.
Este lapso de 250 ms es suficiente para pulsar y liberar el botón cómodamente. Si probáis esta
variante veréis que ahora el LED invierte su valor cada vez que pulsas, siempre y cuando no te
demores demasiado en liberar el botón.
Pues sencillamente que el LED invierte su estado cada 250 ms (milisegundos) y tenemos otra
variante del blinking LED.
Si queremos poder mantener pulsado sin que se produzca este efecto hay que sofisticar un poco
más el programa:
int LED = 10 ; int boton = 6 ;
bool estado = true ;
bool estado_anterior = true ;
void setup()
{
pinMode(boton, INPUT_PULLUP); //Hemos eliminado R3
pinMode(LED, OUTPUT);
P á g i n a 27 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void loop()
{
estado = digitalRead(boton);
if (estado != estado_anterior) //hay cambio : Han pulsado o
soltado
{
if (estado == LOW) //Al pulsar botón cambiar LED, pero
no al soltar
digitalWrite(LED, !digitalRead(LED));
estado_anterior = estado ; // Para recordar el ultimo
valor
}
}
Ya dijimos que para comprobar si dos valores son iguales usamos ==, Para comprobar si son
diferentes usamos != , y existen otros operadores relacionales
Igual que: ==
Distinto de: !=
Vale la pena comentar aquí que, a pesar de su aparente inocencia, los botones tienen una
sorprendente habilidad para complicarnos la vida, y que en la práctica la combinación de rebotes y
la necesidad de corregirlos, junto al uso de pullups que garanticen la correcta lectura, pueden
hacer que su uso se pueda complicar mucho más de lo que parece, sino se estudia el problema
con calma.
Por último, una condición lógica se puede construir mediante los operadores lógicos AND, OR, y
NOT cuyos símbolos son respectivamente: &&, || y !
Si usáramos un circuito dos pulsadores con pullups (True, si no se pulsa) y un LED, dependiendo
del comportamiento que se busque podemos especificar diferentes condiciones:
P á g i n a 28 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
La instrucción while.
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
Más antes que después, vamos a necesitar comunicar nuestro Arduino con nuestro PC. Las
razones son varias, enviarle órdenes o recibir información o señales por ejemplo.
Los PCs disponen de teclados, pantallas y adaptadores de red, pero con Arduino tenemos que usar
el puerto USB que establecerá una conexión en serie con nuestro PC.
La comunicación en serie es muy sencilla, bastan dos hilos para enviar una diferencia de tensión
entre ellos y poder marcar niveles alto (5V) y bajo (0V) y con esto podemos transmitir información
digital. Ahora solo nos falta pactar dos cosas entre quien envía y quien recibe:
El código común que vamos a usar con Arduino se llama código ASCII y es estándar en todos los
PCs. Es una forma de codificar las letras mediantes números que representas estos caracteres.
Recordad que solo podemos transmitir unos y ceros.
Así por ejemplo la letra A se representa por el número 65, la B el 66, C el 67… Prácticamente
todos los PCs actuales utilizan este código y eso incluye a Windows, Mac y Linux (y por eso
P á g i n a 29 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
podemos leer emails enviados desde distintas plataformas), pero es importante comprender que
esté es uno más entre varios códigos de caracteres posibles (EBCDIC por ejemplo).
Actualmente, en realidad, se suele usar una extensión del código ASCII (llamada Unicode) que
permita el uso de caracteres no incluidos en la tabla original, y que permita representar caracteres
como las Ñ, o acentos para el español, pero también alfabetos distintos como el Kanji chino o el
alfabeto cirílico. Y este es el motivo por el que podéis leer las letras chinas o rusas en las páginas de
internet de estos países.
El otro factor a pactar para realizar una comunicación serie es la velocidad. Dado que solo
disponemos de dos hilos para transmitir, necesitamos saber cuándo hay que leer la línea y esto se
hace estableciendo un acuerdo de velocidad. Si la velocidad de envío es distinta de la velocidad de
lectura, el mensaje final será irreconocible.
Buena parte de los errores de comunicación serie programando con Arduino se suelen deber a una
diferencia de velocidad entre el emisor y el receptor.
Esta velocidad se mide en bits por segundo y vamos a ver que Arduino soporta diferentes
velocidades de comunicación serie.
Arduino dispone de una librería serie incluida llamada Serial, que nos permite envía información al
PC y para usarla simplemente tenemos que pedirle en nuestro setup() que la incluya. La
instrucción que se encarga es:
Serial.begin( velocidad ) ;
Nótese que Serial tiene la S mayúsculas y que C diferencia entre mayúsculas y minúsculas
La velocidad es una valor entre 300 y 115.200 bits por segundo. Y suele ser costumbre establecerla
en 9600 (el valor por defecto) pero no hay ninguna razón para ello y esta no es una velocidad
especialmente alta.
Para enviar un mensaje desde Arduino a nuestro PC podemos usar las funciones Serial.print() y
Serial.println().Veamos un ejemplo:
int LED = 10 ; int boton = 6 ;
bool estado = false ;
void setup()
{
Serial.begin(9600) ; // Inicializa el Puerto a 9600 bit/seg
}
void loop()
{
int i = 54 ;
Serial.println( i );
}
P á g i n a 30 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El println() enviara el valor de i al puerto serie de Arduino (repetidamente). Para leerlo en nuestro
PC necesitamos un monitor de puerto serie. El IDE de Arduino incluye uno muy sencillo, pero
suficiente que se invoca con el botón del monitor:
Normalmente la velocidad por defecto son los 9600 bits por segundo o baudios en los que hemos
programado nuestra puerta serie, y si lo desplegáis, veréis las diferentes velocidades aceptables
para Arduino.
Estrictamente hablando, bits por segundo y baudios no son exactamente lo mismo salvo
bajo ciertas condiciones particulares que en Arduino se cumplen, por lo que aquí podemos
usarlos como sinónimos.
En el mundo Arduino parece haber un acuerdo de usar velocidades bajas como 9600 en
lugar de más altas como 115200, para evitar problemas. Esto es algo que hace años estaba
justificado por problemas de transmisión, pero con la tecnología actual no hay motivo para
ello. Es más, en cuanto necesitemos utilizar dispositivos de comunicaciones como
adaptadores Ethernet o Bluetooth para comunicarnos, la velocidad tendrá que subir
necesariamente.
Ahora que sabemos enviar información y resultados al PC, vamos a ver cómo podemos operar con
enteros y mostrar el resultado en la puerta serie. En C los operadores numéricos son los normales
en cálculo (y algunos menos frecuentes):
Adición: +
Resta: -
Multiplicación: *
División entera: / Cociente sin decimales (puesto que operamos con entero
En C tenemos que expresar las operaciones matemáticas en una sola línea y utilizar paréntesis
para garantizar que se opera como necesitamos. Vamos con algunos ejemplos:
P á g i n a 31 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Dada una expresión, la precedencia de operadores indica que operaciones se realizaran antes y
cuales después en función de su rango. Para los que se inician en C no es fácil saber que
operadores tienen preferencia, por lo que es más seguro que ante la duda uséis paréntesis.
Los paréntesis fuerzan las operaciones de una forma clara y conviene utilizarlos ante la duda
porque de otro modo, detectar los errores de operación puede volverse muy difícil especialmente
cuando uno empieza a programar.
El operador resto es más útil de lo que parece a primera vista porque nos permite saber si un
número es múltiplo de otro. Supongamos que queremos saber si un número dado es par.
En este programa hemos usado de un modo diferente el Serial.println() pasándole una String de
texto entrecomillada. Serial.print() envía el texto (entrecomillado) que le pongamos pero no da
salto de línea cuando termina. En cambio Serial.println() hace lo mismo e incluye al final ese salto
de línea.
void setup()
{
Serial.begin(9600) ; // Inicializa el Puerto serie
}
void loop()
{
Serial.print("Buenos ") ;
Serial.print("Dias ") ;
Serial.println("a todos.") ;
}
P á g i n a 32 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
C dispone de un tipo de variables llamadas Strings, capaces de contener textos. Podemos operar
con ellas simplemente definiéndolas como cualquier otro tipo de C:
void loop()
{
int resultado = 25 ;
String s = “ El resultado es: ” ;
Serial.print( s) ;
Serial.println( resultado);
}
Un tipo String se define simplemente poniendo entre comillas dobles un texto, y se puede operar
con ellas de una
void loop()
{
String a = "hola " ;
String b = "a todos." ;
Serial.println( a + b);
}
Hasta ahora solo hemos enviado mensajes desde Arduino hacia el PC, ¿Pero cómo recibimos
mensajes en Arduino?
En primer lugar disponemos de una función llamada Serial.parseInt() que nos entrega lo que se
escribe en el monitor serie convertido a entero:
void loop()
{
if (Serial.available() > 0)
{
int x = Serial.parseInt();
Serial.println ( x) ;
}
}
Este programa simplemente recibe en x los números que nos tecleen en la consola (cuando
pulsemos intro) y si es un texto, lo interpreta como cero.
P á g i n a 33 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Hemos utilizado otra función de Serial.available() que es un booleano. Conviene por costumbre
comprobar que antes de leer el puerto serie hay algo que nos han enviado. Si lo hay available() es
True y en caso contrario es False.
Para leer un String del puerto serie tenemos que complicarnos un poco más y hablar del tipo char.
Para leer una cadena desde el puerto serie necesitamos leer un carácter cada vez y después
montar un String a partir de ellos, pero antes, asegúrate de seleccionar ambos NL & CR en la parte
inferior del monitor serie, para garantizar que se envía el carácter de fin de línea:
void loop ()
{
char c = ' ' ;
String mensaje ="" ;
If (Serial.available()) //Comprobamos si hay algo esperando
{
while( c != '\n') //Si lo hay, lo leemos hasta el intro
{
mensaje = mensaje + c ; // Añadimos lo leído al mensaje
c = Serial.read(); //Leer 1 carácter
delay(25);
}
Serial.println( mensaje); //Al salir imprimir el mensaje
mensaje = "" ; //Bórralo para la próxima vez
}
}
Aquí usamos otra instrucción de C llamada while. Es similar a if, Ejecuta repetidamente el bloque
que le sigue mientras se cumpla la condición que le pasamos entre paréntesis:
while ( condición)
{ ……… }
Cuando lee el intro final de lo que escribimos, La condición c != ‘\n’ se torna falso y sale del while.
P á g i n a 34 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Por lo demás, comprobamos si hay algo disponible en la puerta serie y de ser así montamos el
mensaje leyendo un char cada vez y sumándoselo a mensaje para construir un String que podamos
imprimir al salir.
El motivo del delay (25) es que a una velocidad tan lenta, enviar un char de 8 bits por la
puerta serie, tarda mucho más de lo que tarda Arduino en ejecutar las instrucciones del
while y volver a empezar. Por eso si se suprime el delay (ylesrecomiendo la prueba) leerá un
carácter bueno (de la palabra escrita y como 10 caracteres basura para un Arduino UNO o
Mega).
OBJETIVOS
Modulación PWM
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Una resistencia de 330 Ohmios.
6. Algunos cables de Protoboard.
ANALÓGICO Y DIGITAL
Todas las señales que hemos manejado hasta ahora con nuestro Arduino , de entrada o de salida,
comparten una característica común: Son digitales, es decir que pueden tomar un valor HIGH o
LOW pero no valores intermedios.
Si representamos una el valor de una señal digital a lo largo del tiempo veríamos algo así:
P á g i n a 35 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En la vida muchas cosas son así, apruebas o suspendes, enciendes la luz o la apagas, pero muchas
otras son variables mensurables continuas y pueden tomar cualquier valor que imaginemos, como
el ángulo del reloj o la temperatura, que aun dentro de valores finitos pueden tomar tantos
valores intermedios como podamos imaginar,
A esta clase de variables las llamamos analógicas y una representación por contraposición a lo
digital, sería algo como esto:
No es raro que queramos controlar algo del mundo exterior con una señal analógica de forma que
el comportamiento del sistema siga esa señal. Podemos por ejemplo querer variar la luminosidad
de un diodo LED y no simplemente apagarlo o encenderlo
En esta sección aprenderemos a enviar señales analógicas a los pines de salida de Arduino.
Hasta ahora hemos visto como activar las salidas digitales de Arduino, para encender y apagar un
LED por ejemplo. Pero no hemos visto como modificar la intensidad del brillo de ese LED. Para ello,
tenemos que modificar la tensión de salida de nuestro Arduino, o en otras palabras tenemos que
poder presentar un valor analógico de salida.
Para empezar tenemos que dejar claro que los Arduino carecen de salidas analógicas puras que
puedan hacer esto (con la notable excepción del Arduino DUE).
Pero como los chicos de Arduino son listos, decidieron emplear un truco, para que con una salida
digital podamos conseguir que casi parezca una salida analógica.
P á g i n a 36 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
A este truco se le llama PWM, siglas de Pulse Width Modulation, o modulación de ancho de
pulsos. La idea básica es poner salidas digitales que varían de forma muy rápida de modo que el
valor eficaz de la señal de salida sea equivalente a una señal analógica de menor voltaje.
Fijaros en la anchura del pulso cuadrado de arriba. Cuanto más ancho es,
más tensión promedio hay presente entre los pines, y esto en el mundo exterior es equivalente a
un valor analógico de tensión comprendido entre 0 y 5V. Al 50% es equivalente a una señal
analógica del 50% de 5V, es decir 2,5. Si mantenemos los 5V un 75% del tiempo, será el
equivalente a una señal analógica de 75% de 5V = 3,75 V.
Para poder usar un pin digital de Arduino como salida analógica, lo declaramos en el Setup() igual
que si fuera digital:
pinMode( 9, OUTPUT) ;
analogWrite escribe en el pin de salida un valor entre 0 y 5V, dependiendo de V (que debe estar
entre 0 y 255).
De este modo si conectamos un LED a una de estas salidas PWM podemos modificar su brillo sin
más que variar el valor que escribimos en el pin.
P á g i n a 37 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Pero hay una restricción. No todos los pines digitales de Arduino aceptan poner valores PWM en la
salida.
Si intentas hacer esto con un pin diferente, Arduino acepta la orden tranquilamente, sin
error, pero para valores de 0 a 127 entiende que es LOW y para el resto pone HIGH y sigue
con su vida satisfecho con el deber cumplido.
Vamos a hacer el típico montaje de una resistencia y un diodo LED, pero asegurándonos de usar
uno de los pines digitales que pueden dar señales PWM. En la imagen he usado el pin 9.
P á g i n a 38 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
P á g i n a 39 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Aquí aprovecho para hacer el ciclo de subir y bajar el brillo del LED con un único bucle. La función
abs(num), devuelve el valor absoluto o sin signo de un número num, y por eso mientras que i viaja
de -255 a 255, abs(i) va de 255 a 0 y vuelta a subir a 255.
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED RGB
5. Una resistencia de 330 Ohmios.
6. Algunos cables de Protoboard.
Hasta ahora hemos usado varias combinaciones de LEDS, pero siempre de un color definido.
Habitualmente los rojos y amarillos son los más fáciles de conseguir, pero se pueden comprar
también en tonos azules, verdes y hasta blancos. No suele haber grandes diferencias entre ellos
excepto en el color.
Pero a veces es interesante disponer de una luz piloto que cambie de color según las condiciones.
Por ejemplo, todos identificamos el verde como una señal de OK, mientras que el rojo indica
problemas y el amarillo… bueno pues algo intermedio.
Poner varios diodos para hacer esto es engorroso y complica el diseño, así que estaría bien
disponer de un diodo al que podamos indicar que color queremos que muestre. Esto es un LED
RGB.
P á g i n a 40 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Red : Rojo
Green: Verde
Blue: Azul
Es decir RGB, uno de esos acrónimos que surgen continuamente en imagen, TV, etc.
Un LED RGB es en realidad la unión de tres LEDs de los colores básicos, en un encapsulado
común, compartiendo el Ground (cátodo es otro nombre más para el negativo).
En función de la tensión que pongamos en cada pin podemos conseguir la mezcla de color que
deseemos con relativa sencillez
Para quien haya dibujado con lápices de colores o acuarelas, las mezclas de colores de
arriba les resultará extraña. Esto es porque cuando pintamos en un papel blanco, la mezcla
de colores es substractiva: Si mezclamos los tres colores obtenemos negro, o por lo menos
algo oscuro
En cambio cuando pintamos con luz directamente, la mezcla es aditiva y obtenemos blanco
al mezclar los tres colores básicos. Las reglas de mezcla de color en ambos casos son
opuestas.
El montaje supone sencillamente conectar el negativo (el pin más largo) a Ground mediante una
resistencia que limite la intensidad, y luego identificar los pines de colores:
Al lado de GND hay dos pines a un lado y uno solitario al otro. Por lo normal el solitario es
el rojo R.
Así pues el pin out (patillaje) de un RGB LED suele ser R, GND, G, B.
P á g i n a 41 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
De todos modos conviene asegurarse leyendo las especificaciones del fabricante, o bien
identificando cada PIN. Para identificarlos basta conectar el GND a nuestro Arduino e ir probando
cada una de las patas independientemente para ver qué color producen.
Atención, en contra de la norma habitual, en este caso el cable rojo no indica la tensión Vcc, sino
el pin de gobierno del LED rojo.
En este esquema hemos utilizado los pines 9, 10 y 11. Podemos usar otros pero aseguraros de que
puedan hacer PWM para poder poner distintas intensidades.
Dado que nuestra idea es poder mezclar las tonalidades de los componentes RGB para generar
diferentes matices de colores, parece buena idea escribir una función que haga esta mezcla de
colores y a la que podamos recurrir de forma abstracta y práctica (además de para encapsular una
utilidad curiosa, a la que podremos recurrir en futuros ejemplos y de paso insistir en el concepto
de función).
P á g i n a 42 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
De este modo tendríamos fácil llamar a Color (0, 255, 0) para el verde. De hecho vamos a empezar
asegurándonos de que tenemos identificados correctamente los pines, escribiendo un sketch
como este:
void loop()
{ Color(255 ,0 ,0) ;
delay(500);
Color(0,255 ,0) ;
delay(500);
Color(0 ,0 ,255) ;
delay(500);
Color(0,0,0);
delay(1000);
}
Este programa debería producir una secuencia de rojo, verde, azul, apagado y vuelta a empezar.
Conviene asegurarse de que hemos identificado correctamente los pines del RGB, porque de lo
contrario, las mezclas posteriores de colores no serán lo que esperamos.
Vamos a ver como averiguar qué mezcla de RGB necesitamos para conseguir un color
determinado. Para quienes uséis Windows disponéis del programa Paint incluido (en el menú de
accesorios) y para quienes uséis Mac o Linux tenéis programas similares.
P á g i n a 43 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Si vas moviendo el puntero en la zona de colores de la derecha, en la barra vertical aparecen los
matices próximos al que elegiste. Debajo podéis ver la separación en RGB precisa para conseguir
un tono determinado.
Así pues para conseguir ese tono de azul de la imagen basta con que llames a
Color(13, 227, 201) ;
Dado que Arduino nos permite escribir valores de 0 a 255 en los pines digitales, cuando utilizamos
analogWrite(), en la práctica tendremos 255 x 255 x 255 colores diferentes o lo que es igual:
16.581.375 colores posibles.
La función Color() que hemos creado en esta sesión es muy sencilla pero se va añadiendo a otras
que hemos ido creando en secciones anteriores con lo que vamos haciendo una pequeña
colección de ellas.
El grupo de desarrollo de Arduino ha ido creando también muchas funciones que están disponibles
para incorporar en nuestros programas
Solo como ejemplo introduciremos una de ellas. La función random(N) devuelve un valor al azar,
comprendido entre 0 y N y en este caso, se presta especialmente bien para generar colores
aleatorios en nuestro LED RGB. Proba esto:
void setup() //Prog_11_3
{
for (int i =9 ; i<12 ; i++)
pinMode(i, OUTPUT);
}
void loop()
{
Color(random(255), random(255), random(255)) ;
P á g i n a 44 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
delay(500);
}
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Un potenciómetro de 10KΩ
6. Una resistencia de 330 Ohmios.
7. Algunos cables de Protoboard.
LOS POTENCIÓMETROS
Hasta ahora hemos usado siempre resistencias fijas, de un valor dado. Pero a veces es conveniente
disponer de una señal variable para controlar el circuito que nos interesa. Imaginad el volumen de
un equipo de música, o el dial que sintoniza una emisora en una radio FM.
Hay potenciómetros de tantos tamaños, formas y colore,s como podáis imaginar, pero al final son
una resistencia fija de un valor dado (10 kΩ en nuestro caso actual) y un mecanismo que permita
deslizar un dial conductor sobre esa resistencia, que nos permita tomar una parte de ese valor.
P á g i n a 45 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Por eso un potenciómetro siempre tiene 3 pines en fila. Los del extremo se comportan como una
resistencia del valor de fondo de escala del potenciómetro, y un pin central que va tomando
valores de resistencia en función del movimiento que hagamos con el ajuste.
Vamos a montar un circuito como este (en el que el potenciómetro esta rotulado Pot1):
La idea es conectar 5V y GND a los extremos del Potenciómetro (no importa cual es uno y otro) y
luego conectar el pin central al positivo de un LED y el negativo a GND directo, pasando por una
resistencia de limitación.
De este modo cuando giremos el potenciómetro estaremos modificando la tensión que aplicamos
a la entrada del LED, que variara entre 0 y 5V (Aunque ahora parezca extraño es muy sencillo) y
habremos conseguido un regulador de intensidad del LED.
Con una resistencia de 10k la intensidad en el circuito será de: 5V / 10.000Ω = 0,5 mA Muy
poco para conseguir iluminar el LED que requiere unos 20 mA. Así que durante la mayor
parte del giro del potenciómetro el LED estará apagado.
El montaje en la protoboard sería similar a esto ya que vamos a utilizar el Arduino simplemente
para dar tensión al circuito y nada más, Veréis que la intensidad de la luz varia de forma continúa
al girar el potenciómetro.
P á g i n a 46 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Nótese que en este caso utilizamos nuestro Arduino simplemente como fuente de
alimentación para dar tensión al circuito.
Con Arduino hemos visto que podemos influir en el mundo exterior aplicando salidas todo / nada
en los pines digitales y también que usando PWM podemos simular bastante satisfactoriamente
señales analógicas en algunos de esos pines.
También hemos visto cómo detectar pulsaciones de botones, definiendo como entradas los pines
digitales. Pero en muchas ocasiones los sensores que usamos para supervisar el mundo exterior,
nos entregan una señal analógica. Es el caso de los sensores de temperatura o distancia, de
presión o PH, de intensidad de corriente en un circuito o de caudal de agua en una tubería.
Para leer este tipo de señales continuas necesitamos un convertidor analógico a digital (o ADC por
sus siglas en ingles) y que nos permite leer el valor de una señal analógica en un momento dado.
Estos convertidores toman una muestra del valor actual de la señal y nos entregan su valor
instantáneo, medido en Voltios.
Mediante la lectura repetida de muestras a lo largo del tiempo podemos reconstruir la señal
original con mayor o menor precisión, dependiendo de la exactitud de nuestra medida y de la
velocidad a la que pueda tomar esas muestras.
P á g i n a 47 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Arduino NANO dispone de ocho convertidores analógico a digital, nominados de A0 hasta A7.
Veamos cómo usar las entradas analógicas con un circuito como este, en el que damos tensión a
los extremos de un potenciómetro y conectamos el pin central (el variable) a la entrada de la
puerta A5 de Arduino:
P á g i n a 48 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Parece buen momento para destacar que los convertidores ADC leen valores de tensión y no
resistencia, por lo tanto, lo que vamos a leer es la caída de tensión en el potenciómetro a medida
que giramos el ajuste.
La primera curiosidad es que no necesitamos declarar en el setup() que vamos a usar una puerta
analógica. Y la segunda es que para tomar una muestra (leer) del pin A5, usaremos la instrucción:
int Val = analogRead(A5) ;
Los convertidores de Arduino UNO y Mega son de 10 bits de resolución por lo que nos
devolverá valores entre 0 y 210 = 1.024 para tensiones entre 0 y 5V. En cambio el Arduino
DUE dispone de convertidores de 12 bits por lo que el valor de sus lecturas estará entre 0 y
1012 o sea 4.096, es decir tiene mejor resolución(pero sólo puede leer hasta 3,3V).
Asegúrate de no usar sensores que puedan dar más de 5V máximo (con Arduino UNO y
Mega), ya que dañarías el chip principal de Arduino.
Vamos a escribir un programa que lea el valor del pin A5 y lo envíe a la consola para que podamos
visualizarlo.
void setup()
{
Serial.begin(9600); // Iniciamos la puerta serie
}
void loop()
{
int Lectura = analogRead(A5) ;
Serial.println( Lectura);
delay(200) ;
}
Cuando lo vuelques, arranca la consola y veras que a medida que giras el ajuste las lecturas varían
de forma continua reflejando la posición del potenciómetro, las lecturas reflejan la caída en voltios
en él.
P á g i n a 49 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Les propongo esta prueba: Desconecta el potenciómetro de la puerta A5 y observa los resultados
que arduino envía a la consola. ¿Porque salen esos valores?
Al no estar el A5 conectado a ninguna referencia válida, está flotando y los valores que
captura son muestra de esa incoherencia. En realidad lo que está haciendo tu Duino es
captar ruido aleatorio de radiofrecuencia e intentar darle sentido, pero lo tiene mal, como
podes ver.
No obstante en condiciones normales los valores que leerá serán relativamente bajos.
¿Quieres que las oscilaciones crezcan en valor? Fácil. Ponle una antena. Un simple cable de
protoboard conectado desde el A5 a nada
TRANSISTORES
OBJETIVOS
Conocer el Transistor.
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Un transistor 2N2222
6. Un Motor de corriente continua.
7. Una resistencia de 330 Ohmios.
8. Algunos cables de Protoboard.
En las secciones previas hasta ahora, hemos influido en el mundo exterior poniendo una orden en
los pines digitales de Arduino. Por ejemplo poniendo HIGH en un pin y confiando en que esto sea
suficiente para controlar lo que haya detrás, que hasta ahora han sido diodos LEDs.
P á g i n a 50 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Pero la capacidad de Arduino para alimentar ese elemento externo es limitada, y con mucha
frecuencia insuficiente para excitar un actuador exterior.Por eso necesitamos elementos externos
que reciban la señal de control de nuestro Arduino y adapten este control a las necesidades del
mundo exterior.
Para ello vamos a tener que utilizar elementos como transistores, relés, servos y pequeños
motores de diferentes tipos.
Esto es suficiente para iluminar LEDs o incluso mover un pequeño servo pero es insuficiente
para mover un motorcito de corriente continua o de paso a paso.
EL TRANSISTOR
Siguiendo con las analogías, entre el flujo de corriente eléctrica y flujo de agua, resulta que con el
agua tenemos una cosa muy similar al transistor. Se llama grifo.
Si, uno de esos grifos que abrimos y cerramos para ducharnos o lavarnos las manos y que cumplen
básicamente dos funciones:
Pues básicamente un transistor es exactamente lo mismo pero construido de otro modo, con
diferentes materiales y un poco más rápido de accionar. Un transistor puede trabajar de dos
maneras:
P á g i n a 51 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Cuando un transistor funciona de la primera manera, en modo pasa o no pasa, pero sin medias
tintas, decimos que funciona al corte (no pasa) o a saturación (pasa sin restricciones). Y esto es el
fundamento de toda tecnología digital moderna: Computadoras, teléfonos, consolas, relojes
digitales. De hecho un transistor en corte es un 0 y en saturación es un 1, (o TRUE / FALSE si
preferís).
Los grifos, tiene tres partes: entrada, salida y control. Los transistores igual, pero se llaman emisor,
colector y base (E, C, B).
Si hacemos funcionar un grifo y vamos moviendo sin parar el control en ambas direcciones, el flujo
de salida de agua es proporcional al Angulo del mando en cada momento. Y si la tubería fuese lo
bastante enorme estaríamos amplificando enormemente nuestro movimiento manual.
Cuando hacemos eso con un transistor poniendo en la Base una señal eléctrica variable, el flujo de
corriente entre el Emisor y el Colector sigue la señal de la base pero amplificándola. Se pueden
conseguir ganancias enormes con este sistema y es la base de todos los amplificadores
electrónicos modernos.
Cada vez que escuchas música, hay un transistor (o varios) amplificando una señal débil para que
puedas escucharla.
La mayor parte de los componentes que conocemos en electrónica, como LEDs, transistores
y diodos son semiconductores, y muchos otros menos conocidos como tiristores y hasta
láseres de estado solido
Vamos a empezar con un transistor de uso general, que podemos encontrar con facilidad en
cualquier sitio: P2N2222. Todos los circuitos que incluyen un transistor se suelen parecer a este:
P á g i n a 52 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Un circuito así nos permite que la resistencia entre Emisor y Colector sea proporcional a la señal
de control que inyectamos en la Base. En este ejemplo un valor de 5V en la Base permite el paso
de la corriente sin restricciones. Y para tensiones que vayan decreciendo en la Base (mediante
PWM) la oposición al paso es cada vez mayor hasta que en 0V corta por completo el paso.
Vamos a alimentar nuestra carga con 5V porque no tenemos otra. Pero podríamos conectar 12V,
24V o lo que necesitásemos e ir usando motores más potentes sin preocuparnos de si Arduino
puede alimentarlo o no. De hecho se venden transistores capaces de regular corriente alterna
domestica a 220V.
Una ventaja de usar un transistor es que aísla eficazmente el circuito de control de la base de la
carga entre Emisor y Colector, haciendo casi imposible que queméis un Arduino con un circuito
como este.
No es buena idea buscar transistores raros y caros diseñados para tareas específicas.
Mientras no tengáis muy claro porque compráis un transistor caro, es mejor pegarse a los
modelos baratos de toda la vida.
P á g i n a 53 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El P2N2222 lleva muchos años en el mercado por algo. Empeza con él y ya iremos
hablando de otros.
Para saber que es cada pin, Sostene el transistor con las patas hacia abajo mirando a la cara plana,
donde esta rotulado el nombre. De izquierda a derecha son Emisor, Base y Colector.
P á g i n a 54 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Vamos a empezar por lo sencillo, simplemente, arrancando y apagando el motor sin variar la
velocidad.
const int control = 9 ;
void setup()
{
pinMode(control, OUTPUT) ;
}
void loop()
{
digitalWrite(control, HIGH);
delay(2000);
digitalWrite(control, LOW);
delay(1000);
}
Ya va siendo hora de que empecemos a coger buenas costumbres, y por eso en la primera línea
definimos una constante de tipo entero llamada control, que usaremos en lugar el 9, cuando
queramos referirnos al pin de control.
A medida que el tamaño de los programas crecen, un error en un numero de pin puede ser muy
difícil de detectar, pero en cambio dándole un nombre, no solo ayuda a que sea más fácil de leer,
sino que además, si por cualquier motivo queremos cambiar el pin de control, basta con cambiarlo
en un único sitio sin necesidad de recorrer el programa buscando un número concreto.
P á g i n a 55 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void loop()
{
for ( int n = 0 ; n < 255 ; n++)
{
analogWrite (control, n) ;
delay(15) ;
}
}
Donde escucharemos como va aumentando la velocidad del motor hasta pararse y volver a
empezar. La razón es que al variar la tensión en la base del transistor, este limita la corriente que
lo atraviesa modificando así la velocidad del motor al que está conectado.
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Un transistor 2N2222
6. Un pequeño Relé.
7. Una resistencia de 330 Ohmios.
8. Algunos cables de Protoboard.
Un relé es un interruptor que podemos activar mediante una señal eléctrica. En su versión más
simple es un pequeño electro-imán que cuando lo excitamos mueve la posición de un contacto
eléctrico de conectado a desconectado o viceversa.
P á g i n a 56 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El símbolo del relé muestra la bobina y en este caso, un accionador que conmuta entre dos
contactos, pero también existen relés de múltiples contactos. Mediante una señal de control de
poca intensidad que excite la bobina podemos conmutar grandes tensiones o intensidades.
Hemos visto cómo usar un transistor para hacer lo mismo, ¿Porque entonces usar relés?
En primer lugar, los relés llevan entre nosotros desde finales del siglo 19 (y nadie ha sido
todavía capaz de convertirlos en obsoletos), es una tecnología muy probada y bien
establecida en la industria y además sirve para cosas que son problemáticas para los
transistores.
Hay límites en la corriente que un transistor puede aceptar, pero un relé se puede diseñar
para que aguante cualquier carga, porque basta con los extremos metálicos de los
contactos lo soporten.
Aísla completamente el circuito de control del de potencia, lo que tiene su importancia
especialmente en líneas de media y alta tensión.
En la práctica, con Arduino es más sencillo utilizar un relé para encender una luz fluorescente o la
calefacción, que buscar un transistor de características adecuadas.
Aunque hay relés que necesitan muy poca potencia para excitar la bobina, por regla general
Arduino se quedará corto y vamos a tener que usar un transistor que nos resuelva el problema.
El ejemplo que veremos a continuación incluye un circuito de transistor / relé completo que nos
permitirá atacar cualquier proyecto casero que nos propongamos.
P á g i n a 57 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Para probar que todo está correctamente conectado, bastaría con correr el mismo programa que
para el motor:
P á g i n a 58 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void setup()
{
pinMode(control, OUTPUT) ;
}
void loop()
{
digitalWrite(control, HIGH);
delay(1000);
digitalWrite(control, LOW);
delay(1000);
}
Este programa causará que el relé conmute cada segundo y los LEDs se encenderán
alternativamente.
Para convertir este circuito en unas luces de emergencia bastaría con poner una batería o pilas en el
común del relé en lugar de los 5V de Arduino. De ese modo al desconectar Arduino la luz de
emergencia se activaría sola.
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un diodo LED
5. Un Sensor de temperatura TMP36.
6. Una resistencia de 330 Ohmios.
7. Algunos cables de Protoboard.
P á g i n a 59 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Vamos a ver como los usamos. Lo primero, tenéis que buscar la hoja de especificaciones del
fabricante busca (TMP36 datasheet) Aunque al principio no es fácil acostumbrarse a leer este tipo
de documentación (y que encima vienen en inglés), en último término es a donde hay que ir
cuando queráis saber exactamente las características de su funcionamiento.
El pin central es el de señal, pero para saber cuál es GND y 5V, el encapsulado tiene una cara plana
y otra curva. Poniendo la cara plana mirando hacia vosotros con las patas hacia abajo, el pin de la
izquierda es alimentación 5V y naturalmente el otro es GND.
Si veis que está caliente no tratéis de sacarlo con los dedos, simplemente desconectad el
Arduino y dadle un rato para que se enfríe.
P á g i n a 60 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Vamos a montar un pequeño circuito que lea la temperatura de un sensor, imprima el valor en la
consola y encienda un diodo cuando esta sobrepase un cierto umbral. Aquí tenemos el esquema
electrónico:
P á g i n a 61 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
CALCULANDO LA TEMPERATURA
El fabricante del TMP36 nos dice que la salida de tensión será de 10 mV (mili voltios) por cada
grado de temperatura y además sabemos que nuestro Arduino mide en las puertas analógicas una
máximo de 1.024 para 5V y 0 para 0V, por lo tanto, para una lectura dada, el valor en voltios de la
medida será:
Y como cada voltio equivale a 100ºC (1V / 10mv = 100), la temperatura en grados Celsius es
resultado de multiplicar esto por 100.
Pero para que la cosa no sea tan fácil el fabricante nos dice que el 0V no es 0º sino -50º (y así
poder leer valores bajo cero), así que al total hay que restarle 50.
Así pues, ya tenemos claro como calcular la temperatura, pero como vemos por ahí que tenemos
divisiones, nos conviene utilizar nuestra primera variable de tipo float, o sea que va a tener
decimales.
Ya sé que la tendencia natural es usar int para todo, pero normalmente en cuanto haya una división
de por medio conviene usar un float hasta que tengas muy claro porque usas otro tipo.
Cada vez que tomemos una muestra de nuestra entrada analógica vamos a calcular la temperatura
y si sobrepasa el umbral definido, damos orden de activar la alarma, en caso contrario la
apagamos.
Como la temperatura es algo que varía lentamente usaremos un delay para que solo nos dé una
medida por segundo.
EL PROGRAMA DE CONTROL
P á g i n a 62 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Sensor es el pin analógico (A0) al que conectamos el sensor de temperatura y umbral el valor a
partir del cual disparamos la alarma de temperatura.
El valor de umbral habrá que ajustarlo en función de la temperatura ambiente donde estéis
montando el circuito.
En principio 25ºC son buenos para que si queréis subir la temperatura, lo podáis hacer
simplemente soplando o manteniendo entre los dedos el sensor. Otro sistema de subir la
temperatura rápido, es poner el sensor al lado de la salida de refrigeración de un portátil.
Y pasando los cálculos de la página anterior a C++ nos quedaría algo parecido a:
void loop ()
{
int lectura = analogRead(Sensor);
float voltaje = 5.0 /1024 * lectura ; // Atencion aqui
float temp = voltaje * 100 -50 ;
Serial.println(temp) ;
delay(1000);
}
Importante: En la línea donde calculamos el voltaje hemos escrito 5.0 y no 5. Esto es para evitar
que C++ (que es un poco vago) intente hacer una división entre enteros y nos desprecie los
decimales.
Pues sencillamente porque la parte entera de 5/1024 es 0 y punto. Así que por mucho que
después multipliquemos por lectura seguirá siendo 0. Y nuestro programa dice que para
0V la temperatura es -50ºC.
Hasta que comprendáis como entiende C++ las operaciones andad con piés de plomo y
comprobadlas sino queréis sorpresas. Una parte de esta sesión es provocar este tipo de
situaciones con las variables float.
Ya solo nos resta comprobar si la temperatura alcanza el umbral y encender el LED o apagarlo.
int Sensor = 0 ; // Prog_15_1
int umbral = 25 ;
void setup()
{
Serial.begin(9600);
pinMode(13,OUTPUT);
}
void loop()
{
int lectura = analogRead(Sensor);
float voltaje = 5.0 /1024 * lectura ; // Atencion aqui
float temp = voltaje * 100 -50 ;
Serial.println(temp) ;
if (temp >= umbral)
P á g i n a 63 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
digitalWrite(11, HIGH) ;
else
digitalWrite(LOW);
delay(1000);
}
Si disponéis de un pequeño ventilador de 5V, de los que suelen tener en las tiendas de
informática, sería fácil cambiar el LED por ese ventilador y orientarlo hacia el sensor.
Fijando un umbral superior y otro inferior podemos escribir un programa que arranque o pare el
ventilador cuando la temperatura se sale de los márgenes fijados. Habríais conseguido, de un
modo muy sencillo, una regulación de temperatura con un sensor y un ventilador.
OBJETIVOS
Que es un servo.
La función map().
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un potenciómetro
5. Un Servo
6. Algunos cables de Protoboard.
QUE ES UN SERVO
Normalmente los motores habituales lo que hacen es transformar la energía eléctrica (o química)
en un giro continuo que podemos usar para desarrollar trabajo mecánico.
Los servos son también motores de corriente continua, pero en lugar de diseñarse para obtener
un giro continúo que podamos aprovechar (para mover una rueda por ejemplo), se diseñan para
P á g i n a 64 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
que se muevan un ángulo fijo en respuesta a una señal de control, y se mantengan fijos en esa
posición.
Imaginen por ejemplo un timón de un avión o barco. No queremos un giro continuo, sino un
motor al que le pueda indicar el ángulo que deseamos en grados y que mantenga esa orientación
hasta que le demos una orden en contrario.
Estos servos o servomotores son muy frecuentes en Aero modelismo y en robótica, por la
capacidad que presentan para moverse a un ángulo concreto y mantenerse allí. De hecho se
suelen diseñar para que giren un ángulo proporcional a una señal PWM, de forma que su control
es muy preciso.
Una reductora.
Un motor de CC.
Un circuito de control
Habitualmente los servos tiene un margen de operación, es decir, pueden moverse entre 0º y
ángulo dado, que suele ser de 180º, pero existen modelos comerciales de todas la características
imaginables (incluyendo servos de 360º).
Normalmente estos pequeños servos funcionan sobre 5V y el control se realiza mediante una
señal de control PWM, en la que el ancho el pulso indica el ángulo que deseamos adopte el eje.
Podríamos escribir un pequeño programa en Arduino que controle estos pulsos y los relacione con
el ángulo buscado, pero antes de que nadie se asuste, los servos (y otras cosas) son tan habituales,
que ya ha habido gente que han escrito estos programas y los han puesto a nuestra disposición.
De este modo podemos manejar un servo sin preocuparnos para nada de cómo realizar el control
de las señales, o de la operación interna, basta con instalar estos programas en una forma especial
llamada librería.
Una librería es un conjunto de definiciones y funciones escritas en C++ de Arduino, que podemos
utilizar en nuestros programas. Podemos ver el código de estos programas, aunque normalmente se
requiere un nivel medio alto en C++ para comprender su funcionamiento.
La ventaja de trabajar con una plataforma tan bien establecida como Arduino, es que hay cantidad
de gente en el mundo desarrollando librerías, casi para cualquier cosa que podáis imaginar.
P á g i n a 65 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Servo es una librería estándar en Arduino. Eso quiere decir que viene incluida cuando instaláis el
IDE, a diferencia de otras librerías que debemos buscar, descargar de Internet e instalar para
poder usarlas.
Para usar una librería estándar, basta con pedirle al IDE que la incluya en nuestro programa. Id al
menú Programa \ Importar Librería y les saldrá un desplegable con todas las librerías que tenéis
instaladas en el IDE.
Por ahora solo nos interesa la librería Servo. Pinchad en ella. Arduino incluirá una línea al principio
de su programa como esta:
#include <Servo.h>
Normalmente para usar una librería hay que leer la documentación, en la que se detalla la
forma de usarla, que funciones tenemos disponibles, que parámetros pasarlas…etc.
Como es vuestra primera librería, y nosotros ya nos hemos leído el manual, vamos a
llevaros de la mano. Veréis que es de lo más fácil.
Vamos a montar un circuito en el que hagamos moverse al servo de forma controlada, e iremos
viendo las instrucciones necesarias.
P á g i n a 66 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Vamos a conectar el servo primero a GND y 5V y luego el pin de control, a un pin de Arduino que
permita PWM (Recordad esto o de lo contrario les costara ver el problema). Recordad que es el
ancho el pulso lo que controla el ángulo.
P á g i n a 67 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
EL PROGRAMA DE CONTROL
Vamos a empezar con una línea que ya conocíamos el include y otra nueva:
#include <Servo.h>
Servo servo1;
Para poder utilizar la librería debemos crear, lo que se conoce como un objeto tipo Servo que
llamamos servo1.
C++ es un lenguaje orientado a objetos, esto significa que podemos definir objetos tipo (como
servos) sin más que declarar un nuevo objeto del tipo que deseamos. En la jerga de la
programación se llama crear una instancia, o instanciar un nuevo objeto.
Así, esa segunda línea significa que vamos a crear una nueva instancia de tipo Servo que llamamos
servo1.
Aunque ahora les pueda parecer una forma extraña de hacer las cosas, la programación
orientada a objetos (OOP por sus siglas en inglés), es una de las metodologías más
potentes de las ciencias de computación actuales y todos los lenguajes de programación
que se precien, han incorporado las ideas de la OOP.
Entrar en la teoría del OOP, desborda con mucho las pretensiones de este humilde tutorial
de Arduino, por ahora nos limitaremos a mostraros como usar los objetos.
Una vez creada la instancia del objeto (y podemos crear tantas como necesitemos, para manejar
varios servos a la vez) tenemos que incluir una línea en la función setup() para informar a C++ que
vamos a conectar ese objeto abstracto que todavía es servo1 a un pin físico del Arduino para
controlarlo. En nuestro caso el pin 9:
servo1.attach(9);
Una vez cumplido el trámite para gobernar la posición del servo recurrimos a
servo1.write(angulo);
Vamos a escribir un programa que vaya barriendo un Angulo en grados y moviendo el servo a esa
posición.
#include <Servo.h> // Incluir la librería Servo
Servo servo1; // Crear un objeto tipo Servo llamado
servo1
int angulo = 0 ;
Void setup()
{
servo1.attach(9) ; // Conectar servo1 al pin 9
}
void loop()
{
P á g i n a 68 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Veréis como el servo se va moviendo primero hacia adelante y luego retrocede para volver a
empezar.
Vamos ahora a hacer que el valor del potenciómetro represente la posición del servo de manera
que el servo se mueva siguiendo al potenciómetro. Para ello hay que entender que el valor que
leamos en la puerta A0 está comprendido entre 0 y 1024, y que estos valores tienen que
distribuirse entre 0 y 180º. Así que para calcular el Angulo correspondiente basta con hacer:
Como la experiencia me ha demostrado, que los errores haciendo este tipo proporciones
tienden a infinito, voy a aprovechar para presentaros la función map(), que hace exactamente
eso de un modo cómodo, librándonos de los float (aunque para aprender no les vendría mal
hacer así el programa y luego usar el map()).
angulo = map( analogRead(A0), 0, 1024, 0, 180);
Traducido quiere decir: Haz la proporción de los valores que leas en A0, entre 0 y 1024, en un valor
comprendido entre 0 y 180 y asígnale ese valor al ángulo.
#include <Servo.h> // Incluir la librería Servo
Servo servo1; // Crear un objeto tipo Servo llamado servo1
int angulo = 0 ;
void setup()
{
servo1.attach(9) ; // Conectar servo1 al pin 9
}
void loop()
{
angulo = map( analogRead(A0), 0, 1024, 0, 180);
servo1.write(angulo);
delay(250);
}
P á g i n a 69 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
Leyendo el joystick.
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Un Joystick
5. Un Servo
6. Algunos cables de Protoboard.
QUE ES UN JOYSTICK
Un joystick suele estar formado por dos potenciómetros a 90º que transforman el movimiento en
X e Y del mando en una señal eléctrica proporcional a su posición y que además suele incluir un
botón.
En realidad ya usamos todos estos componentes previamente y la única curiosidad del joystick es
que resulta un elemento muy cómodo para posicionar algo, aunque no sea demasiado preciso.
Vamos a montar un circuito con un servo como en la sesión previa y usaremos uno de los ejes del
joystick para posicionar un servo, y si pulsamos el botón encendemos un LED. (Ignoraremos el otro
eje Y, aunque podríamos usarlo para posicionar un segundo servo).
P á g i n a 70 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Y para la protoboard:
P á g i n a 71 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
EL PROGRAMA DE CONTROL
void setup()
{
servo1.attach(9) ; // Conectar servo1 al pin 9
pinMode( boton, INPUT_PULLUP) ;
}
void loop()
{
angulo = map( analogRead(A1), 0, 1024, 0, 180);
servo1.write(angulo);
if ( ! digitalRead(boton))
digitalWrite(LED, HIGH);
else
digitalWrite(LED, LOW);
delay(250) ;
}
El pulsador está conectado al pin digital 4 y el LED al 12, de forma que si queremos cambiar de
pines, por la razón que sea, bastara con actualizar esta lista al principio del programa.
Insistir en que hemos definido la entrada correspondiente al boto del joystick como
INPUT_PULLUP y no como INPUT, porque de este modo no necesitamos incluir una resistencia,
sino que Arduino conecta un pullup internamente
Por eso leeremos LOW al pulsarlo y entre tanto será HIGH, por ese motivo invertimos la condición
en el if. Encenderemos el botón solo cuando pulsemos.
En el mundo real, las cosas no son nunca blancas o negras, sino más bien en tonos grises, por eso
no es buena idea enviar las lecturas directamente al control el servo, o de lo que sea que estamos
moviendo.
Hay que filtrar un poco la señal. Sin entrar mucho en este tema (sobre el que hay enciclopedias),
vamos a usar una técnica muy básica, pero muy eficaz en muchas ocasiones y que les conviene
conocer.
Vamos a leer el potenciómetro para decidir si subimos o bajamos el valor del Angulo. No para
calcular Angulo directamente.
P á g i n a 72 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Como el potenciómetro nos da valores entre 0 y 10000, cuando está centrado o suelto, leerá sobre
500, poco más o menos (aunque bailará). Así que le vamos a dar un margen de tolerancia. Solo
aumentaremos el Angulo, un valor dado, si la lectura del potenciómetro sobrepasa el valor de 600
y lo disminuiremos cuando baje de 400.
De este modo pequeñas oscilaciones alrededor del punto medio, no nos afectarán. Es decir las
hemos filtrado. Esto reflejado en el programa, podría ser algo así
void setup()
{
servo1.attach(9) ; // Conectar servo1 al pin 9
pinMode( boton, INPUT_PULLUP) ;
}
void loop()
{
int p = analogRead(A1);
if ( p < 400 ) // Si la lectura es menor de 400
angulo = angulo - salto ; // disminuimos el angulo
else if (p>600) // Si mayor de 600
angulo = angulo + salto ; // Aumentamos el angulo
servo1.write(angulo); // Y este es el que mueve el servo
delay (50); // Este delay regula la velocidad del movimiento
}
OBJETIVOS
P á g i n a 73 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Sensor de distancia HC-SR04
5. Un LED y una resistencia
6. Algunos cables de Protoboard.
Hemos visto, en los documentales, que los murciélagos son capaces de volar en completa
oscuridad y sin embargo, sortear obstáculos o atrapar insectos en vuelo. Sabemos que lo hacen,
pero rara vez pensamos como.
Tenemos una vaga idea de que se llama eco localización y que más o menos tiene que ver con
unos sonidos agudos que emiten y que después recogen con esas enormes con sus orejas
Delfines y ballenas utilizan un sistema similar para atrapar a sus presas, y hasta hemos visto que,
en cualquier película de submarinos, en el momento álgido el capitán ordena emitir un pulso único
de sonar para localizar al enemigo.
El concepto básico, es siempre el mismo, sabiendo a qué velocidad viaja el sonido, si emitimos un
pulso sónico corto y escuchamos cuanto tiempo tarda en regresar el eco podemos calcular la
distancia a la que se encuentra el objeto en el que ha rebotado la señal.
El radar funciona de modo similar aunque usando ondas de radio frecuencia muy cortas y con una
problemática propia descomunal. Un pulso de radiofrecuencia se emite desde la antena y se recoge
el eco que vuelve a la velocidad de la luz.
Lo que haremos en esta sesión es utilizar un sensor de distancia sencillo HC-SR04 (y muy parecido
a los sensores de aparcamiento de los coches modernos), que nos permite enviar estos pulsos
ultrasónicos y escuchar el eco de retorno. Midiendo este tiempo, podemos calcular la distancia
hasta el obstáculo.
El oído humano no percibe sonidos por encima de 20kHz. Por eso, a las ondas de mayor
frecuencia las llamamos ultrasonidos (más allá del sonido). Los sensores de ultrasonidos
funcionan sobre los 40 kHz.
No son perfectos, les influye la temperatura ambiente, la humedad y los materiales en los
que reflejan, lo que genera una cierta incertidumbre. Pero a cambio son baratos y efectivos
hasta un poco más de 3 metros en condiciones normales si la precisión no es un problema
determinante
P á g i n a 74 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
DIAGRAMA DE CONEXIÓN
Veamos como conectar uno de esto detectores a nuestros Duinos. Aquí está el esquema eléctrico
y de protoboard por cortesía de Fritzing:
P á g i n a 75 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
EL PROGRAMA DE CONTROL
Hasta ahora habíamos visto que podíamos definir una variable como int, por ejemplo, y también
como una constante (const int pin). Aquí utilizamos otro método, el #define que es una directiva
para el compilador.
Esto solo significa que el compilador (en rigor el pre procesador) cambiará todas las ocurrencias de
estos #define en nuestro programa por su valor antes de compilar. Esta es la forma clásica de C de
hacer esto y tiene la virtud de que no ocupa memoria definiendo una variable (y con un Arduino
UNO, que va muy corto de memoria, esto puede ser crítico en ocasiones).
void setup()
{
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT);
}
Ya estamos más que habituados a la función delay(milis), pero el reloj interno de Arduino mide en
microsegundos y tenemos otra función parecida delayMicroseconds(µs) que simplemente congela
Arduino el número especificado de microsegundos.
Para dar un pulso ultrasónico lo que hacemos es activar el pin Trigger durante unos
microsegundos y para ello lo ponemos en HIGH, antes de escuchar el eco:
digitalWrite(trigPin, LOW); // Nos aseguramos de que el trigger está
desactivado
delayMicroseconds(2); // Para estar seguros de que el trigger ya
está LOW
digitalWrite(trigPin, HIGH); // Activamos el pulso de salida
delayMicroseconds(10); // Esperamos 10µs. El pulso sigue active
este tiempo
digitalWrite(trigPin, LOW); // Cortamos el pulso y a esperar el echo
Para escuchar el pulso vamos a usar otra función, pulseIn(). Para leer el manual de
pulseIn() buscar en google Arduino pulseIn y vereis que pronto lo encontrais.
Básicamente lo que hace es escuchar el pin que le pasamos, buscando una señal que pase de LOW
a HIGH (si le pasamos HIGH como parámetro) y cuenta el tiempo que tarda en volver a bajar desde
que sube.
long duracion, distancia ;
duracion = pulseIn(echoPin, HIGH) ;
Ahora ya sabemos el tiempo que tarda en volver el eco en µs. Como la velocidad del sonido es de
343 metros / segundo, Necesitamos 1/343 = 0,00291 segundos para recorrer un metro.
P á g i n a 76 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Para usar una medida más cómoda podemos pasar esto a microsegundos por centímetro:
Como nuestro eco mide el tiempo que tarda el pulso en ir y venir la distancia recorrida será la
mitad:
void setup()
{ Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT);
}
void loop()
{ long duracion, distancia ;
digitalWrite(trigPin, LOW); // Nos aseguramos de que el
trigger está desactivado
delayMicroseconds(2); // Para asegurarnos de que
el trigger esta LOW
digitalWrite(trigPin, HIGH); // Activamos el pulso de
salida
delayMicroseconds(10); // Esperamos 10µs. El pulso
sigue active este tiempo
digitalWrite(trigPin, LOW); // Cortamos el pulso y a
esperar el echo
duracion = pulseIn(echoPin, HIGH) ;
distancia = duracion / 2 / 29.1 ;
Serial.println(String(distancia) + " cm.") ;
Int Limite = 200 ; // Medida en vacío del
sensor
if ( distancia < Limite)
digitalWrite ( led , HIGH) ;
else
digitalWrite( led , LOW) ;
delay (500) : // Para limitar el número de
mediciones
}
Para convertir esto en un detector de movimiento hemos creado una variable un poco menor de
la medida que el sensor recibe en vacio (en mi caso unos 200 cm). Si la distancia medida cae por
P á g i n a 77 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
debajo este valor es que algo se ha interpuesto y por tanto encendemos una alarma, en nuestro
caso un humilde LED.
Después de este ejercicio de física y matemáticas, que sin duda causará furor entre los estudiantes
aplicados, vamos a hacer el mismo programa pero usando una librería externa, que alguien se ha
molestado en escribir, paras esas pocas personas que no disfrutan de los problemas de ciencias y
que así, podamos ver la diferencia.
http://code.google.com/p/arduino-new-ping
Para instalar una librería externa no incluida en el IDE de Arduino tenemos que importarla con el
menú Programa \ Importar librería\Añadir librería:
En la ventana que sale, buscar el fichero NewPing_v1.5.zip que habéis descargado y seleccionadlo.
Ya está. Arduino ha importado la librería y los ejemplos que incluye. Si ahora volvéis a
Programa\ImportarLibrería, veréis que al final de la lista ya está disponible como NewPing, y
además el zip incluye varios ejemplos de uso. Vamos a cargar el equivalente del programa
anterior. Haced:
Arduino cargara un programa de ejemplo. Las instrucciones claves son primero inicializar la librería
con:
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE) ;
P á g i n a 78 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void setup()
{
Serial.begin(115200); // Open serial monitor at 115200 baud to
see ping results.
}
void loop()
{
delay(50);
unsigned int uS = sonar.ping(); // Send ping, get ping time in
microseconds (uS)
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM);
Serial.println("cm");
}
Como veis la librería se encarga de inicializar los pines necesarios, enviar los pulsos, escuchar el
eco de retorno y de hacer los cálculos. No está mal.
Fijaros, que el ejemplo, utiliza diferentes pines a los que nosotros hemos usado, así que
tendréis que modificarlos. Igualmente, el ejemplo inicializa la puerta serie a 115.200. Es
imprescindible igualar esta velocidad con la que recibe la consola o veréis muchas cosas
raras en pantalla.
Los alumnos avispados se habrán dado cuenta de que Arduino viene forrado de ejemplos
que pueden cargar y usar. les invito a que investiguéis y juguéis con estos ejemplos cuanto
queráis.
BUZZERS O ZUMBADORES
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
P á g i n a 79 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
4. Un buzzer piezoeléctrico.
5. Algunos cables de Protoboard.
PIEZOELECTRICIDAD
Este fenómeno también ocurre a la inversa: se deforman bajo la acción de fuerzas internas al ser
sometidos a un campo eléctrico. El efecto piezoeléctrico es normalmente reversible: al dejar de
someter los cristales a un voltaje exterior o campo eléctrico, recuperan su forma.
Es decir, que son materiales (el cuarzo es el más conocido) que si los sometemos a una tensión
eléctrica variable (como una señal PWM, que ya nos son familiares) vibran.
En otro orden de cosas, los circuitos electrónicos digitales, suelen disponer de un reloj
interno que vibra a una velocidad patrón, basados en cristales de cuarzo piezoeléctrico.
Si conectamos un piezo con una señal digital, vibran a una frecuencia sigue bastante fielmente la
variación eléctrica con que los excita, y si vibran a la frecuencia audible, oiremos el sonido que
producen. A un componente que hace esto, le llamamos Buzzer o zumbador.
Naturalmente, la calidad del sonido que producen dista bastante de lo que podríamos denominar
alta fidelidad. Pero es suficiente para generar tonos audibles (como la típica alarma de los
despertadores digitales) e incluso tonos musicales reconocibles que podemos secuenciar, hasta
en piezas musicales (por más que uno quisiera estar en otro lugar cuando las oyes).
Como antes o después, disponer de una señal acústica en sus proyectos, acaba siendo útil, vamos
a ver cómo podemos montar estos elementos, y que tipo de opciones tenemos disponibles.
P á g i n a 80 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
ESQUEMA ELECTRÓNICO
La conexión es tan simple como conectar negativo a GND y positivo al pin 9. De todas maneras hay
que tener cuidado. Los piezos tienen polaridad y hay que asegurarse de conectarlos
correctamente.
Además para este primer montaje, necesitamos usar un pin PWM (como el 9) porque es la
alternancia entre HIGH y LOW lo que produce el efecto piezoeléctrico (recordad que una
señal PWM envía un tren de ondas cuadradas de amplitud variable), por lo que lo más
cómodo es usar un pin PWM en lugar de programar un efecto equivalente en un pin
normal.
EL PROGRAMA
Vamos a empezar creando una función, Beep(), que haga ruido simplemente:
void beep(unsigned char pausa)
{
analogWrite(9, 20);
delay(pausa); // Espera
analogWrite(9, 0); // Apaga
delay(pausa); // Espera
}
Y ahora prueba
void setup()
{
pinMode(9, OUTPUT);
beep(50);
beep(50);
beep(50);
delay(1000);
}
void loop()
{ beep(200);
}
P á g i n a 81 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Lo único que beep() hace es poner una señal PWM en el pin 9 de 20 sobre 255. Podéis varias el
valor, pero el tono de audio no cambiará gran cosa porque está controlado por la señal de base.
Esto es suficiente para generar una de las molestas señales acústicas de un despertador barato.
¿Qué pasa si quiero generar señales de tono variable para hacer una melodía? Bueno pues
Arduino dispone de la función tone() que genera una señal de la frecuencia indicada, y notone()
que la corta:
void setup()
{
int pinOut = 8;
int freq = 440;
int duration = 1000;
tone(pinOut, freq, duration);
}
Podemos definir una matriz con las frecuencias de las notas a utilizar y lee las correspondencias
con las notas musicales. Veamos cómo generar una escala con un zumbador:
int speakerPin = 9;
void setup()
{ }
void loop()
{
for (int i = 0; i < numTones; i++)
{
tone(speakerPin, tones[i]);
delay(500);
}
noTone(speakerPin);
}
OBJETIVOS
P á g i n a 82 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Una resistencia 330 Ω
5. Un buzzer piezoeléctrico.
6. Algunos cables de Protoboard.
LOS FOTOSENSORES
Se les suele utilizar como sensores de luz, para arrancar luces automáticamente cuando la
oscuridad sobrepasa un cierto umbral, o como detectores de movimiento próximo (Cuando algo
se interpone).
Vamos a utilizar en esta sesión un típico LDR, que es bastante fácil de conseguir y es sensible a los
cambios de luz ambiente. Montaremos un circuito con un LDR y el zumbador que vimos en la
última sesión, para construir un theremin rudimentario, que espero que os haga pasar un rato
entretenido.
El circuito utiliza un LDR como señal de control y calcularemos una frecuencia en función de la
caída de tensión que leamos en nuestra fotorresistencia.
Recordad que los convertidores ADC como los de Arduino no pueden leer resistencia sino
tensión.
Los LDR no son precisamente rápidos en reaccionar a la luz, y puedan tardar hasta algunas
décimas de segundo en reaccionar. Esto no es importante para una alarma de luz, pero
hace imposible que se puedan utilizar para enviar información mediante la luz.
Pero antes de entrar en materia necesitamos hacer un inciso para conocer lo que es un divisor de
tensión.
DIVISORES DE TENSIÓN
P á g i n a 83 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
V=R*I
EN SERIE EN PARALELO
Cuando ponemos las dos resistencias en serie, la resistencia resultante es la suma de ambas:
P á g i n a 84 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Si todavía queda alguien despierto, se habrá dado cuenta que si R1 y R2 son iguales V out será
exactamente la mitad de Vin pero si R1 o R2, fuese un potenciómetro (o un LDR) cualquier
variación en el ajuste, causaría una modificación en el valor de salida de tensión V out.
Esto es lo que se conoce como un divisor de tensión y es un circuito de lo más práctico para
rebajar una señal de entrada, y podéis apostar a que lo usaras más de una vez.
Por ejemplo, los convertidores analógicos de Arduino aceptan un máximo de 5V, pero muchas
señales industriales son de entre 0 y 12V.Si lo conectas sin más al A0, por ejemplo, freirás el chip
de largo.
Pero con el truco del divisor de tensión y calculando adecuadamente las resistencias puedes
adaptarlo tranquilamente para que tu Arduino viva feliz con una señal que originalmente le
hubiera chamuscado.
Los divisores de tensión son un circuito muy sencillo y que conviene que sea parte de nuestro
arsenal electrónico. Resuelven cantidad de problemas con una resistencia y un potenciómetro y
son ideales para tratar señales, que por exceso de tensión, quedarían fuera del alcance de tu
Arduino.
De hecho en esta práctica vamos a montar un divisor de tensión con una resistencia y un LDR y
leeremos la caída de tensión en él. Nos va a servir como ejemplo de los divisores de tensión y
además nos servirá como señal de control para calcular la frecuencia a la que haremos vibrar el
buzzer.
P á g i n a 85 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Fíjate que el LDR R1, junto con R2 forma un divisor de tensión. La lectura de A0 dependerá
de la luz que incida en el LDR. El esquema de protoboard es igual de fácil:
El programa es muy sencillo. Leemos la caída de tensión en A0 y lo usamos para mapear una
frecuencia entre 20 y 5.000 Hz para llamar a la función tone() y eso es todo.
Para probar el circuito les recomiendo que pongan un foco potente a 50 cm por encima del
LDR y prueben a mover la mano por delante y especialmente de arriba abajo y viceversa.
P á g i n a 86 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Escucharan un tono continuo más o menos agudo, que ira variando su frecuencia en
función de la luz que incida en el LDR.
Se acepta que el oído humano se mueve ente 20 Hz y 20Khz (aunque esto es para algún
adolescente de oído muy fino) para los que peinan canas entre 40Hz y 10Khz ya es un rango
optimista. Por eso, mapeamos los valores del potenciómetro, que van de 0 a 1024, entre 20
y 5Khz, pero os recomiendo que cambiéis estos valores y veáis lo que pasa.
El sonido que obtenemos es de espectro continuo, es decir, que reproduce frecuencias continuas
en el margen que es capaz. Pero nuestro oído está acostumbrado a escuchar las notas en tonos y
semitonos de frecuencia dada, como veíamos en el programa de las sesión 20. ¿Cómo haríais para
conseguir que el resultado de este theremin, produjera, las notas que definimos allí?
int tono[ ] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440,466,
494};
// mid C C# D D# E F F# G G# A
void setup()
{ pinMode (pinBuzzer , OUTPUT) ;
}
void loop()
{
int p = analogRead(A0) ;
int n = map (p, 500,1024, 0, 12) ; // Ell array solo tiene 12
notas
tone(pinBuzzer, tono[n]);
delay(300);
}
He usado un array con las frecuencias temperadas de una octava. Después, mapeamos las lectura
de la puerta A0 a un entero entre 0 y 12, porque el array e arriba solo tiene 12 notas, y usamos su
valor para leer la frecuencia correspondiente.
En mi caso, además, A0 solo daba valores entre 500 y 1024, así que por eso he corregido la escala.
Por último el delay impide que el cambio de notas sea instantáneo, porque de lo contrario no
notaríamos mucho cambio el programa anterior.
P á g i n a 87 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Una resistencia 330 Ω
5. Un buzzer piezoeléctrico.
6. Algunos cables de Protoboard.
Ya sabemos que Arduino NANO dispone de 14 pines digitales que podríamos usar para entrada y
salida y que además disponemos de 6 puertas de entrada analógicas de A0 hasta A5. Lo que no
suele ser muy conocido es que las puertas analógicas también se pueden usar como pines digitales
en caso necesario. Podemos leer y escribir valores digitales exactamente como lo hacemos con los
pines digitales normales:
pinMode (A1, OUTPUT) ;
Nuestras puertas analógicas se comportarán gentilmente como puertas digitales (Si, también
podemos hacer lo mismo para la lectura
Así pues, en realidad, disponemos de 20 puertas digitales para nuestras cosas. Pero en la vida de
toda persona, siempre hay un momento en que esto nos suficiente. Podemos pasarnos a un
Arduino Mega que con 54 pines digitales más 16 puertas analógicas hacen el impresionante
numero de 60 puertas disponibles. Pero al final, la combinación entre la ley de Murphy y la
segunda ley de la termodinámica (La de que todo tiende al caos) garantizan que aparezca alguien
que quiere un cuadro de luces con 64 LEDs (o 128 ya puestos) y la catástrofe nos acecha porque
no hay Arduinos con más pines. Afortunadamente la industria electrónica nos provee con una
forma sencilla de aumentar el número de salidas digitales de nuestros Arduinos sin demasiada
P á g i n a 88 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
complicación. Unos pequeños chips llamados Shift Registers fáciles de encontrar como el
74HC595. El 74HC595 es un Shift Register de 8 bits serial-in, parallel-out, pertenece a una familia
de chips que aceptan una entrada de bits en serie y los sacan en 8 pines paralelos. Solo sirve para
escribir señales digitales y no para leerlas.
Si lo que necesitas es aumentar los pines digitales de entrada, prueba a usar 74HC165 que
es un shift register de entrada
Aunque ahora todo parezca un poco confuso (no me extraña) son bastante sencillos de manejar
una vez que entiendes lo que hacen y son sorprendentemente útiles en cantidad de situaciones.
Anteriormente vimos que para comunicar dos puntos con una conexión serie necesitábamos
pactar una velocidad de envío para saber cuándo hay que leer los datos que llegan. A este sistema
le llamamos comunicación serie asíncrona porque la sincronía va implícita en la velocidad. Un Shift
Register funciona mediante la comunicación serie síncrona. Es decir que usamos un pin para
enviar los bits en serie (el Data pin) y usamos un segundo pin (el Clock pin) para indicar cuando hay
que leer el bit. Cuando los 8 bits se han leído en el registro un tercer pin (Latch pin) escribe estos
bits en los pines de salida del chip y los mantiene hasta que se reciban nuevos datos.
Fíjate en el gráfico superior. Nuestro Arduino envía la señal de Clock Pin de modo regular para
indicar cuando hay que leer (Se lee en el flanco de subida, cuando Clock sube de 0 a 1). A medida
que Arduino va poniendo valores en el Data Pin (DS), el chip los va leyendo en el flanco de subida
P á g i n a 89 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
del Clock pin y por eso va a ir leyendo 1 1 1 0 0 0 1 1 sucesivamente. Cada uno de estos valores se
va pasando en orden a los pines de salida de Q0 hasta Q7, pero aún no se activan. Cuando el Latch
Pin se activa (también por flanco de subida) los valores pasan a los pines de salida y se memorizan.
Vamos a montar un circuito que use estas salidas para gobernar un conjunto de 8 LEDs, usando
solo 3 pines de Arduino que corresponden a Clock, Data y Latch.
P á g i n a 90 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Y después el setup
void setup()
{ pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, OUTPUT);
}
Las comunicaciones síncronas son tan frecuentes, que nuestro Arduino las soporta de fábrica con
una serie de funciones. La que nos interesa, se llama shiftOut(). (Podeis Goglear el manual) Para
iniciar la comunicación síncrona basta poner el Latch en LOW
DigitalWrite(latchPin, LOW);
Y ahora enviar los 8 bits llamando a shiftOut() y pasándole que pines usamos para Data y Clock
además indicándole el valor que queremos enviar a la salida:
shiftOut(dataPin, clockPin, MSBFIRST, Num) ;
Lo de MSBFIRST significa Most Significant Bit First, o sea, enviar el número binario empezando por la
izquierda. También podría ser al revés como LSBFIRST (Least Significant Bit First).
Y por último fijar los valores en la salida poniendo HIGH el Latch de nuevo.
void loop()
{
for (int Num = 0; Num < 256; Num++)
{
digitalWrite(latchPin, LOW) ; // Latch a LOW para que no varíe
la salida
shiftOut(dataPin, clockPin, MSBFIRST, Num); // Aqui va Num
Veremos que los LEDs irán contando mostrando los valores de Num en binario.
Una curiosidad del 74HC595, es que si le metemos un tren de más bits de los 8 que puede
almacenar, sencillamente los va empujando hacia la salida por su pin 9 (que os habréis fijado no
hemos utilizado en el ejemplo anterior) y los va dejando caer al olvido. Pero si conectamos este
pin 9, al pin 14 de entrada de datos de un segundo chip 74HC595, y compartimos entre ellos el
P á g i n a 91 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Clock y el Latch, en lugar de caer en el olvido entrarán en el siguiente chip de la cadena y seguirá
en el juego. Hemos conseguido una ampliación de otras 8 salidas digitales sin utilizar pines
adicionales de nuestro Arduino. Y naturalmente una vez visto el truco, no hay límite en principio al
número de chips que podemos concatenar. Si ese que quería un cuadro de luces de 128 LEDS
vuelve, lo podríamos arreglar con 128/8 = 16 chips.
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Una resistencia 330 Ω
P á g i n a 92 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
5. Un sensor DHT11.
6. Algunos cables de Protoboard.
En la seccion Sensor de temperatura TMP36, vimos cómo medir la temperatura con un sensor
TMP36. Es bastante sencillo y no presenta especiales problemas, más allá de tener cuidado con las
operación con números float.
Por eso se desarrollaron los sensores de la familia DHT. Nos proporcionan de forma digital
la temperatura y la humedad, con diferente precisión según el modelo.
Rango de temperatura: de 0º a 50º con 5% de precisión (pero solo mide por grados, no
fracciones)
Bajo consumo
Devuelva la medida en ºC
En cuanto al DHT22:
Barato, entre 4 y 5 €
Bajo consumo.
Devuelva la medida en ºC
P á g i n a 93 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Destacar que el chip incorpora electrónica para hacer internamente la conversión de temperatura
y humedad y nos da un valor de medida de forma digital, es decir, que no necesitamos un pin
analógico como en el caso del TMP36, sino que lo leeremos con un pin digital.
La conexión es trivial, pero cabe destacar que se vende en dos encapsulados, uno de tres pines
que son GND, Data y Vcc, y otro 4 pines y uno de ellos, sencillamente sobra y no se conecta.
Normalmente viene rotulado en el sensor el nombre de cada pin, y si no ya sabes, a buscar el
manual en Google
P á g i n a 94 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En primer lugar, tenemos que descargar una librería para manejarlos cómodamente, DX11.zip e
importarla. Descarguen de este link:
http://bit.ly/1Gtl2vv
Y definimos una instancia del sensor donde declaramos el pin al que esta conectado.
int pin=2;
DHT11 dht11(pin);
Basta con hacer dht11.read pasándole las variables donde queremos el resultado, y comprobamos
que no haya errores (Siempre es buena idea comprobar que no hay error cuando hacemos una
llamada). El programa completo sería más o menos algo así:
#include <DHT11.h>
int pin=2;
DHT11 dht11(pin);
P á g i n a 95 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void setup()
{
Serial.begin(9600);
}
void loop()
{
int err;
float temp, hum;
if((err = dht11.read(hum, temp)) == 0) // Si devuelve 0 es que ha
leido bien
{
Serial.print("Temperatura: ");
Serial.print(temp);
Serial.print(" Humedad: ");
Serial.print(hum);
Serial.println();
}
else
{
Serial.println();
Serial.print("Error Num :");
Serial.print(err);
Serial.println();
}
delay(1000); //Recordad que solo lee una vez por segundo
}
Para hacer variar los valores, de humedad y temperatura y comprobar que todo funciona
correctamente, podes, sencillamente, enviar vuestro aliento al sensor, y salvo que estéis en el
trópico haréis subir tanto la temperatura como la humedad relativa.
P á g i n a 96 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard
4. Un Sensor de Lluvia
SENSORES DE AGUA
Por diferentes razones, no es raro necesitar detectar si hay presencia de agua en un lugar. Puede
ser porque queremos saber si ha habido un escape de agua, o para saber si hay condensación en
una cierta zona, y muy frecuentemente nos viene bien conocer el nivel de un líquido en un
depósito
En el mundo Arduino se comercializan unos detectores de agua muy baratos y simpáticos, que nos
pueden servir para todas estas cosas, siempre y cuando seáis conscientes de que la calidad de
estos detectores baratos es limitada.
En concreto, tengo dudas serias de su durabilidad a medio plazo si los mantenéis en exteriores
como detector de lluvia, o si los sumerges en líquido para tener un medidor de nivel. No dudo de
su utilidad sino de su duración.
En cualquier caso como son bastante baratos, he pensado en incluir un ejemplo sencillo de su uso,
y quien sabe, quizás puedan seros útiles.
Son muy simples y lo único que hay que hacer es conectar a tensión y GND y el tercer pin es una
señal analógica, proporcional a la cantidad de agua que detecta.
DIAGRAMA DE CONEXIÓN
P á g i n a 97 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Hay que tener cuidado de no volcar agua en vuestro Arduino, o morirá en acto de servicio.
Si insertas el sensor en agua, para usarlo como medidor de nivel, tene mucho cuidado de no
sumergir los pines de conexión a Arduino, o provocaras un corto.
No hay suficiente tensión como para provocar un accidente, pero siempre es recomendable
impedir un cortocircuito.
PROGRAMA DE CONTROL
El programa es de lo más simple. Vamos a leer la señal del sensor con nuestro A0 y enviaremos la
lectura a la consola serie para ver la medida. Jugando a mojar más o menos el sensor veremos
cómo los valores van cambiando a más cuanto mayor sea la cantidad de agua que detecta.
void setup()
{
Serial.begin(9600);
}
void loop()
{
Serial.println(analogRead(A0));
}
P á g i n a 98 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un Tilt Switch.
5. Un Led.
6. Una Resistencia.
7. Algunos cables de Protoboard.
Son sensores de unos pocos milímetros de longitud, que llevan en su interior una o dos pequeñas
bolas conductoras, capaces de cerrar el circuito con los pines metálicos inferiores del cilindro.
Cuando hacen contacto permiten el paso de la corriente y cierran el contacto exactamente igual
que si fueran un interruptor (Y de hecho se manejan igual) pero que a partir de un cierto Angulo
de inclinación dejan de hacer contacto y abren el contacto.
P á g i n a 99 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
No es una tecnología reciente, pues llevan en uso mucho tiempo, pero antes se hacían con una
gotita de mercurio líquido, que es conductor y que al desplazarse por el interior del cilindro
acababa por cerrar el circuito entre un par de contactos en el fondo.
Pero dado que el mercurio es sumamente toxico para el entorno y para las personas que lo
manejan, hace ya bastante tiempo que se han reemplazado por el modelo que vamos a usar,
aunque aún es fácil encontrarnos con que se siguen llamando interruptores de mercurio.
A todas luces se comportan igual que un interruptor sencillo y de hecho vamos a tener que hacer
el debouncing igual que estos, porque si aquí rebotaban los contactos, podéis imaginaros los
rebotes que van plantear las bolitas de poca masa.
ESQUEMA DE CONEXIÓN
Vamos a usar el mismo esquema de conexión que con un interruptor normal. Por ello necesitamos
usar una resistencia de pullup, y según el valor que leamos encendemos o apagamos un LED
conectado al pin 13.
Por una vez, y sin que sirva de precedente conectaremos el LED al pin 13 sin resistencia,
porque este pin ya lleva una en serie. Para cualquier otro pin deberíamos poner una
resistencia de limitación o veremos un bonito plof con el LED.
Vamos a usar lógica negativa. Esto es una manera complicada de decir que puesto que en
condiciones normales, el interruptor está cerrado, la señal de disparo será cuando leamos
un LOW en el pin 2.
P á g i n a 100 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
PROGRAMA DE CONTROL
El programa va a ser muy similar al que usamos en la sesión previa, condicionales y botones. Pero
por aquello de variar un poco, vamos a usar un debouncing de tiempo variable
int inPin = 2;
int outPin = 13;
int lectura;
int previo = LOW;
P á g i n a 101 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void setup()
{ pinMode(inPin, INPUT_PULLUP);
pinMode(outPin, OUTPUT);
}
void loop()
{ lectura = digitalRead(inPin);
if (lectura != previo) // Si hay cambio en la lectura
time = millis();
if ((millis() - time) > debounce)
digitalWrite(outPin, lectura);
previo = lectura ;
}
No hay nada Nuevo en el programa. Con lectura vamos leyendo el pin 2 hasta que es diferente del
último valor leído. A partir de esto comprobamos que ha transcurrido el tiempo de
debouncing para filtrar los rebotes y escribimos en el pin de salida lo que leemos.
En la práctica son bastante fáciles de manejar y os permiten detectar un movimiento brusco del
sensor y también detectan una inclinación superior a un cierto ángulo.
DISPLAY DE 7 SEGMENTOS
OBJETIVOS
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un Display de 7 segmentos
5. Una Resistencia.
6. Algunos cables de Protoboard.
P á g i n a 102 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En cuanto empecéis a plantearos hacer un circuito que realice alguna función práctica, hay un 50%
de probabilidades de que acabéis necesitando enviar información al mundo exterior (y claro no
vais a dejar vuestro portátil pegado al invento).
Así que es el momento de ver que nos ofrece el mercado para mostrar información y para
empezar, nada mejor que un sencillo display LED de 1 digito.
Los diodos LED ya no guardan secretos para los que nos siguen, pero esto de un display parece
otra cosa.
Pues no. Es lo mismo pero en lugar de ser un punto luminoso como los familiares LED, tiene forma
de barra: 7 barras más 1 punto.
Estos displays nos son bastante familiares en despertadores y similares, están formados por 7
líneas, que a dependiendo de qué segmentos se iluminan, muestran los dígitos del 0 al 9.
A cada uno de los 7 segmentos se les adjudica una letra para representarlos y suele ser a, b, c, e, f,
g y aparte un punto (o dos, o dos puntos según el fabricante) y es un buen momento para echar un
vistazo a las especificaciones de cada fabricante para estar seguros de que pin es cual.
Todos los circuitos, los displays incluidos, llevan un código de fabricante rotulado. Es buena
política buscar en internet la hoja de especificaciones(o datasheet) y echarle un ojo
Probad a buscar en Google algo así como XXXXX datasheet, donde XXXXX son los códigos que
habéis encontrado rotulado en el display o componente que sea.
Lo importante es que sepáis que es cada pin, y que veáis que segmento es cual. En realidad es
bastante más fácil de lo que parece, localizad primero un GND. En el de arriba son el 3, 5, 11 y 16.
Poned una resistencia (de 330Ω como siempre) de la salida del display a GND. Este es un display
de cátodo común, o sea que todos los LEDS comparten la masa, pero necesitamos poner una
resistencia de limitación o fundiréis el display, y este vale ya lo suficiente, como para que os cueste
verle la gracia al tema.
Una vez que hayáis conectado la masa común con una resistencia, empezad cableando solo un
LED, el a por ejemplo y conectadlo al pin 2 de Arduino. Escribid un programa en Arduino para
iluminar el LED en el pin 2 y veréis como se enciende el segmento a.
Podéis ir conectando y probando el resto de los pines poco a poco, asegurando las conexiones. Es
muy fácil equivocarse si no andáis con tiento.
Otro display ed 1 digito muy típico es el 5611AH, cuyo patillaje os pongo aquí, como
referencia:
P á g i n a 103 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
P á g i n a 104 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
PROGRAMA DE CONTROL
Tenemos que comprobar que las conexiones son correctas lo primero. Probad esto:
void setup()
{
for (int I = 2; i<11; i++)
pinMode(i, OUTPUT);
}
void loop()
{
for ( int j= 2; j<11 ; j++) // Va encendiendo los segmentos
{
digitalWrite(j, HIGH);
delay(400) ;
}
for ( int j= 2; j<11 ; j++) //Apaga todos los segmentos
digitalWrite(j, LOW);
delay(400) ;
}
En el setup, inicializamos los 8 pines de salida con for (recordar que somos vagos) y en el loop
usamos una primera iteración que va iluminando los 8 segmentos con un delay, y en la segunda
los borra y vuelta a empezar. La idea es comprobar que las conexiones son correctas.
Para ello, lo más rápido es hacerte una tabla para ver que segmentos tienes que iluminar para
cada digito decimal, y vas apuntando cuales son 1 (encendido) o 0 (apagado).
P á g i n a 105 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
DIGITO A B C D E F G PUNTO
0 1 1 1 1 1 1 0 0
1 0 0 0 0 0 0 0 0
2 1 1 0 1 1 0 1 0
3 1 1 1 1 0 0 1 0
4 0 0 1 0 0 1 1 0
5 1 0 1 1 0 1 1 0
6 1 0 1 1 1 1 1 0
7 1 1 1 0 0 0 0 0
8 1 1 1 1 1 1 1 0
9 1 1 1 0 0 1 1 0
Ahora solo queda escribir el programa que dibuja los números en el display.
La primera idea que se nos ocurre a todos es hacer una función por cada digito que queramos
representar. Por ejemplo podríamos hacer:
void Display7()
{
digitalWrite(2, 1) ; // Si, podemos decir 1 y 0 en lugar de
HIGH y LOW
digitalWrite(3,1);
digitalWrite(4,1);
digitalWrite(5,0);
P á g i n a 106 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
…………..
}
Es decir, encendemos los pines correspondientes a cada segmento a imagen de la tabla previa.
El problema de este enfoque es que hay que hacer 10 funciones como esta y luego escribir en el
programa principal algo que llame a la función correspondiente según el número que queramos
mostrar.
Esta es, de nuevo, la solución de fuerza bruta y no, aquí no permitimos esas cosas, nos gustan las
soluciones elegantes (y porque, además, somos muy vagos y nos cansamos solo de pensar en
hacerlo así).
Por cierto, para ser alguien en la comunidad freaky, hay que hablar de la elegancia de tu código
siempre que surja la ocasión, si queréis ser programadores es muy importante que empecéis a
adoptar las poses del gremio.
Así que vamos a buscar otra solución más elegante. Para empezar, todos los que al ver la última
tabla, con los segmentos que hay que iluminar, hayáis pensado que se parece sospechosamente a
un array de 10 x 8 podéis anotaros un punto por listos.
De nuevo, como con todo en la vida, es mucho más fácil de lo que parece. Vamos a empezar
definiendo el array de dos dimensiones (porque es una tabla, otra cosa son el número de
elementos por dimensión):
byte Digit[10][8] = // Arduino UNO va muy justo de memoria.
Por eso lo
{ // definimos como byte y no como int
{ 1,1,1,1,1,1,0,0 }, // 0
{ 0,1,1,0,0,0,0,0 }, // 1
{ 1,1,0,1,1,0,1,0 }, // 2
{ 1,1,1,1,0,0,1,0 }, // 3
{ 0,0,1,0,0,1,1,0 }, // 4
{ 1,0,1,1,0,1,1,0 }, // 5
{ 1,0,1,1,1,1,1,0 }, // 6
{ 1,1,1,0,0,0,0,0 }, // 7
{ 1,1,1,1,1,1,1,0 }, // 8
{ 1,1,1,0,0,1,1,0 } // 9
};
Podemos ahora crear una función, que pasándole un número de 0 a 9, elija la fila del array en
función de ese mismo número y busque el array interno correspondiente.
void Display(int N)
{
for (int i= 0 ; i<8 ; i++)
{ int valor = Digit[N][i] ;
int pin = i+2;
digitalWrite(pin , valor) ;
}
}
P á g i n a 107 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Buscamos valor en la tabla cuyo índice principal N apunta al array interno correspondiente. El for
i, va leyendo los 8 elementos del array para escribirlos en el pin correspondiente de salida, que lo
calculamos como i +2, (Porque usamos los pines 2 al 10 para conectar los segmentos del display y
así unos valores de 1 de 0 a 8 se convierten en pines de 2 al 10).
void setup()
{ for (int i= 2; i<11; i++)
pinMode(i, OUTPUT);
}
void loop()
{
for ( int k=0 ; k<10 ; k++) // Llama a Display para k de 0 a 9,
los digitos
{ Display(k);
delay(1000);
}
}
void Display(int N)
{
for (int i= 0 ; i<8 ; i++)
{ int valor = Digit[N][i] ;
int pin = i+2;
digitalWrite(pin , valor) ; // digitalWrite(i+2 ,
Digit[N][i] ) ;
}
}
Fijaros que podíamos haber escrito así (El código compacto también puntúa con los colegas):
void Display(int N)
{ for (int i= 0 ; i<8 ; i++)
digitalWrite(i+2 , Digit[N][i] ) ;
}
DISPLAYS LCD
OBJETIVOS
P á g i n a 108 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un LCD
5. Un Potenciómetro
6. Algunos cables de Protoboard.
Los displays LEDs de 7 segmentos, que vimos en las sesiones anteriores, están muy bien, son
baratos y prácticos, pero tienen el inconveniente de que no pueden mostrar mensajes de texto,
sino solo números.
Se echa de menos algún sistema para mostrar mensajes de texto sencillos, y por eso se
comercializan los displays LCD. Son fáciles de encontrar en diversos formatos: 16×2 (16 caracteres
x 2 líneas) o LCD 16×4 (16 caracteres x4 líneas).
LCD viene del inglés Liquid Crystal Display, o sea Pantalla de cristal líquido.
Son una opción muy sencilla de usar, y además, dan un toque muy pro a vuestros proyectos, y por
eso, en los últimos años los displays LCD han ganado mucha aceptación en productos comerciales
de todo tipo.
Básicamente porque:
Son baratos.
Están disponibles en varios tamaños y configuraciones.
Son de bajo consumo.
Muy prácticos si te basta con mostrar solo texto (y algunos caracteres especiales).
En esta sesión veremos cómo conectarlos a vuestros Duinos y cómo usarlos para sacar mensajes
al exterior.
P á g i n a 109 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
DIAGRAMA DE CONEXIÓN
La conexión no es complicada, pero requiere ser cuidadoso. Así que vamos a ir paso a paso con los
diferentes cables. Empieza conectando tensión y GND a la protoboard.
P á g i n a 110 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Vamos ahora a conectar la alimentación el panel LCD. Conecta el pin16 del LCD a Ground y el 15 a
5V
Si conectas ahora el cable USB a tu Duino, el LCD debería iluminarse, si no, revisa tus cables antes
de seguir.
Vamos a conectar ahora, el potenciómetro de ajuste. Para ello conecta uno de los extremos del
pot a GND y el otro a 5V. El centro al pin 3 del LCD.
Aprovechemos también para dar tensión al panel LCD, El pin 1 va a GND y el 2 a tensión:
P á g i n a 111 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Si todo ha ido bien, ya podemos encender el display y probarlo. Conecta el USB a tu Arduino y
veamos. Si vas girando el potenciómetro, en algún momento tienes que ver unos cuadraditos en la
pantalla, en caso contrario revisa las conexiones. No sigas, si no ves esto.
Vamos a conectar ya los pines de datos y control. Sin entrar en muchos detallas, no vamos a usar
todos los pines disponibles, porque no los necesitamos. Solo usaremos dos pines de control, RS y
EN y los 4 pines de datos D7, D6, D5, y D4 . No necesitamos más por ahora.
P á g i n a 112 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
EL PROGRAMA DE CONTROL
Vamos a usar una librería de control del panel LCD, que viene incluida en nuestro Arduino. Pinchad
en:
\\Programa\Importar Libreria\LiquidCrystal
Y ahora podemos importar uno de los ejemplos o escribir el nuestro, comentando el código.Lo
primero es que al importar la librería nos ha escrito esto:
#include <LiquidCrystal.h>
Despues, hay que inicializar la librería. Creamos una instancia llamada lcd, de la clase LiquidCrystal
y le pasamos como parámetros los pines que hemos usado:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // ( RS, EN, d4, d5, d6, d7)
Tened cuidado porque los pines que hemos usado, no corresponden a los ejemplos de Arduino, así
que podéis cargarlos, pero aseguraros de cambiar la línea de definición de los pines, o no correrán.
El resto es sencillo
void setup()
{
lcd.begin(16, 2); // Fijar el numero de caracteres y de filas
lcd.print("Prometec.net"); // Enviar el mensaje
}
void loop()
{
lcd.setCursor(0, 8); // set the cursor to column 0, line 1
lcd.print(millis() / 1000); // print the number of seconds since reset:
}
P á g i n a 113 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Estos display son muy pesados de cablear, pero muy sencillos de utilizar.
Vamos a probar sacando un reloj (muy sencillo de momento). Si recordáis las funciones que
usamos en las últimas sesiones, podemos recuperar alguna para presentar el valor de millis() como
un reloj
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
void setup()
{
lcd.begin(16, 2); // Fijamos el numero de caracteres y
filas
lcd.print("Prometec.net"); // Aqi va el mensaje
}
void loop()
{
lcd.setCursor(6, 1); // Ponte en la line 1, posicion 6
String s = reloj() ;
lcd.print(s) ;
}
String reloj()
{
int n = millis() / 1000 ; // Lo pasamos a segundos
int segundos = n % 60 ;
int minutos = n / 60 ;
Merece la pena, comentar algunas cosas de este código. En primer lugar en la función reloj,
calculamos los minutos y segundos a partir del reloj interno de Arduino en milisegundos, no hay
nada nuevo en esto. Pero fijaros que hemos definido reloj como String:
String reloj()
Eso significa que vamos a devolver un parámetro tipo String a quien nos haya llamado. En algún
punto de la función habrá que hacer un return( String).
En esta línea no hay que confundir (aunque se escriben exactamente igual), el tipo String para
definir S, con la función String(n) que convierte un numero n en un string de texto para que pueda
mezclar el número de los minutos y los segundos separados por un símbolo de “:”.
Al final le añadimos un par de espacios en blanco, para evitar arrastrar fantasmas en la pantalla
P á g i n a 114 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Quita los espacios y miro lo que pasa en el cambio de minuto. ¿Cómo lo arreglarías, sin el truco de
poner esos espacios al final? Piénsalo.
Para sacar el mensaje de texto. Todo lo que ya sabéis de Serial.print() se usa exactamente igual
con esta instrucción. Y por último, tenemos una línea como esta:
lcd.setCursor(6, 1); // Ponte en la line 1, posicion 6
La librería LCD, viene con varios ejemplos muy interesantes, que os conviene probar. Recordad,
simplemente, que tenéis que cambiar las definiciones de los pines para que corran.
Sin llegar a tanta sofisticación, es muy interesante que veamos cómo definir algunos caracteres
especiales, porque en la tabla base del LCD, no están incluidas ñ, acentos, grados, o €. Así que
dependiendo del uso que le deis pude seros de interés saber cómo definir tus propios símbolos.
Vamos a definir un carácter propio, para digamos, el símbolo de grados centígrados, por ejemplo.
Lo primero que tenéis que saber, es que los caracteres se definen con un array (si, de nuevo) de
8×8, como si los dibujarais en una cuadricula de ese tamaño, y rellenando el cuadradito completo.
byte grado[8] =
{
0b00001100, // Los definimos como binarios 0bxxxxxxx
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
P á g i n a 115 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
0b00000000
};
Y ahora ya están disponibles. Tened en cuenta que solo podemos definir 8 caracteres especiales
en un momento dado (Aunque podemos definir 30 arrays, de caracteres y crearlos y matarlos
sobre la marcha).
byte grado[8] =
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
0b00000000
};
void setup()
{
lcd.begin(16, 2); // Hay que inicializar el LCD
lcd.createChar(1, grado);
lcd.setCursor(0, 0);
lcd.print("Estamos a 25");
lcd.write(1);
}
void loop()
{
}
EL BUS I2C
OBJETIVOS
P á g i n a 116 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
2. Un PC con el entorno de Arduino correctamente instalado y configurado.
3. Una Protoboard.
4. Un LCD con interfaz I2C
5. Un Potenciómetro
6. Algunos cables de Protoboard.
EL BUS I2C
Era relativamente fácil encontrar esos bloques de construcción pero cuando tu diseño requería
usar una docena de esos bloques, ponerlos de acuerdo y conseguir que se comunicaran
eficazmente, se convirtió en un problema.
Por eso, en los primeros 80, uno de los grandes fabricantes de electrónica (Phillips), propuso una
norma de comunicación digital, entre los diferentes componentes de una sistema electrónico.
Una norma que especificaba la velocidad, niveles de tensión, y el protocolo a seguir para
conseguir esa comunicación y la hizo abierta.
Esa norma se llamó Inter Integrated Circuits bus, o IIC, y pronto se convirtió en un estándar de
facto en la industria. Las especificaciones han ido mejorando con los años, pero la idea básica
sigue siendo la misma:
Protocolo de dos hilos de control, uno para transmitir los datos, SDA y otro, el reloj
asíncrono que indica cuando leer los datos SCL. Mas GND y 5V (cuando se requiera).
Cada dispositivo conectado al bus I2C y cada uno tiene su dirección exclusiva, de 7 bits,
(Asi que, en teoría, podemos conectar 27 = 128, dispositivos).
Uno de estos componentes, debe actuar como master, es decir controla el reloj.
No se requiere una velocidad de reloj estricta, ya que es el master quien controla el Clock.
Es multi master, el master puede cambiar, pero solo uno puede estar activo a la vez, y
proporciona un protocolo de arbitraje y detección de colisiones. (Si no has entendido esto,
no te preocupes, todavía es pronto).
P á g i n a 117 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Puedes encontrar que a este bus se le llama I2C, IIC o I2C, y también, como TWI (Two Wire
Interface, o interface de 2 hilos), pero siempre es lo mismo.
La idea es que todos los componentes se conecten en paralelo a las dos líneas del Bus, SDA y SCL.
En cada momento solo puede haber un master, en este caso, nuestro Duino y los demás se
configuran como esclavos.
Y la buena noticia es que nuestro Arduino lo soporta de fábrica con una librería estándar, que
utiliza dos de los pines analógicos para las funciones SDA (Datos) y SCL (Clock).
En el Arduino NANO, los pines I2C están en los pines analógicos A4 (SDA) y A5 (SCL).
La librería I2C, en Arduino se llama Wire (para que no os confiéis), y gestiona el protocolo de
comunicaciones completo, lo que es un detalle, pues nos ahorra la parte aburrida de estudiar el
protocolo y escribir programas para ello.
Esto no es vagancia, sino construir sobre el trabajo de terceros. Es una de las muy grandes virtudes
de la comunidad Arduino. Muchas librerías para incorporar a nuestros proyectos, sin necesidad de
mancharte las manos de grasa.
P á g i n a 118 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
En esta sesión vamos a conectar un display LCD de 16×2 con interface I2C, y así podréis comprobar
porque en la última sesión os recomendé usarlo, en lugar del que se conecta directamente con 16
pines.
SCANNER DE I2C
Cada componente que conectamos al bus I2C tiene una dirección única, y cada mensaje y orden
que transmitimos al bus, lleva anexa esta dirección, indicando cuál de los muchos posibles, es el
receptor del mensaje.
Pero, claro, esto implica que sabemos la dirección del componente. Lo normal es comprobar la
información técnica del fabricante del componente, y ahí suele decirnos cuál es la dirección por
defecto.
Pero como ya sabemos, que en la vida las cosas rara vez son como en los cuentos, algún alma
caritativa (y con mucho mundo a sus espaldas), hizo un programita para Arduino, que nos informa,
de lo que hay en nuestro bus y con qué dirección. I2C scanner
Naturalmente, este programa, no tiene ni idea de quien responde y lo que hace, pero bastante es
que nos informe de que hay alguien en la dirección xx.
Si no sabemos en qué dirección está un componente dado, basta con colocarlo solo en el bus, y
ver qué dirección nos reporta el I2C scanner. EL resultado para el LCD que tengo es 0x27
Hexadecimal.
Así que ya podemos pasar a hablar de como programar el uso del display.
P á g i n a 119 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
DIAGRAMA DE CONEXIÓN
Simplemente Arduino A4 a SDA (Datos) y A5 a SCL (Clock), más GND y alimentación. Vamos con el
programa.
PROGRAMA DE CONTROL
Lo primero, es que descarguéis una nueva librería para maneja el display con I2C, Se llama
LiquidCrystal_I2C y es un añadido para la librería estándar que viene con tu Duino (tranquilo no
duele y debería ser automático).
No he encontrado información del autor o autores, y solo he visto que hacen referencia a que el
nombre de la librería es Malpartida (A mí no me miréis).
http://bit.ly/1PGl0YT
Busca en tu directorio de descargas, la librería LiquidCrystal_I2C .zip y haz doble click, para que se
instale en nuestro IDE.
Ahora vamos a incluir la librería I2c que en Arduino se llama Wire, y como es estándar la incluyes
con:
P á g i n a 120 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
Vamos ahora a definir una variable con la dirección de nuestro display. En mi caso la 0x27
byte dir = 0x27 // Ese 0x significa que es hexadecimal, no decimal
Al que le pasamos la dirección dir del display y varios números que indican que pines debe usar la
librería para el display, no de Arduino. Ignóralo y lo copias así para los displays. El resto queda así:
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
EL BUS SPI
OBJETIVOS
P á g i n a 121 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
LA COMUNICACIÓN SERIE
Si ya tenemos un protocolo de transmisión de datos asíncrono como las puertas series que vimos
anteriormente ¿Por qué necesitamos otro bus serie? ¿Hay algo malo con la comunicación serie
del que no hayamos hablado?
Teóricamente no hay ningún problema, pero ya sabéis que el demonio está en los detalles, y así
dijimos que bastaba con definir una velocidad común para transmitir datos inmediatamente entre
dos puntos, pero la realidad es terca.
No tenemos ninguna garantía de que ambos extremos estén, de hecho, a la misma velocidad, lo
que puede hacer que enviamos todos nuestros datos y la otra parte no se entere, bien porque no
está a la misma velocidad o bien porque sencillamente esta en babia.
No tenemos ninguna manera de garantizar que la otra parte ha recibido el mensaje, sencillamente
suponemos que todo ha ido bien.
El primer problema que suele aparecer es que las velocidades a en los dos extremos sean
diferentes. Fin de la comunicación (Seguro que a estas alturas ya habéis experimentado este
problema entre Arduino y la consola en algún momento)
El segundo problema es que la forma de fijar la velocidad pactada se debe hacer con un reloj
propio a cada extremo. O sea dos relojes a poner de acuerdo. Es cuestión de tiempo de que
pequeñas diferencias entre los cuarzos que los sincronizan den lugar a problemas de
comunicación.
Para corregir este problema, en las comunicaciones seria se pacta otro aspecto que hasta ahora no
habíamos comentado, Se añade un par de bits extra a la comunicación en forma de un bit de Start
y otro de Stop. (Fijaros que para enviar 8 bits de datos ahora tenemos que enviar 10 bits)
Pero esto supone además un aumento en el hardware para decodificar la señal y sincronizar los
relojes. Y puestos a complicar las cosas ¿Porque no buscar una solución síncrona al problema?
La solución que dio la industria fue múltiple, entre las que se encuentran el bus I2C que ya vimos
en su día y el bus SPI que vamos a ver ahora.
P á g i n a 122 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Es un protocolo de transmisión que permite alcanzar velocidades muy altas y que se diseñó
pensando en comunicar un micro controlador con distintos periféricos y que funciona a full dúplex
(Una forma retorcida de decir que puede enviar y recibir datos al mismo tiempo).
SPI utiliza una solución síncrona, porque utiliza unas líneas diferentes para los datos y el Clock. El
Clock es una señal que indica al que escucha exactamente cuándo leer las líneas de datos, con lo
que el problema de perdida de sincronía se elimina de raíz.
En un bus SPI una de las partes genera el Clock al que llamamos master, y el resto son los esclavos,
pudiendo haber uno o varios en el bus. A la señal de reloj se le suele llamar CLK por Clock o SCK
por Serial Clock.
Cuando el master envía información, lo hace por una línea de datos que normalmente de nombre
MOSI (Master Out Slave In) y si el esclavo responde lo hace a través de una línea llamada MISO
(Master In Slave Out) siguiendo una de esas tradiciones de imaginación desbordante en los
nombres tecnológicos.
P á g i n a 123 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Como es el master quien genera el Clock, necesita saber de antemano, si un esclavo va a devolver
una respuesta y de que longitud, para mantener el Clock hasta que la transferencia esté completa.
Esto no es normalmente un problema porque cuando el master pide a, digamos un sensor, que le
envié una lectura, normalmente sabemos que van ser 2 bytes.
Hay una última línea de control, llamada Slave Select o SS, que indica a un esclavo que el mensaje
que viene es para él, o bien que se reclama que envié una respuesta a una petición del master.
P á g i n a 124 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
La línea SS normalmente se mantiene HIGH y se activa con LOW, lo que despierta al esclavo
seleccionado. Cuando se termina la transferencia la línea se levanta a HIGH y el esclavo se
desactiva.
Hay dos maneras de conectar múltiples esclavos a un bus SPI. Con una línea SS por cada esclavo o
en cascada:
En general cada esclavo requiere su propia línea SS para ser activado, y así evitar que dos hablen a
la vez, porque el resultado sería ruido inútil. Basta con activar la línea correspondiente y el esclavo
esta listo para recibir sus órdenes
Es un sistema cómodo, siempre y cuando no sean muchos esclavos porque podemos necesitar
muchas líneas.
Cuando el número de esclavos crece suele ser más frecuente conectarlos en cascada, con el MISO
de uno (Salida), conectado al MOSI (Entrada) del siguiente. En este caso solo usamos una única
línea SS, que se comparte entre todos los esclavos.
Esta configuración es típica de una situación en la que le master envía datos pero no recibe nada
de vuelta, como en el caso de una cadena de múltiples display LEDs ( Matrices de 8×8) , en los que
se envía información para ser mostrada pero, no hay datos de vuelta. En este caso incluso
podemos desconectar la línea MISO
P á g i n a 125 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Por último y para cerrar esta sesión, comentar que naturalmente vuestro Arduino soporta de serie
el bus SPI, con una librería estándar que sorprendentemente se llama SPI y que podéis instalar
tranquilamente, que gestiona todas las complicaciones y el arbitraje del protocolo.
P á g i n a 126 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Aunque últimamente han aparecido algunas librerías que nos permiten mover de sitio los pines de
control del SPI en nuestros Arduino, tradicionalmente estos, estaban fijados a unos ciertos pines.
Eso significa, que para controlar el bus SPI es necesario usar esos pines inexcusablemente, aunque
podemos elegir entre dos juegos de ellos, entre ciertos pines digitales, según el modelo y la tabla
que especificamos abajo, y usando los equivalentes en el bus ICSP.
Fíjate que aunque los pines del bus SPI cambian según el modelo de Arduino que
usemos, siempre son los mismos en el ICSP.
Eso permite diseñar Shields coherentes con todos los modelos de Arduino.
OBJETIVOS
Programas de ejemplo
MATERIAL REQUERIDO
1. Arduino Uno o similar. Esta sección acepta cualquier otro modelo de Arduino.
P á g i n a 127 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Estamos tan acostumbrados a los mandos a distancia infrarrojos que no dedicamos un momento
a pensar en ellos y simplemente nos parece normal, algo que a nuestros abuelos les hubiera
parecido magia.
Nos parece normal que los equipos electrónicos, televisores, cadenas de música, aires
acondicionados, respondan a nuestras instrucciones sin levantarnos del sofá, pero esto no ha sido
siempre así, es más, es relativamente reciente, que estos mandos se popularizaron.
Hemos oído que funcionan por infrarrojos y poco más. Me pregunto cuántos usuarios
responderían correctamente a la pregunta de que son los infrarrojos y cuál es el principio de
funcionamiento de un mando a distancia de este tipo.
Para centrar un poco las ideas, empecemos diciendo que las ondas electromagnéticas se
caracterizan, principalmente, por su frecuencia o lo que es lo mismo, por el inverso de ésta que es
la longitud de onda.
En la parte más baja del espectro, de menor frecuencia, están los infrasonidos, y luego vienen las
ondas de sonido claro. Un poco más arriba tenemos los ultrasonidos (Nombres sorprendentes, que
básicamente significan por debajo y por encima de lo que se oye.
Si seguimos subiendo en la frecuencia nos encontramos con las ondas de radio y luego con las
microondas. Después como veis en este grafico que he pillado de la Wikipedia viene el infrarrojo
(Por debajo del rojo), el espectro de luz visible con los familiares colores (Que solo son una forma
en que nuestro cerebro percibe las frecuencias de luz) y luego el ultravioleta (Por encima del
violeta, eso es echarle imaginación a los nombres, si señor).
Más arriba en la escala encontramos los rayos X (Cuando el alemán Roentgen descubrió esta
radiación a finales del XIX, no tenía ni idea de que era, y le parecía una buena idea llamarlos Rayos
X, o sea desconocidos, y todavía hoy seguimos con este cachondeo) y por último los rayos gamma
o cósmicos.
P á g i n a 128 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
La capacidad energética de la radiación crece rápidamente con la frecuencia y por eso los rayos X y
los gamma son muy dañinos para los seres vivos.
Una manera de describir los infrarrojos, seria como una luz con un color diferente, que no vemos,
pero luz a pesar de todo.
Una curiosidad no muy conocida, es que seguramente la cámara de tu teléfono móvil, o tableta es
capaz de ver, y mostrarte, la radiación IR de tus mandos a distancia.
Utilizan luz en una frecuencia que no tienen consecuencias en los tejidos vivos. Menos
impacto que la luz visible.
Tiene relativamente poco alcance, pero no solemos ver la tele o tener la cadena de música
más allá de 2 o 3 metros.
Así que es práctico, sencillo y barato (lo que les encanta a los fabricantes), aunque tienen también
inconvenientes.
El principal es que cualquier cosa con una cierta temperatura, incluidos nosotros, emitimos
radiación infrarroja. Es por eso que las cámaras IR que veis en las pelis, pueden mostrar
nítidamente en plena oscuridad a una persona o animal.
Y esto podría interferir con el mando a distancia IR, lo mismo que cosas como la calefacción, el sol
y demás cosas calientes. Así que la solución para evitarlo es modular la señal con una portadora.
P á g i n a 129 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
La idea básica es mandar un tren de ondas estable (La portadora) y mezclarlo con la información
que queremos enviar (La señal). Este mismo principio se usa con la radio y casi con cualquier señal
radioeléctrica que se envié por el aire.
El emisor es un sencillo transistor que gobiernan un LED infrarrojo muy similar a los LEDs rojitos
normales que hemos usado hasta ahora, solo que diseñados para emitir luz en un color que no
vemos.
El inverso, extraer la señal de una onda RF y obtener la señal limpia se llama demodular.
El receptor tiene un poco más de complejidad porque, las normas de emisión de IR para mandos a
distancia, aparecieron como setas tras una tormenta y poco menos que cada fabricante presento
su propia norma.
Al final la industria acabo diseñando unos receptores capaces de recibir y demodular casi cualquier
cosa, valen muy poco y son un prodigio tecnológico.
RECEPTORES DE IR
Un típico receptor de infrarrojos, es el AX-1838HS, que se consigue por poco más de unos euros.
En su hoja de normas encontráis este diagrama, y son relativamente fáciles de encontrar, en dos
formas. Independientes y montados en un soporte para utilizar sin complicaciones con nuestros
Duinos.
P á g i n a 130 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
El esquema de conexión nuevamente es trivial, pues el AX-1838HS solo tiene 3 pines: Vcc, GND y
señal. Como vamos a usar una interrupción para leer la señal es imprescindible, que llevéis el pin
de señal a el pin2 de Arduino (La interrupción 0) o al pin3 (La interrupción 1).
PROGRAMA DE CONTROL
Para poderlos usar de una forma cómoda, vamos a descargarnos alguna librería, que nos facilite la
vida. De las varias disponibles me ha gustado la de Nico Hood http://nicohood.wordpress.com/,
por varios motivos.
Es ligera y muy rápida en decodificar las señales IR y además usa muy poca memoria.
Funciona por interrupciones, lo que la hace muy ligera y rápida y así vemos un buen
ejemplo de uso de estas.
P á g i n a 131 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Es de las pocas que es capaz de decodificar las señales simultáneas de varios mandos
diferentes, con diferentes protocolos cada uno.
http://bit.ly/1Q5sEae
Después instalarla siguiendo el procedimiento habitual que vimos en sesiones anteriores. Una vez
hecho para usarla como siempre usamos el importar librería, que os pondrá:
#include "IRLremote.h"
Y para inicializarla:
IRLbegin<IR_ALL>(interruptIR);
Vamos a empezar por un ejemplo que nos recomienda el autor para reconocer el mando a
distancia que usamos. Podeis cargarlo con ejemplos IRLremote\ReceiveInterrupt
#include "IRLremote.h"
const int interruptIR = 0; // Arduino interrupcion 0: Pin 2
void setup()
{ Serial.begin(115200); // Fijate en la velocidad
Serial.println("Startup");
IRLbegin<IR_ALL>(interruptIR);
}
void loop()
{
uint8_t oldSREG = SREG; // Parar las interrupciones
cli();
if (IRProtocol) // Si reconoce el protocolo
{
Serial.print("Protocol:");
Serial.println(IRProtocol);
Serial.print("Address:");
Serial.println(IRAddress, HEX);
Serial.print("Command:");
Serial.println(IRCommand, HEX);
IRProtocol = 0;
}
SREG = oldSREG;
}
Este programa, simplemente tratará de leer tu mando a distancia y enviar esa información a la
consola. Asegúrate de que has puesto la velocidad a 115200:
P á g i n a 132 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Como veréis la rutina de servicio de la interrupción simplemente recoge los valores del protocolo
que amablemente reconoce sobre la marcha la librería. Los valores que presenta son
Nos informa del modelo de señal que usa nuestro mando. En este momento reconoce 4
protocolos y el autor pide la colaboración ciudadana, para aumentar el número de
protocolos disponibles con la librería. Actualmente son:
1. IR_NO_PROTOCOL , 0
2. IR_USER, 1
3. IR_ALL, 2
4. IR_NEC, 3.
5. IR_PANASONIC, 4
Address, dirección de tu mando. Cada mando lleva una dirección para identificarle.
Podrías usar más de un mando a distancia para controlar lo que sea, y reconocerlos de
forma diferenciada.
La orden o identificación del botón pulsado en el mando. Cada botón tiene un código
diferente y estos son los códigos que usaras en tu programa para lanzar acciones
diferentes en función del botón pulsado.
P á g i n a 133 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Conviene comentar que si tienes una tele, o VHS o similares que ya no usas, puedes tirar el aparto si
quieres pero conserva el mando porque hay muchas probabilidades de que puedas leerlo con tu
Arduino.
Además tus antiguos cacharros con mando a distancia incluyen esto receptores de IR que puedes
desarmar y reutilizar para tus cosas. ( Os recomiendo desarmar solo los aparatos viejos e inútiles, no
los que están funcionando, que luego no quiero responsabilidades).
Y en este programa está ya implícito todo lo necesario para utilizar un mando IR en tus proyectos.
EL resto de la sesión será sencillamente un ejemplo de cómo gestionar esos golpes de teclas con u
Switch que es una instrucción C++ que hasta ahora no habíamos usado y que nos viene al pelo.
Vamos a montar un circuito con Arduino y 4 LEDs de colores para encenderlos de uno en uno o
apagarlos todos de golpe, mediante el mando IR a distancia.
ESQUEMA DE CONEXIÓN
P á g i n a 134 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
PROGRAMA DE CONTROL
Al principio de esta sesión vimos que ya recibíamos las instrucciones del mando (Espero) y nos
ponía en la consola el valor del protocolo, dirección del mando y Commando que corresponde al
botón pulsado. Estos comandos son lo que necesitais para diparar vuestro programa
Si tienes mas de un mando y quieres usarlos, tendras que controlar también la dirección de cada
mando.
En primer lugar correr el programa anterior para anotar los códigos que corresponden a cada tecla
de vuestro mando, y haceros una tabla. No hace falta que anoteis todas las teclas por ahora, pero
si al menos las que vayamos a usar.
P á g i n a 135 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
Y con esto ya podemos escribir el programa de control. Vamos a utilizar la instrucción switch case,
que es muy cómoda cuando tienes que comprobar muchos valores y tomar acciones en respuesta
a una variable. LA idea básica es como esto:
switch (IRCommand)
{ case 0x02FD:
Serial.println("Arriba");
digitalWrite(8, HIGH);
break;
case 0x827D:
Serial.println("Abajo");
digitalWrite(9, HIGH);
break;
case 0xE01F:
Serial.println("Izquierda");
digitalWrite(10, HIGH);
break;
case 0x609F:
Serial.println("Derecha");
digitalWrite(11, HIGH);
break;
case 0x22DD:
Serial.println("OK");
for (int k =0 ; k <12 ; k++)
digitalWrite(k, LOW);
break;
}
Le pasamos a switch la variable, cuyo valor determina la acción, en este caso el comando pulsado.
Y después se establece una cláusula de case para cada valor posible finalizando con dos puntos.
Escribe las instrucciones a ejecutar y finaliza con break.
He puesto a propósito lo del Serial.println() para que veais que podeis poner varias líneas sin
necesidad de bloques que ya está implícito en el case. Y por fin finaliza la cláusula con un break.
Puedes incluir una última clausula default, sin otro valor para poner una acción que se ejecute si el
valor de la variable no coincide con niguno de los caso comprobados más arriba.
void setup()
{ Serial.begin(115200); // Fijate en la velocidad
for (int i = 8 ; i<12 ; i++)
pinMode(i, OUTPUT);
IRLbegin<IR_ALL>(interruptIR);
}
La única novedad ha sido hasta aquí, es definir como salidas los pines del 8 al 11
P á g i n a 136 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
void loop()
{ uint8_t oldSREG = SREG; // Parar las interrupciones
cli();
if (IRProtocol)
{
switch (IRCommand) // Aqui tenemos la clausula switch con sus
case:
{ case 0x02FD:
Serial.println("Arriba");
digitalWrite(8, HIGH);
break;
case 0x827D:
Serial.println("Abajo");
digitalWrite(9, HIGH);
break;
case 0xE01F:
Serial.println("Izquierda");
digitalWrite(10, HIGH);
break;
case 0x609F:
Serial.println("Derecha");
digitalWrite(11, HIGH);
break;
case 0x22DD:
Serial.println("OK");
for (int k =0 ; k <12 ; k++)
digitalWrite(k, LOW);
break;
}
IRProtocol = 0;
}
SREG = oldSREG;
}
void IREvent(uint8_t protocol, uint16_t address, uint32_t command)
{
IRProtocol = protocol; // Recogemos los valores
IRAddress = address;
IRCommand = command;
}
La cláusula switch es muy útil para evitar if else encadenados que al final te hacen perder el hilo.
Imagínate si tienes que comprobar todas las posibles teclas del mando.
Por último y antes de terminar, comentar que el autor de la librería recomienda que si vamos a
usar un solo mando, sustituyamos la líne
IRLbegin<IR_ALL>(interruptIR);
P á g i n a 137 | 138
CURSO DE INTRODUCCIÓN A LA PLATAFORMA ARDUINO
P á g i n a 138 | 138