Sei sulla pagina 1di 383

ARDUINO

9 788426 721501
Taller de Arduino
Un enfoque práctico para principiantes

Germán Tojeiro Calaza


Taller de Arduino

Primera edición, 2014

© 2014, Germán Tojeiro Calaza

© 2014 MARCOMBO, S.A.


Gran Via de les Corts Catalanes, 594
08007 Barcelona, España
www.marcombo.com

Diseño de la cubierta: NDENU DISSENY GRÀFIC

Corrección: Raquel Sayas Lloris

«Cualquier forma de reproducción, distribución, comunicación pública o


transformación de esta obra solo puede ser realizada con la autorización de sus
titulares, salvo excepción prevista por la ley. Diríjase a CEDRO (Centro
Español de Derechos Reprográficos, www.cedro.org) si necesita fotocopiar o
escanear algún fragmento de esta obra».

ISBN: 978-84-267-2332-1
A mi hermano, Ibán Toxeiro
Índice

Prólogo ........................................................................................................... xi

Convenciones utilizadas en este libro ............................................................ xiii

Agradecimientos ............................................................................................ xv

Marcas registradas ........................................................................................ xvi

Capítulo 1. INICIO CON ARDUINO DESDE CERO................................................. 1


1.1 ¿Qué es Arduino y para qué sirve? ............................................................... 1
1.2 Configuración e instalación ........................................................................... 5
1.2.1 Instalación del entorno de desarrollo (IDE)........................................... 5
1.2.2 Instalación de los drivers de nuestro Arduino ....................................... 7
1.2.3 Instalación de los drivers bajo entorno
Windows (XP, Vista, Windows 7 y 8) ..................................................... 8
1.3 Una primera práctica: parpadeo de un LED ................................................ 10
1.4 ¿Qué tipo de Arduino escoger? .................................................................. 19
1.5 Herramientas útiles para desarrollar tus proyectos ................................... 31
1.5.1 Herramientas hardware ...................................................................... 31
1.5.2 Herramientas software ....................................................................... 34

Capítulo 2. EL LENGUAJE DE PROGRAMACIÓN DE ARDUINO........................... 37


2.1 Introducción al concepto de programación ................................................ 37
2.2 Cuerpo de un programa en Arduino ........................................................... 41
2.2.1 Estructuras .......................................................................................... 41
2.2.2 Variables ............................................................................................. 42
2.2.3 Operadores matemáticos, lógicos y booleanos .................................. 44
2.2.4 Estructuras de control: condicionales y ciclos ..................................... 45
2.2.5 Funciones ............................................................................................ 50

v
Capítulo 3. TRASMISIÓN SERIE EN ARDUINO .................................................. 51

Capítulo 4. LAS ENTRADAS Y SALIDAS DIGITALES ............................................ 54


4.1 Funcionamiento de los interruptores, pulsadores y poténciometros ........ 55
4.2 Práctica 1: encendiendo y apagando varios leds ........................................ 60
4.3 Práctica 2: controlando el encendido de un LED
mediante un interruptor ............................................................................. 66
4.4 Práctica 3: control de dos semáforos. Un proyecto
completo con LED y pulsadores .................................................................. 70
4.5 Práctica 4: contador de pulsaciones ........................................................... 81
4.6 ¿Qué es eso del PWM? ............................................................................... 84
4.6.1 Práctica 5: variando la luminosidad de un LED ................................... 85
4.6.2 Funcionamiento de un pequeño altavoz ............................................. 87
4.6.3 Práctica 6 y práctica 7: haciendo sonar un altavoz ............................ 88
4.7 Introducción a las interrupciones en Arduino ............................................ 92
4.7.1 Práctica 8: control de un LED mediante un pulsador
sin interrupciones ................................................................................ 94
4.7.2 Práctica 9: control de un LED mediante un pulsador
con interrupciones ............................................................................... 95

Capítulo 5. LAS ENTRADAS ANALÓGICAS ........................................................ 99


5.1 Un poco de teoría analógica. El potenciómetro ....................................... 101
5.1.1 Práctica 10: el potenciómetro y Arduino .......................................... 101
5.2 Funcionamiento de un transductor piezoeléctrico ................................... 105
5.2.1 Práctica 11: monotorizando un transductor piezoeléctrico.............. 106
5.2.2 Práctica 12: tocando música con el zumbador ................................. 108

Capítulo 6. SENSORES BÁSICOS DE LUZ, TEMPERATURA,


DISTANCIA Y PRESENCIA ............................................................. 111
6.1 Práctica 13: funcionamiento de la LDR ..................................................... 111
6.2 Práctica 14: funcionamiento del sensor de temperatura ......................... 114

vi
6.3 Práctica 15: funcionamiento del sensor de distancia por ultrasonidos .... 120
6.4 Práctica 16: funcionamiento de un sensor de movimiento ...................... 124

Capítulo 7. EXTENDIENDO ARDUINO CON LIBRERÍAS .................................... 128


7.1 Librerías core ............................................................................................. 129
7.2 Librerías estándar...................................................................................... 130
7.3 Librerías contributivas............................................................................... 143
7.4 Extendiendo el Arduino con shields .......................................................... 144

Capítulo 8. VISUALIZANDO DATOS CON EL LCD............................................. 150


8.1 Funcionamiento del LCD paralelo. El HD44780 de Hitachi ....................... 155
8.1.1 Práctica 17: el HD44780 de Hitachi .................................................. 157
8.1.2 Práctica 18: diseñando caracteres a medida .................................... 160
8.2 Funcionamiento del LCD serie .................................................................. 161
8.2.1 Práctica 19: mostrando texto con el LCD serie ................................. 164
8.3 Funcionamiento del LCD gráfico. El KS0108.............................................. 165
8.3.1 Práctica 20: utilizando un GLCD ........................................................ 168
8.3.2 Práctica 21: mostrando texto en un GLCD ........................................ 169
8.3.3 Práctica 22: visualizando nuestras propias imágenes ...................... 173

Capítulo 9. CONTROL DE MOTORES CON ARDUINO ...................................... 175


9.1 Funcionamiento de un motor de continua (DC) ....................................... 175
9.2 Práctica 23: haciendo girar un motor DC .................................................. 178
9.3 ¡Más madera! El puente H y el integrado L293D ...................................... 180
9.3.1 Práctica 24: control del giro de un motor DC utilizando el L293D .... 183
9.3.2 Práctica 25: control total de un motor DC utilizando el L293D ......... 186
9.4 Funcionamiento de un motor paso a paso (PAP) ..................................... 189
9.4.1 Práctica 26: giro de un motor PAP unipolar
utilizando el ULN2003A..................................................................... 193
9.4.2 Librería “Steeper.h”: simplificando las cosas .................................... 195

vii
9.4.3 Práctica 27: control básico de un motor PAP bipolar
utilizando el L293D ............................................................................ 197
9.4.4 Práctica 28: utilizando la librería “Stepper.h” en un PAP unipolar ... 199
9.5 Funcionamiento de un servomotor (SERVO) ............................................ 201
9.5.1 Librería “Servo.h”: simplificando las cosas ....................................... 201
9.5.2 Práctica 29: control básico de un SERVO .......................................... 203
9.6 ¡Más caña con el motor brushless! ........................................................... 205
9.6.1 Práctica 30: control básico de un motor brushless ........................... 208
9.7 Haciéndolo todo más fácil con las shields ................................................. 209
9.7.1 Práctica 31: utilizando la Arduino Motor Shield ............................... 211

Capítulo 10. BUSES DE DATOS ...................................................................... 213


10.1 EL BUS I2C ............................................................................................... 213
10.1.1 Práctica 32: utilización de la memoria I2C 24LC512 ....................... 215
10.1.2 Práctica 33: expandiendo los puertos con el I2C MCP23017 .......... 221
10.1.3 Práctica 34: midiendo el tiempo con el I2C DS1307........................ 223
10.2 El bus SPI ................................................................................................. 228
10.2.1 Práctica 35: utilizando el potenciómetro digital SPI AD5206 ......... 230

Capítulo 11. COMUNICACIONES INALÁMBRICAS .......................................... 234


11.1 Comunicaciones inalámbricas XBee........................................................ 234
11.1.1 Configuración de los módulos XBee ................................................ 237
11.1.2 Práctica 36: aviso sonoro inalámbrico ............................................ 240
11.1.3 Práctica 37: visualización remota de temperaturas ....................... 245
11.2 Comunicaciones inalámbricas bluetooth ................................................ 248
11.2.1 Configuración de los módulos bluetooth Bee ................................. 251

Capítulo 12. ARDUINO Y EL INTERNET DE LAS COSAS .................................... 255


12.1 Características de la Arduino Ethernet shield ......................................... 257
12.1.1 La librería Ethernet ......................................................................... 260

viii
12.1.2 Práctica 38: implementando un Arduino web Server ..................... 263
12.1.3 Práctica 39: comunicándose con Twitter ........................................ 271
12.2 Características de la Arduino wifi shield ................................................. 276
12.2.1 La librería wifi ................................................................................. 277
12.2.2 Práctica 40: escaneando tu red inalámbrica WiFi .......................... 279
12.3 El servidor de datos Xively ...................................................................... 284
12.3.1 Práctica 41: monotorizando temperaturas
con el servidor Xively ....................................................................... 288
12.4 El servidor de datos Plotly....................................................................... 293
12.4.1 Práctica 42: adquisición y visualización de datos en Plotly ............ 295
12.4.1.1 El sensor de temperatura/humedad DHT22 .............................. 295

12.5 Arduino Yun............................................................................................. 300


12.5.1 Arduino Yun y el servidor Temboo .................................................. 307
12.5.2 Práctica 43: envío de correos electrónicos con Temboo ................. 307
12.5.3 Práctica 44: utilizando el sensor DHT22
y una hoja de cálculo con Temboo .................................................. 313
12.5.4 Práctica 45: utilizando el YUN para controlar un LED ..................... 316
12.5.5 Utilizando el YUN y Temboo con el generador
mágico de código ............................................................................ 322

Capítulo 13. ENTORNOS GRÁFICOS DE PROGRAMACIÓN ............................. 325


13.1 Entorno gráfico de programación S4A .................................................... 325
13.1.1 Práctica 46: intermitencia de un LED .............................................. 328
13.1.2 Práctica 47: variación de la intermitencia de un LED...................... 330
13.1.3 Práctica 48: control de un LED con un interruptor .......................... 331
13.1.4 Práctica 49: gobierno de un LED mediante un pulsador virtual...... 332
13.1.5 Práctica 50: control de un semáforo ............................................... 335
13.1.6 Práctica 51: control de un motor Servo .......................................... 337
13.1.7 Práctica 52: LM35 como termostato .............................................. 338

ix
13.2 Entorno gráfico de programación LabVIEW ............................................ 340
13.2.1 Práctica 53: control simple de un LED ............................................. 346
13.2.2 Práctica 54: lectura y escritura de valores en Arduino ................... 352
13.2.3 Práctica 55: intermitencia de un LED .............................................. 354
13.2.4 Práctica 56: control de una salida analógica PWM ........................ 356
13.2.5 Práctica 57: control de la velocidad y sentido de un Motor DC ...... 357
13.2.6 Práctica 58: medida de temperatura con un LM35 ........................ 360
13.2.7 Práctica 59: control de un motor paso a paso (PAP) ...................... 361
13.2.8 Práctica 60: control de un LCD ........................................................ 362

Apéndice I. PROTEUS Y ARDUINO ................................................................. 366

x
Prólogo
En verano de 2013, durante el mes de agosto, haciendo el camino de Santiago por
la ruta de Levante desde Valencia, me plantearon desde la editorial la idea de
escribir un libro sobre Arduino que fuera dirigido a estudiantes de formación
profesional de grado medio. La verdad es que no existía en ese momento un texto
en castellano, sencillo y ordenado, que recogiera la inmensa información que existe
en Internet sobre este tema y que fuera lo más ameno y práctico posible para
aquellos alumnos de electrónica que quieran acercarse a la plataforma Arduino.
Por otra parte, no se trataba de realizar un texto excesivamente técnico y
riguroso, sino un libro divertido y claro que fuera accesible a estudiantes con
pocos conocimientos de electrónica. Debía constituir una auténtica guía de
autoaprendizaje que consiguiera «enganchar» a los lectores desde el principio y
les proporcionara un camino para poder desarrollar sus propios proyectos o ideas
sin perderse en la red, o en libros demasiado técnicos que en casi todos los casos
están escritos en el idioma de William Shakespeare.
David Cuartelles (uno de los padres de la criatura Arduino) mencionó una vez, en
una de sus conferencias, que la idea de la que partió todo fue la de poner en
manos de sus alumnos una herramienta de desarrollo que fuera barata y muy
sencilla de utilizar. Hasta ese momento las plataformas microprogramables para
desarrollar proyectos electrónicos eran demasiado caras y demasiado
complicadas para un estudiante que empezara de cero. Personalmente, provengo
del mundo de los microcontroladores PIC y debo reconocer que, aunque en su
momento supusieron una revolución de precios con respecto a los micros de Intel,
el lenguaje ensamblador en que se programaban resultaba bastante tedioso. Pues
bien, al poco tiempo aparecieron compiladores en lenguajes de alto nivel como C
o Basic, pero eran muy caros, y los pocos compiladores que había libres o GNU
venían «pelados», es decir, sin librerías. Con lo cual, para conectarte un PIC a un
LCD tenías que currártelo mucho; y no hablemos de conectarlo a Internet.
Cuando mi amigo Óscar González, uno de los primeros distribuidores de Arduino en
España y responsable de la empresa bricogeek (www.bricogeek.com) me ofreció, hace
unos años, las bondades de este producto, la verdad es que no le hice mucho caso, ya
que yo seguía a pie juntillas realizando mis proyectos con los famosos

xi
microcontroladores PIC de la empresa Microchip y no pensaba que esa aventura fuera a
revolucionar el mundo de los aficionados a la electrónica. Me equivocaba de lleno.

Pues bien, David Cuartelles y Massimo Banzi, ambos profes de universidad,


idearon una primera placa de Arduino con la sana idea de que fuera libre y
gratuita. De tal manera que cualquiera podía bajarse de la red los esquemas y el
pequeño sistema operativo que contiene el micro y hacérselo uno mismo,
comprando los componentes en cualquier tienda de electrónica.

Se me ocurre un símil como cuando surgió Linux; un concepto libre y puesto a


disposición de los internautas y aficionados de lo más variopinto para que lo
modificasen, mejorasen o simplemente arrojasen a la papelera de reciclaje y
pasasen a otra cosa.

Pues algo parecido está pasando con Arduino, una plataforma de hardware libre con
una inmensa cantidad de librerías de su compilador realizadas por aficionados,
entusiastas, etc. que están disponibles en la red de redes para que las descarguemos,
utilicemos o mejoremos. De tal manera que construirse un termómetro con un
visualizador LCD sea algo sencillo al alcance de cualquiera. De ahí, la aparición de un
término tan en boga últimamente que es el DIY (Do It Yourself: ‘hazlo tú mismo’) ya
que esto es posible usando una plataforma libre como Arduino.

El libro que tienes en tus manos pretende ser una guía de autoaprendizaje que te
permita conocer básicamente lo que es Arduino a través de varios proyectos
sencillos resueltos y otros propuestos. Además, aprenderás a manejar algunos
dispositivos como ledes, sensores de diversos tipos, LCD, motores de continua,
servos, motores paso a paso (tan utilizados hoy en día en las impresoras 3D) y,
como no, adentrarte en el novedoso mundo de Internet de las cosas (IOT)
comunicando tu Arduino con Internet. Y todo ello, partiendo de unos
conocimientos muy elementales de electrónica.

Espero que esta aventura que está a punto de comenzar os ilusione lo mismo que me
sucedió a mí cuando descubrí lo que esta pequeña plaquita podía llegar a hacer.

Germán Tojeiro Calaza


Profesor de electrónica en el Instituto Monte Neme (Carballo, La Coruña)
http://arduinorastman.blogspot.com.es/

xii
Convenciones utilizadas en este libro
A lo largo del presente libro se exponen un conjunto de prácticas ordenadas en
dificultad. Además, se proponen otras para que las realices tú mismo, mejorando
tu experiencia en la programación de Arduino. Si tienes la posibilidad de acceder
al software de simulación Proteus a través de tu instituto, universidad o a nivel
particular, podrás simular su funcionamiento porque la mayoría de los
componentes utilizados en estas prácticas están modelizados con este estupendo
software. Las prácticas sugeridas se representan de dos maneras:

Las anotadas con el siguiente símbolo son de un nivel básico y no


comprenden excesiva dificultad.

Con este logotipo se proponen otro tipo de prácticas, que casi


podemos catalogar de pequeños proyectos, y que implican un mayor
esfuerzo por tu parte. Sin duda, te afianzarán definitivamente en el
tema tratado.

Con este indicativo se aclara o se prodfundiza en algún aspecto


relatado del texto próximo.

xiii
Agradecimientos
En primer lugar, agradecer a Jofrer de TFORMICROS.S.A, la revisión de los códigos
de programa relativos al capítulo 12.

Támbien, debo reconocer la ayuda de mi amigo José Abelenda porque, en los


momentos de ofuscación con alguna práctica, me sacaba de casa para tomarnos
unas cañas.

Finalmente, reconocer la paciencia infinita de mi hijo durante estos últimos


meses.

xiv
Marcas registradas
El nombre y el logo de Arduino son marcas registradas por el equipo de Arduino
en todos los países.

El nombre y el logo de Proteus ISIS, VSM y ARES son marcas registradas por
Labcenter Electronics en todos los países.

El nombre y el logo de S4A son marcas registradas por Citilab en todos los países.

El nombre y logo de labVIEW son marcas registradas por National Instruments en


todos los países.

xv
CAPÍTULO

INICIO CON ARDUINO


DESDE CERO

En esta primera parte vamos a acercarnos, tímidamente, pero con decisión, al


Arduino y a la instalación de su entorno de desarrollo (a partir de ahora: IDE).
Examinaremos sus principales características y realizaremos una primera práctica
sencilla que nos va a funcionar a la primera y hará saltar de alegría. Después,
veremos que Arduino no está solo en la vida y que tiene hermanos mayores y
menores. Por último, os recomendaré algunas herramientas, tanto de software
como de hardware, para hacer realidad vuestros proyectos electrónicos.

1.1 ¿Qué es Arduino y para qué sirve?


Arduino es una plataforma de electrónica abierta (open hardware) para la
creación de prototipos basada en software y hardware libre. Se creó para artistas,
diseñadores, aficionados y cualquier interesado en crear entornos u objetos
interactivos.

Arduino puede tomar información y datos del entorno a través de sus pines
de entrada por medio de toda la gama de sensores que existen en el mercado. En
base a ello, puede ser usada para controlar y actuar sobre todo aquello que le
rodea; como por ejemplo luces, motores y otro tipo de actuadores. El
microcontrolador de la placa Arduino se programa mediante un sencillo lenguaje
de programación basado en C/C++ y un entorno de desarrollo (IDE) que responde
a las especificaciones de open software. Los proyectos hechos con Arduino
pueden ejecutarse sin necesidad de conectarlo a un ordenador, si bien tienen la
posibilidad de hacerlo y comunicarse con diferentes tipos de software (por
ejemplo: Flash, Processing, MaxMSP, etc.).

Las placas pueden ser hechas a mano o comprarse montadas de fábrica. El


software puede ser descargado de forma gratuita. Los ficheros de diseño de

1
Taller de Arduino

referencia (CAD) están disponibles bajo una licencia abierta, así pues, eres libre de
adaptarlos a tus necesidades.

Se llama open hardware a los dispositivos de hardware cuyas


especificaciones y diagramas esquemáticos son de acceso público, ya
sea bajo algún tipo de pago o de forma gratuita. Se debe recordar en
todo momento que libre no es sinónimo de gratis. El hardware libre
forma parte de la cultura libre.

Se llama open software al tipo del software que respeta la libertad


de los usuarios sobre su producto adquirido y, por tanto, una vez
obtenido puede ser usado, copiado, estudiado, modificado, y
redistribuido libremente.

Un microcontrolador (abreviado μC, UC o MCU) es un circuito


integrado programable, capaz de ejecutar las órdenes grabadas en su
memoria. Está compuesto de varios bloques funcionales, los cuales
cumplen una tarea específica. Un microcontrolador incluye en su
interior las tres principales unidades funcionales de una
computadora: unidad central de procesamiento, memoria y
periféricos de entrada/salida.

Arduino sirve para implementar cualquier idea que te propongas realizar.


Por ejemplo, puedes pensar en automatizar el control de tu terrario, o en
construir un pequeño robotito, tipo auto, que evite objetos y que suba las
escaleras de tú casa. Este último caso revoloteó por mi cabeza hace algunos
meses; pero cuando miré los precios en Internet de los dichosos robotitos, pegué
un brinco en la silla. Así que me propuse realizar yo mismo (DIY) las carcasas de
los mismos.

¿Y cómo? Pues construyendo mi propia impresora 3D (la prusa 2) y


dándome cuenta de que su placa controladora está basada en un tipo de Arduino,
con lo cual su entorno de programación ya me era conocido. Incluso, este verano,
caminando por tierras de Castilla-La Mancha hacia Santiago, bajo un sol de
justicia, le di vueltas a la cabeza para averiguar cómo coser a uno de los bolsillos
de la mochila algún tipo de célula Peltier gobernada con Arduino que enfriara la
botella de agua. No hay nada más desagradable que beberse agua a la divertida
temperatura de 35 °C.

2
1. Inicio con Arduino desde cero

Podéis echar un vistazo al siguiente enlace en el que veréis cómo un


desarrollador consiguió vulnerar las puertas de un montón de hoteles utilizando
una placa Arduino:

http://blog.bricogeek.com/noticias/arduino/hack-que-
permite-abrir-puertas-de-hoteles-con-arduino/

En definitiva, las posibilidades de Arduino son inmensas y además todos los


días aparecen en la red aplicaciones de lo más insospechado y curioso. Además, si
te cansas del terrario o del robotito, puedes reutilizar la placa reprogramable para
otros nuevos proyectos que se te ocurran.

Figura 1.1

En la figura 1.1 se puede observar la apariencia de un Arduino UNO. Es la


placa más utilizada por su carácter de aplicación general. Cabe en la palma de la
mano y cuesta alrededor de los 25 euros (dichoso IVA). Con ella realizaremos la
mayoría de los proyectos de este libro.

El microcontrolador (el chip más grande de la figura 1.1) es un Atmega328


de la empresa Atmel. Tiene 14 pines digitales que se pueden usar como entrada o
como salida. Funciona a 5 V y cada pin puede suministrar hasta 40 mA. La
intensidad máxima de entrada también es de 40 mA.

También dispone de 6 pines de entrada analógicos que trasladan las señales


a un conversor analógico/digital de 10 bits.

3
Taller de Arduino

Si sabes un poco de electrónica (y si no, lo irás aprendiendo más adelante)


te adelanto que además posee los siguientes pines especiales:

• RX y TX: se usan para transmisiones serie de señales TTL.


• Interrupciones externas: los pines 2 y 3 están configurados para
generar una interrupción en el micro. Las interrupciones pueden
dispararse cuando se encuentra un valor bajo en estas entradas y
con flancos de subida o bajada.
• PWM: Arduino dispone de 6 salidas destinadas a la generación de
señales PWM de hasta 8 bits.
• SPI: los pines 10, 11, 12 y 13 pueden utilizarse para llevar a cabo
comunicaciones SPI que permiten trasladar información full duplex
en un entorno Maestro/Esclavo.
• I2C: permite establecer comunicaciones a través de un bus I2C. El
bus I2C es un producto de Phillips para interconexión de sistemas
integrados. Actualmente se puede encontrar una gran diversidad de
dispositivos que utilizan esta interfaz, desde pantallas LCD,
memorias EEPROM, sensores, etc.

La placa Arduino puede alimentarse directamente a través del propio cable


USB o mediante una fuente de alimentación externa. Puede ser un pequeño
transformador o, por ejemplo, una pila de 9 V. Los límites están entre los 6 y los
12 V. Como única restricción hay que saber que, si la placa se alimenta con menos
de 7 V, la salida del regulador de tensión a 5 V puede dar menos que este voltaje;
y si sobrepasamos los 12 V, probablemente dañaremos la placa. La alimentación
puede conectarse mediante un conector tipo Jack de 2,1 mm con el positivo en el
centro o directamente a los pines Vin y GND marcados sobre la placa.

El «hazlo tú mismo», abreviado: DIY (en inglés: Do It Yourself), es la


práctica de la fabricación o reparación de cosas por uno mismo, de
modo que se ahorre dinero y se aprenda al mismo tiempo. Es una
forma de autoproducción, sin esperar la voluntad de otros, para
realizar proyectos propios. La ética del Do It Yourself está
generalmente asociada a varios movimientos anticapitalistas, ya que
rechaza la idea de tener que comprar siempre a otros las cosas que
uno desea o necesita. Se trata de un movimiento contracultural
trasladable a cualquier ámbito de la vida cotidiana. Hay muchos

4
1. Inicio con Arduino desde cero

ejemplos del uso de esta filosofía. La primera puede ser las


reparaciones que suelen hacer algunas personas en su casa, sin la
necesidad de tener que recurrir a profesionales como fontaneros,
electricistas, etc.

1.2 Configuración e instalación


Supongo que en estos momentos ya tenéis una flamante y reluciente placa
Arduino entre las manos. Ahora ya podemos empezar a configurar e instalar
nuestro entorno de trabajo para desarrollar nuestros proyectos. Además,
conectaremos el Arduino al ordenador e instalaremos, si hace falta, los drivers
adecuados para que ambos se puedan comunicar perfectamente (Figura 1.2).

Figura 1.2

1.2.1 Instalación del entorno de desarrollo (IDE)


Lo primero que tenemos que hacer es descargarnos dicho entorno (IDE) de la
página web oficial de Arduino: http://arduino.cc/en/Main/Software. Dependiendo
del sistema operativo que tengas instalado en tu equipo deberás bajarte una
versión u otra. La verdad es que la apariencia y funcionamiento del entorno de
desarrollo es igual para todos los sistemas operativos. Se trata de un software que
nos permitirá escribir, depurar y desarrollar el código de programa asociado a
nuestros proyectos. Después de instalarlo, lo ejecutamos y, al hacerlo, se nos
abrirá en pantalla una ventana con el aspecto de la figura 1.3.

En Linux, el proceso en realidad depende de la distribución que esté


utilizando. Te sugiero consultar la página de Internet http://www.arduino.cc/
playground/Learning/Linux. De todas maneras, no suele presentar inconvenientes
en las distribuciones más extendidas como Ubuntu o Suse. Vamos, que más fácil,
imposible.

5
Taller de Arduino

Figura 1.3

El IDE proporciona una interfaz gráfica en la que se puede escribir el código,


depurarlo, compilarlo y cargarlo o subirlo al Arduino. En un primer vistazo,
observamos que en la parte superior tenemos seis iconos en la barra de botones
que utilizaremos muy a menudo (Figura 1.4).

Figura 1.4

Además, si desplegamos el menú de Opciones de la barra superior,


observamos que cada elemento del menú ofrece más opciones que iremos
descubriendo progresivamente a lo largo de este libro. Aunque ahora es necesario
que os fijéis en el submenú de Herramientas (Figura 1.5) ya que presenta dos
opciones imprescindibles para que todo funcione desde el principio:

6
1. Inicio con Arduino desde cero

• Tarjeta Serie: determina el tipo de Arduino con el que trabajamos.


• Puerto Serial: indica el puerto serie del ordenador al cual tenemos
conectado nuestro Arduino.

Estos dos datos se pueden observar debajo de la ventana de mensajes tal y


como se muestra en la figura 1.5. Volveremos sobre este tema más adelante.

Figura 1.5

1.2.2 Instalación de los drivers de nuestro Arduino


Para que nuestro ordenador reconozca la placa Arduino mediante el conector y su
correspondiente cable USB (Figura 1.6 y Figura 1.7) es necesario instalar los
controladores o drivers adecuados.

Figura 1.6

7
Taller de Arduino

Figura 1.7

Un controlador de dispositivo (llamado normalmente controlador, en


inglés, driver) es un programa informático que permite al sistema
operativo interaccionar con un periférico, haciendo una abstracción
del hardware y proporcionando una interfaz para usarlo. Se puede
esquematizar como un manual de instrucciones que le indica cómo
se debe controlar y comunicarse con un dispositivo en particular. Por
tanto, es una pieza esencial, sin la cual no se podría usar el hardware.

Si utilizas Linux o Mac lo tienes muy sencillo: solo tienes que conectar el
Arduino. Este estará preparado para trabajar y no necesitaremos instalar ningún
driver. En cambio, si eres de los que no quieres renunciar a las bondades y
pantallazos azules de error de Windows, deberás seguir los siguientes pasos para
que todo vaya bien.

1.2.3 Instalación de los drivers bajo entorno


Windows (XP, Vista, Windows 7 y 8)
PASO 1: conectamos el Arduino al ordenador mediante el cable USB. Si
observamos una ventana de aviso como la mostrada en la Figura 1.8 no nos
debemos preocupar en absoluto.

Figura 1.8

8
1. Inicio con Arduino desde cero

PASO 2: nos vamos al panel de control de Windows y después al


Administrador de dispositivos para observar que nuestro Arduino no está
instalado (Figura 1.9).

Figura 1.9

Abrimos las opciones de este «dispositivo desconocido» y actualizamos el


software del controlador (Figura 1.10) buscándolo en el equipo (Figura 1.11).

Figura 1.10

Figura 1.11

9
Taller de Arduino

PASO 3: examinamos la carpeta donde hemos descomprimido el fichero


Arduino.zip y abrimos la subcarpeta drivers. (Figura 1.12)

Figura 1.12

PASO 4: finalmente, y como Windows es software propietario y no le gusta lo


relacionado con lo libre, nos mostrará un aviso en rojo (Figura 1.13) advirtiéndonos
de que vamos a instalar algo que no reconoce. Sin embargo, le decimos que sí, que
lo instale de todas maneras. Ahora recibimos la confirmación de que nuestro
Arduino se ha instalado perfectamente en un puerto serie. Si volvemos al
Administrador de dispositivos del panel de control saltamos de alegría al comprobar
que ya no nos pone «dispositivo desconocido», sino que aparece el Arduino
conectado a un puerto serie tal y como se muestra en la Figura 1.14.

Figura 1.13

Figura 1.14

1.3 Una primera práctica: parpadeo de un led


Llegó la hora de realizar nuestra primera práctica. Vamos a hacer parpadear un
diodo LED conectado a una patilla digital de nuestro Arduino. La tarea es sencilla,
pero no trivial. Aprenderemos el procedimiento general de realización de
proyectos con Arduino. Aplicaremos este método a todos los diseños que
llevemos a cabo a lo largo de todo el libro.

10
1. Inicio con Arduino desde cero

Lo primero que tenemos que hacer es abrir el IDE y seleccionar el tipo de


Arduino que tenemos y el puerto al que está conectado. Esto lo llevamos a cabo
desde el submenú Herramientas (Figuras 1.15 y 1.16.)

Figura 1.15

Figura 1.16

Un truco que empleo a menudo, cuando no me acuerdo del número del


puerto serie al que está conectado mi Arduino, es desconectarlo del PC y observar
la lista de puertos series en el IDE. A continuación, vuelvo a conectar el Arduino y
veo de nuevo la lista de los mismos. Ahora aparecerá un nuevo puerto al final de
esa lista. Ahí es donde está mi Arduino.

11
Taller de Arduino

Si eres afortunado y estás utilizando una distribución Linux te habrás dado


cuenta de que los puertos serie presentan una nomenclatura diferente a lo
explicado anteriormente. Por ejemplo, un caso típico sería el siguiente:
/dev/ttyUSB0 o /dev/ttyUSB3. En OSX varía un poco: /dev/tty.usbmodem. De
todas maneras, el procedimiento de selección es el mismo.

La palabra española «led» proviene del acrónimo inglés LED (Light


Emitting Diode: diodo emisor de luz). Los LED se usan como
indicadores y en iluminación. Existe una forma básica de conocer la
polaridad de un led. La pata más larga siempre va a ser el ánodo y la
más corta el cátodo.

Ahora nos fijamos en el diodo LED y cómo se conecta a nuestro Arduino. En


la figura 1.17 observamos el aspecto que presenta el hardware y en la figura 1.18
una representación gráfica realizada con el programa fritzing. Comentaré las
maravillas de este software al final de este primer capítulo.

Figura 1.17

Figura 1.18

12
1. Inicio con Arduino desde cero

Es decir, debemos montar el circuito tal y como aparece en la figura 1.17,


con el terminal más largo del LED (ánodo) al pin referenciado con el número 13 y
el otro terminal (cátodo) al pin de masa o GND. El siguiente paso es escribir el
código que subiremos al Arduino y hará parpadear el LED rojo. Para ello, o bien
abrimos el sketch (‘programa’) llamado blink.pde (los programas de Arduino
tienen la extensión pde) desde la opción Archivo->Ejemplos bajo el menú de
Opciones (Figura 1.19) o bien, molestándose un poco y escribiendo el código que
os muestro en la figura 1.20. Personalmente os recomiendo que hagáis esto
segundo, ya que de esta manera os acostumbraréis rápido a utilizar el lenguaje de
programación de Arduino. Para esto debéis abrir un fichero nuevo en blanco
desde la opción Archivo->Nuevo.

Figura 1.19

Figura 1.20

13
Taller de Arduino

Un programa diseñado para ejecutarse sobre un Arduino se conoce como


sketch. Podríamos traducirlo como ‘boceto’ o ‘borrador’. Un sketch siempre tiene
la misma estructura. Lo que se escriba entre las llaves que acompañan al nombre
setup, se ejecuta una única vez siempre que se encienda o resetee la placa. Lo que
se escriba dentro de las llaves que acompañan al nombre loop se ejecutará
constantemente hasta que se apague el Arduino.

Como vemos en la figura 1.21 la estructura básica de un programa consiste


en cuatro bloques. El primero es opcional y contiene una barra inclinada seguida
de un asterisco: “/*” para abrir el bloque y una segunda barra y asterisco para
cerrarlo: “*/”. Contiene texto en el que puedes escribir una referencia al autor
(ojalá, seas tú mismo), la fecha de creación del mismo, a quién va dedicado, etc.,
es decir, lo que quieras. En el siguiente bloque defines las variables que utilizarás
en el sketch. Más adelante veremos lo que es una variable, o sea, que no te
preocupes. El tercer bloque sí que es importante, porque ahí defines la
configuración del hardware de la placa. En nuestro caso le decimos que el pin 13
funcionará como salida ya que lo tenemos conectado al LED. El cuarto bloque
repetirá continuamente y en bucle las instrucciones que contiene entre las llaves
(de ahí el nombre de loop).

Figura 1.21

14
1. Inicio con Arduino desde cero

Práctica 1. Parpadeo de un lED (Encabezado)

/* Parpadeo. Enciende y apaga un led con intervalos de 1


segundo.*/

El encabezado contiene solo información y de ninguna manera se ejecuta.


En este caso, informa de qué es lo que hace el programa.

Práctica 1a. Parpadeo de un lED (Inicialización)

int led = 13; // El LED está conectado al Pin 13

void setup()
{
pinMode(led, OUTPUT);
}

En este bloque setup() (inicialización) establecemos las variables que


utilizamos durante todo el programa. Definimos una variable llamada led de tipo
entero int y le asignamos el número 13. De ahora en adelante cada vez que
aparezca la palabra led, en realidad, estaremos haciendo referencia al número 13.
Debemos fijarnos que todas las sentencias o instrucciones que contenga nuestro
programa acaban en un punto y coma. Esto es una regla del lenguaje de
programación C obligatoria. Observamos también un comentario de texto: “// El
LED está conectado al Pin 13”. Nos aclara que el LED está conectado a dicho pin o
patilla de nuestro Arduino. Es recomendable añadir de vez en cuando comentarios
a nuestro programa para clarificar el código.
Las instrucciones o funciones que van entre llaves solo se ejecutan una sola
vez y configuran el hardware de Arduino. En este caso tenemos solo una:
pinMode (número de pin, entrada o salida).
pinMode es una función que configura uno de los pines digitales de nuestro
Arduino como entrada o salida. En el caso del Arduino UNO tenemos catorce
pines digitales; el primero es el 0 y el último es el 13. Pues bien, pinMode
establece que «tal pin» sea entrada o salida. La palabra INPUT establece entrada y
la palabra OUTPUT inicializa el pin como salida. Así que para configurar el pin 13
como salida tendremos que escribir:
pinMode(13, OUTPUT);

Si lo quisiéramos configurar como entrada tendríamos que escribir:


pinMode(13, INPUT);

15
Taller de Arduino

De esta forma tan sencilla podemos configurar todos los pines digitales del
Arduino para que actúen como entradas o salidas, dependiendo de lo que
tengamos conectados a los mismos.

Práctica 1b. Parpadeo de un LED (Bloque repetitivo)

Dentro de la estructura loop() (repetitivo) y también entre llaves, aparece el


trozo de programa que se va a repetir continuamente. Ahora tenemos una nueva
función llamada digitalWrite (número de pin, estado alto o bajo).
A estas alturas, ya tienes que haberte dado cuenta de que esto tiene que
ver con señales digitales. Como sabes, las señales digitales binarias representan
dos estados: un estado bajo, conocido como 0, apagado u OFF; y un estado alto
conocido como 1, encendido u ON. El estado alto o HIGH se representa con 5 V y
el estado bajo o LOW se representa con 0 V.
digitalWrite es una función que necesita dos parámetros: el primero, una
vez más, es el número de pin digital y el siguiente es el estado lógico que
queremos mantener en ese pin, por lo tanto, si quiero enviar un valor alto al pin
13 tendré que escribir:

digitalWrite(13, HIGH);

Si quiero tener 0 V en el pin 13 escribiré:


digitalWrite(13, LOW);

void loop()
{
digitalWrite (led, HIGH); // Enciende el LED
delay(1000); // Espera 1 segundo
digitalWrite (led, LOW); // Apaga el LED
delay (1000); // Espera 1 segundo
}

Delay es una función muy sencilla. Hace que toda la ejecución de Arduino
pare o se detenga durante los milisegundos que le indiquemos como parámetro.

Por lo tanto, si quiero esperar medio segundo escribiré:


delay(500);

16
1. Inicio con Arduino desde cero

Si quiero esperar diez segundos escribiré:


deLay(10000);

Por tanto, echando un nuevo vistazo al bloque loop(), observamos que el


diodo LED conectado a la patilla 13 se va a encender (estado HIGH) durante 1
segundo y se va a apagar (estado LOW) durante otro segundo, consiguiendo el
ansiado efecto de parpadeo.

Lo que nos queda por hacer ahora es subir nuestro flamante código a la
placa Arduino y ver si funciona. Para ello presionamos el botón de compilación y
subida de código indicado en la Figura 1.22. Si todo va bien veremos dos lucecitas
(dos diodos leds) serigrafiadas como TX y RX en la placa parpadear durante un
momento (Figura 1.23). Esto indica que el programa está cargándose en el
microcontrolador de Arduino. Este breve parpadeo es un importante aviso de que
las cosas van por buen camino: la placa está conectada correctamente al puerto
serie y el código del sketch no tiene errores de sintaxis. Si algo de esto fuera mal
observaríamos errores en la ventana de mensajes del entorno de desarrollo IDE
(Figura 1.24).

Figura 1.22

Figura 1.23

17
Taller de Arduino

Figura 1.24

Observamos que el error cometido se muestra con una barra de color


amarillo a continuación de la línea de programa responsable del mismo.

Por otra parte, si queremos en algún momento, comprobar o verificar si el


código está bien escrito porque nos hemos olvidado algún punto y coma o si, por
ejemplo, hemos escrito digitalwrite en vez digitalWrite, podemos recurrir al
botón de verificación de programa que nos avisará si todo va bien. (Figura 1.25).

Figura 1.25

Si te fijas en la placa, justo enfrente del pin digital número 13, tienes
un pequeño LED que tiene serigrafiada una letra «L» justo al lado. Es
un diodo que está conectado directamente al pin 13 y que no
necesita de ningún componente adicional. La manera de programarlo
es exactamente la misma que en el caso anterior. Por eso, cuando
pruebes el sketch, notarás que aparte del parpadeo del led rojo, se
producirá el mismo efecto en este led pequeñito ya que ambos están
en paralelo. Si el primer día que adquieres tu Arduino, no tienes un
led a mano, puedes utilizar ese diodo para probar el sketch anterior.

18
1. Inicio con Arduino desde cero

Realiza el mismo montaje anterior, pero utilizando el pin 8 para


conectar el diodo LED.
Con el montaje anterior haz que el LED esté encendido 1 segundo y
apagado 2.
Diseña un montaje con dos LED conectados a los pines digitales 9 y 4.
El primer LED deberá encenderse y apagarse cada 4 segundos. El
segundo LED cada 3 segundos.

1.4. ¿Qué tipo de Arduino escoger?


Hace unos años, cuando me decidí a meterme en el mundo Arduino y visité la
página web del distribuidor www.bricogeek.com, me percaté de que existían
numerosas variantes del mismo producto Arduino (Arduino UNO, Mega, Mini,
Pro, Lilypad, Ethernet, etc.). Todas ellas parten de la misma base, pero
presentaban diferencias que podían ser determinantes a la hora de elegir una u
otra: el tamaño, el número de entradas, el número de salidas, el voltaje de
alimentación, la necesidad de programadores externos, el nivel de conocimientos
requerido, etc.

Por eso, y aunque recomiendo el Arduino UNO para principiantes, voy a


enumerar y describir los tipos de Arduino que ofrece el mercado para que os
hagáis una idea de lo grande y variopinta que es su familia. Además, más
adelante, cuando emprendáis proyectos más ambiciosos, seguro que elegiréis un
tipo Arduino acorde a vuestras necesidades (Figura 1.26).

Figura 1.26

19
Taller de Arduino

Arduino UNO Rev 3. Esta versión de Arduino es la que recomiendo para


empezar. Está basada en el chip microcontrolador ATmega328, pero en lugar de
integrar un chip FTDI (conversor de señal serie/USB) como su predecesora, la
mítica Duemilanove, incorpora un chip ATmega16U2. Esto permite ratios de
transferencia mayores a la hora de comunicarse con el ordenador y no precisa
que se instalen los drivers para los sistemas operativos de Linux o Mac. Además,
presenta la capacidad para mostrarse como un teclado, un ratón, un joystick, etc.

 Es tremendamente popular y se utiliza como estándar en institutos y


universidades.
 Incorpora un chip microprocesador ATmega328.
 Utiliza un chip ATmega16U2 para la conversión USB a serie.
 Funciona a 5 V y 16 MHz.
 La alimentación recomendada es de 7 a 12 V.
 14 pines de E/S (6 de ellos proporcionan PWM).
 6 pines de entrada analógica.
 Memoria Flash de 32 kB.
 Dispone de un puerto USB para la transmisión de datos.
 Dispone de un conector tipo Jack (cilíndrico) para la alimentación.
 Dispone de botón de Reset.
 Todos los pines están desglosados en terminales hembra para
facilitar las conexiones.

Dada su rápida curva de aprendizaje y su precio económico es ideal para


educadores, diseñadores y cualquiera interesado en la electrónica y robótica.

Arduino Leonardo es la sucesora de la Arduino UNO y es una placa de


prototipado electrónico que lleva un microprocesador integrado basado en el chip
ATmega32U4. Dispone de 20 entradas/salidas digitales (7 de las cuales se pueden
utilizar como salidas PWM) y de 12 entradas analógicas, un oscilador de cristal de
16 MHz, un conector micro USB, un conector a la fuente de alimentación, un
conector ISCP y un pulsador para el reset.

Arduino Leonardo (Figura 1.27) se diferencia de todos los modelos


anteriores en que el chip ATmega32U4 integra la comunicación USB, evitando la
necesidad de un microprocesador secundario (como los cables y tableros FTDI, o
el chip convertidor USB/Serial de la Arduino UNO). Esto significa que los sketches

20
1. Inicio con Arduino desde cero

de Arduino con Arduino Leonardo ocuparán más espacio en la memoria de


programa del micro porque también administran la interacción USB, pero al
mismo tiempo, permiten que Arduino Leonardo se muestre como un ratón o un
teclado cuando se conecta al ordenador. Para ello, se han preparado una serie de
librerías, además de un puerto serie CDC (o puerto COM virtual).

Figura 1.27

Por otro lado, Arduino Leonardo presenta una serie de variaciones en


cuanto al comportamiento de la placa que se detallan en la Guía de iniciación:

http://arduino.cc/en/Guide/ArduinoLeonardoMicro?from=Guide.ArduinoLeonardo

También ha cambiado el tipo de conector USB (de USB a micro USB) y la


posición del botón reset (que ahora se encuentra cerca del borde superior). En
cuanto al microcontrolador, Arduino Leonardo usa un chip ATmega32U4 que va
soldado a la placa por lo que no se puede cambiar. La placa Leonardo está
disponible en 2 versiones diferentes. Una con terminales para poder soldar los
cables directamente a la placa, y otra sin terminales para proyectos de
prototipado (formato utilizado habitualmente para educación). No te olvides de
comprar un cable USB microUSB para poder programarlo.

 Conviene tener experiencia previa con otros modelos de Arduino.


 Actualizada con un chip ATmega32u4.
 No dispone de un microprocesador secundario para la conversión
USB a Serie.
 Funciona a 5 V y 16 MHz.
 La alimentación recomendada es de 7 V a 12 V.
 20 pines de E/S (7 de ellos proporcionan PWM).

21
Taller de Arduino

 12 pines de entrada analógica.


 Memoria Flash de 32 kB.
 Dispone de un puerto micro USB para la transmisión de datos.
 Dispone de un conector tipo Jack (cilíndrico) para la alimentación.
 Dispone de botón de reset.
 Disponible en 2 versiones diferentes: con terminales y sin terminales.
 Solo funciona con la versión 1.0.1 y superiores del IDE de Arduino. Es
más barato que el Arduino UNO.

Arduino Mega 2560 REV3. Esta es la versión más reciente (Figura 1.28) de
Arduino Mega. Esta placa ha sido actualizada con un chip ATmega2560. Este chip
proporciona una memoria flash de 256 K (el doble que el modelo anterior). Otra
diferencia con su predecesora es la sustitución del chip FTDI por un chip
ATmega8U2.

La forma de manejar de esta placa es muy parecida a la de una placa


Arduino UNO pero dispone de más espacio de programación y una usabilidad algo
más compleja. Esta placa posee 54 pines digitales de entrada/salida, de los cuales
14 proporcionan PWM, 16 son entradas analógicas y 4 son UART serie. Con esta
placa, las posibilidades son amplísimas. Es la placa ideal para proyectos más
complejos en los que necesitemos más entradas y salidas o más memoria.

Figura 1.28

Esta placa es una revolución para el mundo de la robótica o los proyectos


con grandes necesidades de memoria para el programa (como por ejemplo
haciendo la función de placa controladora de las impresoras 3D). Hay que tener
en cuenta que su tamaño también es mayor lo que en algunas circunstancias
puede suponer un inconveniente.

22
1. Inicio con Arduino desde cero

 Es ideal para proyectos más complejos.


 Actualizada con un chip ATmega2560.
 Utiliza un chip ATmega8U2 para la conversión USB a Serie.
 Funciona a 5 V y 16 MHz.
 La alimentación recomendada es de 7 V a 12 V.
 54 pines de E/S (14 de ellos proporcionan PWM).
 16 pines de entrada analógica.
 Memoria Flash de 256 kB.
 Dispone de un puerto USB para la transmisión de datos.
 Dispone de un conector tipo Jack (cilíndrico) para la alimentación.
 Dispone de botón de reset.
 Todos los pines están desglosados en terminales hembra para
facilitar las conexiones.

Arduino Mega ADK es una de las placas más recientes desarrolladas por
Arduino. Esta es una placa que está basada en la Arduino Mega 2560, pero
modificada para permitir su uso con el kit de desarrollo Android Open Accessory
Development Kit (ADK) de Google. Para hacer esto posible, dispone de un puerto USB
Host como interfaz de conexión con dispositivos Android basados en el chip
MAX3421e.
Esta sería la placa ideal (Figura 1.29) para todas aquellas personas que
quieran integrar accesorios de hardware con un dispositivo Android haciendo uso
de la plataforma de Arduino. Para más información sobre cómo utilizar esta placa
con Google ADK, puedes echar un vistazo en la web oficial de Android.

Figura 1.29

 Utiliza un chip ATmega8U2 para la conversión USB a Serie.


 Funciona a 5 V y 16 MHz.

23
Taller de Arduino

 La alimentación recomendada es de 9 V.
 54 pines de E/S (14 de ellos proporcionan PWM).
 16 pines de entrada analógica.
 Memoria Flash de 256 kB.
 Dispone de un puerto miniUSB Host como interfaz de conexión con
dispositivos Android.
 Dispone de un puerto USB para la transmisión de datos.
 Dispone de un conector tipo Jack (cilíndrico) para la alimentación.
 Dispone de botón de reset.
 Todos los pines están desglosados en terminales hembra para
facilitar las conexiones.

Arduino Ethernet (Figura 1.30) es una placa basada en el microcontrolador


ATmega328 (igual que el modelo Arduino Uno). Se trata de la combinación en una
sola placa de un Arduino UNO y una Ethernet Shield, para usar en todos aquellos
proyectos que necesiten de menor espacio físico. Esta placa es algo diferente al
resto de modelos, ya que no dispone de ni un conector USB ni del chip
ATmega8U2, por lo que es necesario un cable FTDI para programarla. Se
recomienda utilizar la librería Ethernet.

También dispone de un zócalo para tarjetas de memoria microSD que


puede ser utilizado para leer y escribir datos (muy interesante en el caso de
pequeños proyectos de servidores web). El pin 10 está reservado para la interfaz
con el chip Wiznet. El pin SS para la tarjeta MicroSD está disponible en el pin 4.
Esto hay que tenerlo en cuenta al utilizar la SD Library.

Figura 1.30

Añadiendo un módulo (opcional) se puede añadir la posibilidad de POE


(Power Over Ethernet) para alimentar la placa desde la misma conexión de red.
Ideal para aplicaciones en red o IOT (Internet of Things).

24
1. Inicio con Arduino desde cero

 Incorpora un chip ATmega328.


 Requiere de una conexión serie externa para poder programarla.
 Funciona a 5 V y 8 Mhz.
 La alimentación recomendada es de 6 V a 18 V (de 36 V a 57 con
POE).
 14 pines de E/S (4 de ellos proporcionan PWM).
 6 pines de entrada analógica.
 Memoria Flash de 32 kB.
 Dispone de un puerto Ethernet RJ45.
 Lleva un controlador de Ethernet W5100 TCP/IP integrado.
 Jack preparado para POE (Power Over Ethernet).
 Zócalo para tarjetas microSD con conversores activos de voltaje.
 Dispone de un conector barrel jack (cilíndrico) para la alimentación.
 Dispone de botón de reset.
 Todos los pines están desglosados en terminales hembra para
facilitar las conexiones.

Arduino Due (Figura 1.31) es el modelo más potente de las placas Arduino.
Está basado en un potente microcontrolador SAM3X8E ARM Cortex-M3 que
incorpora todas las funcionalidades clásicas de Arduino y añade otras nuevas.
Ofrece un total de 54 pines de entrada/salida (12 de las cuales son PWM con
resolución configurable) 12 entradas analógicas con una resolución de 12 bits, 4
puertos UART por hardware y dos conversores DAC (digital a analógico), un
resonador de cuarzo de 84 MHz, dos conexiones USB (uno de programación y otro
que puede actuar como USB Host). También incluye los pines de programación
ICSP y JTAG. El voltaje máximo de los pines es de 3,3 V por lo que hay que tener
precaución y no conectar dispositivos de 5 V ya que podrían dañar la placa.

Figura 1.31

25
Taller de Arduino

 Microcontrolador: AT91SAM3X8E.
 Voltaje de operación: 3,3 V.
 Voltaje de entrada (recomendado): 7-12 V.
 Límites de voltaje: 6-20V.
 Pines I/O: 54 (12 con PWM).
 Entradas analógicas: 12.
 Salidas analógicas: 2 (DAC).
 Salida máxima I/O: 130 mA.
 Corriente máxima: 800mA.
 SRAM: 96 kB (64 + 32 kB).
 Memoria para programa: 512 kB.
 Velocidad: 84 MHz.

Arduino Fio (Figura 1.32) es una placa desarrollada por Shigeru Kobayashi
(basándose en el diseño original de la placa LilyPad) y especialmente diseñada
para aplicaciones inalámbricas. Para programarla es necesario un cable FTDI o una
FTDI Basic breakout. También se puede reprogramar de forma inalámbrica
mediante un adaptador de USB a Xbee.

Dispone de conectores para una batería de polímero de litio e incluye un


circuito de carga vía USB y de un zócalo XBee en la parte inferior de la placa, pero
no trae las barras de terminales incorporados, por lo que son necesarios ciertos
conocimientos de soldadura. Aunque, en caso necesario, las conexiones también
se pueden hacer directamente sobre la placa.

Figura 1.32

26
1. Inicio con Arduino desde cero

 Diseñada especialmente para aplicaciones inalámbricas.


 Actualizada con un chip ATmega328p.
 Requiere de una conexión serie externa para poder programarla.
 Funciona a 3,3 V y 8 Mhz.
 La alimentación recomendada es de 3,3 V a 12 V.
 14 pines de E/S (6 de ellos proporcionan PWM).
 8 pines de entrada analógica.
 Memoria Flash de 32 kB.
 Incluye un circuito de carga a través del puerto miniUSB (solo de
carga).
 Dispone de un conector para baterías LiPo.
 No dispone de terminales de conexión. Habría que soldar.

Arduino MINI (Figura 1.33). Las funcionalidades de esta placa son idénticas,
pero con un chip ATmega328s, que es una variante (llevada a la mínima
expresión) del chip ATmega328. Esta placa requiere de una conexión serie externa
para poder programarla. Se trata de una versión miniaturizada de Arduino para
proyectos en los que el espacio sea limitado, pero requiere de conexiones que
pueden resultar algo más complicadas que las de una placa Arduino convencional.

Figura 1.33

 Versión miniaturizada de Arduino.


 Actualizada con un chip ATmega328s.
 Requiere de una conexión serie externa para poder programarla.
 Funciona a 5 V y 16 MHz.

27
Taller de Arduino

 La alimentación recomendada es de 7 V a 9 V.
 14 pines de E/S (6 de ellos proporcionan PWM).
 8 pines de entrada analógica.
 Memoria Flash de 32 kB.
 No dispone de puerto USB.
 No dispone de conector para la alimentación.
 No dispone de botón de reset.

Arduino LilyPad (Figura 1.34) es una de las placas de Arduino más


interesantes del mercado. LilyPad es una tecnología E-Textil, desarrollada para
usarla en proyectos con textiles electrónicos. Ha sido diseñada por Leah Buechley
y desarrollada por Sparkfun. Consiste en un chip ATmega328 con el gestor de
arranque de Arduino y un número mínimo de componentes externos que
permiten mantener el conjunto lo más pequeño y simple posible. La placa, al igual
que todos sus accesorios, ha sido diseñada con unos ojales de conexión grandes
que permiten coser la PCB a los tejidos.

Figura 1.34

 Desarrollada para usarla en proyectos con textiles electrónicos.


 Se puede coser a cualquier tejido.
 Se puede lavar.
 Incorpora un chip ATmega328.
 Requiere de una conexión serie externa para poder programarla.

28
1. Inicio con Arduino desde cero

 Funciona de 2,7 V a 5,5 V y 8 MHz.


 La alimentación recomendada es de 2,7 a 5,5 V.
 14 pines de E/S (6 de ellos proporcionan PWM).
 6 pines de entrada analógica.
 Memoria Flash de 16 kB.
 Dispone de un montón de accesorios LilyPad.
 No dispone de terminales de conexión. Habría que soldar.

Arduino Bluetooth (Figura 1.35) se basa en un microcontrolador Arduino


ATMega328 junto con un módulo Bluetooth incorporado Bluegiga WT11. Soporta
comunicación de datos de forma inalámbrica, aunque no puede transmitir audio.
También es muy práctico ya que no dispone de puerto USB como otras placas
Arduino, pero se puede programar de forma inalámbrica. Es ideal para proyectos
de control inalámbricos de vehículos.

Figura 1.35

 Microcontrolador: ATmega328.
 Alimentación de entrada: 2.5-12 V.
 Pines digitales I/O: 14 (6 con PWM).
 Entradas analógicas: 6.
 Corriente por pin: 40 mA max.
 Memoria Flash: 32 kB (2 kB usados por el bootloader).
 SRAM: 2 kB.
 EEPROM: 1 kB.
 Velocidad de reloj: 16 MHz.
 Módulo Bluetooth 2.1: WT11i-A-AI4.

29
Taller de Arduino

Arduino Yún (Figura 1.36) es el primer miembro de una nueva serie de


placas Arduino que combinan la potencia de Linux junto con la sencillez
característica de Arduino. Combina el chip del modelo Leonardo (ATMega32U4)
junto con un módulo SOC (System-On-a-Chip) corriendo una distribución de Linux
llamada Linino, basada en OpenWRT. Una de las características más interesantes
es que soporta red cableada ethernet y wifi.

Figura 1.36

El chip Arduino está conectado al módulo Linux, por lo que es muy fácil que
se comuniquen entre ambos y delegar procesos pesados a la máquina Linux
integrada en la placa.

Conectividad
Dispone de dos conexiones de red. Una red ethernet 10/100 mbps y otra wifi
(IEEE 802.11 b/g/n, 2,4GHz) que puede montarse como cliente o como punto de
acceso.

Conexión entre procesadores


Para comunicar el pequeño ATMega32U4 con el módulo Linux, se utiliza la librería
Bridge, que facilita mucho las cosas y es soportada directamente por el grupo de
desarrollo de Arduino. El puerto serial del AR9331 está conectado al serial del
32U4 con los pines 0 y 1. El puerto serie del AR9331 es un acceso a la consola, lo
que permite lanzar procesos y recuperar mensajes directamente desde la consola.
Varios paquetes de gestión del sistema de archivos y administración ya están
preinstalados por defecto (incluso el intérprete de Python) y la librería bridge
permite también instalar y lanzar aplicaciones propias con ese mismo sistema.

30
1. Inicio con Arduino desde cero

Una de las ventajas más interesantes es que la placa (del lado del 32U4)
puede ser programada directamente por wifi a través del módulo Linux.

Es una placa llena de posibilidades algunas de la cuales las veremos en el


capítulo 12. También cabe destacar que dispone de un zócalo para memoria
MicroSD que permite almacenar datos en ella como páginas web, datos logeados
o cualquier otra cosa que necesitemos, ampliando aún más las posibilidades de la
placa. Las características del lado del Arduino son iguales a su hermano pequeño.
La parte Linux tiene las siguientes especificaciones:

 Procesador: Atheros AR9331.


 Arquitectura: MIPS @400MHz.
 Alimentación: 3.3 V.
 Puerto Ethernet: IEEE 802.3 10/100Mbit/s.
 Conexión wifi: IEEE 802.11b/g/n.
 USB Type-A: 2.0 Host/Device.
 Lector de tarjetas: Micro-SD.
 RAM: 64 MB DDR2.
 Memoria Flash: 32 MB.
 Soporte para PoE tipo 802.3a.f.

En este apartado hemos descrito la mayor parte de los tipos de Arduino que
ofrece el mercado hoy en día. Evidentemente, a estas alturas, se nos hacen
incomprensibles, dada su complejidad, muchas de sus características técnicas. No
hay de qué preocuparse, a medida que avancemos en el mundo Arduino veremos
que se van clarificando aquellos conceptos que en este momento nos suenan a
chino.

1.5 Herramientas útiles para desarrollar


tus proyectos.
Existen una serie de herramientas, tanto de hardware como de software, que nos
van a ayudar mucho cuando desarrollamos un proyecto basado con Arduino.

1.5.1 Herramientas hardware


Es necesario disponer, de ahora en adelante, de una placa para montar los
circuitos y sus componentes. A esta placa de montaje se le llama: Protoboard o

31
Taller de Arduino

Breadboard (Figuras 1.37 y 1.38). Es ideal para el montaje de circuitos,


especialmente durante la fase de desarrollo de un proyecto.

Básicamente, estas placas universales se componen de una pieza de


plástico con muchas perforaciones. La distancia entre dos perforaciones o tomas
es 2,54 mm (medida estándar). La placa de pruebas se compone de un número
determinado de agujeritos o tomas. En la parte central, estas tomas están
conectadas verticalmente con una separación en el centro. Además, están
conectadas horizontalmente en la parte superior e inferior. Las zonas superior e
inferior se utilizan para proporcionar voltaje al circuito.

Figura 1.37

Figura 1.38

Otra herramienta básica es el polímetro digital. Este aparato de medida lo


utilizaremos fundamentalmente para medir voltajes y corrientes en los circuitos.
Su precio va desde los 20 euros a los 200 euros. Pero podemos adquirir uno de
precio bajo ya que no vamos a necesitar mucha precisión.

32
1. Inicio con Arduino desde cero

Desde luego vamos a necesitar algunos componentes básicos (Figura 1.39)


para ir montando nuestras primeras prácticas. Por ello es recomendable adquirir
una caja de plástico (Figura 1.40) con diferentes compartimentos donde
separarlos de manera ordenada y etiquetada. Este tipo de cajas no tienen por qué
ser caras; las podemos encontrar a precios muy asequibles. Finalmente, debemos
hacernos con un buen montón de cablecitos de colores (Figura 1.41) para
interconectar los diferentes componentes en el protoboard y con los pines del
Arduino.

Figura 1.39

Figura 1.40

Figura 1.41

33
Taller de Arduino

1.5.2 Herramientas software


Ya hemos visto la principal herramienta software para trabajar con Arduino que es el
entorno de desarrollo integrado (IDE). Pero, además, existen otros programas que
nos van a facilitar el desarrollo de nuestros proyectos. El primero de ellos es: fritizing.
Lo podemos descargar gratuitamente de http://fritzing.org/ y lo tenemos disponible
para diferentes sistemas operativos. Fritzing es un programa de automatización de
diseño electrónico libre que fue creado bajo los principios de Processing y Arduino y
que permite a los diseñadores, artistas, investigadores y aficionados en general,
documentar sus prototipos basados en Arduino y crear esquemas de circuitos
impresos para su posterior fabricación. Además, cuenta con un sitio web
complementario que ayuda a compartir y discutir circuitos y experiencias.

En la Figura 1.42 se puede observar un diseño básico realizado con este


software. En realidad, todo se reduce en ir arrastrando los componentes, por
cierto, muy visuales, de la ventana de la izquierda e irlos soltando en el panel
frontal que contiene además un protoboard que funciona igual que uno real. En
un paso posterior uniremos los diferentes elementos con cables que podemos
configurar de diferentes colores para distinguirlos. La magia radica en el hecho de
que a medida que vamos construyendo nuestro circuito, automáticamente, se
realiza la vista del esquema y la vista PCB o placa de diseño. Solo tenemos que
cambiar de vista con un clic de ratón (Figura 1.43).

Figura 1.42

Una función interesante es la de autorruteado. Nos permite linealizar las


conexiones y presentar el circuito con un aspecto muy profesional.

Existen una gran cantidad de componentes ya diseñados especialmente


para Fritzing e incluso, puedes crear el tuyo propio con bastante facilidad.

34
1. Inicio con Arduino desde cero

Figura 1.43

Te recomiendo visitar la página http://fritzing.org/parts/ para este


propósito. De todas maneras, la biblioteca nativa contiene todos los dispositivos
necesarios para realizar infinidad de proyectos. De hecho, muchos de los circuitos
presentados en este libro están realizados con Fritzing.

Y por último, si eres de los reacios a pelearte, aunque sea un rato, con un
software nuevo, existen en YouTube muchos videotutoriales que en cuestión de
minutos te explican paso a paso cómo hacerlo.

Otro de los programas que te ayudaran a trabajar con Arduino es el


denominado PROTEUS (http://www.labcenter.com/). Cabe decir que es un
software de pago, pero que cada vez está más extendido en los centros
educativos y universidades. Proteus (Figura 1.44) es un sistema de diseño
electrónico basado en la simulación analógica, digital o mixta de circuitos, que
brinda la posibilidad de interacción con muchos de los elementos que integran el
circuito. Incluye componentes animados para la visualización de su
comportamiento en tiempo real, además de un completo sistema de generación y
análisis de señales. También cuenta con un módulo para el diseño de circuitos
impresos. La característica principal que hace de Proteus uno de los simuladores
preferidos por muchos aficionados y profesionales de la electrónica es la
posibilidad de simular circuitos que incluyen microprocesadores o
microcontroladores (y como no, también Arduino).

Si visitamos su página web podremos descargar una versión demo del


programa y, además, encontrar información acerca de las licencias, características,
funciones, controladores y módulos extra, entre otros elementos. En la figura 1.44
podemos ver un pantallazo de Proteus simulando un circuito con Arduino.

35
Taller de Arduino

Figura 1.44

Una de las grandes ventajas de utilizar este programa es que podemos


simular el funcionamiento de nuestros proyectos utilizando una amplísima librería
de dispositivos electrónicos. Por ejemplo, supongamos que deseamos proyectar
un sistema de control de temperatura basado en Arduino que utilice un sensor I2C
tipo DS1621 y que active un motor de continua DC si la temperatura sube de 30 °C.
Afortunadamente, podemos simularlo con Proteus, depurar su conexionado y
funcionamiento. Después ya estamos en condiciones de aventurarnos a comprar
el sensor y el motor para montarlo en el protoboard. Es más, podemos probar
otro tipo de sensores del mercado en lugar del anterior, sin tener que gastar un
duro. Pero lo más importante es que tenemos la oportunidad de aprender
electrónica con Arduino seleccionando diferentes dispositivos y utilizándolos en
nuestros proyectos personales.

Y aunque no existe una coincidencia cien por cien exacta entre lo simulado
y lo real, sí que es gratificante que nos pueda aclarar muchas dudas en cuanto a
los patillajes, conexiones y comportamiento de los circuitos. En el apéndice 1 os
muestro cómo simular Arduino bajo el entorno de Proteus.

No hay que olvidar que PROTEUS es un programa profesional de


diseño electrónico y su manejo puede no ser fácil en un principio. Sin
embargo, hoy en día existe bastante información y tutoriales en la
red.

36
CAPÍTULO

EL LENGUAJE DE
PROGRAMACIÓN DE
ARDUINO

En esta segunda parte abordaremos la tarea de comprender los aspectos básicos


del lenguaje de programación de Arduino y entraremos con detalle en el
funcionamiento de sus pines digitales y analógicos. Os mostraré algunos ejemplos
básicos de ello, manejando diodos LED e interruptores. También veremos lo que
son las entradas analógicas y su principal finalidad. Acabaremos esta segunda
parte con una amplia exposición de cómo utilizar algunos sensores sencillos para
dotar de vida a nuestro Arduino. En esta sección aprenderemos cómo elaborar
secuencias de órdenes para enviar a nuestro Arduino y que este se comporte
como nosotros queramos. A esta acción se le llama: PROGRAMAR.

2.1 Introducción al concepto de programación


Buscando una similitud entre el Arduino y el ordenador, programar es el proceso
de diseñar, escribir, probar, depurar y mantener el código fuente de programas. El
código fuente es escrito en un lenguaje de programación. El propósito de la
programación es crear programas que presenten un comportamiento deseado.

Para crear un programa que el ordenador o el Arduino interpreten y


ejecuten las instrucciones escritas para ellos, debe usarse un lenguaje de
programación. En sus inicios los ordenadores interpretaban solo instrucciones en
un lenguaje específico del más bajo nivel conocido como código máquina, siendo
este excesivamente complicado para programar. De hecho, solo consiste en
cadenas de números 1 y 0 (sistema binario).

Para facilitar el trabajo de programación, los primeros técnicos que


trabajaban en esa área decidieron reemplazar las instrucciones, secuencias de

37
Taller de Arduino

unos y ceros, por palabras o letras provenientes del inglés, codificándolas así y
creando un lenguaje de mayor nivel que se conoce como assembly o lenguaje
ensamblador. Por ejemplo, para sumar se usa la letra A de la palabra inglesa add
(sumar). En realidad, escribir en lenguaje ensamblador es básicamente lo mismo
que hacerlo en lenguaje máquina, pero las letras y palabras son bastante más
fáciles de recordar y entender que secuencias de números binarios.

A medida que creció la complejidad de las tareas que realizaban las


computadoras, se hizo necesario disponer de un método sencillo para programar.
Entonces, se crearon los lenguajes de alto nivel. Mientras que una tarea tan trivial
como multiplicar dos números puede necesitar un conjunto de instrucciones en
lenguaje ensamblador, en un lenguaje de alto nivel bastará con solo una.

Un lenguaje de programación es un idioma artificial diseñado para expresar


operaciones que pueden ser llevadas a cabo por máquinas como los ordenadores
o, como en nuestro caso, el Arduino. Puede usarse para crear programas que
controlen el comportamiento físico y lógico de una máquina, para expresar
algoritmos con precisión, o como modo de comunicación humana.

Está formado por un conjunto de símbolos y reglas sintácticas y semánticas


que definen su estructura y el significado de sus elementos y expresiones. Al
proceso por el cual se escribe, se prueba, se depura, se compila y se mantiene el
código fuente de un programa informático, se le llama programación.

El lenguaje de máquina es el sistema de códigos directamente


interpretable por un circuito microprogramable, como el
microprocesador de un ordenador o el microcontrolador que lleva
dentro el Arduino. Este lenguaje está compuesto por un conjunto de
instrucciones que determinan acciones a ser tomadas por la
máquina. Estas instrucciones son normalmente ejecutadas en
secuencia, con eventuales cambios de flujo causados por el propio
programa o eventos externos. El lenguaje máquina trabaja con dos
niveles de voltaje. Dichos niveles se simbolizan con el cero (0) y el
uno (1), por eso el lenguaje de máquina solo utiliza dichos signos.

El lenguaje ensamblador es un lenguaje de programación de bajo


nivel para los ordenadores, microcontroladores y otros circuitos
integrados programables. Implementa una representación simbólica
de los códigos de máquina. Esta representación es usualmente

38
2. El lenguaje de programación de Arduino

definida por el fabricante de hardware. Está basada en códigos


mnemotécnicos que simbolizan los pasos de procesamiento (las
instrucciones). Un lenguaje ensamblador es por lo tanto específico a
cierta arquitectura de computador física (o virtual). Esto está en
contraste con la mayoría de los lenguajes de programación de alto
nivel que idealmente son portables.

Un algoritmo es un conjunto de instrucciones o reglas bien definidas y


ordenadas que permite realizar una actividad mediante pasos sucesivos
que no generen dudas a quien deba realizar dicha actividad.

Un lenguaje de programación de alto nivel se caracteriza por


expresar los algoritmos de una manera muy cercana al lenguaje
humano. Para los lenguajes de alto nivel se requiere de ciertos
conocimientos de programación para escribir las secuencias de
instrucciones lógicas. Los lenguajes de alto nivel se crearon para que
el usuario común pudiese solucionar un problema de procesamiento
de datos de una manera más fácil y rápida.

Cuando nos disponemos a realizar un programa, lo primero que tenemos


que hacer es diseñar un algoritmo gráfico de la tarea que vamos a emprender. Por
ejemplo, si retomamos el primer programa de parpadeo de un led que os expliqué
en la primera parte de este libro, podríamos dibujar un algoritmo parecido al que
se muestra en la figura 2.1. Vemos que estamos representando una secuencia de
pasos que debe ejecutar más tarde el Arduino. En primer lugar, aparece un bloque
llamado «cabecera» que contendrá todos los comentarios relativos al propósito
del programa, autor, fecha, lugar donde se ideó, etc. Después tenemos un bloque
que hace referencia a la configuración del Arduino, es decir, en nuestro caso
definir que la patilla 13 de la placa se comporte como salida ya que a esta va
conectada el LED. Después entramos en varios bloques que realizan las tareas de
encender un led, esperar un tiempo, apagarlo, esperar otro tiempo y volver al
principio, que es volver a encenderlo.

De una forma visual estamos representando lo que deseamos hacer. De


esta manera sencilla es posible corregir o depurar, cómodamente, los pasos de
nuestro proyecto.

Además, cualquier persona que le eche un vistazo al gráfico se dará cuenta


rápidamente de lo que estamos intentando hacer.

39
Taller de Arduino

Figura 2.1

Ya nos ocuparemos más tarde de cómo traducir estas acciones escritas


dentro de los bloques, en instrucciones o sentencias del lenguaje de
programación de Arduino.

Al principio lo importante es tener claros los pasos que debemos seguir. No


es cuestión de ponerse a escribir código de programación como un poseso sin
saber muy bien adónde me conduce todo ello. Y claro está que estamos
programando, por si algún programador sesudo nos advierte de que no lo
estamos haciendo, pero en un lenguaje muy cercano a nuestra forma natural de
entender las cosas.

En todo caso, estamos programando en un lenguaje de ultra alto nivel. Es


de vital importancia construirnos este tipo de bocetos, esquemas, gráficos,
organigramas o como queramos llamarlo, siempre que abordemos un proyecto
nuevo con Arduino.

Veamos ahora cómo traducir todo esto al lenguaje propio de Arduino. Pero
antes, hay que examinar la estructura básica de que consta un programa en
Arduino y los elementos con los que jugar.

40
2. El lenguaje de programación de Arduino

2.2 Cuerpo de un programa en Arduino


Un programa diseñado para ejecutarse sobre un Arduino se conoce como sketch,
que podríamos traducir como ‘boceto’ o ‘borrador’. Un sketch siempre tiene la
misma estructura general (Figura 2.2) y consta de dos estructuras: setup() y
loop(). Estas constituyen el cuerpo general e imprescindible de un programa.

Figura 2.2

2.2.1 Estructuras
En primer lugar tenemos la estructura setup(). Lo que se escriba entre las llaves
que acompañan a su nombre, se ejecuta una única vez siempre que se encienda o
resetee la placa. El bloque o estructura setup() contendrá toda la configuración
hardware del Arduino, es decir, cómo queremos que funcionen determinados
pines del Arduino como entrada o como salida. A medida que vayamos
conociendo sus posibilidades iremos aumentando el tamaño de la configuración
de este bloque.

En segundo lugar, todo programa en Arduino tiene que poseer también la


estructura loop(). Todo lo que se escriba dentro de las llaves que acompañan a su
nombre, se ejecutará constantemente hasta que se apague o resetee la máquina.
El bloque o estructura loop() incluirá nuestro programa propiamente dicho, y este
se ejecutará ininterrumpidamente y en bucle.

Por otra parte, Arduino se programa en el lenguaje de alto nivel C/C++.


Generalmente tiene los siguientes componentes para elaborar el sketch o
programa:

 Variables.
 Operadores matemáticos, lógicos y booleanos.

41
Taller de Arduino

 Estructuras de control (Condicionales y ciclos).


 Funciones.

Vamos a echar un vistazo por encima a estos elementos que componen un


típico programa en Arduino. No es mi intención aburriros con una larga, teórica y
tediosa exposición de toda la sintaxis y referencia del lenguaje de programación
de Arduino. El planteamiento que os propongo es conocer lo mínimo para
empezar a programar y, a medida que lo necesitemos, ir abordando cada uno de
los nuevos tipos de variables, operadores, funciones o características nuevas de
este lenguaje. Pienso que es la mejor manera de aprender, sin que programar se
vuelva una tarea demasiado ardua y memorística. Es el método que
habitualmente empleo en mis clases de electrónica en el instituto. Los nuevos
componentes electrónicos van apareciendo a medida que se van planteando
nuevos proyectos, retos o ideas. La idea principal es: «Si no lo necesito, para qué
voy a conocerlo».

2.2.2 Variables
Una variable es una manera de nombrar y almacenar un valor numérico para su
uso posterior en el programa. Como su nombre indica, las variables son números
o caracteres que se pueden variar continuamente en contra de lo que ocurre con
las constantes, cuyo valor nunca cambia. Todas las variables tienen que declararse
antes de que puedan ser utilizadas. Para declarar una variable se comienza por
definir su tipo, asignándoles siempre un nombre y, opcionalmente, un valor
inicial. Esto solo debe hacerse una vez en un programa, pero su valor se puede
cambiar en cualquier momento. Una variable puede ser declarada en cualquier
lugar del programa y en función de dónde se lleve a cabo su definición, se
determinará en qué partes del programa se podrá hacer uso de ella.

Una variable puede ser declarada al inicio del programa, a nivel local dentro
de las funciones, y, a veces, dentro de un bloque. En función del lugar de
declaración de la variable así se determinará su ámbito de aplicación y la capacidad
de ciertas partes de un programa para hacer uso de ella. Una variable global es
aquella que puede ser vista y utilizada por cualquier función y sentencia de un
programa. Esta variable se declara al comienzo del programa, antes de la estructura
setup(). Una variable local es aquella que se define dentro de una función o como
parte de un bucle. Solo es visible y solo puede utilizarse dentro de la función en la
que se declaró. El ámbito de utilización de las variables se entenderá mejor cuando
conozcamos un poco mejor los fundamentos de la programación.

42
2. El lenguaje de programación de Arduino

Existen diferentes tipos de variables en concordancia con el tipo de dato


que almacenen. Las variables que más utilizaremos en nuestros programas son
estos tres tipos:

 Tipo entero: int.


 Tipo carácter: char.
 Tipo booleano: boolean.

El tipo entero denominado int almacena valores numéricos de 16 bits sin


decimales comprendidos en el rango 32,767 a -32,768. La siguiente sentencia
define una variable de tipo entero con el nombre «Ventrada». Además, le asigna
un valor inicial y numérico de 200.

int Ventrada = 200; // declara una variable de tipo entero.

El tipo carácter llamado char de un tamaño de 1 byte que almacena valores


tipo carácter. Es decir, que solo puede contener un carácter tipo ASCII. La
siguiente sentencia define una variable de tipo carácter con el nombre
«Ventrada» y además le asigna un valor inicial con la letra ´a´.

char Ventrada = ’a’; // declara una variable de tipo carácter.

El tipo booleano (boolean) solo puede contener dos valores: TRUE o FALSE.
De esta manera cada una de estas condiciones ocupa 1 byte de memoria. La
siguiente sentencia define una variable de tipo booleano con el nombre
«Ventrada» y además le asigna un valor inicial verdadero o TRUE.

boolean Ventrada = true; // declara una variable


de tipo booleano.

Existen más tipos de variables, pero para comenzar, nos llegan. A medida
que avancemos en la programación de Arduino las iremos conociendo. Si estás
interesado en adelantarte puedes visitar la siguiente página:

http://arduino.cc/en/Reference/HomePage.

Las variables deben tomar nombres descriptivos para hacer el código


más legible. Nombres de variables pueden ser «contactoSensor» o
«pulsador». Sirven para ayudar al programador y a cualquier otra
persona a «leer» el código y entender lo que representa la variable.

43
Taller de Arduino

Nombres de variables como «var» o «valor» facilitan muy poco que el


código sea inteligible. Una variable puede ser cualquier nombre o
palabra que no sea una palabra reservada en el entorno de Arduino.

2.2.3 Operadores aritméticos, lógicos y booleanos


Los operadores aritméticos que se incluyen en el entorno de programación de
Arduino son: la suma, la resta, la multiplicación y la división. Estos devuelven la
suma, diferencia, producto, o cociente de dos operandos. Esto es lo que
normalmente llamamos matemáticas de andar por casa, de toda la vida, como se
suele decir.

y = y + 3; // Suma 3 a la variable y
x = x - 7; // Resta 7 a la variable x
i = j * 6; // Realiza el producto de 6 y de la variable j
r = r / 5; // Divide la variable r entre 5

Los operadores de comparación de una variable se utilizan con frecuencia


en las sentencias condicionales del tipo if (las veremos más adelante) para testear
si una condición es verdadera o falsa; es decir para tomar decisiones en el
programa. Los símbolos de los operadores de comparación se muestran a
continuación:

x == y // x es igual a y
x != y // x no es igual a y
x < y // x es menor que y
x > y // x es mayor que y
x <= y // x es menor o igual que y
x >= y // x es mayor o igual que y

Los operadores booleanos son una forma de comparar dos expresiones y


devolver un TRUE (verdadero) o FALSE (falso) dependiendo del operador. Existen
tres operadores lógicos:
&& Operador AND
|| Operador OR
! Operador NOT

44
2. El lenguaje de programación de Arduino

2.2.4 Estructuras de control: condicionales y ciclos


Son instrucciones que nos permiten tomar decisiones durante la ejecución del
programa y hacer diversas repeticiones de acuerdo a unos parámetros. Dentro de
las más importantes podemos destacar las siguientes:

 If
 Switch/case
 For
 While

Estructuras condicionales. Sirven para tomar decisiones después de evaluar


condiciones lógicas. Tenemos dos principales: If y Switch/case.

If. Es una estructura (Figura 2.3) simple que se utiliza para evaluar si una
determinada condición se ha alcanzado, como, por ejemplo, determinar si un valor
analógico es igual a un valor de referencia preestablecido y ejecutar una serie de
operaciones que se escriben dentro de llaves si es cierta la condición. Si es falsa (la
condición no se cumple), el programa salta y no ejecuta las operaciones que están
dentro de las llaves. Un ejemplo de utilización es el siguiente:

if x==15
{
x=x+30;
}
x=x+1000;

Figura 2.3

45
Taller de Arduino

Evaluamos si la variable x es igual a 15. Si se cumple la condición le


sumamos el valor 30 y después le sumamos 1000. Entonces la variable x
contendrá el valor 1045. Si no es igual, solo le sumamos 1000, ya que nos
saltamos las posibles operaciones que hubiera dentro de las llaves (en este caso la
suma del valor 30). Hay que tener en cuenta el uso especial del símbolo '=' dentro
de if: x = 15 podría parecer que es válido, pero, sin embargo, no lo es ya que esa
expresión asigna el valor 15 a la variable x. Por eso dentro de la estructura if, se
utiliza x==15, que, en este caso, lo que hace el programa es comprobar si el valor
de x es 15. Ambas cosas son distintas. Dentro de las estructuras if, cuando se
pregunte por un valor se debe poner el signo doble de igual “==”. Una variedad
muy utilizada y más completa de la estructura anterior es la denominada if/else
que responde la idea «si esto no se cumple se hace esto otro». Variando el
ejemplo anterior podemos evaluar, en un nuevo ejemplo, si la variable x es igual a
15; si no es así, se le suma un valor de 1000 (opción else). Pero ahora en el caso de
que fuera igual a 15, se le suma el valor de 30 como en el sketch anterior. Sin
embargo, no se le suma después el valor de 1000 (Figura 2.4).

if x==15
{
x=x+30;
}
else
{
x=x+1000;
}

Figura 2.4

46
2. El lenguaje de programación de Arduino

Switch/case. Una estructura switch compara el valor de una variable con el


valor especificado en las sentencias case. Cuando se encuentra una sentencia case
cuyo valor coincide con dicha variable, el código de esa sentencia se ejecuta. La
palabra clave break sale de la estructura switch y es usada típicamente al final de
cada case. Sin una sentencia break, la sentencia switch continuaría ejecutando las
siguientes expresiones hasta encontrar un break o hasta llegar al final de la
sentencia switch. Volviendo al ejemplo anterior, podríamos comparar el valor de
la variable x con distintos valores y en función de si es igual a alguno de ellos,
ejecutar las operaciones o expresiones a partir de ese case o caso particular
(Figura 2.5).

switch (x)
{
case 15: x=x+30;
break;
case 67: x=x*2;
break;
default: x=x+1000;
}

Figura 2.5

En el programa comprobamos si x vale 15 (de ser así, le sumamos el valor


de 30) o si vale 67 (en este caso multiplicamos por dos su valor). Si x posee
cualquier otro valor distinto se le añade el valor 1000.

47
Taller de Arduino

Estructuras de bucle o de ciclo. Sirven para tomar y ejecutar continuamente un


conjunto de operaciones o sentencias hasta que se cumplan ciertas condiciones
lógicas, aritméticas o booleanas. Las dos más importantes son: For y While.

For. Esta estructura se usa para repetir un bloque de sentencias encerradas


entre llaves un número determinado de veces. Cada vez que se ejecutan las
instrucciones del bucle se vuelve a evaluar la condición y si deja de cumplir se sale
de este bucle continuo. La estructura for tiene tres partes separadas por (;). Su
formato es el siguiente:

for (inicialización; condición; expresión)

La inicialización de una variable local que se produce una sola vez y la


condición se testea cada vez que se termina la ejecución de las instrucciones
dentro del bucle. Si la condición sigue cumpliéndose, las instrucciones del bucle se
vuelven a ejecutar. Cuando la condición no se cumple, el bucle termina. Veamos
un programa para clarificar su uso:

for (int i=0; i<20; i++)


{
digitalWrite(13, HIGH);
delay(250);
digitalWrite(13, LOW);
delay(250);
}

El sketch (Figura 2.6) hace parpadear veinte veces, y solo veinte, la patilla
13 del Arduino con un intervalo de medio segundo. En este caso, la variable de
inicialización i se pone a cero. A continuación, se comprueba (condición) el valor
de i en cada ejecución de todo lo que va entre llaves, si esta variable es menor
que el valor 20. Si es así, sigue realizando el bucle; si no es así, se sale de la
estructura for. Por último, apreciar que cada vez que se ejecuta un bucle la
variable i se incrementa en uno (expresión).

48
2. El lenguaje de programación de Arduino

Figura 2.6

While. Una estructura de este tipo (Figura 2.7) es un bucle de ejecución


continua «mientras» se cumpla la expresión colocada entre paréntesis en la
cabecera del bucle. La variable de prueba tendrá que cambiar para salir del bucle.
La situación podrá cambiar a expensas de una expresión dentro el código del
bucle o también por el cambio de un valor en una entrada. Veamos un ejemplo
para aclarar su utilización.

while (x < 200)


{
z = z +500;
x++;
}

Figura 2.7

49
Taller de Arduino

En este caso se evalúa si la variable x es menor que 200. Si es así, se suma


500 a otra variable llamada z y además se autoincrementa la variable x. Cuando
esta variable sea igual a 200, se sale del bucle while. Existe una variedad de esta
última estructura que es la llamada: do while. Funciona de la misma manera que
el bucle while, con la salvedad de que la condición se prueba al final del bucle. El
bucle siempre se ejecutará al menos una vez. A lo largo del libro la utilizaremos
más de una vez.

2.2.5 Funciones
Una función es un conjunto de líneas de código que realizan una tarea específica.
Las funciones pueden tomar parámetros que modifiquen su funcionamiento. Las
funciones son utilizadas para descomponer grandes problemas en tareas simples,
y para implementar operaciones que son comúnmente utilizadas durante un
programa y de esta manera reducir la cantidad de código. Cuando una función es
invocada se le pasa el control a la misma; una vez que esta finalizó con su tarea, el
control es devuelto al punto desde el cual la función fue llamada.

No confundir el concepto de función con el de librería. De hecho, una


librería es un conjunto de funciones con un objetivo específico.

50
CAPÍTULO

TRANSMISIÓN SERIE
EN ARDUINO

Ya sabemos que la placa Arduino puede establecer comunicación con el


ordenador a través de una conexión por un cable USB para recibir los programas y
que queden grabados en el microcontrolador. Solo es necesario indicar el número
de puerto USB (Figura 3.1) donde está conectado nuestro Arduino y desde el IDE
visible en nuestro PC, presionar el botón de enviar o subir.

Figura 3.1

Además, dentro del interfaz IDE disponemos de la opción «Monitor Serie»


que posibilita la visualización de datos procedentes del Arduino. Es decir, que la
comunicación serie es en los dos sentidos. Podemos, por tanto, monotorizar lo
que me pudiera enviar el Arduino y verlo en una ventana del IDE. Si nuestra placa
está captando datos de temperatura o de humedad o de lo que sea del entorno

51
Taller de Arduino

ambiental, estos datos se pueden observar en tiempo real en el PC. Pero ojo, no
podemos guardarlos, solo ir visualizándolos a medida que van siendo adquiridos
por el Arduino.

Para ilustrar de forma práctica esta característica vamos a examinar un


sketch que envíe desde el Arduino un mensaje de texto. El contenido del mismo lo
veremos en la ventana del monitor serie del IDE.

Figura 3.2

En el programa mostrado en la figura 3.2 observamos dos líneas nuevas:

Serial.begin(9600);

Esta sentencia debe colocarse dentro de la estructura de configuración


setup() y establece la velocidad en bits por segundo (baudios) entre la placa de
Arduino y el PC. Debe ser igual en ambos dispositivos. La segunda sentencia envía
al PC el texto (entre paréntesis y comillas) añadiendo un salto de línea.
Serial.println(“Esto del arduino es un rollo macabeo”);

Al estar dentro de la estructura loop() se ejecutará indefinidamente; de ahí


que se escriba la dichosa frase un montón de veces dentro de la ventana del
programa monitor (Figura 3.3). Pero, además, podríamos utilizar el programa

52
3. Transmisión serie en Arduino

monitor para enviarle órdenes al Arduino a través de texto o códigos ASCII. Es


decir, se puede gobernar el Arduino desde el ordenador.

Figura 3.3

El campo que nos abre está lleno de posibilidades, tanto en la visualización


de datos como la del propio control del Arduino.

53
CAPÍTULO

LAS ENTRADAS Y
SALIDAS DIGITALES

Llegó el momento de empezar a poner a trabajar a nuestro Arduino. Y lo vamos a


hacer con los pines de la placa que sirven para manejar señales digitales. Las
patillas digitales del Arduino están numeradas del 0 al 13, ambas incluidas. Sin
embargo, como se observa en la figura 4.1, solo debemos utilizar los pines del 2 al
13, ya que los pines 0 y 1 están reservados para la comunicación serie entre el PC
y el propio Arduino. De hecho, a lado de dichos números están serigrafiados en la
placa, las etiquetas TX y RX, que son las abreviaturas de trasmisión y recepción
serie respectivamente. El estudio de las patillas analógicas lo posponemos para el
siguiente capítulo. Por ahora nos vamos a centrar en lo más básico y sencillo:
escribir y leer unos y ceros. Pero antes de nada, debemos conocer cómo
funcionan esos dispositivos que normalmente están asociados a los pines
digitales. Usaremos los diodos LED como salidas para mostrar un cero o un cero
(encendido/apagado). Los interruptores o pulsadores se utilizarán para
proporcionar información digital de entrada al Arduino. Eso es lo que vamos a
abordar en el siguiente punto.

Figura 4.1

54
4. Las entradas y salidas digitales

Figura 4.2

Una señal analógica (Figura 4.2) es continua y puede tomar infinitos


valores. Una señal digital es discontinua y solo puede tomar dos valores
o estados: 0 y 1. Estos dos valores pueden ser impulsos eléctricos de
baja y alta tensión, interruptores abiertos o cerrados, pulsadores, etc.

4.1 Funcionamiento de los interruptores,


pulsadores y potenciómetros
El diodo LED. Es un componente muy común, infinitamente útil que convierte en
luz la intensidad eléctrica que circula por él. Los LED vienen en diferentes formas,
tamaños y colores. La conexión de un LED en un circuito está «polarizada», es
decir, la corriente puede entrar y salir del mismo en una sola dirección. Entra por
el lado de la patilla llamada ánodo (positivo) y sale por la patilla denominada
cátodo (negativo). No puede circular en sentido contrario. Para identificar cuáles
son las patillas descritas, podemos echar un vistazo a la figura 4.3.

Figura 4.3

55
Taller de Arduino

Figura 4.4

Al añadir un LED a un proyecto se deben tener en cuenta los valores de


voltaje y corriente. Por ejemplo, los LED rojo comunes requieren alrededor de 1.7
a 5 voltios de tensión entre ánodo y cátodo y una corriente mínima de 20 mA para
encenderse normalmente. En el extremo contrario del valor máximo de corriente,
todo diodo LED tiene que llevar asociado en serie una resistencia para limitar la
corriente que pase por él. Sin esta resistencia, el diodo LED podría quemarse. Por
ello, el problema que se nos presenta es calcular la resistencia adecuada para
nuestro LED. Esto es algo muy sencillo, usaremos la Ley de Ohm:

donde:

R es la resistencia limitadora;
Vcc es la tensión de alimentación (valor de la batería);
Vf es la caída típica de voltaje en el LED; y
If es la corriente típica que debe pasar para que se encienda el LED.

Por ejemplo, tenemos una alimentación de 9 V y queremos poner un diodo


LED rojo con Vf = 1.2 voltios y If = 20 mA. Su resistencia limitadora R será de 390
ohmios. Aunque este valor siempre es estimativo, ya que si escogemos un valor
comercial de la resistencia un poco más bajo, no pasará nada, circulará una
corriente más alta y el LED se encenderá un poco más. Claro está, sin pasarse
demasiado, porque si elegimos por «avaricia de luminosidad» una resistencia muy
baja que permita una intensidad muy alta (por encima de los 100 mA),
destruiríamos el LED.

56
4. Las entradas y salidas digitales

Examina el circuito con LED mostrado en la figura 4.4 y averigua si


está bien conectado a la batería. Además determina si el valor de la
resistencia es apropiado para un funcionamiento normal. En caso de
duda, consulta la tabla de colores de las resistencias.

El interruptor, como su nombre indica, es un dispositivo que permite o no


el paso de corriente eléctrica. En el mercado existen muchos tipos. Los que
utilizaremos nosotros para insertarlos en nuestro protoboard son los llamados de
tipo DIP (Dual in-line Package).

Figura 4.5

Figura 4.6

En la figura 4.5 observamos un conjunto de interruptores de tipo DIP con


dos posiciones de funcionamiento: ON/OFF.

En la figura 4.6, averigua si el autor del libro ha metido la pata y si el


interruptor número 6 cumple su cometido de encender o apagar el
LED. Investiga, por otra parte, si las conexiones están bien y si los
valores de los distintos elementos del circuito son correctos.

57
Taller de Arduino

El pulsador. Los pulsadores son de diversas formas y tamaño y se


encuentran en todo tipo de dispositivos, aunque principalmente en aparatos
eléctricos y electrónicos. Los pulsadores son, por lo general, activados al ser
presionados con un dedo. Permiten el flujo de corriente mientras son accionados.
Consta del botón pulsador, una lámina conductora que establece contacto con los
dos terminales al oprimir el botón, y un muelle que hace recobrar a la lámina su
posición primitiva al cesar la presión sobre el pulsador. Cuando ya no se presiona
sobre él, vuelve a su posición de reposo. Puede ser un contacto normalmente
abierto en reposo NA (NO: Normally Open en inglés), o con un contacto
normalmente cerrado en reposo NC.

El tipo de pulsadores que usaremos con Arduino son los de tipo llamado
mini. Se aprecia en la figura 4.7. Llevan cuatro contactos unidos dos a dos, de tal
manera que cuando pulsamos, se establece conexión eléctrica entre un lado y
otro del pulsador.

Figura 4.7

En la figura 4.8, averigua la tensión o voltaje que existe en el cablecito


amarillo en el caso de que activemos el pulsador, y en el caso de que
no lo hagamos. Suponemos que la batería es de 9 voltios.

Figura 4.8

58
4. Las entradas y salidas digitales

El potenciómetro. La mayoría de la gente no lo sabe, pero cualquiera de


nosotros utiliza un potenciómetro casi todos los días. Puedes encontrarlos en los
automóviles, equipos de música, interruptores de luz y otra serie de dispositivos.
Sin ellos, tendríamos serias dificultades para accionar la mayoría de los aparatos
electrónicos. Sin embargo, ¿qué son exactamente los potenciómetros y qué
funciones tienen? Los potenciómetros (Figura 4.9) son resistencias que tienen tres
terminales (A, B, C). Estas resistencias tienen divisores de tensión (circuitos
lineales) que proporcionan una salida de tensión (terminal B), que es menor que
el voltaje de entrada. Los potenciómetros proporcionan transiciones suaves de los
niveles de tensión y pueden ser rotativos o lineales. Uno de los principales usos de
los potenciómetros son las perillas de control de audio. Al girar el dial del
potenciómetro hacia un lado o el otro, controlamos el volumen del dispositivo de
audio. Se pueden encontrar otros potenciómetros en las perillas de audio de los
graves, los agudos y las perillas de las pistas que nos permiten seleccionar el grado
de frecuencias altas y bajas. Los productores de un estudio tienen docenas de
potenciómetros en su equipo de sonido para conseguir el sonido adecuado y el
equilibrio en una grabación.

Los potenciómetros también se encuentran habitualmente en los


reguladores de intensidad de las luces. Los reguladores de intensidad operan de
forma lineal, pero trabajan de la misma forma que los potenciómetros del tipo
circular o a perilla.

Figura 4.9

Cuando una persona ajusta un potenciómetro afecta la corriente que está


tomando parte en la iluminación y por lo tanto puede hacer que las luces se
atenúen o sean más brillantes, de acuerdo con la cantidad de electricidad que
deje llegar a la bombilla. En nuestros proyectos con Arduino utilizaremos un tipo
de potenciómetro denominado trimmer que es adecuado para los montajes en la
protoboard.

59
Taller de Arduino

4.2 Práctica 1: encendiendo y apagando varios leds


En esta primera práctica vamos a simular el juego de luces del famoso coche
fantástico de la serie de televisión que se hizo popular en los años ochenta.

El algoritmo que implementaremos es el que se muestra en la figura 4.10.

Se trata de apagar y encender LED con esperas de tiempo intercaladas para


producir un efecto de movimiento de la luz que recorre estos diodos.

Figura 4.10

En cuanto al hardware que necesitamos:

 Cinco diodos LED.


 Cinco resistencias de 220 Ω.
 Una protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Conectaremos los cinco diodos LED a los pines digitales (2 al 6) a través de


las cinco resistencias limitadoras. Examinemos ahora el sketch que debemos
escribir, guardar y subir a nuestro Arduino para comprobar su funcionamiento.
Práctica 1. Empezando a programar

/* Práctica 1 – Coche fantástico */


/* Ideada mientras miraba las estrellas un día sin luna */

60
4. Las entradas y salidas digitales

void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}

void loop()
{
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(6, LOW);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);
digitalWrite(4, HIGH);
delay(500);
digitalWrite(4, LOW);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
}

61
Taller de Arduino

En este programa aparecen tres funciones que hacen todo el trabajo. Las
estudiamos con detalle a continuación. ¡Prepárate porque empezamos a programar!

pinMode (pin, mode). Esta instrucción es utilizada en la parte de


configuración setup() y sirve para configurar el modo de trabajo de un pin,
pudiendo ser el parámetro mode como INPUT (entrada) u OUTPUT (salida). Los
terminales de Arduino, por defecto, están configurados como entradas, por lo
tanto no es necesario definirlos en el caso de que vayan a trabajar como entradas.
Los pines configurados como entrada quedan, bajo el punto de vista eléctrico,
como entradas en estado de alta impedancia.

Cuando un dispositivo tiene alta impedancia de entrada quiere decir


que consume muy poca corriente en forma directa. La impedancia es
la resistencia que presenta un dispositivo ante una señal, ya sea en su
entrada o salida. Es bueno que un dispositivo tenga alta impedancia
de entrada ya que cuando lo conectemos a algo no va «tomarte» una
corriente apreciable.

Estos pines tienen a nivel interno una resistencia de 20 kΩ a las que se puede
acceder mediante software. A estas resistencias se accede de la siguiente manera:
pinMode(pin, INPUT); // configura el ‘pin’ como entrada
digitalWrite(pin, HIGH); // activa las resistencias internas

Las resistencias internas normalmente se utilizan para conectar las entradas a


interruptores. En el ejemplo anterior no se trata de convertir un pin en salida, es
simplemente un método para activar las resistencias interiores. Los pines configurados
como OUTPUT (salida) se dice que están en un estado de baja impedancia y pueden
proporcionar 40 mA de corriente a otros dispositivos. Esta corriente es suficiente para
alimentar un diodo LED, pero no es lo suficientemente grande como para alimentar
cargas de mayor consumo como relés, solenoides o motores.

digitalWrite(pin,mode). Envía al pin definido previamente como OUTPUT el


valor HIGH o LOW (poniendo en 1 o 0 la salida). Por ejemplo:

digitalWrite(pin, HIGH); // Saca por el pin un valor


HIGH (alto o 1).
digitalWrite(3, LOW); // Saca por la patilla 3 un valor
LOW (bajo o 0).

62
4. Las entradas y salidas digitales

delay(milisegundos). Detiene la ejecución del programa la cantidad de


tiempo en milisegundos que se indica en la propia función, de tal manera que
1000 equivale a 1 segundo.

delay(2000); // espera 2 segundos

Ahora vamos a construir el circuito (Figura 4.11). Os recomiendo que


primero lo realicéis con el software fritzing que os he mostrado al final del
capítulo 1. Es una buena forma de aprender a documentar vuestros proyectos y,
sobre todo, impactar a los amigos con una excelente presentación.

Figura 4.12

Figura 4.13

63
Taller de Arduino

En la figura 4.12 se puede observar el mismo circuito pero realizado en


Proteus. Como hemos visto en el capítulo 1, puedo simular su funcionamiento, lo
cual es importante para asegurar que cuando lo monte en la protoboard, todo va
a ir bien. Además, me brinda la posibilidad de ir trabajando en mis proyectos sin la
necesidad de tener un Arduino a mano.

Cuando reviso el sketch anterior me doy cuenta que tanto el algoritmo


como el programa propiamente dicho, tienen partes que se repiten
continuamente y aunque utilice la opción «copiar y pegar» dentro del IDE, la
verdad es que no es muy flexible. Por ello voy a cambiar un par de cosas.

Primero introduciré una variable de tipo int para poder variar el tiempo de
espera en la función delay(ms). Después reemplazaré el código principal por otro
más corto que use la potencia de la estructura for que vimos anteriormente. A
esto, los programadores experimentados lo llaman: optimizar el código.
Práctica 1.1. Mejorando el código

/* Práctica 1.1 – Repitiendo con bucles for el Coche


fantástico */
/* Vamos a hacer los cosas como si fuera un programador
avezado*/
int d = 100;
void setup()
{
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(4, OUTPUT);
pinMode(5, OUTPUT);
pinMode(6, OUTPUT);
}
void loop()
{
for ( int a = 2; a < 7 ; a++ )
{
digitalWrite(a, HIGH);
delay(d);

64
4. Las entradas y salidas digitales

digitalWrite(a, LOW);
delay(d);
}
for ( int a = 5 ; a > 1 ; a-- )
{
digitalWrite(a, HIGH);
delay(d);
digitalWrite(a, LOW);
delay(d);
}
}

El primero de los bucles for repetirá el código dentro de las llaves siempre y
cuando la condición sea verdadera. En este caso hemos utilizado una variable de
tipo entero «a» que comienza con el valor 2. Cada vez que se ejecuta el código, se
le sumará 1 a dicha variable. El bucle continuará de esta manera mientras que «a»
sea menor de 7. Una vez que sea igual o mayor que 7 se sale del bucle for y vuelve
al principio de la estructura void(loop), es decir, vuelve a iniciarse otro bucle for
desde el principio. El segundo bucle for inicializa la variable «a» con el valor 5 que
es el penúltimo LED. Ahora se va decrementando esta variable hasta llegar al valor
2 que se corresponde con el primer LED. De esta manera invertimos la secuencia
de encendido. Podéis probar otros valores de la variable «a» para comprobar si he
cometido una errata de código.

Además, dentro de la función delay(ms) hemos introducido una variable de


tipo entero «d» que permite cambiar de manera sencilla el intervalo de espera.

Darse cuenta de que en la condición del primer bucle for recorremos


los cinco LED ya que la variable «a» empieza en 2 y termina en 6.

Realiza una modificación del sketch anterior de tal manera que


encendamos y apaguemos dos LED al mismo tiempo.

Diseña un nuevo sketch que provoque varios efectos de luces con


varios leds de forma consecutiva. Imagina aplicárselo al típico árbol
de navidad.

65
Taller de Arduino

4.3 Práctica 2: controlando el encendido


de un led mediante un pulsador
El propósito de esta práctica es encender un LED mediante un pulsador. El LED
permanecerá prendido durante 2 segundos tras los cuales se apagará hasta que
volvamos a presionar el pulsador.

El algoritmo, por otra parte, muy simple es el que se muestra en la figura


4.13.

Figura 4.13

En cuanto al hardware que necesitamos:

 Un diodo LED.
 Una resistencia de 220 Ω.
 Una resistencia de 10 kΩ.
 Un pulsador tipo mini.
 Una protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

66
4. Las entradas y salidas digitales

Conectaremos el pulsador al pin digital 7 a través de una resistencia pull-up


de 10 kΩ. Esta resistencia se lleva por el otro terminal a 5 voltios. El diodo LED se
conecta al pin 2 a través de una resistencia de 220 Ω.

Las resistencias pull up y pull down no son más que resistencias


dispuestas en una configuración determinada. Dicha configuración
(Figura 4.14) determina si la resistencia es de pull up o pull down.
Este tipo de configuración establece un estado lógico a la entrada de
un circuito lógico cuando dicho circuito está en reposo, siendo para
pull up un estado lógico alto y para pull down, bajo. De esta forma, se
evita falsos estados producidos por ruido eléctrico si dejáramos una
entrada con un valor indeterminado.

Figura 4.14

En la configuración pull up, cuando el pulsador está en reposo, Vout será


prácticamente Vcc pudiéndose considerar como nivel lógico alto. Ahora bien,
cuando se pulsa S1, se deriva toda la corriente a masa, por tanto Vout será 0. Esto
mismo ocurre con la configuración pull down pero a la inversa. Cuando el circuito
está en reposo, la caída de tensión en R1 es prácticamente 0 que es la misma
tensión de Vout. En ese momento tendremos un nivel lógico bajo. Al pulsar S1, la
caída de tensión en R1 ahora será Vcc, Vout será un nivel lógico alto.
Generalmente, se suele usar un valor de 10 kΩ para estas resistencias.

Examinemos ahora el sketch que debemos escribir, guardar y subir a


nuestro Arduino para comprobar su funcionamiento.

67
Taller de Arduino

Práctica 2. Encendiendo un LED con un pulsador

/* Práctica 2 – Encendiendo un LED durante dos segundos con


un pulsador. */
/* Si no fuera por los 2 segundos de espera, sería una
tontería */

#define LED 12
#define BUTTON 7

void setup()
{
pinMode(LED, OUTPUT);
pinMode(BUTTON, INPUT);
}
void loop()
{
if (digitalRead(BUTTON) == HIGH)
{
digitalWrite(LED, HIGH);
delay(2000);
digitalWrite(LED, LOW);
}
}

La dinámica del programa es simple. Testeamos continuamente el estado


del pulsador cuyo estado en reposo produce un 0 en el pin de entrada 7 del
Arduino. Si no activamos el pulsador testeamos el if indefinidamente. En cuanto
pulsemos, el estado de la patilla 7 cambia a voltaje positivo y entonces se ejecuta
las acciones que van comprendidas entre llaves, es decir, el encendido del LED, la
espera de 2 segundos y el apagado del diodo. Tras esto, volvemos al principio del
void(loop), ejecutando de nuevo el testeo del pulsador con la estructura if.

Descubrimos varias cosas nuevas:

#define. Es un comando del lenguaje C muy útil que permite al


programador dar un nombre a un valor constante antes de que se compile el
programa. Las constantes definidas en Arduino no aumentan el tamaño que el

68
4. Las entradas y salidas digitales

programa ocupa en el chip. El compilador reemplaza las referencias a estas


constantes con el valor definido en tiempo de compilación. Básicamente
utilizaremos “#define” para etiquetar los pines digitales y de esta manera cada vez
que en el programa se haga referencia a esa etiqueta se apuntará a su valor. Por
ejemplo, en nuestro sketch cada vez que utilizamos la palabra LED hacemos
referencia al pin 12 del Arduino.

digitalRead(pin). Lee el valor de un pin (definido como digital) dando un


resultado HIGH (alto) o LOW (bajo) y pudiendo depositar este valor en una
variable. Por ejemplo:

valor = digitalRead(4);

En esta sentencia se lee el estado del pin 4 y se deposita su estado alto o


bajo, en la variable valor que se supone que se ha definido previamente como de
tipo booleano o entero. Evidentemente, esto es útil para evaluar el estado abierto
o cerrado de un pulsador o interruptor. Por ello, cuando en el sketch anterior
tenemos la expresión: “if (digitalRead(BUTTON) == HIGH)” lo que estamos
haciendo es evaluar si el pin 7 definido con el nombre BUTTON, está HIGH o LOW.
Es decir, testeamos el estado del pulsador y en función de su estado ejecutamos
lo que está dentro de las llaves del if o no lo hacemos. En la figura 4.15 se observa
el circuito diseñado y probado con Proteus.

Figura 4.15

Dibuja el circuito anterior con el programa fritzing.

69
Taller de Arduino

4.4 Práctica 3: control de dos semáforos. Un proyecto


completo con led y pulsadores
Este verano, recorriendo el camino de Santiago, me encontré con este túnel a la
salida de Orense por la travesía de Canedo (los lugareños la llaman la Costiña).
Hice un alto y me pregunté cómo regulaban los dos semáforos y el paso de
peatones. Mientras atravesaba el túnel, por unos momentos pensé en cómo se
haría con un Arduino. Pensamientos fugaces que se le ocurren a uno cuando lleva
más de un mes sin tocar nada de tecnología, salvo las llamadas de rigor con el
móvil a la familia. La verdad es que después de atravesarlo, me encontré con una
cuesta empinadísima de unos 3 km que me obligó a concentrarme en las piernas y
en dónde estaba el final de esta tremenda cuesta o costiña (para sorna de los
vecinos). Pasados unos meses, me acordé de este tramo del camino y, ya metido
en los berenjenales de Arduino, decidí retomar el tema de diseñar un proyecto
que resolviera el control de los dos semáforos de entrada y salida del túnel.

Entrada del túnel

Salida del túnel

70
4. Las entradas y salidas digitales

En un primer programa vamos a resolver el diseño solo considerando la


sincronización de los dos semáforos: el de entrada al túnel y el de salida. De
nosotros depende que no se encuentren dos coches en medio del mismo, ya que
como observamos en las fotos, la carretera solo tiene un carril. Para simular los dos
semáforos utilizaremos 6 diodos LED: 2 de color rojo, 2 de color verde y 2 de color
amarillo (a falta del color ámbar). Esto se puede observar en la Figura 4.16, cuyo
esquema se ha realizado con Proteus. Vemos el diagrama de flujo (Figura 4.17) en el
que observamos cómo se cumple la secuencia típica de un cruce de semáforos
normal. Mientras que un semáforo está en rojo, el otro luce en verde, y viceversa.
Los cambios de un color a otro se producen tras una espera determinada, que en
nuestro caso, suponemos de varios segundos. El tiempo de cambio de cada
semáforo podemos establecerlo en 2 minutos ya por esta carretera no existe
demasiado tráfico. En cuanto al hardware que necesitamos:

 6 diodos LED de varios colores.


 6 resistencias de 220 Ω.
 Una protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Figura 4.16

71
Taller de Arduino

Figura 4.17

Un vistazo al esquema de semáforos siguiente te permitirá entender mejor


el diagrama de flujo anterior y el listado de programa que se muestra.

Color ROJO asociado al pin 7


Color AMARILLO asociado al pin 6
Color VERDE asociado al pin 5
Semáforo 1 (Situado entrada túnel)

Color ROJO asociado al pin 4


Color AMARILLO asociado al pin 3
Color VERDE asociado al pin 2

Semáforo 2 (Situado salida túnel)

Práctica 3. Control de dos semáforos


/* Práctica 3 – Control de dos semáforos en un cruce. */
/* Anda que como me equivoque en el código… vaya desastre de
circulación!!! */

72
4. Las entradas y salidas digitales

void setup()
{
for (int pin = 2; pin <= 7; pin++)
{
pinMode(pin,
OUTPUT);
}
}
void semaforo_1()
{
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(500);
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(500);
digitalWrite(2, HIGH);
delay(500);
digitalWrite(2, LOW);
delay(500);
digitalWrite(3, HIGH);
delay(3000);
digitalWrite(3, LOW);
digitalWrite(4, HIGH);
digitalWrite(7, LOW);
semáforo_2();
}
void semaforo_2()
{
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);

73
Taller de Arduino

delay(500);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);
delay(500);
digitalWrite(5, HIGH);
delay(500);
digitalWrite(5, LOW);
delay(500);
digitalWrite(6, HIGH);
delay(3000);
digitalWrite(6, LOW);
digitalWrite(7, HIGH);
digitalWrite(4, LOW);
semaforo_1();
}
void loop()
{
for (int pin = 2;
pin <= 7; pin++)
{
digitalWrite(pin, LOW);
}
digitalWrite(2, HIGH);
digitalWrite(7, HIGH);
Semáforo_1();
}

Ahora tenemos un nuevo concepto que es el de función. Como se expuso


anteriormente, una función es un trozo de código que se va a utilizar varias veces
dentro del mismo programa. Una función es, por tanto, un bloque de código que
tiene un nombre y un conjunto de sentencias. Las funciones se declaran asociadas
a un tipo de valor: type. Este valor será el que devolverá la función, por ejemplo
int se utilizará cuando la función devuelva un dato numérico de tipo entero. Si la
función no devuelve ningún valor, entonces se colocará delante la palabra void,

74
4. Las entradas y salidas digitales

que significa «función vacía». Después de declarar el tipo de dato que devuelve la
función se debe escribir el nombre de la función y entre paréntesis se pondrán, si
es necesario, los parámetros que se deben pasar a la función para que se ejecute.
Su formato específico es el siguiente:

type nombreFunción (parámetros)


{
Sentencias que se ejecutan al llamar a esta función;
}

En el ejemplo anterior tenemos dos funciones diferenciadas: la función


semáforo_1() y la función semáforo_2(). Son de tipo void porque no devuelven
nada; solo ejecutan una serie de acciones para gobernar las luces de las que
consta cada semáforo. Además, como vemos, las hemos definido antes de la
estructura loop().

Ahora nos toca prestar un poco de atención a los peatones o peregrinos


que deseen atravesar el túnel, sin miedo a ser atropellados. Para ello dotamos al
diseño de dos pulsadores que, cuando sean activados, deben cambiar el flujo
normal de funcionamiento de los dos semáforos. La idea es que cuando
cualquiera de los dos pulsadores, tanto en una boca u otra del túnel, sea
presionado y, tras una espera de tiempo razonable, se actúe sobre los dos
semáforos poniéndolos en luz ROJA para permitir que los peatones circulen sin
peligro.

Para ello vamos a testear los dos pulsadores de los peatones durante la
secuencia de funcionamiento de los dos semáforos; exactamente, después del
parpadeo de la luz amarilla. Si cualquiera de los pulsadores ha sido activado se
deben poner en rojo los dos semáforos de los coches y en verde los dos
indicadores de paso de peatones.

Se han utilizado cuatro pines más para el control del paso de peatones. Por
otra parte, se han añadido cuatro luces: una roja y otra verde para el control de
paso del peatón posible en la entrada del túnel. Una más para el peatón de la
salida del túnel.

Veamos el hardware del proyecto (Figura 4.18 y Figura 4.19) para hacernos
mejor una idea de lo que tenemos entre manos.

75
Taller de Arduino

Figura 4.18

Figura 4.19

76
4. Las entradas y salidas digitales

Evidentemente, los peatones pueden pulsar el botón de solicitud de paso en


cualquier momento. Por ello, debemos «enclavar» o retener esa petición hasta que
la ejecución del programa pase después de hacer parpadear la luz amarilla en
cualquiera de los dos semáforos. La retención de la solicitud a través de los
pulsadores se realiza con dos biestables asíncronos RS. Cuando algún peatón
presione cualquiera de los dos pulsadores, la salida de su correspondiente biestable
se pondrá en estado alto, y permanecerá así hasta que obliguemos a pasar su salida
a un estado bajo mediante la patilla del Arduino: REINICIO_BIESTABLE.

Un biestable (flip-flop o LATCH en inglés) es un dispositivo capaz de


permanecer en uno de dos estados posibles durante un tiempo
indefinido en ausencia de perturbaciones. Esta característica es
ampliamente utilizada en electrónica digital para memorizar
información. Existen distintos tipos de biestables. El biestable tipo RS
es un dispositivo con dos entradas R y S (Reset y Set) y salida Q capaz
de almacenar un bit de información. Su funcionamiento es el siguiente:
• Si su entrada Set se activa su salida Q se pone en Alto.
• Si su entrada Reset se activa su salida Q se pone en Bajo.
• Si no se activa ni Set ni Reset su estado no cambia.
• Por supuesto, no se permite activar Set y Reset
simultáneamente.

La parte del diseño correspondiente a los pulsadores de los peatones y sus


correspondientes biestables RS se puede observar en la figura 4.20. El listado de
código se muestra a continuación.

Práctica 3.1. Control de circulación del túnel completo


/* Programación de dos semáforos en un túnel con un pulsador
para peatones*/
/* Desde luego mira que es largo el código……… */
int pin;
void setup()
{
for (int pin=2;pin<=7;pin++)
{
pinMode(pin, OUTPUT);
}

77
Taller de Arduino

pinMode(8,INPUT);
pinMode(9,OUTPUT);
pinMode(12,OUTPUT);
pinMode(13,OUTPUT);
}
void semaforo_peatones()
{
digitalWrite(2,LOW);
digitalWrite(3,LOW);
digitalWrite(5,LOW);
digitalWrite(6,LOW);
digitalWrite(4,HIGH);
digitalWrite(7,HIGH);
digitalWrite(13, LOW);
digitalWrite(12, HIGH);
delay(3000);
digitalWrite(12, LOW);
digitalWrite(13, HIGH);
digitalWrite(9, HIGH);
delay(10);
digitalWrite(9, LOW);
}
void semaforo_1()
{
digitalWrite(2, HIGH);
delay(3000);
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
delay(500);
digitalWrite(3, HIGH);
delay(500);
digitalWrite(3, LOW);
delay(500);
digitalWrite(3, HIGH);

78
4. Las entradas y salidas digitales

delay(500);
digitalWrite(3, LOW);
if(digitalRead(8)==HIGH)
{
semaforo_peatones();
}
digitalWrite(7, LOW);
digitalWrite(4,HIGH);
semaforo_2();
}
void semaforo_2()
{
digitalWrite(5, HIGH);
delay(3000);
digitalWrite(5, LOW);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(6, LOW);
delay(500);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(6, LOW);
delay(500);
digitalWrite(6, HIGH);
delay(500);
digitalWrite(6, LOW);
if(digitalRead(8)==HIGH)
{
semaforo_peatones();
}
digitalWrite(7, HIGH);
digitalWrite(4, LOW);
semaforo_1();
}

79
Taller de Arduino

void loop()

{
for (int pin=2;pin<=7;pin++)
{
digitalWrite(pin, LOW);

}
digitalWrite(2, HIGH);
digitalWrite(7, HIGH);
digitalWrite(13, HIGH);
digitalWrite(9, HIGH);
delay(10);
digitalWrite(9, LOW);
semaforo_1 ();
}

Como observamos, el listado es bastante largo, pero muy sencillo de


seguir. Lo que hemos añadido es una función llamada semáforo_peatones() que
actúa sobre los indicadores de los mismos cuando alguno de los pulsadores de
peatones se han activado. El testeo de dichos pulsadores se hace siempre después
de parpadear la luz amarilla de los dos semáforos. En la figura 4.21 vemos el
circuito completo diseñado y simulado en Proteus.

Figura 4.20

80
4. Las entradas y salidas digitales

Figura 4.21

4.5 Práctica 4: contador de pulsaciones


El programa debe mostrar en la pantalla del ordenador el número de veces que
un pulsador ha sido presionado. Se realiza un proceso que, de acuerdo al número
de pulsaciones, encienda o apague un LED. Para hacernos una idea os muestro el
esquema realizado con Proteus en la figura 4.22.

El LED se encenderá cuando se pulse cinco veces consecutivas y se apagará


cuando el número de pulsaciones sea de ocho. El condensador de 100 nf produce
una pequeña espera que amortigua el rebote del pulsador. En cuanto al hardware
que necesitamos:

 1 diodo LED de cualquier color.


 1 condensador de 100 nF.
 1 resistencia1 de 220 Ω.
 1 pulsador tipo mini.
 Un protoboard.

81
Taller de Arduino

 Cablecitos de conexión.
 Un Arduino y un cable USB.

Figura 4.22

Práctica 4. Contando pulsaciones


*/ Encendiendo y apagando un LED en función del número de
pulsaciones */
*/ Lo interesante de enviar datos, por primera vez, al
ordenata */
int conta = 0;
void setup()
{
Serial.begin(9600);
pinMode(2,INPUT);
pinMode(13,OUTPUT);
}

82
4. Las entradas y salidas digitales

void loop()
{
if ( digitalRead(2) == LOW )
{
if ( digitalRead(2) ==
HIGH )
{
conta++;
Serial.println(conta);
delay (100);
}
}
if (conta==5)
{
digitalWrite(13,HIGH);
}
if (conta==8)
{
digitalWrite(13,LOW);
conta=0;
}
}

Como novedad en este sketch, tenemos dos nuevas funciones relacionadas


con la trasmisión serie entre Arduino y PC, vistas anteriormente en capítulo 3.
También, jugamos con los If anidados.

Realiza un programa que cuente en binario utilizando tres LED del


mismo color para señalizar el contaje. El avance de la cuenta se
realizará cuando presionemos un pulsador. Al llegar al final (111) de
la cuenta volverá al principio (000) con la próxima pulsación.

Realizar un programa que cuente y descuente en binario utilizando


tres LED para señalizar el contaje. Usaremos un pulsador para
avanzar la cuenta y otro pulsador para descontar.

83
Taller de Arduino

4.6 ¿Qué es eso del PWM?


Las siglas PWM provienen de Pulse Wide Modulation, o lo que es lo mismo,
modulación por amplitud de pulsos. Mediante una señal PWM, que es una señal
digital en la que se envían ceros o unos más o menos largos, podemos simular una
salida analógica y hacer creer al receptor (LED, motor, etc.) que tengamos
conectado a esa salida, que lo que está recibiendo es una variación «suave» de
voltaje. La primera particularidad de esta función es que no puede utilizarse con
cualquier pin, solo con los que tienen dibujado a su lado este símbolo “~”. Si echas
un vistazo a la figura 4.23 detectarás los pines que pueden generar señales PWM:
3, 5, 6, 9, 10, 11. La segunda característica curiosa es que solo podemos enviar
valores entre 0 y 255, correspondiendo el “0” a 0 voltios y “255” a 5 voltios.

Figura 4.23

La técnica PWM permite generar ondas cuadradas con una frecuencia y


ciclo de actividad determinada. El ciclo de actividad (duty cycle) representa la
anchura del pulso: cuánto tiempo de cada onda cuadrada hay pulso (5V) y cuándo
no lo hay (0 V). En la figura 4.24 se observan diferentes señales PWM con
diferentes ciclos de trabajo (DC).

De todas maneras, por si no te has enterado bien de la utilidad de la


característica PWM del Arduino, vamos a realizar una práctica muy sencilla que te
clarificará todo lo anterior.

84
4. Las entradas y salidas digitales

Figura 4.24

4.6.1 Práctica 5: variando la luminosidad de un LED


En esta práctica vamos a variar la luminosidad de un LED conectado en la patilla 5
de nuestro Arduino. Para ello le inyectaremos una señal PWM con diferentes
valores de ciclo de trabajo.

En lugar de encender y apagar continua y rápidamente el LED utilizamos la


función: analogWrite() para dar la sensación de que se enciende levemente. El ojo
humano percibe un parpadeo rápido como un cierto nivel de brillo y podemos
utilizar la modulación de ancho de pulso (PWM) para especificar la cantidad de
tiempo que el pin digital “~” está alto (HIGH) en comparación con el tiempo que
permanece bajo (LOW). Variando esta proporción (duty cycle,DC) entre los dos
estados a lo largo del tiempo, obtenemos diferentes brillos o luminosidades del LED.

Para crear una señal PWM se utiliza la función analogWrite() donde


especificamos el pin digital implicado y el valor entre 0 (0 %) y 255 (100 %) que
deseamos para su ciclo de trabajo.

analogWrite(pin,value). Esta función sirve para escribir un valor


proporcional de trabajo (DC) utilizando la técnica PWM. El parámetro pin indica la
patilla digital implicada. El parámetro value contiene un número entre 0 y 255.
Por ejemplo: “analogWrite(5,128)” enviará por el pin 5 una salida cuadrada (128
es la mitad de 256). Un LED conectado a esta patilla brillará con una luz que será
la mitad de su máxima luminosidad. En cuanto al hardware que necesitamos:

 1 diodo LED.
 1 resistencia de 220 Ω.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

85
Taller de Arduino

Observamos el montaje en la figura 4.25.

Figura 4.25

Práctica 5. Haciendo variar el brillo de un led


/* Variando el brillo de un led conectado al pin 5 del
Arduino. */
/* ¿Y cómo lo haría si fuera una lámpara normal en vez de un
ridículo led? */
int led = 5;
int brillo = 0;
int aumento = 5;
void setup()
{
pinMode(led, OUTPUT);
}
void loop()
{
analogWrite(led, brillo);
brillo = brillo + aumento;

86
4. Las entradas y salidas digitales

if (brillo == 0 || brillo == 255)


{
aumento = -aumento;
}
delay(30);
}

En este sketch establecemos la cantidad de aumento de luminosidad


mediante la variable aumento que posee un valor de 5 y se irá sumando a la
variable brillo que es la que determina definitivamente el brillo de led a través de
la función analogWrite(). Cuando la variable aumento llega a 255 o a 0, invertimos
su signo para decrecer su valor. La función delay() es utilizada para que podamos
visualizar el efecto sobre el LED.

4.6.2 Funcionamiento de un pequeño altavoz


Un altavoz piezoeléctrico es un dispositivo pequeño y redondo que puede ser
utilizado para genera ruidos fuertes y molestos. Son perfectos para las alarmas o
para divertirse reproduciendo melodías.

Los altavoces contienen una placa muy delgada dentro del soporte que se
mueve cuando se aplica corriente eléctrica. Cuando se aplica una tensión alterna
(por ejemplo: on… off… on… off… etc.) la placa vibra y generan ondas de sonido.

Figura 4.26

Los zumbadores piezoeléctricos (Figura 4.26) están polarizados y no pueden


ser conectados de cualquier manera. Dependiendo de la frecuencia de la señal
que se aplica al altavoz, así oiremos sonidos más graves o más agudos.

87
Taller de Arduino

4.6.3 Práctica 6 y práctica 7: haciendo sonar un altavoz


Vamos a probar un altavoz conectado al Arduino utilizando una señal PWM para
producir sonidos. El esquema (Figura 4.27) y el sketch son muy sencillos.

En cuanto al hardware que necesitamos:

 1 altavoz o zumbador piezoeléctrico.


 1 resistencia de 220 Ω.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Figura 4.27

Práctica 6. Haciendo sonar un pequeño zumbador


/* Pitidos simples con Arduino */
/* Una manera simple de llamar la atención….*/
#define PIEZO 3
int del = 10;
void setup()
{
pinMode(PIEZO, OUTPUT);
}

88
4. Las entradas y salidas digitales

void loop()
{
analogWrite(PIEZO, 255);
delay(del);
analogWrite(PIEZO, 0);
delay(del);
}

En este ejercicio utilizamos una patilla 3 digital con propiedades PWM para
inyectar una señal cuadrada a un zumbador. La señal cuadrada variará entre 0 y 5
voltios con una cadencia o frecuencia marcada por el valor de la función delay(). Si
variamos dicho valor, escucharemos pitidos distintos.

Ilusionados por escuchar al Arduino, queremos más caña… Vamos a


aumentar el volumen del sonido. Para ello nos hacemos con lo que propiamente
llamamos: altavoz piezoeléctrico. Por poco más de 3 euros adquirimos este
pequeño, pero potente altavoz de 2 W. Pequeño pero matón, este altavoz es de
gran calidad y ofrece una mejor reproducción de sonido que el zumbador del
ejercicio anterior. Simplemente con la ayuda de un pequeño transistor, podrás
amplificar cómodamente tu señal PWM. Lo observamos en la figura 4.28
fijándonos en los dos terminales: negro (masa) y rojo (positivo).

Figura 4.28

El dispositivo llamado transistor nos va a proporcionar una corriente mayor


que la que produce el Arduino. Además, permite manejar voltajes mayores que 5
voltios que es el valor con el que trabaja nuestra placa. Todo ello se traduce en un
aumento de sonido, que sin duda, sorprenderá a nuestros amigos.

Casi todo el mundo ha oído hablar de un transistor, pero la mayoría de la


gente realmente no entiende cómo funciona. Voy a explicarlo lo más sencillo

89
Taller de Arduino

posible: un transistor puede activar o desactivar un flujo de mayor corriente que la


que puede proporcionar nuestro Arduino. Al igual que el LED, los pines del
transistor tienen una función única y es imprescindible, antes de nada, identificarlos
para su correcta conexión. En la figura 4.29 observamos la disposición que tienen
las patillas del transistor 2N3904. Todos los transistores poseen tres patillas
llamadas: Colector (C), Base (B) y Emisor (E). Cuando una pequeña corriente se
aplica al terminal de Base, procedente, por ejemplo, de un pin del Arduino, se
establece una corriente mayor desde el Colector hacia masa pasando por el Emisor.

Es decir, que podemos controlar un flujo de corriente más o menos grande


(depende del tipo de transistor) desde el Colector al Emisor con una pequeña
corriente en la Base. En el caso del 2N3904, la máxima corriente que podemos
gobernar es de unos 200 mA, suficiente para activar el altavoz

Figura 4.29

Echemos un vistazo al esquema del circuito (Figura 4.30).

Figura 4.30

90
4. Las entradas y salidas digitales

En cuanto al hardware que necesitamos:

 1 altavoz 4 Ω.
 1 resistencia de 220 Ω.
 1 resistencia de 1 kΩ.
 1 transistor típico 2N3904.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

El lenguaje de programación de Arduino proporciona una interesante


función para simplificar la generación de sonidos o tonos. Probemos el siguiente
sketch:

Práctica 7. Reproduciendo tonos


*/ Utilizamos la patilla 3 (PWM) para generar diferentes
tonos */
*/ Y se puso a llover al sonar el altavoz… */
void setup()
{
int pinOut = 3;
int freq = 110;
int duracion = 1000;
for(int i=0; i<40 ; i++)
{
tone(pinOut, freq*i, duracion);
int pausaEntreNotas = duracion * 1.30;
delay(pausaEntreNotas);
noTone(3);
}
}
void loop()
{
}

91
Taller de Arduino

tone(pin, frecuencia, duración). Genera una onda cuadrada de la


frecuencia especificada (y un 50 % de ciclo de trabajo) en un pin. La duración
puede ser especificada, en caso contrario, la onda continúa hasta que haya una
llamada a noTone(). Solo puede generarse un tono cada vez. Si un tono está
sonando en un pin diferente, la llamada a tone() no tendrá efecto. Si el tono está
sonando en el mismo pin, la llamada establecerá la nueva frecuencia. La duración
se define en milisegundos y la frecuencia en hertzios.

Si quieres reproducir varias notas seguidas, es muy importante esperar un


tiempo antes de reproducir la próxima nota. Se recomienda un tiempo de un 30 %
de la duración de la nota. Eso es precisamente lo que hace la variable
pausaEntreNotas.

Si quieres hacer sonar diferentes tonos en múltiples pines necesitas


llamar a noTone() en un pin antes de llamar a tone() en el siguiente
pin. Las frecuencias audibles por el oído humano van de los 20 Hz a
los 20 kHz, por lo que el parámetro «frecuencia» debería estar
comprendido entre estos dos valores.

El fichero pitches.h contiene todos los valores de las frecuencias de


las notas típicas. Por ejemplo, NOTE_C4 es una C media. NOTE_FS4 es
F aguda y así sucesivamente. Esta tabla de notas fue originalmente
escrita por Brett Hagman y que está basada en la función tone(). La
encontrarás útil cada vez que tengas que reproducir notas musicales.
Busca en Internet este fichero y utilízalo para componer alguna
melodía de tu gusto.

4.7 Introducción a las interrupciones en Arduino


Las interrupciones en el Arduino son muy poderosas ya que pueden interrumpir el
flujo de programa en cualquier momento. Una interrupción es como si alguien
toca el timbre de tu casa cuando estás a punto de entrar en la ducha y tienes que
atenderlo de inmediato a no ser que seas un moroso empedernido. El Arduino
hace exactamente lo mismo, cuando se activa una interrupción se pasa el control
a la gestión de la misma, a no ser que, puntualmente, la hayas deshabilitado.
Entendemos por gestión de la interrupción, el hecho de ejecutar una rutina,
llamada de interrupción (ISR), que contiene un trozo de código de programa. Tras
haberse procesado dicha rutina, se retorna al programa principal y se continúa
ejecutando. El Arduino UNO puede utilizar un máximo de dos interrupciones.

92
4. Las entradas y salidas digitales

Los Arduino basados en los microcontroladores Amtel AVR pueden ejecutar


una sola secuencia de instrucciones a la vez. El problema de esto es, por ejemplo,
que si estamos enviando números a un dispositivo cualquiera y, en cualquier
momento, un usuario presiona un botón para llamar la atención del Arduino,
pongamos el caso, para apagar un LED, puede suceder que perdamos ese evento
y no atendamos al usuario porque nuestro ciclo de programa emplea mucho
tiempo en ejecutarse y hayamos perdido la lectura del estado del botón. Esto es
una desventaja de los microcontroladores sencillos y es algo con lo que las
computadoras han tenido que convivir prácticamente desde que fueron
inventadas.

EL micro AVR de cualquier Arduino tiene dos tipos de interrupciones:

 Externas. El Arduino cuenta con solo dos pines de interrupción


externa: INT0 e INT1, y están asignadas a los pines 2 y 3. Cuando se
produce un cambio en el estado lógico del pin_2 o del pin_3 se activa
dicha interrupción. Estas interrupciones pueden activarse en subidas
o bajadas de señal, en bajo nivel o en alto nivel. Las activaciones son
interpretadas por el hardware y son muy rápidas.
 Internas. Utilizan los recursos hardware del propio micro. Se utilizan
para provocar eventos internos como el contaje de un tiempo
determinado que interrumpa, periódicamente, la ejecución del
programa principal. Debido a su complejidad no las trataremos,
debido a que su uso implica conocer profundamente la arquitectura
interna del microcontrolador AVR.

Si nos fijamos en las interrupciones externas podemos asociar el código de


ese tipo de rutina de interrupción, a través de la función attachInterrupt(). Las
interrupciones o eventos que podemos asociar a los pines implicados mediante
esta función son las siguientes:

 Cuando el nivel lógico de la línea es 0 (LOW).


 Cuando el nivel lógico de la línea cambia independientemente de su
estado lógico (CHANGE).
 Cuando el nivel lógico cambia de 0 a 1 (RISING).
 Cuando el nivel lógico cambia de 1 a 0 (FALLING).

93
Taller de Arduino

4.7.1 Práctica 8: control de un led mediante


un pulsador sin interrupciones
Pero basta de teoría por ahora, que es lunes por la mañana y nos dormimos.
Vamos a realizar un ejemplo práctico de utilización de interrupciones para
entender esto perfectamente. Consideremos que no sabemos nada de
interrupciones y deseamos encender y apagar un LED cuando presionemos un
pulsador. Así de simple. El caso es que el programa principal va a estar ocupado
haciendo una tarea repetitiva en el bucle loop(). No hay problema, pensamos,
hemos hecho algo parecido en la práctica 2. De hecho, el esquema de conexión es
muy parecido (Figura 4.31). Ahora, el diodo led está conectado al pin 4 y el
pulsador al pin 5 del Arduino.

Como se puede observar, es un código sencillo. Definimos el pin 2 como


entrada y el 4 como salida. Además consideramos una variable para controlar en
qué estado está actualmente el botón. Lo interesante es que para poder comparar
eficientemente el uso de la interrupción con este código, agregamos una estructura
for que se repite 100 veces, con una delay() de 10 milisegundos cada vez.

Esto causará salidas impredecibles en el LED debido a que el for (que simula
un proceso lento) está en un punto indeterminado en relación a cuando el botón
es presionado. Algunas veces el LED cambia de estado inmediatamente, otras
veces nada pasa y otras veces es necesario mantener el botón presionado por un
mayor tiempo para que el estado cambie y sea reconocido.

Figura 4.31

94
4. Las entradas y salidas digitales

Mucha culpa de esto lo tiene la función delay() que paraliza siempre el micro
de Arduino impidiendo atender a las pulsaciones del pulsador en tiempo real.

Práctica 8. Pulsador sin gestión de interrupciones


*/ Encendiendo y apagando un led sin usar interrupciones */
*/ Programando a la antigua usanza… */
int pulsador = 5;
int led = 4;
int estado = LOW;
void setup()
{
pinMode(pulsador, INPUT);
pinMode(led, OUTPUT);
}
void loop()
{
estado = digitalRead(pulsador);
digitalWrite(led, estado);
for (int i = 0; i < 100; i++)
{
delay(10);
}
}

Monta el circuito y prueba su funcionamiento. Juega con el pulsador


y observa si te obedece al encendido y apagado del LED.

4.7.2 PRÁCTICA 9: control de un LED mediante


un pulsador con interrupciones
Reprogramemos el sketch utilizando la técnica de interrupciones.

Práctica 9. Pulsador con gestión de interrupciones


*/ Encendiendo y apagando un led usando interrupciones */

95
Taller de Arduino

*/ Ahora sí que me obedece el pulsador */


int pulsador = 5;
int led = 4;
volatile int estado = LOW;
void setup()
{
pinMode(pulsador, INPUT);
pinMode(led, OUTPUT);
attachInterrupt(pulsador, cambio_estado, CHANGE);
}
void loop()
{
estado = digitalRead(pulsador);
digitalWrite(led,estado);
for (int i = 0; i < 100; i++)
{
delay(10);
}
}
void cambio_estado()
{
estado = !estado;
digitalWrite(led, estado);
}

La palabra clave es: volatile. Es agregada a la variable estado. Esto causa


que el compilador use la RAM en vez de un registro de almacenamiento. Esto es
así debido a que el registro de almacenamiento puede ser temporalmente
impreciso si es modificado por áreas diferentes a las del programa principal. Este
tipo de variable se caracteriza por que su valor pueda ser modificado por algo
fuera de la sección del código en el que aparece, o sea, por una función externa
como una interrupción. Si la variable estado no la definimos como volatile, no
podría ser modificada por la rutina de interrupción.

96
4. Las entradas y salidas digitales

En segundo lugar, hay que informar a Arduino que utilizaremos la


interrupción. Ello lo hacemos dentro de setup() con la instrucción: attachInterrupt().
Este mandato especifica la función a invocar cuando se produce una interrupción
externa. La mayoría de las placas Arduino tienen dos interrupciones externas: las
número 0 (en el pin digital 2) y la 1 (en el pin digital 3). Arduino Mega tiene otras
cuatro: las número 2 (pin 21), 3 (pin 20), 4 (pin 19) y 5 (pin 18).

attachInterrupt(nint, nfuncion, modo). Avisa al Arduino de que vamos a


utilizar una interrupción. Sus parámetros son los siguientes:

nint. Número de interrupción. 0 si utilizamos el pin 2 y 1 si utilizamos


el pin 3.
nfuncion. Nombre de la función de interrupción que invocamos.
modo. Es el evento que provoca la interrupción. Están descritos
anteriormente.

Concretando la exposición teórica a nuestro caso, tenemos tres puntos


reseñables:

volatile int estado = LOW;

Define la variable estado como volatile para que pueda ser «vista» y
modificada por la interrupción. Se inicializa en estado bajo.

attachInterrupt(pulsador, cambio_estado, CHANGE);

Define una rutina de interrupción (ISR) en el pin 2 (pulsador) que se activará


cuando el estado de esta patilla cambie (CHANGE) de estado lógico. Siempre que
varíe, se ejecutará la rutina de interrupción a la que hemos llamado:
cambio_estado.

void cambio_estado()
{
estado = !estado;
digitalWrite(led, estado);
}

La rutina de interrupción cambio_estado lo único que hace es invertir el


valor lógico de la variable estado y encender o apagar el LED.

97
Taller de Arduino

Compila y sube a tu Arduino el código del listado anterior. Juega de


nuevo con el pulsador para observar si ahora ha mejorado el
funcionamiento del circuito.

Proyecta un circuito basado en un sistema de alarma. El programa


principal debe encender y apagar tres LED uno a uno tal y como
vimos en la práctica del coche fantástico. Por otra parte, debemos
dotar al sistema de un pulsador y de un interruptor. Cuando se
presione el pulsador en cualquier momento, se activará un zumbador
o altavoz durante cinco segundos. Cuando se cambie el estado del
interruptor de alto a bajo, se deben apagar todos los diodos durante
3 segundos.

Por otra parte, Arduino tiene la habilidad de temporalmente ignorar todas


las interrupciones. Esto es deseable en el caso en el que se tenga un código
sensible que debe ser ejecutado sin interrupción. En este caso, se debe realizar un
llamado al método noInterrupts(). Cuando termine el código sensible, las
interrupciones pueden reiniciarse con el método interrupts().

98
CAPÍTULO

LAS ENTRADAS
ANALÓGICAS

En los capítulos anteriores, hemos experimentado con botones y diodos leds que
pueden tomar solo dos estados: encendido o apagado. Si ahora queremos medir
una temperatura, una fuerza, una distancia u otro valor que variará con el tiempo,
necesitamos utilizar la potencia de las entradas analógicas que posee el Arduino.

Figura 5.1

Si el Arduino fuera puramente un dispositivo digital, no seríamos capaces


de medir estas variables y limitaría el alcance de nuestros proyectos. Por suerte, el
Arduino puede interactuar con el mundo analógico también. El Arduino puede
alterar el brillo de un LED mediante la variación de la tensión aplicada a ella, pero
mediante el uso de una técnica especial llamada modulación de ancho de pulso
(PWM) que hemos visto anteriormente.

99
Taller de Arduino

Además de proporcionar una salida «cuasi» analógica por medio de PWM, el


Arduino también puede adquirir una entrada analógica de entre 0 y 5 voltios. El
Arduino estándar tiene seis entradas analógicas (Figura 5.1) etiquetadas: ANALOG
IN A0, A1, A2, A3, A4, A5. En este capítulo, nos concentraremos en la función
analogRead(). Vamos a empezar por echar un vistazo a la diferencia entre los
dispositivos digitales y analógicos. Entonces, ¿cuál es la diferencia entre el mundo
analógico y el digital? En el mundo digital, todo tiene dos estados: un interruptor
solo puede estar encendido o apagado, un LED está encendido o apagado. En el
mundo analógico, las cosas tienen un rango de valores: la música tiene notas que
abarcan una gama de frecuencias, un coche acelera a través de una gama de
velocidades, una onda sinusoidal fluye suavemente entre los valores máximo y
mínimo, la temperatura varía entre un máximo y un mínimo. A menudo es
necesario explorar el mundo analógico y el Arduino seis posee entradas analógicas
que nos permiten hacer esto. Pero el Arduino no es un dispositivo digital, por lo que
necesita un medio para convertir una señal de entrada en una representación
digital. Esto se hace mediante un convertidor analógico-digital (ADC).

La Tabla 5.1 muestra la resolución, rango de voltaje y los pines usado para
las entradas analógica y salida del Arduino y Arduino Mega.

Entrada Analógica Salida Analógica


Resolución 10 bits (0 al 1023). 8 bits (0 al 254).
Rango de voltaje 0 a 5 voltios. 0 a 5 voltios.
Pines digitales: 3, 5, 6, 9,
Patillas del Arduino UNO A0 a A5.
10, 11.
Patillas del Arduino Mega A0 a A15. Pines digitales: 3 al 13.
Tabla 5.1

El hecho de que el convertidor analógico-digital (ADC) de nuestro Arduino


sea de 10 bits significa que puede distinguir entre 1024 valores distintos. Si no te
aclaras con esto, no te preocupes y sigue leyendo, que no es tan complicado. Si
tenemos un dispositivo que nos envía información analógica codificada como
cambios de voltaje y la diferencia de potencial máxima que puede establecer
entre una entrada analógica y tierra es de 5 V, nuestro Arduino podrá informarnos
de cómo evoluciona esa señal en intervalos de:

100
5. Las entradas analógicas

Cada 4,9 mV de voltaje de incremento supondrá un incremento de 1 en el


número equivalente digital. Por ejemplo, si tienes 10 mV en la entrada A0, en la
salida del convertidor ADC interno del Arduino aparecerán 10 mV / 4,9 mV = 2 (00
0000 0010). Para obtener el número 3 (00 0000 0011) la entrada analógica tiene
que aumentar 4,9 mV más. Y así sucesivamente, por eso a ese valor mínimo para
que aumente el equivalente digital se le llama peldaño (no puedes subir la
escalera de tu casa a base de medios peldaños).

5.1 UN POCO DE TEORÍA «ANALÓGICA».


EL POTENCIÓMETRO
Ahora vamos a utilizar un potenciómetro para proporcionar una señal analógica
de entrada que se pueda variar manualmente. Observaremos el efecto de estos
cambios mostrando los resultados en el monitor serial del IDE.

Un potenciómetro es una de las formas más sencillas de entrada


analógica del Arduino. Los potenciómetros vienen en todas formas y tamaños
y son utilizados en muchos dispositivos diferentes que nos rodean. La mayoría
de los potenciómetros tiene tres conexiones, la patilla del medio se utiliza
para variar la resistencia al mover un contacto a lo largo de una resistencia fija
(Figura 5.2).

Figura 5.2

5.1.1 Práctica 10: el potenciòmetro y Arduino


En el siguiente ejemplo vamos a adquirir valores distintos de voltaje a través de
un potenciómetro lineal conectado a la entrada analógica A0 del Arduino. A
medida que giramos el potenciómetro hacia la derecha o hacia la izquierda,
podremos ajustar el voltaje entre 0 y 5 voltios.

101
Taller de Arduino

Figura 5.3

Figura 5.4

En las figuras 5.3 y 5.4 se muestran los esquemas de la práctica realizados


con Fritzing y Proteus. En cuanto al poco hardware que necesitamos:

 1 potenciómetro 10 kΩ.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

102
5. Las entradas analógicas

Práctica 10. Potenciómetro y arduino


/* Adquirir valores con el potenciómetro en A0 y mostrarlos
con el monitor serial.*/
/* Probando un potenciómetro… */
int sensorPin = A0;
int sensorValor = 0;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValue = analogRead(sensorPin);
Serial.print("Sensor = ");
Serial.println(sensorValue, DEC);
delay(10);
}

No es necesario establecer la entrada analógica A0 como entrada durante


la configuración porque todos los pines analógicos se establecen de forma
predeterminada como entrada. La variable almacena el sensorValor leído por la
función analogRead() que devuelve un número entre 0 y 1023 inclusive. El 0
representa 0 voltios y 1023 representa 5 voltios. La función delay() de 10
milisegundos de retardo entre cada lectura permite dar tiempo al convertidor
ADC del Arduino a resolver y capturar una lectura precisa. El parámetro «DEC» en
la línea: Serial.println (sensorValor,DEC) indica que la función println envía datos
en base decimal. Otras opciones son: HEX (hexadecimal), BIN (binario) y OCT
(octal).

analogRead(pin). Lee el valor de un determinado pin definido como


entrada analógica con una resolución de 10 bits. Esta instrucción solo funciona en
los pines (0-5). El rango de valor que podemos leer oscila de 0 a 1023. Los pines
analógicos (0-5), a diferencia de los pines digitales, no necesitan ser declarados
como entradas o salidas ya que son siempre entradas.

103
Taller de Arduino

Figura 5.5

Después de realizar la compilación bien, conectamos el Arduino al PC y


subimos el programa. Abrimos el IDE y ejecutamos el monitor de serie. Giramos el
potenciómetro (utilícese un destornillador plano si es un trimmer) en sentido
horario y antihorario. Debemos ver la salida del número en el monitor cambiando
(entre 0 y 1023) a medida que el potenciómetro gira (Figura 5.5).

Los potenciómetros de ajuste (Trimmer o Trimpot) son


potenciómetros que se ajustan con la ayuda de un destornillador.
Sirven para que el circuito al que pertenecen actúe adecuadamente
(en su punto) y compense las tolerancias en otros componentes. Los
potenciómetros normales están previstos para que su posición se
pueda variar a voluntad. Van sujetos a un botón de mando a mano.
Los de ajuste, no. Los hay de dos clases genéricas según el recorrido
para el ajuste. En los sencillos este es de aproximadamente 3/4 de
vuelta y los multivuelta es de alrededor de 20 vueltas. Un
potenciómetro lineal varía su resistencia en función directa del
ángulo de giro y los logarítmicos de acuerdo con el logaritmo del
desplazamiento. Los logarítmicos se utilizan exclusivamente en
cuestiones de sonido pues se trata de conseguir el efecto de los
lineales respecto del sonido. El oído responde logarítmicamente.

Ya has visto cómo leer un valor en uno de los pines de entrada analógica. En
el siguiente apartado se va a conectar el Arduino a un transductor piezoeléctrico.
Para ello voy a necesitar algunos componentes adicionales debido a que un

104
5. Las entradas analógicas

transductor piezoeléctrico puede producir algunas tensiones muy altas que


podrían dañar nuestro Arduino.

5.2 FUNCIONAMIENTO DE UN TRANSDUCTOR


PIEZOELÉCTRICO
Si alguna vez has recibido una tarjeta de cumpleaños que toca una melodía
cuando se abre, probablemente lleve un transductor piezoeléctrico que funcione
como un altavoz. Los transductores piezoeléctricos también se encuentran en una
variedad de otros dispositivos, incluyendo teléfonos móviles, timbres de puertas e
incluso el sónar submarino. La figura 5.6 muestra un transductor piezoeléctrico
típico que se puede utilizar para producir sonidos similares a los utilizados en
algunas tarjetas musicales.

Figura 5.6

¿Cómo funcionan? La palabra piezoelectricidad significa «electricidad como


resultado de una presión». Cuando un dispositivo piezoeléctrico se comprime,
produce una carga eléctrica. Una aplicación típica con un Arduino es utilizar el
transductor como un sensor de contacto. Cuando el transductor se golpea o se
cae, el Arduino lo detecta y actúa en consecuencia, como, por ejemplo,
encendiendo un LED o produciendo un sonido en un altavoz.

Por otra parte, si se aplica un voltaje variable con una cierta


frecuencia, la vibración de la membrana del transductor puede producir un
sonido o nota. Es de este modo que los transductores piezoeléctricos se usan
en las tarjetas de felicitación musicales o como timbres. Como hemos visto, un
solo transductor piezoeléctrico puede ser utilizado como una entrada o un
dispositivo de salida.

105
Taller de Arduino

5.2.1 Práctica 11: monotorizando un transductor piezoeléctrico


En esta práctica vamos a medir la presión con que apretamos un transductor
piezoeléctrico conectado a nuestro Arduino. Además, visualizaremos estos valores
a través del monitor serie que nos proporciona el IDE. En cuanto al hardware que
necesitamos:

 1 Diodo Zener (BZX55C5) de 5.1 Voltios y ½ W.


 Una resistencia de 1 MΩ.
 Un transductor piezoeléctrico comprado en www.bricogeek.com por
1.6 €.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Cuando se presionan los transductores piezoeléctricos pueden producir


voltajes muy altos, que son capaces de causar daños a la placa Arduino. Un diodo
Zener se utiliza para proteger el Arduino de estas altas tensiones. Es importante
prestar atención a la polaridad del transductor que normalmente posee un cable
rojo y otro negro.

Los diodos Zener (Figura 5.7) son dispositivos para estabilizar la


tensión e intensidad que hay en un circuito cuando se presenta una
variación de voltajes en el circuito. El diodo Zener debe ser polarizado
inversamente para que adopte su característica de regulador de
tensión. Los diodos Zener se utilizan mucho para la protección de los
circuitos que no pueden recibir una variación de voltaje, ya que, si así
fuera y se le suministran variaciones de voltaje e intensidad, el
dispositivo se dañaría.

En la figura 5.7 se observa el símbolo y la curva característica que explica su


funcionamiento. El diodo Zener debe estar conectado de manera correcta para
que proteja la entrada analógica de Arduino de cualquier voltaje superior a 5.1
voltios. El diodo Zener funciona solo cuando su tensión de ruptura supera 5.1 V.
Las tensiones de más de 5.1 voltios harán que el Zener estabilice a 5.1 V,
protegiendo de este modo la entrada del Arduino de tensiones más altas.

106
5. Las entradas analógicas

Figura 5.7

Figura 5.8

107
Taller de Arduino

Una vez montado el esquema según se observa en la figura 5.8, trata de


apretar ligeramente el transductor y verás cómo cambian los valores del sensor.
Los verás en el monitor serie del IDE. Es importante revisar las conexiones del
circuito si no pasara nada.

Práctica 11. Monotorizando un transductor piezoeléctrico


/* Prueba de un transductor piezoeléctrico como sensor de
fuerza */
/* Se trata de apretar con cuidado el piezo… */
int sensorPin = A0;
int sensorValor = 0;
int referencia = 200;
void setup()
{
Serial.begin(9600);
}
void loop()
{
sensorValor = analogRead(sensorPin);
if (sensorValor > referencia)
{
Serial.print("Sensor = ");
Serial.println(sensorValor, DEC);
}
delay(10);
}

Se ha establecido un valor de referencia mínimo de 200 para que a partir de


ahí muestre valores en monitor serie. Estos valores los leemos (0 a 1023) con la
función analogRead(A0) y los visualizamos en decimal (DEC).

5.2.2 Práctica 12: tocando música con el zumbador


En esta nueva práctica vamos a añadirle un zumbador como vimos anteriormente
en nuestro último proyecto. Lo conectaremos al pin 8 tal y como se muestra en la
figura 5.9.

108
5. Las entradas analógicas

Figura 5.9

Práctica 12. Tocando un poco de música


/* Tocando música desde el transductor piezoeléctrico. */
/* No es U2 ni se le parece… */
int sensorPin = 0;
int sensorValor = 0;
int threshold = 200;
int toneDuración = 40;
int toneFrecuencia = 262;
int speakerPin = 8;
void setup()
{
}
void loop()
{
sensorValor = analogRead(sensorPin);
if (sensorValor > referencia)
{
tone(speakerPin,toneFrecuencia,toneDuracion);
}
}

109
Taller de Arduino

En este sketch hacemos pitar el zumbador si al presionar el transductor


piezoeléctrico superamos un valor de referencia de 200. Y suena con una
frecuencia de tono y una duración definidos al principio del programa.

Añade otro transductor piezoeléctrico y juega a tocar dos tipos


diferentes de tonos utilizando el mismo zumbador.

110
CAPÍTULO

SENSORES BÁSICOS DE
LUZ, TEMPERATURA,
DISTANCIA Y
PRESENCIA

En este capítulo veremos cómo utilizar las entradas analógicas del Arduino con
diferentes tipos de sensores. Usaremos el monitor serie para visualizar las
medidas. Sí, ya sé que es un poco cutre. No os preocupéis, ya nos queda poco
para manejar los famosos LCD (visualizadores de cristal líquido) y dotar a nuestros
proyectos de un aspecto profesional.

6.1. Práctica 13: funcionamiento de la LDR


Una LDR (Light Dependent Resistor) es una resistencia que varía su valor en
función de la luz recibida, cuanta más luz recibe, menor es su resistencia. Una LDR
está fabricada con un semiconductor de alta resistencia como puede ser el sulfuro
de cadmio. Si la luz que incide en el dispositivo es de alta frecuencia, los fotones
son absorbidos por la elasticidad del semiconductor dando a los electrones la
suficiente energía para saltar la banda de conducción.

Figura 6.1

111
Taller de Arduino

El electrón libre que resulta (y su hueco asociado) conduce electricidad, de


tal modo que disminuye la resistencia. Las células de sulfuro del cadmio se basan
en la capacidad del cadmio de variar su resistencia según la cantidad de luz que
incide la célula. Cuanta más luz incide, más baja es la resistencia. Las células son
también capaces de reaccionar a una amplia gama de frecuencias, incluyendo
infrarrojo (IR), luz visible y ultravioleta (UV).

El rango de resistencia que nos puede dar un LDR desde la total oscuridad
hasta la plena luz, nos va a variar de un modelo a otro, pero en general oscilan
entre unos 50 Ω a 1000 Ω cuando están completamente iluminadas y entre 50 kΩ
y varios MΩ cuando está completamente a oscuras.

Y eso es toda la teoría de momento. Vamos a utilizarla en una práctica


sencilla (Figura 6.2) como sensor para variar el parpadeo de un led conectado al
pin 7 del Arduino. Según haya más o menos luz sobre ella, el led parpadeará con
más o menos frecuencia. La LDR la conectamos a la entrada analógica A0.

Al tener la LDR en la parte superior del divisor de tensión, tendremos la


tensión máxima cuando esté completamente iluminada, ya que se comportará
prácticamente como una resistencia de 50 Ω o 100 Ω. Si está a oscuras, no dejará
pasar corriente, comportándose como un circuito abierto.

Figura 6.2

El valor de la resistencia que acompaña a la LDR no es crítico. Cualquier


valor de 1 K a 10 K se puede utilizar. El nivel de luz en la LDR (LDR GL5528)
cambiará el nivel de tensión en el pin analógico A0. La función analogRead()

112
6. Sensores básicos de luz, temperatura, distancia y presencia

proporciona un valor que oscila entre 500 (cuando el LDR está en la oscuridad) y
950 (cuando hay mucha luz), lo cual determina la duración de encendido y
apagado del led, por lo que la frecuencia de parpadeo aumenta con la intensidad
de la luz.

Si quieres visualizar el valor de la variable de parpadeo en tu ordenador,


puedes utilizar el monitor serie del IDE.

En cuanto al hardware que necesitamos:

 Un diodo LED.
 Una resistencia de 10 kΩ.
 Una LDR GL5528.
Resistencia (con luz): ~1 k Ohm.
Resistencia (oscuridad): ~10 k Ohm.
 Un protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Práctica 13. Variando el parpadeo de un led con una LDR


/* Ejemplo de funcionamiento de una LDR */
/* Ideada una tarde de lluvia */
const int ledPin = 13;
const int sensorPin = 0;
const int minDuracion = 100;
const int maxDuracion = 1000;
void setup()
{
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
}
void loop()
{
int rango = analogRead(sensorPin);
rango = map(rango,500,950,minDuracion, maxDuracion);

113
Taller de Arduino

Serial.println(rango);
digitalWrite(ledPin, HIGH);
delay(rango);
digitalWrite(ledPin, LOW);
delay(rango);
}

En este sketch nos aparece una función nueva que utilizaremos a menudo
con las entradas analógicas del Arduino. Se trata de la función de ajuste de escala
denominada map().

map(valor, desde_bajo, desde_alto, hasta_bajo, hasta_alto). «Re-mapea»


un número desde un rango hacia otro. Esto significa que un valor con respecto al
rango desde_bajo-desde_alto, será mapeado al rango hasta_bajo-hasta_alto.
• valor: el número (valor) a mapear.
• desde-bajo: el límite inferior del rango actual del valor.
• desde_alto: el límite superior del rango actual del valor.
• hasta_bajo: el límite inferior del rango deseado.
• hasta_alto: el límite superior del rango deseado.

En nuestro caso, cuando llegue un valor de 500 se le escalará el valor a


minDuracion y cuando tengamos 950 lo «remapearemos» a maxDuracion. Todos
los valores intermedios se ajustarán por interpolación. Básicamente, lo que
estamos haciendo es igualar escalas de rango de valores. De ahí que
establezcamos una duración mínima y una máxima para el retardo implicado en el
parpadeo del LED.

Diseña un circuito que avise mediante un zumbador cuando la luz


que incide sobre una LDR caiga por debajo de un valor determinado.
Por ejemplo, cuando se «haga la oscuridad».

6.2 Práctica 14: funcionamiento del sensor


de temperatura
Vamos a ver cómo poder realizar mediciones de temperatura con nuestro Arduino
y el sensor LM35. Dicho sensor es un sensor analógico de la casa Texas
Instruments. Nos permite realizar medidas de temperatura de una forma bastante

114
6. Sensores básicos de luz, temperatura, distancia y presencia

precisa a través de las entradas analógicas del Arduino (pines A0-A5) sin
necesidad de emplear ninguna librería específica para su programación.

Figura 6.3

Figura 6.4

Como se puede ver en las figuras 6.3, 6.4 y 6.5, es un sensor que presenta
únicamente 3 pines (VCC, GND y Data). Por ello su conexión es muy sencilla. Este
sensor tiene una salida analógica proporcional a la temperatura que registra (pin
del centro). Para conectarlo al Arduino, el pin +Vs debe conectarse al pin 5 V de la
placa. El pin VOUT, al cualquier pin de entradas analógicas y el pin GND, al
conector GND de nuestro Arduino. Además, presenta las siguientes características
eléctricas:

 Está calibrado en grados Celsius.

115
Taller de Arduino

 Rango de medición de -55 °C a 150 °C.


 La tensión de salida es proporcional a la temperatura (1 °C = 10
mV).
 Presenta una precisión de 0.5 °C.
 Rango de alimentación entre 4 y 30 V.
 Presenta baja impedancia de salida.
 Presenta baja corriente de alimentación.

Figura 6.5

Este circuito en particular funcionará únicamente con temperaturas por


encima de 0 °C, por lo que sirve para proyectos en un interior (o en exterior de
zonas cálidas). Si queréis medir temperaturas por debajo de 0 °C, hay que variar el
circuito tal y como como se muestra en la hoja de características del LM35
proporcionada por el fabricante.

La práctica que vamos a realizar consiste en medir la temperatura ambiente


constantemente e ir mostrándola en el monitor serie del IDE de nuestro
ordenador.

En la figura 6.6 observamos el montaje desde otra perspectiva, utilizando el


software de simulación Proteus. En cuanto al hardware que necesitamos:
 Un LM35 o TMP36. (coste aproximado: 1.70 euros)

116
6. Sensores básicos de luz, temperatura, distancia y presencia

 Una protoboard.
 Cablecitos de conexión.
 Un Arduino y un cable USB.

Figura 6.6

Hoy en día el sensor de temperatura TMP36 es muy popular,


sustituye perfectamente al clásico LM35 y es totalmente compatible
con él para la mayoría de las aplicaciones.

El listado del sketch para visualizar las temperaturas a través del monitor
serie es el siguiente:

Práctica 14. Midiendo temperaturas


/* Medidas de temperaturas con el LM35 y visualización en el
monitor serie */
/* Realizada un día de frío, por eso la temperatura de la
terraza era tan baja */
float temperatura;
int tempPin = 0;

117
Taller de Arduino

void setup()
{
Serial.begin(9600);
}
void loop()
{
temperatura = analogRead(tempPin);
temperatura = temperatura * 0.48828125;
Serial.print("TEMPERATURA = ");
Serial.print(temperatura);
Serial.print("*C");
Serial.println();
delay(1000);
}

Figura 6.7

Como se observa en la Figura 6.7 el monitor serie muestra los valores de


temperaturas constantemente. Más adelante veremos la forma de visualizar estos
datos en un LCD para independizar el Arduino del PC, y también para no pasar frío
y poder verlos a distancia desde dentro de casa utilizando una comunicación de
datos inalámbrica muy sencilla.

Pero vamos al grano y expliquemos el código del sketch anterior. Viene con
cosas nuevas que merecen nuestra atención ya que van a ser habituales en los
programas que utilicen algún tipo de sensor de tipo analógico.

118
6. Sensores básicos de luz, temperatura, distancia y presencia

Para leer las temperaturas tenemos una orden muy simple:


analogRead(tempPin). Nos devolverá un valor digital entre 0 y 1024 directamente
proporcional a la tensión recibida. Mirando la hoja de datos del sensor, vemos
que por cada °C, la tensión en el pin Vout aumenta 10 mV, por lo que para dar los
5 V máximos (que corresponderían a una lectura de 1024) necesitaríamos 500 °C.

Esta temperatura no la vamos a alcanzar nunca (el sensor se fundiría antes).


Por tanto, mediante una regla de 3, calculamos la operación de conversión desde
el valor que leemos en el pin hasta la temperatura real:

temperatura = lectura * 500/1024.


temperatura = lectura * 0.48828125.

Pero ahora nos sale un número con decimales (flotante) como resultado de
la primera división; por tanto, no podemos utilizar un tipo de variable entero (int)
para la temperatura. Es necesario usar otro tipo de variable denominado float.

float (nombre variable). Este tipo variable se usa para los números en coma
flotante (número decimal). Estos números son usados habitualmente para
aproximar valores analógicos debido a que ofrecen una mayor resolución que los
enteros. Las variables tipo float tienen el valor máximo 3.4028235E+38 y como
mínimo pueden alcanzar el -3.4028235E+38. Ocupan 4 bytes (32 bits). Tienen una
precisión de 6 o 7 dígitos decimales. Esto abarca el número total de dígitos, no el
número a la derecha de la coma decimal. En nuestro programa hemos definido la
variable temperatura como de tipo float.

Si quisiéramos conseguir mayor precisión podríamos utilizar voltajes de


referencia, lo que nos ayudaría a tener un rango de temperatura menor ganando
en calidad o resolución de lectura. Por ejemplo, podríamos usar la salida de 3.3 V
del Arduino para alimentar el LM35. En este caso la parte de código implicada
sería:

temperatura = lectura * 330/1024.


temperatura = lectura * 0.322265625.

Pero para una aplicación usual no es necesario tanto. Con el método


utilizado tenemos una precisión aproximada de 0.5 °C. Por último, enviamos o
«imprimimos» en el monitor serie tanto las temperaturas medidas, como el texto
formateado para darle un poco de alegría a nuestro código.

119
Taller de Arduino

Diseña un circuito que produzca una señal de alarma sonora que se


active cuando la temperatura ambiente suba por encima de 35 °C.
Utiliza un LM35 (TMP36), un pequeño zumbador o altavoz y un
mechero para, con cuidado, acercar al sensor y simular una subida de
temperatura.

6.3 Práctica 15: funcionamiento del sensor


de distancias por ultrasonidos
Si algún día queremos construir nuestro propio robotito necesitaremos medir
distancias para que el artilugio móvil que hemos creado no choque con todo lo
que se encuentre delante.

Para ello podemos utilizar el sensor PING de Parallax. Funciona como un


sonar mediante ultrasonidos y es capaz de detectar objetos a una distancia de
entre 2 centímetro a 3 metros. Dispone de un indicador LED y tan solo requiere de
un pin para su funcionamiento. Se puede utilizar en una placa de prototipo o
directamente en tu robot.

El sensor envía ultrasonidos por un lado y mide el tiempo de rebote del


sonido. En su pin de salida podremos medir el ancho de pulso PWM en función de
la distancia del obstáculo. Es muy sencillo hacerlo funcionar con un Arduino.
Funciona exactamente igual que un radar, de hecho, es un pequeño radar. Emite
un pulso de sonido a una frecuencia tan alta que es imperceptible para el oído
humano y cronometra el tiempo que el sonido tarda en llegar a un obstáculo,
rebotar y volver al sensor. Como la velocidad de propagación del sonido en el aire
es un dato bien conocido (343.2 m/s) echamos mano de una conocidísima
formula (e = v * t) y calculamos la distancia recorrida por el sonido.

Figura 6.8

120
6. Sensores básicos de luz, temperatura, distancia y presencia

Figura 6.9

En la figura 6.8 se observa el aspecto real del sensor que no es


precisamente barato. De todas maneras, se pueden encontrar «clónicos» a un
precio más asequible. En la figura 6.9 vemos un gráfico que explica perfectamente
su funcionamiento. Pero…

¿Cómo puede funcionar con un solo pin? ¿Acaso no necesitamos uno para
mandarle una señal y otro para recibir la respuesta? Pues no; se puede hacer todo
por el mismo y de una forma nada complicada lo que también nos servirá, de
paso, para disipar una de las dudas más comunes entre los principiantes: la
inamovilidad de la declaración de pines como entrada o salidas.

En todos los sketch que hemos ido escribiendo a lo largo de este libro
definimos los pines de Arduino o bien como entradas o bien como salidas dentro
de la estructura setup(), pensando que no se pueden cambiar. Sin embargo, esto
no es así. Podemos cambiarlos de sentido a lo largo del programa sin problema,
aunque esto no sea lo estrictamente correcto dentro de la estructura habitual de
programación en Arduino. Pero volvamos al sensor de ultrasonidos: solo tiene tres
pines, uno de alimentación, uno de masa y uno de señal. Alimentación a +5 V,
masa a GND y señal a un pin digital (por ejemplo, el 8). A través de este pin
enviaremos una señal de activación o de comienzo al sensor y para ello lo
pondremos como salida; lo activaremos durante 10 microsegundos y lo
desactivaremos. Luego cambiaremos el pin y lo dejaremos como entrada para
escuchar la señal de respuesta del sensor. Esto lo haremos cada vez que
necesitemos tomar una medida. Esta será cada segundo.

La señal de salida del sensor proporciona un pulso de la misma duración


que el tiempo cronometrado, es decir, si el sonido tardó 10 microsegundos en ir
del sensor al objeto y volver al sensor, nos devolverá un pulso de una duración de
10 microsegundos. Así que será fácilmente medible mediante la función pulseIn().

121
Taller de Arduino

También hay que tener en cuenta que ese tiempo es de ida y vuelta, por lo que
tenemos que dividirlo por la mitad a la hora de hacer el cálculo.

pulseIn(pin,valor). Lee un pulso (ya sea alto o bajo) en un pin. Por ejemplo,
si el valor es HIGH, pulseIn() espera a que el pin sea alto, empieza a cronometrar,
espera a que el pin sea LOW y entonces detiene la medida de tiempo. Devuelve la
anchura del pulso en microsegundos. Funciona correctamente en pulsos con una
anchura de 10 microsegundos a tres minutos.

Figura 6.10

En cuanto al hardware mínimo que necesitamos (Figura 6.10):

 Un Parallax PING.
 Un protoboard.
 Un Arduino.

Como dije antes, el dispositivo Parallax PING es bastante caro (unos 30


euros). Sin embargo, podemos encontrar un equivalente fabricado en Asia por
menos de 5 euros y que funciona bien.

Práctica 15. Midiendo distancias


/* Midiendo distancia con el sensor Parallax PING */
/* Se me ocurre ponerlo en la parte trasera del coche para
aparcar bien */

122
6. Sensores básicos de luz, temperatura, distancia y presencia

unsigned long pulso;


float distancia;
int pin = 7;
void setup()
{
Serial.begin(9600);
}
void loop()
{
pinMode(pin, OUTPUT);
digitalWrite(pin, HIGH);
delayMicroseconds(10);
digitalWrite(pin, LOW);
pinMode(pin, INPUT);
pulso = pulseIn(pin, HIGH);
Serial.print("tiempo = ");
Serial.print(float(pulso/1000.0));
Serial.print("ms, distancia = ");
distancia = ((float(pulso/1000.0))*34.32)/2;
Serial.print(distancia);
Serial.println("cm");
delay(1000);
}

Lo primero que observamos en el sketch, es que aparece un nuevo tipo de


variable llamada unsigned long asociada al pulso.

unsigned long. Este tipo de variable numérica de tipo extendido se refiere a


números enteros (tipo 32 bits) sin decimales y solo positivos (unsigned: sin signo)
que se encuentran dentro del rango de 0 a 4.294.967.295.

La razón de utilizarla se debe a que la función pulseIn() devuelve el ancho


del pulso (la distancia que medimos) con este tamaño de variable. Por ello, para
que exista concordancia con lo que vamos a recibir, definimos previamente la
variable «distancia» como tipo unsigned long. Es una característica de esta
función y que no podemos cambiar, sino adaptarnos a ella.

123
Taller de Arduino

En la figura 6.11 se observa el tiempo medido del pulso recibido que es


convertido a la distancia que hay entre el objeto y el sensor.

Finalmente, si optamos por medir distancias más pequeñas, podemos


utilizar los sensores de infrarrojos. Son mucho más baratos y en muchas
aplicaciones son suficientes.

Figura 6.11

Diseña un circuito que produzca una señal de alarma sonora que se


active cuando nos acerquemos a un sensor Parallax PING. Utiliza un
pequeño zumbador o altavoz.

6.4 Práctica 16: funcionamiento de un sensor


de movimiento
Para terminar nuestras prácticas con sensores, vamos a realizar una práctica que
demuestre lo fácil que es la utilización de un sensor de movimiento como es el
denominado sensor PIR (sensor pasivo de infrarrojos). En cuanto a su principio de
operación, el sensor PIR se basa en la idea de que todos los objetos emiten
energía en forma de radiación a causa de tener un calor corporal por encima del
cero absoluto.

Los sensores PIR (Figura 6.12) están compuestos por dos ranuras, cada una
de ellas sensible a los infrarrojos. Cuando un cuerpo caliente pasa por delante del
campo de detección del sensor, una de las dos mitades detecta la diferencia de
calor y provoca un diferencial entre las dos mitades de las ranuras. Ocurre lo
mismo cuando el cuerpo sale de la zona de detección; la otra mitad detecta un
cambio y provoca otra diferencia de potencial igual, pero de sentido contrario. De

124
6. Sensores básicos de luz, temperatura, distancia y presencia

esta manera el sensor es capaz de distinguir si ha habido movimiento en la


habitación. Son sensores de infrarrojo pasivo porque, por un lado, capturan los
infrarrojos y por el otro, como no irradian ninguna energía sobre los objetos, son
pasivos. La clave son las lentes de Fresnel que juegan un papel decisivo en los
sensores PIR ya que consiguen ampliar su campo de detección. Una lente de
Fresnel es una lente plano-convexa que se utiliza para conseguir focalizar una
mayor cantidad de radiación sobre el sensor.

Figura 6.12

El proyecto que vamos a implementar consiste en detectar movimiento y


encender un diodo LED. Así de simple, ya que solo nos interesa conocer su
funcionamiento básico. Está de tu mano «barrenar» algún tipo de aplicación
donde puedas usarlo. El tipo de PIR que utilizaremos es el que podemos adquirir
online en www.bricogeek.com por un precio de 11 euros sabiendo de antemano
que está muy probado con Arduino (Figura 6.13).

Figura 6.13

125
Taller de Arduino

El fabricante nos proporciona el conexionado que es el siguiente:

 Cable rojo: VCC (5 a 12V).


 Cable Negro: Pin «Alarma» en colector abierto.
 Cable Marrón: GND.

También nos advierte, dado que el pin de alarma es de colector abierto, que
se necesita una simple resistencia Pull-Up. En nuestro caso elegiremos de 10 kΩ.

Práctica 16. Detectando movimiento


/* Detectando movimiento con el sensor PIR */
/* Se me ocurre ponerlo en la huerta para que no me roben las
lechugas */
int ledPin = 13;
int inputPin= 2;
int movimiento = LOW;
int val = 0;
int calibrationTime=30;
void setup()
{
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
Serial.begin(9600);
Serial.print("calibrando... ");
for(int i = 0; i < calibrationTime; i++)
{
Serial.print(".");
delay(1000);
}
Serial.println(" Sensor Calibrado");
delay(50);
}
void loop()
{
val = digitalRead(inputPin);

126
6. Sensores básicos de luz, temperatura, distancia y presencia

if (val == HIGH)
{
digitalWrite(ledPin, HIGH);
if (movimiento == LOW)
{
Serial.println("Movimiento detectado!");
movimiento = HIGH;
}
} else
{
digitalWrite(ledPin, LOW);
if (movimiento == HIGH)
{
Serial.println("No hay movimiento!");
movimiento = LOW;
}
}
}

Como observamos en el código, existe una parte dedicada a lo que llamo:


calibrado del sensor. Este tiempo es necesario para esperar a que el PIR se
inicialice convenientemente.

127
CAPÍTULO

EXTENDIENDO
ARDUINO CON
LIBRERÍAS

En los capítulos anteriores se mostró lo que lo que Arduino puede llegar a hacer y
se construyeron algunos proyectos básicos que demostraron sus posibilidades
más elementales. Sin embargo, el Arduino es capaz de hacer mucho más y
también puede extender su funcionalidad mediante el uso de librerías de
software externas o tarjetas de expansión de hardware denominadas mochilas o
shields. En este capítulo, vamos a aprender diferentes maneras de conectar
nuestro Arduino a otros dispositivos más complejos. Veremos la utilización de
librerías externas que potenciarán, sin duda, las posibilidades de diseño de tus
futuros proyectos.

Por ejemplo, si estás construyendo un robot para evitar obstáculos que


pueda detectar objetos en su camino y maniobrar alrededor de ellos, el Arduino
sería una obvia elección. Existen librerías de software y shields de hardware
disponibles para que nuestro Arduino controle motores, se conecte a Internet, se
comunique a través de wifi o se relacione con otros Arduino a través de Xbee o
bluetooth.

En el mundo del software, una librería es una pieza de software que


proporciona algún tipo de funcionalidad como escribir un texto en una pantalla
LCD o el cálculo de la posición de un GPS mediante un sistema de navegación.

En el mundo de Arduino, una librería es un trozo de código que incluimos


en nuestro sketch y que proporciona funciones determinadas que, simplemente,
llamamos cuando nos interesa. Por ejemplo, si vamos a utilizar un determinado
sensor, podemos buscar si existe una librería asociada. En caso de que la
encontremos, podemos añadirla a nuestro programa y utilizar las funciones que
ofrece para manejar dicho sensor. No tenemos que conocer cómo está hecha o
programada, simplemente debemos saber qué funciones nos ofrece y cómo

128
7. Extendiendo Arduino con librerías

utilizarlas. Es lo mismo que saber conducir un coche, no estamos obligados a


entender el funcionamiento del motor o cómo es capaz de moverse.

Algunas librerías funcionan por sí mismas, es decir, incluyéndolas


directamente en nuestro programa; otras precisan de un hardware adicional para
ser utilizadas. Normalmente, cuando adquirimos una shield nueva para, por
ejemplo, controlar un servomotor, nos descargamos la librería asociada que se
ocupa de manejar este hardware, facilitándonos mucho el trabajo ya que nos
despreocupamos de la comunicación entre dicha shield y el Arduino. De esta
manera, solo nos centramos en lo que es nuestro propio código. Este tipo de
librerías y shields las abordaremos más tarde. Ahora nos centraremos en las
librerías propias de Arduino que se catalogan en tres tipos:

 Librería core.
 Librería estándar.
 Librerías añadidas o contributivas.

7.1 Librerías core


La librería principal o core está proporcionada con el IDE de Arduino y es
fundamental para los usuarios principiantes como para los más experimentados.
Oculta gran parte de la complejidad que tradicionalmente supone el trabajar con
un microcontrolador. Los miembros del equipo de desarrollo de Arduino que
participaron en enseñar a los estudiantes cómo usar microcontroladores en sus
proyectos, reconocieron que el poco uso de muchos microcontroladores
tradicionales, por parte de muchos principiantes y neófitos en el campo de la
electrónica, era la dificultad de su programación. Estudiaron cuáles eran las
acciones o proyectos que muchos de sus estudiantes querían llevar a cabo con un
microcontrolador y, basándose en esto, diseñaron una biblioteca central que
evitara la complejidad de las tareas más engorrosas e hiciera la programación de
manera fácil.

La mayoría de los proyectos leen datos en los pines de entrada y escriben


datos en los pines de salida. La librería core hace que estas tareas comunes sean
sencillas de utilizar. Por ejemplo, para leer el valor de una patilla digital, solo
tienes que utilizar la función digitalRead. Si recordamos los proyectos en que
utilizábamos el altavoz, usábamos la función tone() para producir sonidos de lo
más variado. Lo mismo pasa con la función serial() que nos permitían interactuar

129
Taller de Arduino

con el programa monitor sin excesiva dificultad. Piensa por un momento si


tuvieras que «currarte» el programa sin esa librería.

7.2 Librerías estándar


Cuando haya descargado e instalado el IDE de Arduino observarás que algunas
librerías llamadas estándar fueron incluidas con la instalación. Las bibliotecas
estándar son los que el equipo de desarrollo Arduino pensó que eran necesarias
por muchas personas en sus propios proyectos. Estas librerías no son incluidas por
defecto, como la librería core, debido a que el Arduino ha limitado incluirlas
automáticamente, ya que sería una pérdida de recursos (sobre todo, en memoria
del propio microcontrolador) dejando poco espacio para tu propio código.

Para utilizar las librerías estándar, tienes que incluirlas explícitamente en


tus sketchs. Para ello, es necesario agregar una sentencia include en la parte
superior de tu programa. Por ejemplo, si quieres incluir la librería LiquidCrystal,
que se utiliza para mostrar datos sobre una pantalla LCD, tienes que añadir lo
siguiente al principio de tu sketch:

#include <LiquidCrystal.h>

El nombre de la librería está delimitado por paréntesis angulares y, además,


la línea no termina con un punto y coma (;) como es usual. Te darás cuenta de que
todas las librerías que forman parte del core de Arduino llevan la extensión h.

Las librerías estándar proporcionadas hasta el momento por Arduino son


las siguientes:

 Librería de testeo ArduinoTestSuite.


 Librería EEPROM.
 Librería SD.
 Librería Ethernet.
 Librería Firmata.
 Librería LiquidCrystal.
 Librería Servo.
 Librería Stepper.
 Librería SPI.
 Librería Wire.
 Librería SoftwareSerial.

130
7. Extendiendo Arduino con librerías

Figura 7.1

No voy a explicaros con detalle cada una de las librerías arriba expuestas
porque sería muy largo y bastante tedioso. Simplemente, os mostraré para lo que
vale cada una. En el futuro, cuando quieras desarrollar un proyecto con una
tarjeta SD para almacenar datos, podrás acordarte de que «algo había» para
controlar esto. Buscarás en el IDE del Arduino (tal como se muestra en la Figura
7.1) y verás que existe una librería llamada: SD library. Entonces, le echarás un
vistazo a la documentación de la librería que está en la web oficial de Arduino y
sabrás por dónde empezar.

Librería de testeo ArduinoTestSuite. Es relativamente nueva, pero va a ser


esencial para el futuro desarrollo de Arduino. La librería ArduinoTestSuite
proporciona métodos estándar y funciones que se pueden utilizar para probar tus
programas antes de subirlos a la placa. Esto asegura que tu código funcionará
como se esperaba antes de usarlo con mundo real. Aún está en fase de desarrollo.

Librería EEPROM. La EEPROM es un tipo de memoria programable


eléctricamente que almacena datos, incluso cuando el microcontrolador se apaga.
La cantidad de EEPROM en una placa Arduino depende del microcontrolador. En
el Arduino UNO es de 1024 bytes. Si necesitamos más memoria no volátil,
podemos optar por adquirir un Arduino más potente, o bien, utilizar una memoria
externa, como veremos más adelante. La librería EEPROM del Arduino
proporciona dos funciones: leer y escribir. En la Tabla 7.1 se observan dichas
funciones.

131
Taller de Arduino

Función Descripción
read Lee un byte almacenado en la memoria
write Escribe un byte en la memoria
Tabla 7.1

Un buen uso de la librería EEPROM sería almacenar datos en el Arduino que


deseamos volver a utilizar después de reiniciar el Arduino. Por ejemplo, vamos al
supermercado a comprar algo de fiambre para la cena. Cogemos el típico tique del
turno y esperamos, mirando constantemente el indicador que muestra los
números. En eso se va la luz, y cuando vuelve tras unos minutos, observamos que
la cuenta ha vuelto a cero y el dependiente tiene que preguntar a los clientes por
qué número iba el turno. Si la electrónica estuviese implementada con Arduino, se
podría haber diseñado un programa que guardase siempre el contaje en su
memoria EEPROM. De esta manera, aunque se fuese la luz, siempre se podrá
recuperar el número de turno. Por otra parte, si tenemos una cantidad de datos
(imágenes, ficheros, etc.) mucho más grande, no nos quedaría más remedio que
pensar en utilizar una tarjeta SD y su correspondiente librería.

Librería SD. Sirve para almacenar gran cantidad de datos como, por
ejemplo, los registrados desde un GPS o en un servidor web basado en Arduino.
Las tarjetas SD (Secure Digital) presentan un formato de tarjeta de memoria
inventado por Panasonic. Se utilizan en dispositivos portátiles tales como cámaras
fotográficas digitales, PDA, teléfonos móviles, computadoras portátiles e incluso
videoconsolas (Figura 7.2).

Figura 7.2

132
7. Extendiendo Arduino con librerías

William Greiman escribió una librería para Arduino llamada SdFat que
soporta el FAT16 y FAT32 (sistemas de archivos) en tarjetas SD. Esta librería
ofrece una amplia gama de funciones: crear, borrar archivos y directorios, y la
realización de formateo básico. El equipo de Arduino se dio cuenta de que
muchos usuarios podrían tener dificultades para utilizar la librería SdFat por lo
que escribió una capa de software alrededor de ella, para hacerla más amigable
de cara al programador más inexperto. En la Tabla 7.2 os muestro las funciones
que contiene esta librería.

Arduino utiliza un bus de interfaz periférico llamado: SPI para comunicarse


con la tarjeta SD. Utiliza los pines digitales 11, 12 y 13 en un Arduino UNO. Es
importante que tengas en cuenta que antes de que una tarjeta SD puedas
utilizarla con tu Arduino, primero debes formatearla (FAT16 o FAT32) usando tu
PC y un lector de tarjetas.

Clase Función Descripción


SD begin Inicializa la librería y tarjeta SD.
Testea si existe un fichero o directorio en la
exists
tarjeta SD.
mkdir Crea un directorio en la SD.
rmdir Borra un directorio de la SD.
remove Borra un fichero de la SD.
open Abre un fichero de la SD.
Testea sin se pueden leer algunos bytes de un
Archivos available
fichero.
close Cierra el fichero guardándolo en la SD.
seek Busca una posición en un fichero.
position Retorna la posición actual dentro de un fichero.
size Retorna el tamaño de un fichero en la SD.
print Envía datos a un fichero abierto.
Envía los datos a un archivo y añade nueva
println
línea.
write Escribe datos a un fichero.
read Lee un byte de un fichero.
Tabla 7.2

133
Taller de Arduino

Si vas a trabajar con las funciones relativas a ficheros, es conveniente


que te mires cómo se utilizan los ficheros en lenguaje C. En la red
encontrarás muchísima información sobre el uso de archivos en C.

Librería Ethernet. La librería Ethernet simplifica la pila TCP/IP por lo que es


más fácil que un Arduino se comunique a través de Internet o la red doméstica. La
librería está diseñada para trabajar con tarjetas basadas en W5100 WIZnet. La
última apuesta de Arduino es que Ethernet tenga soporte para tarjetas microSD,
lo cual es muy atractivo para aplicaciones con registro de datos. Podemos utilizar
nuestro Arduino para tomar lecturas en un lugar remoto y mostrar las lecturas en
una página web básica, así como guardar los datos en una tarjeta microSD que
pueden ser recuperados y analizados más adelante. La librería Ethernet es muy
amplia y permite que el Arduino se configure como un servidor recibiendo las
conexiones de clientes, o como un cliente que se conecta a servidores.

Librería Firmata. Firmata es un protocolo de comunicación que permite a un


ordenador host utilizar el software para controlar un microcontrolador. La librería
Firmata proporciona los protocolos de comunicación serie para comunicarse con el
software en un ordenador host. Usando Firmata, un ordenador central puede
controlar los dispositivos conectados a la placa Arduino tales como servos, motores
y LED. Puedes ampliar más información en la página oficial de Arduino.

Librería LiquidCrystal. En capítulos anteriores hemos visto como el Arduino


puede mostrar información utilizando el monitor serie del IDE. ¿Pero cómo
hacemos cuando nuestro Arduino no está conectado al PC y deseamos mostrar
datos o mensajes? Puede ser útil usar un pequeño LCD de 16 caracteres de 2 filas
por dos columnas (16 x 2) para mostrar información. La mayoría de estas
pequeñas pantallas LCD se basan en un HD44780 de Hitachi o chip compatible.
Este tipo de pantallas son tan extendidas que le he dedicado un capítulo entero
en este libro, por lo que las veremos más adelante. El punto central de todo esto
es la librería LiquidCrystal que se utiliza para controlar la pantalla. La siguiente
Tabla 7.3 enumera algunas de las funciones disponibles en la librería.

Función Descripción
begin Establece las dimensiones del LCD en filas y columnas.
LiquidCrystal Inicializa la librería y configura los pines de conexión.
print Envía datos al LCD.
clear Limpia la pantalla del LCD.

134
7. Extendiendo Arduino con librerías

Función Descripción
setCursor Posiciona el cursor en la pantalla del LCD.
Tabla 7.3

Librería Servo. Los servomotores son comúnmente utilizados en el mundo


de radio-control para controlar con precisión movimientos tales como los flaps en
un avión, o el timón de dirección en un barco. Son ideales para proyectos que
requieren un movimiento preciso, como los dispositivos que eviten obstáculos en
los robots. Los veremos más adelante en profundidad cuando tratemos el tema de
motores. De momento echemos un vistazo a algunas de las principales
características de la librería Servo. La biblioteca Servo permite controlar hasta 12
servomotores en un Arduino UNO y la friolera de 48 en los Arduino MEGA. La
Tabla 7.4 muestra las principales funciones que ofrece la biblioteca Servo.

Función Descripción
attach Se conecta el servo a un pin.
Attached Chequea el servo conectado al pin.
Detach Desconecta el servo a un pin.
Read Lee el ángulo de un servo.
Escribe el ángulo de un servo normal entre 0-180º y
write establece la velocidad de rotación en un servo de
rotación continua.
Escribe el valor, en microsegundos, en el servo, para
writeMicroseconds
ajustar el ángulo de su eje.
Tabla 7.4

Librería Stepper. Esta librería se usa para gobernar los motores llamados
paso a paso. Los veremos con detenimiento más adelante. Brevemente, un motor
paso a paso gira el eje en pasos concretos, siendo un paso definido como un
ángulo mínimo de giro. La especificación de un motor paso a paso se da a menudo
en pasos, por lo que un motor con una especificación de 200 pasos tomaría 200
pasos para girar una vuelta completa o 360º. A veces, la especificación se da en
grados, lo que puede ser fácilmente convertida a pasos dividiendo una vuelta
completa (360 grados) por el número de grados dado en la especificación. Por
ejemplo, para un motor paso a paso con una especificación de 1,5 grados, el
número de pasos por vuelta completa sería:

135
Taller de Arduino

360 grados / 1,5 grados por paso = 240 pasos.

Los motores paso a paso, por tanto, son una buena manera de controlar
dispositivos de precisión. La librería Steeper le da el control del Arduino tanto en
motores de tipo unipolares como bipolares. Con el uso de esta librería se puede
establecer la velocidad de rotación del motor, el número de pasos a seguir y la
dirección del motor. La Tabla 7.5 enumera las principales funciones
proporcionadas por la librería Stepper.

Función Descripción
Inicializa la librería y establece el número de pasos por
Stepper
vuelta.
Establece la velocidad a la que el motor debe girar, en
setSpeed
revoluciones por minuto (RPM).
Establece el número de pasos del motor que debe girar el
step motor. Los números positivos rotan en un sentido y los
números negativos en el otro.
Tabla 7.5

Librería SPI. El bus SPI (serial peripherical interface) es un bus de cuatro


líneas sobre el cual se transmiten paquetes de información de 8 bits. Cada una
de estas cuatro líneas lleva la información entre los diferentes dispositivos
conectados al bus. Cada dispositivo conectado al bus puede actuar como
transmisor y receptor al mismo tiempo, por lo que este tipo de comunicación
serial es full duplex. Dos de estas líneas trasfieren los datos (una en cada
dirección) y la tercera línea es la del reloj. Algunos dispositivos solo pueden ser
transmisores y otros solo receptores. Generalmente, un dispositivo que
tramite datos también puede recibir. Presenta un protocolo de
comunicaciones serie solo válido para distancias cortas. El bus SPI (Figura 7.3)
se puede utilizar para comunicaciones entre una gran variedad de periféricos,
incluyendo sensores de temperatura, sensores de presión, pantallas táctiles o
controladores de videojuegos. De hecho, Arduino utiliza SPI para comunicarse
con las tarjetas SD.

El protocolo utiliza cuatro conexiones, tres de los cuales son comunes a


cada dispositivo y una sirve para seleccionar el dispositivo esclavo.

136
7. Extendiendo Arduino con librerías

Figura 7.3

La designación de sus conexiones con Arduino se muestran en la Tabla 7.6.

Designación Pin Arduino Descripción


MISO 11 Envío de datos al Maestro (Master).
MOSI 12 Envío de datos al Esclavo (Slave).
SCK 13 Señal de reloj.
SS 10 Selección del Esclavo.
Tabla 7.6

La librería SPI proporciona funciones para interactuar con los periféricos SPI
como se muestra en Tabla 7.7.

Función Descripción
Inicializa el bus SPI y establece los pines MOSI y
begin
SCK bajos y el pin SS alto.
end Deshabilita el bus SPI.
Establece el orden en el que los bits se cargan en
setBitOrder
el bus.
Ajusta el reloj divisor del SPI como una división
setClockDivider
del reloj del sistema.
setDataMode Establece el modo de trabajo del SPI.
transfer Trasfiere 1 byte al bus.
Tabla 7.7

Aunque esto parece complicado, haciendo buen uso de la hoja de datos del
dispositivo SPI, haciendo las cosas por pasos y con cuidado, no deberías tener
problemas para comunicar un Arduino con periféricos SPI. De todas maneras, en
el capítulo 10 abordaremos este tipo de comunicación realizando una práctica
suficientemente explicativa.

137
Taller de Arduino

Librería Wire. El bus I2C, comúnmente conocido como interfaz de dos hilos
(TWI), se utiliza para comunicarse con una amplia gama de productos. Es perfecto
para aplicaciones de registros, pantallas LCD, sensores ultrasónicos para
mediciones de distancia y potenciómetros digitales cuya resistencia se puede leer
o establecer de forma remota. Curiosamente, I2C también se utiliza en
dispositivos de juego de Nintendo: la Wii Motion Plus y Wii Nunchuk. Solo se
necesitan dos pines para la interfaz del bus I2C. La Tabla 7.8 identifica estos pines
para el Arduino UNO.

Función Arduino
SDA Pin 4
SCL Pin 5
Tabla 7.8

En la Tabla 7.9 se enumeran las principales funciones de la librería Wire.

Función Descripción
begin Inicializa la librería.
requestFrom Solicita datos desde el maestro al esclavo.
beginTransmission Comienza la trasmisión.
write Envía los datos del esclavo al maestro.
endTransmission Finaliza la trasmisión.
Tabla 7.9

Figura 7.4

138
7. Extendiendo Arduino con librerías

En la Figura 7.4 puedes observar un sensor de temperatura I2C (DS1621)


muy utilizado. Fijaos en los pines del integrado. Con la librería I2C, el Arduino
puede actuar como maestro o como dispositivo esclavo. En la mayoría de los
casos, el Arduino será el dispositivo maestro y va a interactuar con uno o más
dispositivos como esclavos.

Te propongo que estudies el siguiente proyecto (Figura 7.5) y hagas las


variaciones que quieras para adecuarlo a tus posibles necesidades. Se
trata de utilizar el sensor digital de temperatura I2C DS1621 con
nuestro Arduino. Las temperaturas medidas las va a mostrar en el
monitor serie del IDE de Arduino. El proyecto está simulado con
Proteus y se utiliza el instrumento: virtual terminal para emular el
funcionamiento de la trasmisión serie. Puedes adelantarte al capítulo
10 en la que se detalla el funcionamiento del bus de datos I2C.

Figura 7.5

Proyecto 1. Arduino y el sensor DS1621


/* Medida de temperatura con arduino y ds1621. */
/* Tómate tu tiempo. Puedes avanzar al capítulo 10 donde
explico este protocolo */

139
Taller de Arduino

#include <Wire.h>
#define DEV_ID 0x90 >> 1
int LED = 11
int temp = 0;
void setup()
{
pinMode(LED,OUTPUT);
Serial.begin(9600);
Wire.begin();
Wire.beginTransmission(DEV_ID); // Conectamos el ds1621
Wire.write(0xAC); // Accedemos a su configuración
Wire.write(0x02); // Establecemos una conversión continua
de temperatura
Wire.beginTransmission(DEV_ID); // Lo reseteamos
Wire.write(0xEE); // Empieza a convertir
Wire.endTransmission(); // Finalizamos la comunicación
}
void loop()
{
delay(1000); // Le damos un tiempo para convertir cada
temperatura
Wire.beginTransmission(DEV_ID);
Wire.write(0xAA);
Wire.endTransmission();
Wire.requestFrom(DEV_ID, 1);
temp = Wire.read(); // Leemos el dato de temperatura
Serial.print("TEMPERATURA: ");
Serial.print(temp); // Enviamos el dato al terminal
serie
Serial.println(" Grados Centigrados.");
digitalWrite(LED,HIGH);
delay(100);
digitalWrite(LED,LOW);
}

140
7. Extendiendo Arduino con librerías

Librería SoftwareSerial. Ya sabemos que nuestro Arduino utiliza los pines


reservados 0,1 para comunicarse con nuestro PC. Sin embargo, muchos proyectos
requieren a mayores uno o varios puertos serie. Los dispositivos GPS envían la
posición y su estado a través de mensajes de serie y algunos LCD pueden ser
conectados de esta misma manera. Un puerto serie se compone de solo dos
conexiones: una RX para recibir mensajes y otra TX transmitir mensajes. Pero si tu
Arduino necesita conectarse a más dispositivos serie como, por ejemplo, a la vez,
a un GPS y una pantalla LCD serie, tenemos que optar por una de las dos
opciones.

1. Comprar el más potente Arduino MEGA, que tiene cuatro puertos serie.
2. Utilizar la librería SoftwareSerial que se distribuye con el IDE del Arduino.

La librería SoftwareSerial original solamente podía proporcionar un puerto


serie a través de una emulación por software, limitando la velocidad a 9.600
baudios. Estas limitaciones fueron superadas por Mikal Hart con su librería
NewSoftSerial. Al darse cuenta de las ventajas que incorporaba esta nueva
librería, el equipo de desarrollo Arduino le cambió el nombre y la reemplazó en
lugar a la de la obsoleta librería SoftwareSerial existente a mediados de 2011.

Las funciones que ofrece esta nueva librería se muestran en la siguiente


tabla 7.10.

Función Descripción
begin Establece el puerto y la velocidad de trasmisión.
available Cambia a ese puerto.
isListening Devuelve el puerto activo.
listen Escucha el puerto.
end Finaliza la conexión con el puerto.
read Lee datos del puerto.
write Escribe datos en el puerto.
Tabla 7.10

Esta nueva librería por emulación software crea varias instancias de los
puertos serie, lo que permite comunicarse hasta velocidades de 115.000 baudios.
Pero toda esta funcionalidad adicional tiene un precio, ya que el Arduino solo
puede escuchar o recibir datos en un puerto software o virtual serie a la vez.

141
Taller de Arduino

Cuando se utiliza esta librería con más de un puerto serie virtual, tendremos que
pensar el orden en que se reciben los datos. Veamos un ejemplo: deseamos
conectar tanto un GPS y un termómetro usando puerto serie virtuales. Los
dispositivos GPS tienden a enviar sus datos en ráfagas y a intervalos de un
segundo, por lo que empezaremos por escuchar el puerto virtual conectado al
GPS y después de que haya terminado de enviar datos, escuchar el otro puerto
serie virtual que está conectado al termómetro antes de reanudar la lectura del
puerto donde estaba enchufado en GPS. Una posible solución sería la siguiente:

Proyecto 2. Trabajando con dos puertos serie virtuales

/* Dos dispositivos usando dos puertos serie por software */


/* Un GPS y un termómetro se ponen de acuerdo. */

#include <SoftwareSerial.h>
SoftwareSerial gpsPort(2, 3);
SoftwareSerial thermPort(4, 5);
void setup()
{
gpsPort.begin(9600);
thermPort.begin(9600);
}
void loop()
{
gpsPort.listen();
while (gpsPort.available() > 0)
{
char inByte = gpsPort.read();
}
thermPort.listen();
while (thermPort.available() > 0)
{
char inByte = thermPort.read();
}
}

142
7. Extendiendo Arduino con librerías

7.3 Librerías contributivas


Las librerías contribuidas son librerías aportadas por determinados usuarios del
mundo Arduino, pero que no se distribuyen de forma estándar con el IDE. Vamos,
que no son oficiales. Podemos encontrar que muchas de estas librerías listadas en
la web principal de Arduino. Algunas de ellas son extensiones de las librerías
estándar, ofreciendo más funciones. Si con el tiempo estas mejoras se consideran
adecuadas, el equipo de desarrollo de Arduino puede agregarlas a las librerías
estándar (como sucedió con la NewSoftSerial).

Figura 7.6

Debido a que estas librerías no se distribuyen con el IDE, es necesario


realizar varios pasos previos antes de poder utilizarlas.

PASO 1. Descargar la librería, por lo general es un archivo con extensión zip.


PASO 2. Añadir la librería seleccionando: Sketch > Importar librería > Añadir
librería (Figura 7.6).

143
Taller de Arduino

Busca y descarga de la web la librería del sensor de temperatura


DHT22. Añádela a vuestro IDE. La utilizaremos más adelante.

7.4 Extendiendo el Arduino con shields


Las shields o mochilas son otra gran manera de añadir funcionalidad a tu Arduino.
¿Deseas controlar un robotito por wifi? Consigue una shield wifi. ¿Quieres
controlar motores sin añadir circuitería suelta? Adquiere un shield para motores.
Existen muchos tipos de mochilas que permiten conectar el Arduino a una amplia
gama de hardware y periféricos.

Básicamente, las shields son placas de hardware conectables que se añaden


sobre la propia placa de Arduino. Además, poseen la ventaja de que muchas de
ellas son apilables o escalables, es decir, que se pueden disponer unas encima de
otras para aumentar aún más si cabe la potencia de tu proyecto.

Para sacar el máximo provecho de una shield, a menudo se necesita incorporar


alguna librería asociada a esta, que, por lo general, es descargable gratuitamente
desde la web del propio fabricante. Por otra parte, las shields pueden venir
completamente ensambladas o como un kit. Si no estás seguro de tus habilidades con
el soldador, podría ser un buen momento para aprender. Si no te quieres complicar la
vida y prefieres pagar un poco más, puedes adquirirlas completamente montadas y
preparadas para enchufarlas directamente sobre el Arduino.

Demos una vuelta por el mundillo de la shields, observando las que me


parecen más relevantes:

Shields de motores. Son generalmente adecuadas para controlar pequeños


motores de corriente continua. Son lo suficientemente poderosas para alimentar
pequeños robots o vehículos. También se pueden utilizar con motores paso a paso
y servomotores. Existe una amplia variedad de versiones disponibles. Una muy
extendida y documentada es la que distribuye la propia empresa de Arduino.

Se denomina Arduino Motor Shield (Figura 7.7). Esta shield permite a una
placa Arduino UNO, Arduino Mega 2560, Arduino Mega ADK y Arduino Leonardo,
controlar cargas inductivas tales como, relés, solenoides, motores DC y motores
paso a paso, es decir, es extremadamente útil para interactuar físicamente con
otros equipos. Es capaz de controlar hasta dos motores DC de forma simultánea o
un motor paso a paso.

144
7. Extendiendo Arduino con librerías

Figura 7.7

Figura 7.8

Como complemento, también disponemos de la Shield Módulos a Reles


(Figura 7.8), que permite acoplar a una placa Arduino dos relés de forma que se
puedan controlar de forma independiente equipos que exijan cierta carga (de
hasta 10 A por canal). Existen de varias salidas y su precio es muy asequible.
Ideales para controlar dispositivos que funcionen con tensión alterna, como
lámparas, incandescentes, motores grandes, etc.

Shield ETHERNET. Si tienes pensado conectar tu Arduino a una red local o a


la denominada: internet de las cosas, esta shield puede ser una buena opción.
Encaja perfectamente sobre tu placa Arduino formando un conjunto sólido.

Con esta placa (Figura 7.9) y la ayuda de la librería proporcionada,


podremos realizar tanto un pequeño servidor web, como un cliente. La
configuración de red se realiza mediante software, por lo que podremos adaptar

145
Taller de Arduino

con facilidad la placa a nuestra red local. Lo más destacado es que dispone de un
zócalo para tarjetas de memoria micro-SD para poder almacenar ficheros o
servirlos como servidor web integrado.

Figura 7.9

La placa Arduino se comunica con el módulo W5100 y la micro-SD


utilizando el bus SPI. Ten en cuenta que el W5100 y la micro-SD comparten el bus
SPI, por lo que solo uno de ellos puede ser utilizado a la vez. Si deseas utilizar
ambos simultáneamente, debes tenerlo en cuenta al escribir tu código.

Es importante notar que seguimos teniendo disponibles muchos de los


pines de la placa Arduino que está debajo. Como siempre, es necesario examinar
la documentación para averiguar qué pines son de exclusivo uso por la shield y
cuáles están libre para nuestras aplicaciones. Por otra parte, si tu presupuesto es
ajustado, puedes adquirir una variante mucho más barata llamada Ethernet Shield
V1.1 que está basada en el chip ENC28J60 SPI Ethernet. Presenta menos
funcionalidad, pero puede ser más que suficiente para la mayoría de tus
proyectos.

Shields wifi. Hoy en día todo el mundo habla de conectarse


inalámbricamente a través de wifi. Arduino no podía ser la excepción.

La shield oficial distribuida por Arduino es bastante cara pero de altas


prestaciones. Denominada Wifi Shield SD (Figura 7.10), está realizada
especialmente para que sea lo más hackeable posible y con librerías que
pretenden hacer sencillo el paso de nuestros códigos desde la ethernet shield a
esta nueva placa. Dispone de un zócalo para tarjetas de memoria microSD así

146
7. Extendiendo Arduino con librerías

como un conector propio mini USB para utilizarla sin necesidad de conectarla a
una placa Arduino (actualizando el firmware).

Figura 7.10

Soporta encriptaciones WEP y WPA2 y se conecta a la placa Arduino


mediante SPI. Trabajaremos con ella más adelante.

Shield XBee. Hoy en día, el protocolo de comunicaciones XBee (variante


más simple del protocolo ZigBee) es muy utilizado. Esta shield (Figura 7.11)
permite conectar entre sí, de forma inalámbrica, múltiples placas Arduino. El
rango operativo oscila entre 30 y 100 metros, dependiendo de las condiciones de
transmisión. Está basado en el módulo XBee de Maxstream y permite, entre otras
cosas, el montaje de redes sensoriales (sensores inalámbricos). Disponemos
además de una versión que incluye zócalo para tarjetas de memoria microSD. La
utilizaremos, más adelante, en el capítulo 11.

Un detalle importante es si son compatibles, a nivel de zócalo, con los


módulos Bluetooth Bee (Figura 7.12). Este es un pequeño módulo para transmitir
datos de forma inalámbrica de un punto a otro utilizando el protocolo Bluetooth.
Por tanto, la shield XBee respeta los pines originales de los XBee por lo que se
puede conectar directamente como sustituto. Estos módulos Bluetooth Bee
tienen una antena incorporada que permite un alcance de unos 10 metros
aproximadamente o hasta un máximo de 30 metros en espacio abiertos. Se
comporta como un puerto serial y dispone de comandos AT para cambiar el
baudrate.

147
Taller de Arduino

Figura 7.11

Figura 7.12

Shield GSM. Recientemente el equipo de Arduino ha sacado esta nueva


mochila para descubrir el mundo de «Internet de las cosas». Esta shield GSM –
GPRS (Figura 7.13) es capaz de enviar y recibir SMS, realizar y recibir llamadas de
voz y de datos. El modulo utiliza el GPRS. Esta es la red inalámbrica de datos con la
mayor cobertura en el mundo para conectarse a Internet.

Es compatible con el Arduino UNO, Mega y Mega ADK. Con una pequeña
modificación del software se puede utilizar con Arduino Leonardo. El módulo se
entrega con una tarjeta SIM de la compañía Telefónica Digital donde se puede
comprar un plan mundial de roaming para sus aplicaciones. Sin embargo, el
módulo no está bloqueado y se puede utilizar con cualquier proveedor de
telecomunicaciones, lo que le permite adquirir un plan y la tarjeta SIM de
cualquier operador.

148
7. Extendiendo Arduino con librerías

Figura 7.13

Finalmente, cabe apuntar que existen multitud de mochilas diferentes,


además de las arriba descritas. Te recomiendo que visites www.bricogeek.com o
www.sparkfun.com para hacerte una idea de la posibilidades que tienes para
ampliar la potencia de tu Arduino.

149
CAPÍTULO

VISUALIZANDO
DATOS CON
EL LCD

A estas alturas ya has comenzado a dominar el arte de la interacción con el


Arduino, tanto en el terreno de lo digital como en el analógico. Sin embargo, nos
queda un tema pendiente: la visualización de datos. Hasta ahora hemos utilizado
el monitor serie que viene integrado con el IDE de Arduino para mostrar los datos
que generábamos en nuestros proyectos. Llegó el momento de independizarse
del PC y empezar a observar la información directamente.

Uno de las formas más sencillas para mostrar la información es con una
pantalla de cristal líquido (LCD). Podemos mostrar texto, caracteres
personalizados, datos numéricos y gráficos. Las pantallas de cristal líquido (LCD) se
han vuelto omnipresentes. Desde el momento en que nos despertamos hasta el
momento de irnos a la cama, estamos continuamente interaccionando con
pantallas LCD. Te despiertas por la mañana y, al ver la pantalla LCD de tu reloj de
alarma, te das cuenta de que vas a llegar tarde a clase y el profesor te va a echar
una bronca por el retraso. En el descanso entre clases, necesitas la pantalla del
LCD de tu reproductor MP3 para navegar hasta tu canción favorita de Eminem. Un
poco más tarde, te llaman por teléfono y le echas un vistazo a la pantalla LCD de
tu móvil y decides si contestar o no. Y finalmente, después de un día horrible,
ajustas el despertador mediante la pantalla LCD para que no te vuelvas a retrasar
al día siguiente y te expulsen definitivamente de la asignatura de electrónica
digital.

La visualización de las pantallas LCD es una de las principales formas en que


experimentamos con los datos electrónicos. En este capítulo, vamos a ver los
tipos comunes de las pantallas LCD que se pueden utilizar con Arduino. Los
primeros dos tipos de pantallas de LCD son: paralelo y serie. Son normalmente
pantallas de caracteres. El carácter es idóneo para la visualización de algún tipo de
texto e incluso formas pequeñas o iconos (generalmente 5 x 7 píxeles). El otro tipo

150
8. Visualizando datos con el LCD

de LCD que vamos a cubrir en este capítulo es el LCD gráfico que, como habrás
adivinado, es ideal para la elaboración de gráficos e imágenes.

Pero antes de empezar a explorar las pantallas de caracteres, vamos a


echar un vistazo a los tipos de variables de cadena, que son la forma en que
tratamos un texto en Arduino.

Tipo de variable array. Llegó la hora de abordar un nuevo tipo de variable


denominada array. A diferencia del tipo de variables vistas anteriormente que
solo podían almacenar un valor único a la vez, los arrays son un caso especial de
variables que pueden almacenar un conjunto de valores, y modificar solo uno, o
algunos, o incluso todos los valores contenidos en el mismo en cualquier
momento y según nuestra conveniencia. También sería posible evitar el uso de
arrays y en vez de ello crear «muchas» variables con distintos nombres. Sin
embargo, esto no resultará cómodo de utilizar. La traducción de array es
literalmente «colección», ya que se utiliza para «juntar» varios objetos de un
mismo tipo. En otras materias, como matemáticas, se conoce con el nombre de
matriz y generalmente se usan las de 2 dimensiones, por su facilidad para
representarlas en un plano, ya que tienen ancho y alto. Cada elemento de la
matriz se identifica por un par de números que indican la fila y la columna en que
se ubica el elemento. También podríamos tener una matriz de 3 dimensiones
(cubo). En ese caso cada elemento de la matriz se identificará con 3 valores
ordenados (que indicarán la posición relativa del elemento dentro de la matriz),
por ejemplo, el elemento A(1,8,76) habría que encontrarlo dentro de la matriz A,
en la fila 1, columna 8, «nivel» o «capa» 76.

En el caso de Arduino es todavía más simple. Utilizaremos un tipo de matriz


de una sola dimensión. Por ejemplo, se podría declarar un array de las siguientes
formas:
int minume[6];
// se define una array que tendrá 6 elementos de tipo
entero (int).
int minume[] = {2, 4, 8, 3, 6};
// se define el array y se le rellena con valores
númericos.
char mensaje[6] = "hola";
// ahora almacena caracteres individuales.

151
Taller de Arduino

Los arrays son zero indexed, esto significa que, al referirse a una matriz, el
primer elemento de la matriz está en el índice 0. Por lo tanto:
minume[0] == 2, minume[1] == 4, y sucesivamente.

Esto también significa que en una matriz con 10 elementos el índice 9 es el


último elemento. Por lo tanto:
int myArray[10]={9,3,2,4,3,2,7,8,9,11};
// myArray[9] 11.
// myArray[10] es invalido y contiene información
aleatoria.

Tipo de variable string (‘s’ minúscula). Las variables de tipo string se


representan como un tipo particular de arrays de caracteres (tipo char) que
terminan con el carácter NULL. Por ejemplo:
char Str1[15];
// Declara un array de carácteres sin incializarlo.
char Str2[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o'};
// Declara un array de carácteres (con un caracter
extra) y el compilador añadirá el carácter NULL
requerido.
char Str3[8] = {'a', 'r', 'd', 'u', 'i', 'n', 'o', '\0'};
// Explicita el caracter NULL.
char Str4[ ] = "arduino";
// Inicializa con un string constante entre comillas
dobles; el compilador medirá el tamaño del array para
ajustar el string constante y caracter NULL para
finalizar.
char Str5[8] = "arduino";
// Inicializa el array con un tamaño explícito y un
string constante.
char Str6[15] = "arduino";
// Inicializar el array, dejando un espacio extra para
un string más largo.

152
8. Visualizando datos con el LCD

Generalmente, los strings se finalizan con un carácter NULL (código ASCII: 0).
Esto permite a funciones como Serial.print(), establecer dónde está el final del string.
De otra forma, seguiría leyendo los siguientes bytes de la memoria que no forman
parte del string. Los strings siempre se definen entre comillas dobles ("Abc") y los
caracteres siempre se definen dentro de comillas simples ('A'). A menudo es
conveniente, al trabajar con grandes cantidades de texto, como proyectos con
displays o LCD, configurar un array de strings, es decir, una matriz de cadenas de
textos.

Tipo de variable String (‘S’ mayúscula). El tipo String merece toda una
explicación ya que es un poco más que un tipo de variable. De hecho, es un objeto
(en el sentido de la programación orientada a objetos). Los objetos cuentan con
propiedades y funciones especiales. Propiedades y funciones son disponibles de
forma nativa en el núcleo de Arduino y se pueden ver como una entidad
preexistente, incluso si nuestro IDE no contiene ninguna línea. Una vez más, el
núcleo de Arduino se ocupa de las cosas para nosotros y nos proporciona
funciones de gran alcance ya preparadas para utilizar directamente.

El tipo de datos String es diferente que el tipo de datos de cadena (nótese la


mayúscula S para este tipo de datos en comparación con el anterior). Este tipo de
datos es en realidad una construcción a partir del tipo de datos de cadena, pero es
tratado como un objeto o instancia en lugar de una sencilla matriz de caracteres. Lo
que esto significa es que tiene una gran cantidad de funcionalidad integrada con el
tipo de datos String. Hemos hablado de la definición de las variables, pero los objetos
tienen un concepto similar llamado «construcción». Para objetos String, hablamos de
construcción en términos similares a declaración de una variable. Declarar un tipo
String en el núcleo de Arduino incluye un constructor de objeto, que es un concepto
de programación orientada a objetos que podemos obviar, ya que el núcleo de
Arduino lo hace por nosotros de tal manera que es mucho más fácil.

Por ejemplo, supongamos que tenemos una secuencia de caracteres que se


leen de un sensor en una variable de cadena denominada miDato. Además,
supongamos que necesitamos convertir todos los caracteres en letras mayúsculas.
Con el tipo de datos de cadena string, tendríamos que escribir el código para
hacer la conversión.

Si definimos miDato como un objeto String, entonces podríamos escribir la


conversión simplemente como:
miDato = miDato.ToUpperCase ();

153
Taller de Arduino

¡Y ya está! La razón por la que esto funciona es porque dentro del objeto
String existe una función (también denominada método) que contiene el código
para hacer la conversión por nosotros. Solo tenemos que definir la variable como:

miDato = String (100);

Así definimos una cadena denominado miDato con espacio suficiente para
99 caracteres. Para utilizar una función integrada de este tipo, escribe el nombre
de la variable seguida de un punto (llamado el operador de punto) seguida por la
función que deseas llamar.

Por ejemplo:

miDato = miDato.ToLowerCase ();

Dicha funcionalidad es común con los lenguajes de programación como


C++, C # y Java (Programación Orientada a Objetos). Aunque Arduino C no es
exactamente un lenguaje de programación orientada a objetos, contiene algunas
de las características. La Tabla 8.1 muestra algunas de las funciones incorporadas
que están disponibles cuando utilizamos objetos String (la tabla completa la
puedes examinar en la web oficial de Arduino).

Función Descripción
compareTo(String two) Comprueba si dos cadenas son iguales.
concat(String two) Combina dos cadenas en una nueva cadena.
Realiza la comparación entre mayúsculas y
equals(String two)
minúsculas entre dos cadenas.
replace(String one, String Reemplaza todas las apariciones de un carácter o
two) de una subcadena por otra.
Devuelve una copia de la cadena original con
toLowerCase()
todos los caracteres en minúsculas.
length() Devuelve la longitud en caracteres de la cadena.
Devuelve una copia de la cadena original con
Trim() todos los espacios en blanco, antes y después de la
cadena, eliminados.
Tabla 8.1

154
8. Visualizando datos con el LCD

En este punto, creo que he desmitificado las diferencias entre el tipo String
y la matriz de cadenas tipo char que te vas a encontrar cuando se trabaja con
Arduino y los LCD. Ahora, y sin más preámbulos, le damos dar la bienvenida al
HD44780 de Hitachi.

8.1 Funcionamiento del LCD paralelo.


El HD44780 de Hitachi
El Hitachi HD44780 es uno de los circuitos integrados más comunes del
controlador LCD diseñados para sistemas y microcontroladores integrados. El chip
soporta muchas formas y tamaños de las pantallas. En este ejemplo, vamos a
utilizar uno para controlar un 16 x 2 LCD (2 líneas, 16 caracteres de largo). La
omnipresencia del controlador Hitachi HD44780 es una gran ventaja para
nosotros, porque es un estándar, porque es barato y porque puede ser incluso
reciclado de viejos dispositivos que tengamos olvidados en el trastero de nuestra
casa. Algunos de estos LCD pueden ser retroiluminados (diodos leds debajo de la
pantalla). Esto es ideal para situaciones de poca luz. Los LCD basados en HD44780
de Hitachi vienen con muchas configuraciones diferentes, pero hay dos formas en
las que podemos interactuar con la pantalla LCD Hitachi HD44780: 4 bits y 8 bits.

La desventaja principal entre las configuraciones de 4 bits y de 8 bits es el


número de pines necesarios en el Arduino frente a la velocidad de ejecución. En
un LCD paralelo el medio más simple de comunicación sería enviar el byte
completo (8 bits) de datos de una sola vez (en un mensaje 1 byte). Para ello se
requieren por lo menos 10 pines del Arduino. Por el contrario, el modo de 4 bits
requiere solo 6 pines dividiendo el byte en dos nibbles de 4 bits. Esto ahorra pines,
pero necesita un poco de más tiempo (dos mensajes frente a un solo mensaje). El
modo de 4 bits sigue siendo una comunicación «paralela» en el sentido de que
recibimos 4 bits a la vez, pero está dividido en dos mensajes que se envían uno
después de otro.

Por suerte para nosotros, trabajar con los LCD basados en el chipset Hitachi
HD44780 (u otros similares) es una gozada (Figura 8.1 y Figura 8.2). Como se
mencionó anteriormente, una de las librerías estándar preinstalada en el IDE de
Arduino es la denominada LiquidCrystal(). Es compatible con configuraciones tanto
de 4 bits y 8 bits, ofreciéndonos muchas funciones útiles para controlar nuestro
LCD. La Tabla 8.2 detalla las funciones disponibles y más utilizadas de esta librería.

155
Taller de Arduino

Función Descripción
begin(int column, int row) Establece las dimensiones del LCD.
clear() Limpia la pantalla.
Establece el cursor a la parte superior izquierda
home()
de la pantalla.
setCursor(int column,int row) Coloca el cursor en la posición determinada.
Imprime el texto que puede ser un tipo: char,
print(data)
byte, int, long, o una cadena.
cursor() Muestra un subrayado en la posición actual.
noCursor() Oculta el carácter del cursor.
blink() Parpadea el carácter del cursor.
noBlink() Desactiva el parpadeo del carácter del cursor.
scrollDisplayLeft() Desplaza en el texto un espacio hacia la izquierda.
scrollDisplayRight() Desplaza en el texto un espacio hacia la derecha.
autoscroll() Desplaza automáticamente el texto.
Desactiva el desplazamiento automático del
noAutoscroll()
texto.
Establece la dirección del texto que se muestra
leftToRight()
(izq-dch).
Establece la dirección del texto que se muestra
rightToLeft()
(dch-izq).
Tabla 8.2

Figura 8.1

156
8. Visualizando datos con el LCD

Figura 8.2

En la Figura 8.2 se puede observar un tipo de conexión que utiliza un


potenciómetro o trimpot para ajustar externamente el contraste del LCD.
Además, si tiene retroiluminación, como es este caso, utilizamos los pines LED+ y
LED- para llevarlos a alimentación y masa (A y K) a través de una resistencia
limitadora de un valor especificado por el fabricante (entre 70 y 200 Ω).

Figura 8.3

8.1.1 Práctica 17: el HD44780 de Hitachi


Ahora que tenemos una buena comprensión de cómo se comunica el HD44780 de
Hitachi, tanto a nivel de hardware como de software, estamos listos para empezar
a conectar todo. Y lo vamos a realizar con una sencilla práctica que muestre un
simple mensaje en el LCD (16x2). En la Figura 8.3 observamos las conexiones con
Frizting.

157
Taller de Arduino

Se ha optado por la comunicación en modo 4 bits para ahorrar pines del


Arduino. La asignación de estos se muestra a continuación:

• LCD 1 (0V) a masa (GND) del Arduino.


• LCD 2 (5V) a +5V del Arduino.
• LCD 3 (V0) a un potenciómetro de 10 kΩ conectado entre +5 V y
masa.
• LCD 4 (RS) al pin 12 del Arduino.
• LCD 5 (R/W) a masa (GND) del Arduino.
• LCD 6 (E) al pin 11 del Arduino.
• LCD 11 (DB4), 12 (DB5), 13 (DB6), 14 (DB7) a los pines 2, 3, 4, 5 del
Arduino.

Los pines LED+ y LED- se pueden llevar a una resistencia limitadora si el LCD
posee estos pines para la retroiluminación. En la Figura 8.4 se observa la práctica
simulada con Proteus.

Figura 8.4

Para realizar esta práctica necesitamos el siguiente hardware:

 Un Arduino UNO.
 Una pantalla LCD basada en HD44780 de Hitachi.
 Un potenciómetro de 10 kΩ.

158
8. Visualizando datos con el LCD

 Una resistencia adicional. Esto solo es necesario si el LCD tiene luz de


fondo.

Práctica 17. El HD44780


/* Utilizando por primera vez un LCD (16 x 2) con Arduino. */
/* Si no ves nada, mueve el potenciómetro del contraste del
LCD */
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
void setup()
{
lcd.begin(16, 2);
lcd.print("Arduino");
lcd.setCursor(0,1);
lcd.print("LCD funciona");
}
void loop()
{
}

En primer lugar, se debe incluir el archivo de cabecera de la librería


LiquidCrystal() para decirle al Arduino que la utilice. A continuación, se crea una
instancia de clase de la librería con los pines de nuestro Arduino conectados a la
pantalla LCD. El número de pines que se le pasa configura automáticamente el
LCD con objeto para funcionar en modo 4 bits o en el modo de 8 bits. Con la
función lcd.begin(16,2) configuramos el número de filas y columnas de nuestro
LCD. A continuación, imprimimos el texto en la pantalla LCD. Debido a que el texto
que se desea imprimir es más largo que una fila, imprimimos primero la mitad y
luego nos posicionamos en la segunda línea con la función lcd.setCursor(0,1) para
enviar al LCD la segunda mitad del texto.

La librería LiquidCrystal() que hemos incluido con la línea #include ya viene


incluida con el IDE de arduin0. Se trata de un tipo de librería estándar.

Además de usar los caracteres estándar, números y símbolos disponibles en


el teclado, puedes definir tus propios caracteres. Fijaros que, en cada LCD, un
carácter está compuesto por ocho filas de cinco puntos o píxeles cada una. La

159
Taller de Arduino

Figura 8.5 muestra el detalle en primer plano. Para visualizar tus propios
caracteres se debe definir cada uno, usando un array. Por ejemplo, para crear una
cara sonriente, se podría utilizar el array siguiente en que cada número en la
matriz se dirige a un píxel individual en la pantalla. Un 0 apaga un píxel y un 1 lo
activa. Los elementos de la matriz representan las filas de píxeles en la pantalla. El
elemento superior es la fila superior y el siguiente elemento es la segunda fila
hacia abajo.
byte a[8] = {B00000,
B01010,
B01010,
B00000,
B00100,
B10001,
B01110,
B00000};

Figura 8.5

8.1.2 Práctica 18: diseñando caracteres a medida


En este ejemplo, ya que el primer elemento es B00000, todos los píxeles en la
parte superior de la fila se apagan porque solo vemos ceros. En el siguiente
elemento, B01010, se encienden con un 1 los píxeles que forman la parte superior
de los ojos. Cada fila y pixel se siguen rellenando para formar la cara sonriente. A
continuación, se asigna una matriz con la siguiente función:

lcd.createChar(0, a); asigna una matriz “a” de 8 elementos.

160
8. Visualizando datos con el LCD

Finalmente se escribe el nuevo carácter personalizado utilizando la función:


lcd.write(0);

El listado completo se muestra a continuación:


Práctica 18. Mostrando un emoticón en el LCD
/* Generando caracteres a medida en un LCD */
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2));
byte a[8] = { B00000,
B01010,
B01010,
B00000,
B00100,
B10001,
B01110,
B00000 };
void setup()
{
lcd.begin(16, 2);
lcd.createChar(0, a);
}
void loop()
{
lcd.write(0);
}

8.2 Funcionamiento del LCD serie


¿Quieres ahorrar aún más pines en tu placa Arduino? Los LCD serie son una
opción asequible y requieren solo tres pines para operar. Estos trabajan de
manera diferente a los LCD paralelos. Interpretan comandos de tipo serie a través
de la patilla TX. El problema es que son un poco más caros que sus hermanos
aralelos. De todas maneras, sus precios han disminuido notablemente en los
últimos años. Además, podemos comprar una mochila serie LCD, convirtiendo el
LCD paralelo Hitachi HD44780 en un LCD serie. En esta sección, vamos a ver la

161
Taller de Arduino

conexión y la comunicación con un LCD serie y construir un proyecto para medir,


en tiempo real, la temperatura de tu casa.

La manera en la que las pantallas LCD de serie se comunican con Arduino es


fundamentalmente diferente a como lo hacen los LCD paralelo que vimos en el
apartado anterior.
En los LCD paralelo enviábamos datos en grupos de 4 u 8 bits. La principal
diferencia es que los LCD serial envían datos u órdenes a través de una sola línea
de 1 bit. Por ello, este tipo de pantallas se comunican con el Arduino con tan solo
una línea de datos. La comunidad de Arduino ha creado una librería muy parecida
a la librería LiquidCrystal(), que permite realizar las operaciones básicas de control
del LCD de forma muy sencilla.
La librería que se va a utilizar para comunicarse con nuestra pantalla LCD
serial es la SerLCD(). Esta librería está pensada para ser utilizada con el LCD 16 x 2
de la casa “SparkFun” pero funciona con la mayoría de los tipos de LCD de otros
fabricantes. A diferencia de LiquidCrystal() que viene por defecto con el IDE de
Arduino, esta nueva librería SerLCD() es del tipo contributiva, es decir, no ha sido
escrita por el equipo oficial de Arduino sino que ha sido diseñada por un miembro
particular de esta comunidad. Para hacerla operativa e integrarla en nuestro IDE
hay que seguir una serie de pasos muy simples:

1. Descargarla en formato zip de: https://github.com/nemith/serLCD


2. Añadirla desde el IDE.
3. Observar las funciones que contiene desde:
http://arduino.cc/playground/Code/SerLCD

Esta librería utiliza a su vez otra denominada: SoftwareSerial(), permitiendo


trabajar sobre una sola línea de comunicación serie. Además, ha remodelado la
mayoría de las funciones que teníamos disponibles en la librería LiquidCrystal() de
tal manera que es muy sencillo y trasparente para el usuario pasar de un LCD
paralelo a uno serial. Por ello, podremos compartir código entre ambos con pocos
cambios. La Tabla 8.3 nos muestra sus principales funciones.

Función Descripción
serLCD(int pin) Establece el pin TX de comunicación serie.
clear() Limpia la pantalla.
Establece el cursor a la parte superior izquierda de
home()
la pantalla.

162
8. Visualizando datos con el LCD

Función Descripción
clearLine(int num) Limpia una línea determinada.
Imprime el texto que puede ser un tipo: char, byte,
print(data)
int, long, o una cadena.
setBrightness(int num) Establece por software el contraste del LCD.
cursor() Muestra un subrayado en la posición actual.
noCursor() Oculta el carácter del cursor.
blink() Parpadea el carácter del cursor.
noBlink() Desactiva el parpadeo del carácter del cursor.
Establece las dos líneas que conforman la
setSplash()
«bienvenida» del LCD.
toggleSplash() Habilita o deshabilita el pantallazo de «bienvenida».
createChar(int num, byte[]
Define un caracter personalizado 5 x 8.
charData)
printCustomChar(int num) Imprime un carácter personalizado.
Tabla 8.3

La pantalla de bienvenida o splash es una característica de los LCD serial


que permite mostrar durante medio segundo un mensaje tan pronto lo
encendamos. Transcurrido dicho tiempo el mensaje desaparece. Por otra parte,
observamos que las dos últimas funciones de la tabla nos permiten trabajar con
los caracteres personalizados de forma muy sencilla.
En las Figuras 8.6 y 8.7 que se muestran debajo, observamos un típico LCD
serial.

Figura 8.6

Figura 8.7

163
Taller de Arduino

8.2.1 Práctica 19: mostrando texto con el LCD serie


Un ejemplo de utilización básica del LCD serie es el que se muestra a
continuación. Vamos a mostrar un simple mensaje utilizando la librería
anteriormente descrita. Para realizar esta práctica solo necesitamos el siguiente
hardware:

 Un Arduino UNO.
 Una pantalla LCD serie compatible.

Práctica 19. Mostrando un simple texto con el LCD serie


/* Utilización simple del LCD serie */
#include <SoftwareSerial.h>
#include <serLCD.h>
serLCD miLcd(7);
void setup()
{
Serial.begin(9600);
miLcd.clear();
}
void loop()
{
miLcd.setCursor(1,1);
miLcd.print("LCD funcionando");
}

En primer lugar incluimos las dos librerías necesarias para trabajar con este
tipo de LCD.

#include <SoftwareSerial.h>
#include <serLCD.h>

Definimos un objeto de la librería serLCD() llamado miLcd que establece el


pin 7 como línea de comunicación serie entre el LCD y nuestro Arduino.

serLCD miLcd(7);

164
8. Visualizando datos con el LCD

A partir de ahí siempre que hagamos referencia a las funciones de la librería


expuestas en la tabla anterior, utilizaremos esta construcción. Por ejemplo, para
imprimir un mensaje (función print):

miLcd.print("LCD funcionando");

El esquema del ejercicio simulado en PROTEUS se observa en la Figura 8.8.

Diseñar un proyecto que mida la temperatura ambiente utilizando un


sensor LM35 y muestre la información en un LCD serie.

Figura 8.8

8.3 Funcionamiento del LCD gráfico. El KS0108


Si necesitamos mostrar en una pantalla algo que sea de tipo gráfico como líneas,
círculos o imágenes en general, estamos obligados a utilizar un tipo de LCD
denominado GLCD. Este tipo de pantallas abunda hoy en día en los más diversos
dispositivos de uso común como teléfonos móviles, calculadoras científicas,
relojes digitales, etc.
Considerando que anteriormente un carácter era definido por 5 x 8 píxeles,
los LCD gráficos usan toda la pantalla como lienzo de dibujo permitiendo un
control completo para representar lo que queramos, pixel a pixel. Las
posibilidades de representación son inmensas, desde el diseño de un videojuego a

165
Taller de Arduino

la visualización de datos complejos y precisos. Existen muchos tipos de LCD


gráficos, pero nosotros vamos a utilizar un estándar clásico basado en el chip
KS0108. Este presenta una configuración de 128 x 64 píxeles en blanco y negro. Al
igual que en los LCD alfanuméricos vistos antes, los GLCD disponen de una
extensa librería que permiten dibujar fácilmente a lo largo y ancho de toda su
pantalla.
Para comunicarse con el KS0108 GLCD se va a utilizar la librería glcd-v3()
disponible en http://code.google.com/p/glcd-arduino/downloads/list. Es necesario
añadirla al IDE descargándola en formato zip. Viene acompañada de varios ejemplos y
un documento en PDF ampliamente documentado.
La Tabla 8.4 enumera algunas de las diversas funciones de esta extensa
librería.

Función Descripción
GLCD.Init() Inicializa la librería.
ClearScreen() Limpia la pantalla.
Dibuja una imagen bitmap en unas coordenadas
DrawBitmap()
dadas.
GotoXY() Mueve el cursor gráfico a las coordenadas dadas.
SetDot() Establece el color de un determinado pixel.
DrawVLine() Dibuja una línea vertical.
DrawHLine() Dibuja una línea horizontal.
DrawLine() Dibuja una línea entre dos coordenadas dadas.
DrawRect() Dibuja un rectángulo.
FillRect() Rellena el interior de un rectángulo.
DrawRoundRect() Dibuja un rectángulo con esquinas redondeadas.
DrawCircle() Dibuja un círculo.
FillCircle() Rellena el interior de un círculo.
SelectFont() Establece una fuente de texto.
SetFontColor() Establece el color de la fuente de texto.
ClearArea() Limpia la actual área de texto con el color de fondo.
Borra todo el texto en la fila dada dentro del área
EraseTextLine(row) de texto y mueve el cursor a la posición de la
izquierda.

166
8. Visualizando datos con el LCD

Función Descripción
EraseTextLine() Borra el texto en la línea actual.
CursorTo() Mueve el cursor de texto a una fila y columna dadas.
CursorToXY() Mueve el cursor de texto a unas coordenadas dadas.
GLCD.print() Imprime un carácter, entero, cadena o tipo float.
Tabla 8.4

Vamos a ver ahora las conexiones entre el patillaje del Arduino y el GLCD
(Figura 8.9). Esta librería viene documentada y preparada para utilizar con el
Arduino UNO o con el Arduino MEGA. En función de que usemos uno u otro, varía
la referencia de los pines del mismo tal y como se observa en la Figura 8.9. El
esquema que se muestra a continuación (Figura 8.10) representa el conexionado
entre Arduino UNO y un GLCD.

Figura 8.9

Evidentemente, se ha realizado con PROTEUS ya que con el software


fritizing el circuito se vuelve difícil de entender debido a la gran cantidad de
conexiones que son necesarias entre ambos dispositivos. El GLCD visualiza una
imagen de un logotipo de Arduino. Si lo deseas ver, te animo a que lo simules o lo
montes.

167
Taller de Arduino

Figura 8.10

Aunque este esquema parezca enrevesado, si se sigue de forma ordenada


la lectura de las conexiones de la Figura 8.9, resulta bastante sencillo de
implementar. En cuanto al listado del programa es muy simple ya que la librería es
muy cómoda de utilizar.

8.3.1 Práctica 20: utilizando un GLCD


Vamos a mostrar un sencillo logotipo de Arduino en un GLCD.

Práctica 20. Utilizando un GLCD


/* LCD gráfico basado en el chip ks0108 */
#include <glcd.h>
#include "bitmaps/ArduinoIcon.h"
void setup()
{
GLCD.Init();
GLCD.DrawBitmap(ArduinoIcon, 32,0, BLACK);
}
void loop()
{
}

168
8. Visualizando datos con el LCD

Las dos primeras líneas del sketch incluyen la librería GLCD y la imagen
bitmap del logotipo que deseamos mostrar.

#include <glcd.h>
#include "bitmaps/ArduinoIcon.h"

En el bloque de configuración tenemos la función de inicialización de la


pantalla y la que imprime o dibuja la imagen en unas coordenadas x, y de la
misma.

GLCD.Init();
GLCD.DrawBitmap(ArduinoIcon, 32,0, BLACK);

Como vemos el programa es muy sencillo y con pocas órdenes podemos


realizar presentaciones muy vistosas de nuestros proyectos. Es conveniente
explorar la librería para darse cuenta de su potencia gráfica.

8.3.2 Práctica 21: mostrando texto en un GLCD


Sin cambiar el hardware, observemos ahora cómo mostrar texto y elegir el tipo de
fuente para visualizarlo en un GLCD.

Práctica 21. Mostrando texto en un GLCD


/* Ejemplo sencillo para mostrar un texto en un GLCD */
#include <glcd.h>
#include <fonts/allFonts.h>
void setup()
{
GLCD.Init();
GLCD.SelectFont(Arial_14);
}
void loop()
{
GLCD.CursorTo(20, 1);
GLCD.print("Arduino y GLCD");
}

169
Taller de Arduino

En primer lugar, incluimos la famosa librería glcd.h y la correspondiente a


los diferentes tipos de fuentes de texto denominada: allFonts.h.

#include <glcd.h>
#include <fonts/allFonts.h>

Inicializamos la pantalla y establecemos el tipo de fuente de texto que


queremos usar. En este caso una Arial de tamaño 14.

GLCD.Init();
GLCD.SelectFont(Arial_14);

Por último, definimos las coordenadas del origen del texto en pantalla e
imprimimos la cadena de caracteres deseada.

GLCD.CursorTo(20, 1);
GLCD.print("Arduino y GLCD");

Con el documento PDF completo de la librería glcd.h a la vista, estudia


el siguiente sketch y averigua a la salida visualizada en tu GLCD.

Proyecto 2. Profundizando en la librería GLCD


/* A ver lo que te sale...*/
#include <glcd.h>
#include "fonts/Arial14.h"
#include "fonts/SystemFont5x7.h"
#include "bitmaps/ArduinoIcon.h"
unsigned long startMillis;
unsigned int loops = 0;
unsigned int iter = 0;
void setup()
{
GLCD.Init(NON_INVERTED);
GLCD.ClearScreen();

170
8. Visualizando datos con el LCD

GLCD.DrawBitmap(ArduinoIcon, 32,0, BLACK);


GLCD.SelectFont(System5x7);
countdown(5);
GLCD.ClearScreen();
introScreen();
GLCD.ClearScreen();
}
void introScreen()
{
GLCD.SelectFont(Arial_14);
GLCD.GotoXY(20, 2);
GLCD.Puts("GLCD version ");
GLCD.PrintNumber(GLCD_VERSION);
GLCD.DrawRoundRect(16,0,99,18, 5, BLACK);
GLCD.SelectFont(System5x7);
showCharacters();
countdown(5);
}
void showCharacters()
{
byte line = 3;
for(byte c = 32; c <=127; c++)
{
if( (c-32) % 20 == 0)
GLCD.CursorTo(1,line++);
GLCD.PutChar(c);
}
}
void drawSpinner(byte pos, byte x, byte y)
{
switch(pos % 8)
{
case 0 : GLCD.DrawLine( x, y-8, x, y+8, BLACK);
break;

171
Taller de Arduino

case 1 : GLCD.DrawLine( x+3, y-7, x-3, y+7, BLACK);


break;
case 2 : GLCD.DrawLine( x+6, y-6, x-6, y+6, BLACK);
break;
case 3 : GLCD.DrawLine( x+7, y-3, x-7, y+3, BLACK);
break;
case 4 : GLCD.DrawLine( x+8, y, x-8, y, BLACK);
break;
case 5 : GLCD.DrawLine( x+7, y+3, x-7, y-3, BLACK);
break;
case 6 : GLCD.DrawLine( x+6, y+6, x-6, y-6, BLACK);
break;
case 7 : GLCD.DrawLine( x+3, y+7, x-3, y-7, BLACK);
break;
}
}
void countdown(int count)
{
while(count--)
{
GLCD.CursorTo(0,1);
GLCD.PutChar(count + '0');
delay(1000);
}
}
void loop()
{
iter = 0;
startMillis = millis();
while( millis() - startMillis < 1000)
{
GLCD.DrawRect(0, 0, 64, 61, BLACK);
GLCD.DrawRoundRect(68, 0, 58, 61, 5, BLACK);
for(int i=0; i < 62; i += 4)
GLCD.DrawLine(1,1,63,i, BLACK);

172
8. Visualizando datos con el LCD

GLCD.DrawCircle(32,31,30,BLACK);
GLCD.FillRect(92,40,16,16, WHITE);
drawSpinner(loops++,100,48);
GLCD.CursorTo(5,5);
GLCD.PrintNumber(++iter);
}
GLCD.ClearScreen();
GLCD.CursorTo(14,2);
GLCD.Puts("FPS= ");
GLCD.PrintNumber(iter);
}

Diseña un proyecto que muestre en un GLCD basado en el


controlador KS0108, una temperatura obtenida de un sensor LM35.
Añádele algún tipo de elemento gráfico, como un rectángulo o círculo
que realce la vistosidad del dato mostrado.

8.3.3 Práctica 22: visualizando nuestras propias imágenes


Podemos utilizar nuestras propias imágenes (mapas de bits) con la pantalla GLCD.
Los mapas de bits se definen en los archivos de cabecera con una extensión “.h”.
Por ejemplo, la imagen anteriormente usada del icono Arduino, llamada
“ArduinoIcon.h”, se almacena en la carpeta de mapa de bits del directorio de la
librería GLCD. Esta carpeta también contiene un archivo denominado
“allBitmaps.h” que almacena otros ficheros de imágenes. Ahí es donde podemos
incluir las nuestras.

Para añadir nuestros propios mapas de bits, la librería GLCD incluye una
utilidad llamada glcdMakeBitmap.pde que convierte un fichero con formato gif,
jpg, bmp, tga o png, en un archivo de encabezado que puede ser utilizado por la
librería GLCD. Este fichero, en realidad, es un programa que debe ser ejecutado en
Processing ( http://processing.org ).

Processing es un lenguaje de programación y entorno de desarrollo


integrado de código abierto basado en Java, de fácil utilización, y que
sirve como medio para la enseñanza y producción de proyectos
multimedia e interactivos de diseño digital.

173
Taller de Arduino

Después de haber descargado Processing, abre su entorno y ejecuta el


fichero glcdMakeBitmap.pde.

Ahora arrastra a su ventana un fichero de imagen que hayas creado tú o


que hayas bajado de la red. Processing creará un archivo de cabecera con el
mismo nombre de tu archivo de imagen. El archivo se agrega automáticamente al
fichero al fichero allBitMaps.h; con lo cual ya lo puedes usar directamente en tu
sketch. Vamos a verlo.

Partimos que ya hemos generado fichero de cabecera yomismo.h a partir


de una imagen llamada yomismo.bmp, según el procedimiento anteriormente
descrito.

Práctica 22. Mostrando imágenes propias en un GLCD


/* Visualizando bitmaps propios */
/* La verdad es que es alucinante … /
#include <glcd.h>
#include "bitmaps/allBitmaps.h"
void setup()
{
GLCD.Init();
GLCD.ClearScreen();
GLCD.DrawBitmap(yomismo, 0,0);
}
void loop()
{
}

El sketch nos mostrará la imagen que hemos creado con la sencilla función:

GLCD.DrawBitmap(yomismo, 0,0);

Diseñar un proyecto que muestre en un GLCD basado en el chip


KS0108, una imagen bitmap de tu elección.

174
CAPÍTULO

CONTROL DE
MOTORES CON
ARDUINO

En capítulos anteriores hemos adquirido una base sólida en el uso de nuestro


Arduino para comunicarse con los entornos digitales y analógicos. Hemos
realizado, y se os ha propuesto, una serie de proyectos básicos para afianzar los
conceptos de programación y de electrónica básica. También, hemos explorado
cómo utilizar las librerías y os he mostrado las diferentes shields para extender la
funcionalidad básica del Arduino. Hemos visto el funcionamiento de los diferentes
tipos de LCD y cómo se trabaja con sus propias librerías.
Ahora es el momento de considerar las técnicas en las que Arduino se
puede utilizar en tus propios proyectos, ya sea en un control determinado a través
de Internet, un robot a control remoto o una puerta automática de garaje. En este
y en los sucesivos capítulos, te proporcionaré las herramientas y técnicas para
lograr estos objetivos.
En este capítulo, vamos a explorar la manera de añadir movilidad a un
proyecto. Abordaremos las diferentes maneras de controlar una gran variedad de
motores. Tal vez tengáis por casa o arrinconado en el trastero, una vieja
impresora que pueda ser aprovechada por sus motores paso a paso, o quizás,
viejos juguetes accionados por pequeños motores de corriente continua.
A medida que avancemos usaremos Arduino para controlar pequeños
motores de corriente continua para accionar un pequeño vehículo o motores paso
a paso para controlar una posible impresora 3D.
Vamos a empezar con los motores más sencillos: los de corriente continua.
Se utilizan normalmente para el control de pequeños robots.

9.1 Funcionamiento de un motor de continua (DC)


Los motores eléctricos de corriente continua (DC) se pueden encontrar en una
amplia gama de dispositivos incluyendo los coches y barcos de radio control,

175
Taller de Arduino

reproductores de DVD, ventiladores eléctricos, etc. Muchos de estos pueden ser


reutilizados para el uso con nuestro Arduino (decididamente, hay que rebuscar en
el trastero).
Alternativamente, podemos comprarlos por módicos precios en tiendas de
electrónica o a través de Internet. Son pequeños motores (Figura 9.1) cuyas
tensiones de trabajo varían entre 2 V y 30 V. Cada fabricante proporciona una
tensión recomendada que si la sobrepasamos (suelen ser bastantes «duros»)
podemos quemar el motor. Si, por el contrario, aplicamos poca tensión, el motor
ni se entera, es decir, no gira.

Figura 9.1

Figura 9.2

El control de estos motores se realiza mediante dos cables. La velocidad del


motor se establece con la tensión que se le aplica. Una variación de tensión
producirá un cambio proporcional de su velocidad de giro. Para invertir el giro,
simplemente, se debe invertir la polaridad de los terminales. Si estamos usando el
motor DC para accionar un pequeño robot, a menudo se acopla su eje a una caja
reductora mecánica (Figura 9.2) ya que permite trasformar la alta velocidad de
giro a baja velocidad, pero con un par de fuerza más alto de la que por defecto
proporciona el motor solo. Esto es adecuado para potenciar la fuerza de los

176
9. Control de motores con Arduino

motores, aunque sea a costa de su velocidad de giro. Por otra parte, el Arduino
solo puede proporcionar una pequeña cantidad de corriente, insuficiente para
excitar las bobinas del motor DC. Por ello se hace imprescindible aumentar o
amplificar dicha corriente si deseamos que nuestro motor se mueva.
Las características de un pequeño motor DC típico se pueden resumir en los
siguientes puntos:

 La tensión de trabajo. Esta puede variar desde 3 V a más de 12 V.


 La corriente sin carga. Es la cantidad de corriente que el motor
absorbe cuando gira libremente sin nada conectado.
 Par de fuerza del eje del motor.
 La cantidad de corriente que absorbe el motor cuando tiene carga en
el eje.
 La velocidad a la tensión de trabajo expresada en revoluciones por
minuto (RPM).

Para el control de nuestro motor usaremos un transistor debido a sus


necesidades de corriente. Vamos a utilizar un transistor llamado Darlington como
típico TIP120. Los transistores Darlington pueden manejar altas corrientes y
tensiones. El TIP120 Darlington puede controlar hasta 5 A de corriente a 60 V.
Esto es más que suficiente para controlar nuestro pequeño motor. El TIP120
utiliza un símbolo esquemático similar al BC548 (Figura 9.3 y Figura 9.4).

Figura 9.3

Figura 9.4

177
Taller de Arduino

9.2 Práctica 23: haciendo girar un motor DC


Realicemos ahora un simple control de un motor DC. Para ello necesitaremos el
siguiente hardware:

 Un pequeño motor eléctrico DC de 6 V.


 Una resistencia de 1 kΩ.
 Un diodo 1N4004.
 Un transistor TIP120 Darlington
 Una pila de 9 V.

Nos puede sorprender que necesitemos una fuente de alimentación a


mayores. Ello es debido a que cuando se trabaja con motores, el Arduino no les
puede suministrar suficiente corriente para unas condiciones normales de
funcionamiento. Usaremos una pila de 9 V que es más que suficiente para
pequeños motores.
El esquema es el que se muestra a continuación (Figura 9.5):

Figura 9.5

Nota: el símbolo del transistor Darlington utilizado es el de un transistor


normal.
La función del diodo 1N4004 es la de proteger el motor en los momentos de
arranque, parada o cambio de sentido de giro, debido a la corriente inducida por
las bobinas del mismo. El diodo permite que circule esa corriente inversa de fuga
disipando una pequeña cantidad de calor.

178
9. Control de motores con Arduino

En este proyecto vamos a ajustar la velocidad del motor desde cero, a un


valor máximo y a continuación, tras una pausa, reducirla desde ese máximo a
cero. Utilizaremos la característica PWM de nuestro Arduino para variar el tiempo
de conducción del transistor y, en consecuencia, el valor medio del voltaje
aplicado al motor. Con ello, modificaremos la velocidad del mismo.

Práctica 23. Control simple de velocidad de un motor DC


/* Variando por software la velocidad de un motor DC */
/* Empezamos a trabajar con motores... */
void setup()
{
pinMode(5, OUTPUT);
}
void loop()
{
for (int a=0; a<256; a++)
{
analogWrite(5, a);
delay(100);
}
delay(5000);
for (int a=255; a>=0; a--)
{
analogWrite(5,a);
delay(100);
}
delay(5000);
}

En primer lugar, definimos la patilla 5 del Arduino como salida PWM para
atacar la base del transistor y hacerlo conmutar.

pinMode(5, OUTPUT);

El núcleo de esta práctica es el bucle for que va dando valores crecientes a la


variable «a» que se van enviando, con intervalos de 100 ms (para dar tiempo a

179
Taller de Arduino

responder al motor), a la base del transistor. Con ello iremos subiendo la velocidad
del motor. Al llegar a su valor máximo, esperamos 5 segundos y entramos en otro
bucle for que hace justamente lo contario: va decreciendo el valor de la variable a y
con ello la velocidad del motor hasta llegar a pararse (a = 0).

for (int a=0; a<256; a++)


{
analogWrite(5, a);
delay(100);
}

Realiza una práctica que controle la velocidad de un motor DC


mediante el valor de una entrada analógica que esté conectada a un
potenciómetro.

Realiza una práctica que gobierne la velocidad de dos motores


independientemente. Cada motor tendrá asociado un pulsador de tal
manera que cada vez que pulsemos, se incremente su velocidad
hasta llegar a un máximo. Superado este valor, cada pulsación
siguiente irá decreciendo la velocidad hasta que el motor se pare.

9.3 ¡Más madera! El puente H y el integrado L293D


Vamos a potenciar el control del motor DC. Ahora deseamos poder invertir el
sentido de giro del motor y regular su velocidad en cada momento. La inversión
del sentido de giro del motor DC se puede realizar manualmente, cambiando la
polaridad de sus terminales; pero queremos hacerlo electrónicamente. Para ello
necesitamos utilizar lo que se denomina: puente en H. Un puente H es una forma
común de controlar la velocidad y dirección de un motor DC. Inicialmente, vamos
a utilizarlo para controlar su sentido de giro y luego volveremos a lo que hemos
aprendido en la última sección y usar PWM para controlar su velocidad.
La figura 9.6 muestra el diagrama esquemático de un puente H formado por
cuatro interruptores. En la figura 9.7 se observa el sentido de giro del motor en
función de la posición de los cuatro interruptores S1, S2, S3 y S4. Cuando los
interruptores S1 y S3 están cerrados, el motor gira en un sentido. Si los
interruptores S2 y S4 se cierran y lógicamente se abren S1 y S3, el motor gira en
sentido contrario al anterior ya que la corriente circula al revés.

180
9. Control de motores con Arduino

Figura 9.6

La figura 9.6 muestra el diagrama esquemático de un puente H formado por


cuatro interruptores. En la figura 9.7 se observa el sentido de giro del motor en
función de la posición de los cuatro interruptores S1, S2, S3 y S4. Cuando los
interruptores S1 y S3 están cerrados, el motor gira en un sentido. Si los
interruptores S2 y S4 se cierran y lógicamente se abren S1 y S3, el motor gira en
sentido contrario al anterior ya que la corriente circula al revés.

Figura 9.7

Para llevar este esquema a un circuito real, podríamos sustituir los


interruptores por transistores como se observa en la figura 9.8. Sin embargo, la
solución definitiva que se ha adoptado, considerando que vamos a manejar
motores de pequeña potencia, es la de utilizar un circuito integrado que está
diseñado específicamente para esta tarea. El L293D (Figura 9.9) contiene dos
puentes H integrados y proporciona una manera fácil de controlar tanto la
dirección como la velocidad de motores DC. La ventaja de utilizar este chip es que
se pueden controlar dos motores al mismo tiempo, además de que se puede
controlar su dirección. El chip también se puede utilizar para controlar un motor
paso a paso (PAP) que veremos más adelante.

181
Taller de Arduino

También, se puede usar un chip compatible pin-a-pin con el L293D. Se


referencia por SN754410. Tiene una corriente nominal superior. Además, el chip
tiene sus propios diodos internos de protección del motor por lo que no necesitan
añadir externamente.

Figura 9.8

Figura 9.9

Patilla Descripción
1,2 EN Habilita un puente H (12).
1A Entrada 1 del driver.
1Y Salida 1 del driver.
GND Masa.
2A Entrada 2 del driver
2Y Salida 2 del driver.

182
9. Control de motores con Arduino

Patilla Descripción
Vcc2 Alimentación del motor (hasta 36 V).
3,4 EN Habilita el otro puente H (34).
3A Entrada 3 del driver.
3Y Salida 3 del driver.
4A Entrada 4 del driver.
4Y Salida 4 del driver.
Vcc1 Alimentación del integrado (5 V).
Tabla 9.1

En cuanto al LD293D su patillaje y su funcionamiento se observan en la


Tabla 9.1. El L293D tiene las siguientes características eléctricas:

 Corriente de salida máxima de 1,2 amperios.


 Corriente de salida continúa de 600 miliamperios.
 Rango de tensión de 4,5 a 36 voltios.
 Dos drivers o puentes H.
 Se puede accionar dos motores de corriente continua o un motor
paso a paso.

Aunque el L293D puede accionar dos motores de corriente continua, solo


se va mostrar cómo controlar uno. Puedes usar la misma técnica empleada en el
caso de que vayas a utilizar dos motores (algo necesario en el supuesto control de
un pequeño vehículo). Por otra parte, es necesario asegurarse de que conectamos
a la misma masa las dos baterías o fuentes de alimentación: la del Arduino y la
externa del motor.

9.3.1 Práctica 24: control del giro de un motor DC


utilizando el L293D
Se trata de utilizar el clásico chip L293D para realizar un proyecto que controle el
sentido de giro de un motor DC. Dicho motor girará en un sentido durante un
determinado tiempo, tras el cual invertirá su giro durante otro tiempo. El
hardware necesario para esta práctica es el siguiente:

 Un motor DC.
 Una batería externa para alimentar el motor.

183
Taller de Arduino

 Un controlador H dual L293D o equivalente.


 El Arduino, los cablecitos y la protoboard ya se suponen a estas
alturas del libro.

El circuito se muestra en la figura 9.10.

Figura 9.10

El listado del programa se estudia a continuación:

Práctica 24. Control del giro de un motor utilizando el L293


/* Usando el L293D */
/* El Arduino moviendo un motor, empezamos a tener fe en sus
posibilidades. */
int enablePin = 11;
int in1A = 4;
int in2A = 7;
void setup()
{
pinMode(enablePin, OUTPUT);
pinMode(in1A, OUTPUT);
pinMode(in2A, OUTPUT);
digitalWrite(enablePin, LOW);
}

184
9. Control de motores con Arduino

void loop()
{
digitalWrite(in1A, HIGH);
digitalWrite(in2A, LOW);
digitalWrite(enablePin, HIGH);
delay(5000);
digitalWrite(enablePin, LOW);
delay(2000);
digitalWrite(in1A, LOW);
digitalWrite(in2A, HIGH);
digitalWrite(enablePin, HIGH);
delay(5000);
digitalWrite(enablePin, LOW);
delay(2000);
}

Para analizar el sketch es aconsejable echar un vistazo a la siguiente Tabla


9.2. Nos resume el funcionamiento del motor en función de los estados lógicos de
los pines de control: 1,2 EN, 1A y 2A del chip L293 que provienen de las patillas
11,4 y 7 de nuestro Arduino.

1,2 EN 1A 2A Motor
ALTO BAJO ALTO Giro en sentido horario.
ALTO ALTO BAJO Giro en sentido antihorario.
ALTO BAJO BAJO Freno del motor.
ALTO ALTO ALTO Freno del motor.
BAJO X X Freno del motor.
Tabla 9.2

Examinando la tabla, se puede ver que para que el motor funcione la patilla
de habilitación (1,2EN) debe ser alta. Los pines 1A y 2A controlan el sentido de
giro del motor. Durante un ciclo de trabajo, se habilita el puente H estableciendo
el pin 1,2 EN (enable) en alto. Los pines in1A y in2A que están conectados a las
patillas 2 (1A) y 7 (2A) en el L293D, cambian de estado lógico en el bucle principal
de manera que el motor gira en una dirección durante cinco segundos y luego en
la otra dirección durante cinco segundos, con un intervalo de dos segundos en el
medio.

185
Taller de Arduino

Es necesario intercalar estas esperas con la función delay() para dar tiempo
al motor a reponerse ya que es un dispositivo «lento» en comparación con el
Arduino. El valor de estos retardos se puede ajustar sobre la marcha cuando
afinemos el funcionamiento del circuito.

9.3.2 Práctica 25: control total de un motor DC utilizando el L293D


Sin necesidad de modificar en esencia el hardware de la práctica anterior,
podemos añadir más control al motor DC. Se va a regular la velocidad del mismo
con solo cambiar algunas cosas en el sketch utilizado anteriormente.
En la sección anterior se trató el tema de cómo la técnica PWM puede
usarse para controlar la velocidad de un motor. Ahora se usa esta técnica en el pin
de habilitación (1,2 EN) para activar y desactivar el puente H.

Práctica 25. Control total de un motor DC


/* Control total de un motor DC: sentido de giro y velocidad. */
/* Ya nos queda menos para pensar en hacer un robotito móvil. */

int enablePin = 11;


int in1A = 4;
int in2A = 7;
int Pot = A0;
int botonD = 1;
int botonI = 2;
int botonParo = 3;
int estado1 = 0;
int estado2 = 0;
int estado3 = 0;

void setup()
{
pinMode(botonD, INPUT);
pinMode(botonI, INPUT);
ppinMode(botonParo, INPUT);
pinMode(enablePin, OUTPUT);
pinMode(in1A, OUTPUT);
pinMode(in2A, OUTPUT);
}

186
9. Control de motores con Arduino

void Derecha()
{
int Velocidad = analogRead(Pot);
Velocidad = map(Velocidad, 0, 1024, 0, 256);
digitalWrite(in1A, HIGH);
digitalWrite(in2A, LOW);
digitalWrite(enablePin, HIGH);
analogWrite(enablePin, Velocidad);
delay(50);
}

void Izquierda()
{
int Velocidad = analogRead(Pot);
Velocidad = map(Velocidad, 0, 1024, 0, 256);
digitalWrite(in1A, LOW);
digitalWrite(in2A, HIGH);
digitalWrite(enablePin, HIGH);
analogWrite(enablePin, Velocidad);
delay(50);
}

void Paro()
{
digitalWrite(in1A, LOW);
digitalWrite(in2A, LOW);
digitalWrite(enablePin, LOW);
}

void loop()
{
estado1 = digitalRead(botonD);
if (estado1 == HIGH)
{
Derecha();
}
estado2 = digitalRead(botonI);

187
Taller de Arduino

if (estado2 == HIGH)
{
Izquierda();
}
estado3 = digitalRead(botonParo);
if (estado3 == HIGH)
{
Paro();
}
}

Este programa controla el movimiento de un motor mediante tres


interruptores: izquierda, derecha y paro. Por otra parte, regulamos la velocidad
mediante un potenciómetro conectado en la patilla analógica A0. El esquema se
muestra en la figura 9.11

Figura 9.11

Te he mostrado cómo utilizar este circuito para controlar un motor. Si


quieres añadir otro motor (un vehículo tiene dos ruedas de tracción y cada una de
ellas necesita un motor) el control de dos motores es solo una cuestión de utilizar
el otro puente H que contiene el L293D.
El circuito que se ha construido en esta práctica solo es adecuado para el
control de motores pequeños. Motores de corriente continua de gran tamaño

188
9. Control de motores con Arduino

pueden ser controlados de manera similar con PWM, pero requieren


componentes que manejen mayores potencias, tal es el caso de los transistores
MOSFET. Es decir, habría que construir el puente o los puentes H con dispositivos
discretos basados en este tipo de transistores. La disipación de su potencia es
elevada por lo que vas a necesitar dotarlos de disipadores adecuados.

Diseña un proyecto basado en el L293D que te permita seleccionar


mediante interruptores o pulsadores, el sentido de giro de un motor
DC. Además, deberá poder regularse la velocidad de giro mediante
un potenciómetro o trimmer.

Diseña un proyecto que obtenga la temperatura de un sensor LM35 y


la muestre en cualquier tipo de LCD. Si la temperatura se hace mayor
que 30 °C se accionará un motor DC que no dejará de girar hasta que
dicha temperatura baje por debajo de los 25 °C.

9.4 Funcionamiento de un motor paso a paso (PAP)


Un motor paso a paso es un tipo especial de motor que puede moverse en una
serie de pasos discretos. Motores paso a paso son una buena opción para los
proyectos que requieren un movimiento controlado y preciso. Los proyectos
típicos incluyen las impresoras 3D, sistemas de posicionamiento del telescopio,
control numérico por computadora (CNC) de tornos, etc.
Como se comentó anteriormente, se pueden obtener motores paso a paso
de viejas impresoras de inyección de tinta o de las impresoras láser. En ellas, estos
motores se usan para mover los cabezales de impresión y para controlar la
alimentación del papel.
En la figura 9.12 se puede observar el aspecto del motor paso a paso que
utilicé para construirme este verano mi flamante impresora 3D tipo Prusa 2
(gracias a Obijuan y que la fuerza te acompañe…).
Los motores paso a paso se pueden clasificar en términos de la torsión que
pueden proporcionar. Como el par es proporcional a la longitud del cuerpo,
cuanto más largo sea el cuerpo, mayor será el par de torsión que pueden
desarrollar.
El ángulo de paso es también una forma de clasificarlos. Un motor paso a
paso con un ángulo de 9 grados requerirá 40 pasos para completar una vuelta
completa. El par o torque es una medida de la fuerza de rotación que un motor
puede proporcionar. A menudo se expresa en onzas-pulgadas o en kg/cm.

189
Taller de Arduino

El PAP de la figura 9.12 es un tipo NEMA 17 bipolar que tiene un ángulo de


paso de 1.8º (200 pasos por vuelta) y cada bobinado requiere 1.2 A a 4 V. Es capaz
de cargar con 3.2 kg/cm (44 oz-in).

Figura 9.12

Existen dos tipos principales de motores paso a paso: bipolares y


unipolares. Cada uno con sus propias ventajas y desventajas. Echemos un vistazo
a las diferencias entre ellos con la Tabla 9.3.

Unipolares Bipolares
Más sencillo de controlar. Más eficiente.
Menor coste. Mayor torque.
Cinco o seis conexiones
Cuatro conexiones de los cables.
de los cables.
Mayor velocidad de rotación Construcción más simple.
Tabla 9.3

La elección de un motor paso a paso puede ser un poco complicada


dependiendo de su uso previsto. Para los proyectos que requieran un alto par
extremadamente preciso, selecciona uno bipolar; para proyectos más simples, el
tipo unipolar es más barato y es una buena opción. Aunque hoy en día, los
motores bipolares se están volviendo más populares debido a la reducción en el
costo de los integrados necesarios para su control.
Echemos un vistazo a los pasos necesarios para identificar un tipo de
motor PAP y las conexiones del mismo. Si observamos el PAP que utilicé en mi
impresora 3D, averiguo a través de las características proporcionadas por el

190
9. Control de motores con Arduino

fabricante que posee un ángulo de paso de 1,8 grados y que requiere 1.2
amperios. Como tiene un ángulo de paso de 1,8 grados, podemos calcular el
número de pasos para completar una vuelta al dividir 360 grados por ese ángulo:

360 / 1,8 = 200 pasos.

Sobre la base de este cálculo, el motor paso a paso necesita 200 pasos para
completar una revolución. Además, el motor cuenta con cuatro cables de
conexionado por lo deduzco que es de tipo bipolar. Por otra parte, el color de
dichos cables es fundamental para conocer a que bobinas están conectadas. En la
figura 9.13 se observa el esquema interno de este motor bipolar y la disposición
de sus dos bobinas con los colores asociados a cada terminal.

Figura 9.13

En esta estupenda página disponemos de un tutorial muy clarito que


explica la teoría de dichos motores PAP: http://www.monografias.com/
trabajos37/motores/motores.shtml. En ella se nos muestra una técnica sencilla
basada en un polímetro para averiguar la polaridad de los terminales. La
usaremos cuando no dispongamos de esta información clave del motor porque la
impresora que hemos reciclado es muy vieja.
Pero no siempre es adecuado utilizar PAP bipolares. Podemos usar los PAP
unipolares mucho más baratos y más fáciles de encontrar en viejos aparatos
olvidados en el trastero. Vamos a verlos.
Los motores paso a paso unipolares (Figura 9.14) básicamente se
componen de dos bobinas con una derivación en el centro. Las derivaciones del
centro son llevadas fuera del motor como dos cables separados o conectados
entre sí internamente. Como resultado de esto, los motores unipolares tienen 5 o
6 cables. Independientemente del número de cables, los motores unipolares son
manejados de la misma manera. El cable de toma central (1,2) está ligado a una
fuente de alimentación y los extremos de las bobinas son llevados
alternativamente a tierra.

191
Taller de Arduino

Figura 9.14

Figura 9.15

La figura 9.15 muestra la sección transversal de un motor paso a paso


unipolar de 30 grados. El bobinado número 1 del motor se distribuye entre los polos
de la parte superior e inferior del estator, mientras que la bobina número 2 del
motor se distribuye entre los polos izquierdo y derecho del rotor. El rotor es un
imán permanente con seis polos, tres al norte y tres al sur, como se muestra en la
figura anterior. Para hacer girar un motor unipolar se aplican impulsos en secuencia
a sus devanados. La secuencia de estos impulsos se aplica con un controlador
electrónico externo como nuestro Arduino. Los motores unipolares se pueden hacer
avanzar a frecuencias de audio, lo que les permite girar muy velozmente. Este es el
motivo por el que se suele decir que un motor «gruñe», debido a la frecuencia a la
que se produce la conmutación. Con Arduino se les puede hacer arrancar y
detenerse en cualquier instante y en una posición determinada. Por otra parte, para
gobernar estos motores tenemos una ventaja respecto a los bipolares: no
necesitamos un L293, sino que utilizaremos un array de transistores Darlington
integrado (ULN2003A) que es sensiblemente más barato.
La idea al manejar un motor paso a paso Unipolar es ir «encendiendo» y
«apagando» las bobinas de a pares siguiendo una determinada secuencia, como
se muestra en la siguiente tabla, extraída de http://www.todorobot.com.ar/
informacion/tutorial%20stepper/stepper-tutorial.htm.

192
9. Control de motores con Arduino

9.4.1 Práctica 26: giro de un motor PAP unipolar


utilizando el ULN2003A
Muchas veces se rehúye del uso de los motores unipolares porque se piensa que
son difíciles de controlar. Tenemos enfrente los bipolares que nos hacen un guiño
amistoso para hacerse querer. Sin embargo, esto no es así. Vamos a realizar una
práctica que demuestra que todo es producto de falsos perjuicios. En este caso,
haremos girar un motor unipolar en un sentido durante una vuelta y, después,
otra vuelta en el sentido contrario.
Nos valdremos del ULN2003A cuyo aspecto es el mostrado en la figura 9.16.

Figura 9.16

Según el fabricante el terminal 1 (color rosa) y el 3 (color amarillo) forman


una bobina. El terminal 2 (color naranja) y el 4 (color azul) constituyen la otra
bobina del motor. El hilo que sobra es el común y debe ir a alimentación.
El listado del código se muestra a continuación:

Práctica 26. Control de un PAP Unipolar


/* Motor Unipolar y ULN2003A */
/* Cuidado con las conexiones que si se hace mal el motor ni
se inmuta */
int pin1=8;
int pin2=10;
int pin3=9;
int pin4=11;
int tiempo= 5;
int vuelta=2000;
int cuenta=0;

193
Taller de Arduino

void setup()
{
pinMode(pin1,OUTPUT);
pinMode(pin2,OUTPUT);
pinMode(pin3,OUTPUT);
pinMode(pin4,OUTPUT);
}
void loop()
{
digitalWrite(pin1,HIGH) ;
digitalWrite(pin2,HIGH) ;
digitalWrite(pin3,LOW) ;
digitalWrite(pin4,LOW) ;
cuenta++;
delay(tiempo);

digitalWrite(pin1,LOW) ;
digitalWrite(pin2,HIGH) ;
digitalWrite(pin3,HIGH) ;
digitalWrite(pin4,LOW) ;
cuenta++;
delay(tiempo);

digitalWrite(pin1,LOW) ;
digitalWrite(pin2,LOW) ;
digitalWrite(pin3,HIGH) ;
digitalWrite(pin4,HIGH) ;
cuenta++;
delay(tiempo);

digitalWrite(pin1,HIGH) ;
digitalWrite(pin2,LOW) ;
digitalWrite(pin3,LOW) ;
digitalWrite(pin4,HIGH) ;
cuenta++;
delay(tiempo);

194
9. Control de motores con Arduino

if (cuenta>=vuelta)
{
int aux=pin2;
pin2=pin4;
pin4=aux;
cuenta=0
}
}

Observamos que la secuencia que le enviamos al motor consta de 4 pasos.


Cada uno de ellos polariza las dos bobinas de una determinada manera para
mover el motor. Si no lo entiendes bien, estudia el tutorial anterior. Es importante
añadir que este tipo de motor en particular tiene 2000 pasos por vuelta. Para
cambiar el sentido de giro invertimos uno de los pares de la bobina (1-3 o 2-4).
Con la variable tiempo cambiamos la velocidad del PAP.
En la figura 9.17 observamos la práctica funcionado en Proteus. El IDE de
Arduino nos hace la vida más fácil y luminosa, incluyendo una librería estupenda
que nos evita confundirnos en las secuencias de los motores unipolares. Ahora la
aplicaremos en el control de los bipolares.

Figura 9.17

9.4.2 Librería “Steeper.h”: simplificando las cosas


El IDE de Arduino tiene un excelente soporte para motores paso a paso y
proporciona una librería denominada Steeper.h que se puede utilizar con este tipo
de motor, ya sea bipolar o unipolar. Esta librería presenta tres funciones

195
Taller de Arduino

principales que controlan la velocidad y dirección de la rotación del motor paso a


paso.
La primera de las funciones se llama Stepper() y ofrece dos posibilidades de
trabajo, dependiendo de los circuitos utilizados para controlar el PAP, ya que es
posible controlarlo utilizando solo dos pines del Arduino añadiendo componentes
adicionales. Estas son las dos posibilidades:

Stepper (number_steps, pin1, pin2)


Stepper (number_steps, pin1, pin2, pin3, pin4)

La variable number_steps es el número de pasos que el PAP necesita para


completar una revolución o vuelta, que, si no lo recuerdas, se puede calcular
dividiendo 360 entre el paso angular. Por ejemplo, si tienes un motor con un
ángulo de paso de 1,5 grados, el cálculo es la siguiente:

360 / 1,5 = 240 pasos.

Las variables pin1, pin2, pin3 y la opcional pin4 son los pines digitales del
Arduino que se utilizan para controlar el motor. La segunda función es la
denominada setSpeed(). Esta función, que es opcional, ajusta la velocidad del
motor de giro en revoluciones por minuto (RPM). Esta función, en realidad, no
activa el motor, pero sí establece la velocidad a la que girará cuando se inicializó
con la función anterior Stepper().

setSpeed(rpm)

La última función es la llamada step(). Esta función mueve el motor el


número de pasos especificados: un número negativo hace que el motor paso a
paso gire en un sentido. Un número positivo provoca que gire en el sentido
contrario.

steps(num_steps)

La velocidad a la que el motor PAP se mueve entre los pasos se


establece por la función setSpeed(). Cuando no utilizamos esta
función, el motor se moverá tan rápido entre los pasos como sea
capaz.

Ahora que ya has visto las funciones disponibles de la famosa librería,


vamos a usar el motor PAP en una práctica muy sencilla.

196
9. Control de motores con Arduino

9.4.3 Práctica 27: control básico de un PAP bipolar


utilizando el L293D
Utilizamos un ejemplo que viene contenido en el IDE de nuestro Arduino. Está
bajo la carpeta de ejemplos, en la subcarpeta Stepper y aparece con el nombre:
stepper_oneStepAtATime.
El hardware necesario para esta práctica es el siguiente:

 Un motor paso a paso (PAP).


 Una fuente de alimentación o batería externa de 12 V.
 El circuito integrado dual L293D.

El L293 puede trabajar con un PAP un bipolar o unipolar. En la práctica lo


haremos con uno bipolar. Este ejemplo es una estupenda manera de comprobar
que tu motor paso a paso está conectado correctamente.

Práctica 27. Probando el PAP


/* Diagnósticando las conexiones de un motor paso a paso. */
/* Si esto funciona ya podemos olvidarnos del hardware */

#include <Stepper.h>

const int pasosPorRevolucion = 200;


Stepper mypap(pasoPorRevolucion, 8, 9, 10, 11);
int pasoCont = 0;

void setup()
{
Serial.begin(9600);
}

void loop()
{
mypap.step(1);
Serial.print("pasos:" );
Serial.println(pasoCont);
pasoCont++;
delay(500);
}

197
Taller de Arduino

La primera línea del sketch carga la librería paso a paso. Ello es siempre
necesario porque incluso, aunque la librería se proporciona como parte del IDE de
Arduino, no es parte de su núcleo de librerías.

#include <Stepper.h>

A continuación, ajustamos el número de pasos de nuestro PAP, que en este


caso es de 200, aunque podría ser otro número dependiendo del motor que
tengas entre las manos. Además, definimos las patillas que van a controlarlo
desde el Arduino.

const int pasosPorRevolucion = 200


Stepper mypap(pasoPorRevolucion, 8, 9, 10, 11)

Durante el bucle de configuración, configuramos el puerto serie para que


podamos ver en el programa monitor del PC el número de pasos recorridos.

Serial.begin(9600)

En el bucle principal el motor paso a paso se mueve un paso a la vez. El


número de pasos se envía como salida al puerto serie visualizándose en el
programa monitor. La variable pasoCont se incrementa en 1, y tras una espera de
500 milisegundos, volvemos al principio del bucle y movemos el motor otro paso
más. Y así continuamente.

mypap.step(1);
Serial.print("pasos:" );
Serial.println(pasoCont);
pasoCont++;
delay(500);

Es el momento de observar el esquema (Figura 9.18) con las conexiones


entre el motor y Arduino.
Como se observa en la figura 9.18, los pines digitales 8 al 11 del Arduino se
utilizan para proporcionar las entradas de control del L293D. Los pines 1 y 9 del
L293D están ligados a la alimentación de 5 voltios de tal manera que los puentes
H del integrado siempre están habilitados (cuando se controló el motor de
corriente continua, se utilizaron estos pines para proporcionar el control PWM
cambiando de estado alto a bajo).

198
9. Control de motores con Arduino

El Pin 8 del L293D proporciona la alimentación del motor. En este caso es


de 12 V. Es un valor habitual en los motores bipolares empleados en impresoras
3D. El PAP conecta una de sus bobinas a los pines de salida 3 y 6, y la otra a los
pines 11 y 14 del chip L293D.

Si utilizamos un motor paso a paso unipolar habría que conectar la


toma central de las bobinas a tierra como hemos visto antes.

Usa la función setSpeed() para variar la velocidad de un PAP


mediante un potenciómetro conectado a una entrada analógica A0
del Arduino.

Figura 9.18

9.4.4 Práctica 28: utilizando la librería “Stepper.h”


en un PAP unipolar
Realicemos una práctica que haga girar un motor PAP unipolar mediante los pines
digitales 7, 8, 9 y 10 siguiendo la posición de un potenciómetro conectado al pin
analógico 5. Utilicemos la librería Stepper.h.
El hardware necesario para esta práctica es el siguiente:
 Un motor paso a paso (PAP) Unipolar ST-28
 Una fuente de alimentación o batería externa de 9 V.
 El circuito integrado ULN2003A.

199
Taller de Arduino

Práctica 28. Control básico de un PAP unipolar


/* Control básico de un motor Unipolar */
/* Vamos con los unipolares que son más baratos */
#include <Stepper.h>
#define STEPS 2000
int previo = 0;
void setup()
{
stepper.setSpeed(30);
}
void loop()
{
int val = analogRead(5);
stepper.step((val - previo/5);
previous = val;
}

El esquema dibujado y simulado en Proteus se muestra en la figura 9.19.

Figura 9.19

Diseña un proyecto en el que gobiernes el motor PAP unipolar de un


parabrisas de un coche. Considera un ángulo de 120º de movimiento
en los dos sentidos.

200
9. Control de motores con Arduino

9.5 Funcionamiento de un servomotor (SERVO)


Los servomotores son muy comunes en el mundo del aeromodelismo ya que son
excelentes para controlar los alerones en pequeños aviones o timones en los
barcos radio-controlados. Un servomotor es un motor con un engranaje en el que
se puede controlar un ángulo de giro (por lo general entre 0 y 180 grados).
Normalmente es alimentado por una tensión pequeña de aproximadamente 5
voltios. Debido a su bajo costo y su sencillez de control, son ideales para utilizar
en una amplia variedad de proyectos que requieran un movimiento preciso.
Un servomotor (Figura 9.20) tiene tres conexiones: tierra, alimentación y
una conexión de control o señal. El cable de alimentación suele ser rojo y debe ser
conectado a 5 V. El cable a tierra es normalmente de color negro o marrón. El
cable de señal es generalmente de color amarillo, naranja o blanco y debe ser
conectado a un pin digital del Arduino. La señal de control actúa directamente
sobre el ángulo de giro del servomotor. Y lo hace mediante la recepción de un
pulso. El ancho del pulso indica el valor del ángulo de giro del servo entre 0 y 180
grados. El pulso tiene que ser repetido cada 20 milisegundos o el motor volverá a
una posición arbitraria. La figura 9.21 muestra la relación entre el ancho de pulso
y el ángulo de servo.

Figura 9.20

Examinado la figura 9.21, la posición neutra o centrada para un servo es de


90 grados. Es obtenida con una anchura de impulso de 1,5 milisegundos. El ancho
de pulso oscila aproximadamente entre 1,0 milisegundo y 2,0 milisegundos,
situando el servomotor con un ángulo de 0 grados para el primer ancho de pulso y
180 grados para los 2 ms.

9.5.1 Librería “Servo.h”: simplificando las cosas


Del mismo modo que en el IDE de arduino disponíamos de una librería para manejar
los motores PAP, ahora tenemos otra librería denominada “Servo.h” que nos ayudará
a controlar un servomotor. De hecho, esta librería nos proporciona la capacidad de
controlar hasta 12 servomotores en un Arduino UNO y la friolera de 48 con el Mega.
Las funciones proporcionadas por la biblioteca Servo.h figuran en la Tabla 9.4.

201
Taller de Arduino

Figura 9.21

Función Descripción
Servo miServo Crea un objeto miservo.
«pin» es la patilla de control desde el
arduino al servomotor. Los parámetros
attach(pin)
«min» y «max» son los valores mínimo
attach(pin,min, max)
y máximo, en microsegundos, de los
valores de la anchura del pulso.
Establece el ancho de pulso del servo en
writeMicroseconds(pulse_width)
microsegundos.
Establece el ángulo de rotación del
write(angle)
servo en grados.
Devuelve el último ancho de pulso
read()
expresado en grados.
Devuelve el último ancho de pulso
readMicroseconds()
expresado en microsegundos.
Asocia la variable Servo a un pin de
attach()
control.
Desasocia la variable Servo de su pin de
control. Si todas las variables Servo son
detach()
desasociadas, entonces los pines 9 y 10
se pueden usar para salidas PWM.
Tabla 9.4

202
9. Control de motores con Arduino

En los tipos de Arduino que no sean el Mega, el uso de esta librería


deshabilita la funcionalidad analogWrite() (PWM) en las patillas 9 y
10, exista o no, un servo conectado en esos pines. De ahí la
importancia de la función detach() descrita en la Tabla 9.4.

9.5.2 Práctica 29: control básico de un SERVO


Utilizamos de nuevo un ejemplo que viene contenido en el IDE de nuestro
Arduino. Está bajo la carpeta de ejemplos, en la subcarpeta Servo y aparece con el
nombre: sweep.
El hardware necesario para esta práctica es el siguiente:

 Un servomotor tipo Futaba S35 de rotación continua.


 Una fuente de alimentación o batería externa de 5 V (opcional).

Para un servo modelo S35/STD de GWS el fabricante recomienda pulsos de


0,9 ms para conseguir el giro en el sentido de las agujas del reloj; pulsos de 1,5 ms
para bloquear el motor en una posición y mantenerlo parado, y pulsos de 2,1 ms
para que gire en el sentido antihorario. También hay que controlar la duración del
período, que es el tiempo total de la zona activa de la señal y la zona inactiva. La
duración del período recomendada para conseguir una velocidad óptima está
entre 16 y 23 ms. Para conectar el motor en un Arduino tendremos en cuenta los
colores de los cables de conexión del motor. El cable marrón para GND, el cable
rojo a 5 V y el cable amarillo para el pin de control digital.
Si quieres profundizar un poco más en esta librería te recomiendo que le
eches un vistazo al siguiente enlace: http://arduino.cc/es/Reference/Servo.

Práctica 29. Control básico de un Servo


/* Control básico de un Servo. */
/* Jugueteando con un servomotor */
#include <Servo.h>
Servo miservo;
int pos = 0;
void setup()
{
miservo.attach(9);
}

203
Taller de Arduino

void loop()
{
for(pos = 0; pos < 180; pos += 1)
{
miservo.write(pos);
delay(10);
}
for(pos = 180; pos>=1; pos-=1)
{
miservo.write(pos);
delay(10);
}
}

La primera línea del sketch carga la librería Servo.h. Ello es siempre


necesario porque incluso, aunque la librería se proporciona como parte del IDE de
Arduino, no es parte de su núcleo de librerías.
#include <Servo.h>

A continuación, se crea un objeto Servo llamado miservo.


Servo miservo

En el bucle de configuración se define el pin digital 9 del Arduino como pin


de control de nuestro servomotor.
myservo.attach(9)

En el bucle principal, el código barre el servomotor de 0 a 180 grados con


un retraso de 15 milisegundos entre cada nueva posición para dar tiempo al
servomotor a trasladarse al nuevo ángulo. A continuación, el servomotor se barre,
a la inversa, desde 180 hasta 0 grados; de nuevo, con un retraso de 15
milisegundos entre cada movimiento.
{
for(pos = 0; pos < 180; pos += 1)
{
miservo.write(pos);
delay(15);
}

204
9. Control de motores con Arduino

for(pos = 180; pos>=1; pos-=1)


{
miservo.write(pos);
delay(15);
}
}

Vamos a pasar ahora a construir el esquema de conexionado entre Arduino


y el servo (Figura 9.22).

Figura 9.22

Aunque es posible alimentar el servomotor desde el Arduino para


proporcionarle voltaje, se recomienda alimentarlo con una fuente de
alimentación externa.

Realiza un proyecto que controle dos servomotores de tal manera


que uno gire en un sentido, mientras que el otro servo lo haga en
sentido contario.

9.6 ¡Más caña con el motor brushless!


El motor de corriente continua típico DC ha estado vigente durante muchos años.
Pero ahora le ha salido un serio competidor: el motor brushless. Su producción en

205
Taller de Arduino

masa ha bajado rápidamente el precio de estos motores de alta eficiencia. De


hecho, se pueden ver «volando» en los extraños «drones» (cuadricópteros) que
amenazan con invadir nuestro espacio aéreo en los próximos años.
Comparados con los motores de continua clásicos, los motores sin
escobillas o brushless ofrecen más par, son más eficientes, ofrecen una mayor
fiabilidad y han reducido el ruido eléctrico. Una desventaja es que requieren un
controlador más especializado que un motor DC, a pesar de que son fáciles de
controlar. Estos motores a menudo son etiquetados con un valor de KV, que es el
RPM teórico por voltio al que un motor puede girar. Por ejemplo, en un motor de
mercado de 2400 kV que esté alimentado a 6 voltios, la velocidad máxima del
motor a la que podría girar sería:
6 x 2.400 = 14.400 RPM.
Los motores sin escobillas son de dos tipos: inrunner y outrunner. En un
motor inrunner solo el eje interior gira; con un motor outrunner, la capa exterior
gira también. Los motores inrunner tienden a tener una mayor kV y menos par,
mientras que los de tipo outrunner tienden a ser más bajos en cuanto a su valor en
kV pero ofrecen un par más alto. En las figuras 9.23 y 9.24 se muestran ambos tipos.

Figura 9.23. Motor inrunner

Figura 9.24. Motor outrunner

Los motores inrunner tienden a ser utilizados para cualquier vehículo. En


cambio, los motores outrunner, normalmente, se utilizan en aeromodelismo con
modelos de aviones y helicópteros. Para alimentar estos motores, es necesario

206
9. Control de motores con Arduino

utilizar baterías diseñadas para suministrar altos valores corriente. Estas pueden
ser NiCd, NiMH o de litio POLYMORE (LiPo).
Los controladores o variadores (Figura 9.25) de este tipo de motores se
denominan ESCs (electronic speed controllers) y hay que prestar atención al tipo
de motores que queremos controlar debido a que no disponemos de un
controlador universal que valga para cualquier tipo de motor.
Una de las mejores ventajas de este tipo de controladores es que pueden
ser gobernados de la misma manera que los servomotores. Esto significa que
podemos utilizar la misma librería Servo que en el apartado anterior. Al igual que
los servomotores, esperan un pulso cada 20 milisegundos con una anchura de
entre 1,0 y 2,0 milisegundos.

Figura 9.25

Con 1,0 milisegundos de pulso tendremos la velocidad más baja y con 2,0
milisegundos, la más alta. Seleccionado un pulso de 1,5 milisegundos provocamos
la parada del motor. Cuando un motor y su controlador se encienden por primera
vez, por motivos de seguridad, el motor esperará un tiempo antes de empezar a
girar. La forma de conectar el motor a Arduino se muestra en la figura 9.26. En la
figura 9.27 se observa un batería LIPO típica.

Figura 9.26

207
Taller de Arduino

Figura 9.27

9.6.1 Práctica 30: control básico de un motor brushless


El listado del programa es casi el mismo que el de la práctica 29 salvo la adición de
un impulso de arranque para permitir que el hardware ESC estabilice el motor.
El hardware necesario para esta práctica es el siguiente:
 Un motor brushless tipo outrunner de 1000 kV (Figura 9.28).
 Un variador de velocidad ESC.
 Una fuente de alimentación o batería externa de 12 V.

Figura 9.28

Características del motor


Modelo: A2212/13. Bateria:2-3 Li-Poly (11.1V). RPM/V:1000 RMP/V. Eficiencia
máxima: 80 %. Eficiencia máxima: 4-10 A (>75 %). Corriente sin carga: 10 V a 0,5 A.
Corriente máxima: 12 A/60 segundos. Resistencia interna: 90 mΩ. Dimensiones:
27.5 x 30 mm. Diámetro del eje: 3.17 mm. Peso: 47 gramos.

Práctica 30. Control básico de un motor sin escobillase en un sentido de


giro
/* Control básico de un motor outrunner en un solo sentido de
giro. */
/* Sujetar bien el motor porque gira de manera muy rápida… */
#include <Servo.h>
Servo miservo;

208
9. Control de motores con Arduino

int pos = 0;
void setup()
{
miservo.attach(9);
miservo.write(pos);
delay(1000);
}
void loop()
{
for(pos = 0; pos < 180; pos += 1)
{
miservo.write(pos);
delay(15);
}
for(pos = 180; pos>=1; pos-=1)
{
miservo.write(pos);
delay(15);
}
}

Estas dos funciones establecen un pulso de inicio para inicializar el motor.

myservo.write(pos);
delay(1000);

Cuidado con el precio de los cargadores de las baterías que


acompañan a este tipo de motores. Suelen ser caras (>80 euros).

Escribe un programa que controle la velocidad de un motor y su


sentido de giro en los dos sentidos.

9.7 Haciéndolo todo más fácil con las shields


Como vimos anteriormente las shields extienden funcionalidad al Arduino. Existen
muchos tipos de shields dedicadas al control de motores. Vamos a examinar una

209
Taller de Arduino

de ellas; me parece la más documentada, es razonable en cuanto al precio (unos


27 euros) y fácil de conseguir.
Se denomina: Arduino Motor Shield Rev3 (Figura 9.29). Se trata de la shield
oficial del equipo de Arduino por lo que tendremos abundante información en su
página web.
La Arduino Motor Shield se basa en el L298 que es un controlador de puente
H dual diseñado para manejar grandes cargas inductivas como relés, solenoides,
DC y motores paso a paso. Te permite conducir dos motores de corriente continua
con tu placa Arduino, además del control de la velocidad y la dirección de cada
uno de forma independiente. También se puede medir el consumo de corriente
del motor de cada motor, entre otras características.

Figura 9.29

Características
 Voltaje de funcionamiento 5 V a 12 V.
 Controlador del motor L298P, dos motores DC o 1 motor paso a paso.
 Max 2 A por canal o 4 A máx (con fuente de alimentación externa).
 Detección de corriente 1.65 V A.
 Función de freno.

Esta shield tiene dos canales separados denominados A y B donde cada uno
usa 4 de los pines de Arduino para conducir y sensar el motor. Se puede utilizar
cada canal por separado para conducir dos motores DC o combinarlos para
conducir un motor paso a paso. Los cables de la figura deben conectarse bien a la
placa según el par de bobinas o según los colores que se indican: bobina 1 (cables
azul y rojo), bobina 2 (cables negro y azul). Mira en las características de tu motor
si los colores son diferentes.

210
9. Control de motores con Arduino

Los pines son divididos por cada canal y se muestran en la siguiente Tabla 9.5.

Función Pines Canal A Pines Canal B


Dirección D12 D13
PWM D3 D11
Brake D9 D8
Current Sensing A0 A1
Tabla 9.5

Además, tiene dos pines de alimentación exterior para el motor a los cuales
conectaremos una batería externa. La conexión ente esta placa y un motor bipolar
se muestran en la figura 9.30. En el siguiente enlace tienes toda la información
oficial de esta shield: http://arduino.cc/en/Main/ArduinoMotorShieldR3.

Figura 9.30

9.7.1 Práctica 31: utilizando la Arduino Motor Shield


Vamos a realizar una práctica utilizando esta shield para controlar un motor paso
a paso bipolar utilizando la librería Stepper.h.
El hardware necesario para esta práctica es el siguiente:

 Un motor PAP bipolar.


 Una Arduino Motor Shield.
 Una fuente de alimentación o batería externa de 9 V.

Práctica 31. Control de un motor bipolar utilizando la Arduino Motor Shield


/* Control de un motor bipolar utilizando una shield.*/
/* El motor gira una vuelta en un sentido y otra vuelta en el
contrario.*/

211
Taller de Arduino

/* Merece la pena gastarse 27 euros en esta placa……*/


#include <Stepper.h>
#define motorPasos 200
#define motorPin1 13
#define motorPin2 12
Stepper miStepper(motorPasos, motorPin1,motorPin2);
void setup()
{
const int pwm_cha = 3;
const int pwm_chb = 11;

pinMode(pwm_cha, OUTPUT);
pinMode(pwm_chb, OUTPUT);

digitalWrite(pwm_cha, HIGH);
digitalWrite(pwm_chb, HIGH);

myStepper.setSpeed(100);
Serial.begin(9600);
}
void loop()
{
Serial.println("En un Sentido");
miStepper.step(200);
delay(500);

Serial.println("En el otro");
miStepper.step(-200);
delay(500);
}

En el siguiente enlace se puede visualizar un vídeo en el que explico con


detalle el sketch anterior: http://www.youtube.com/watch?v=KSfRjcf1JTk.
Además, podemos ver el motor bipolar funcionando.
En resumen, aconsejo encarecidamente usar este tipo de shields para
controlar los motores DC, los PAP y Servos porque es muy sencillo y nos ahorra
cableado. Sobre todo, en el caso de que queramos motorizar un pequeño robot u
otro tipo de vehículo.

212
CAPÍTULO

BUSES DE DATOS

El Arduino se puede comunicar con otros dispositivos utilizando lo que denomina:


buses de datos. Los dos tipos de protocolos más extendidos de buses de datos
hardware son el I2C (bus de circuitos integrado) y el SPI (interfaz serie de
periféricos). En el mercado existe una amplia gama de sensores y dispositivos que
utilizan estos tipos de protocolos de comunicación.

10.1 El bus I2C


El bus I2C, también conocido como interfaz de dos hilos (two Wire Interface) o
abreviadamente: bus TWI es una forma simple de comunicar estos dispositivos
mediante dos cables. El Arduino proporciona este tipo de bus a través de dos de
sus patillas llamados SDA y SCL (Figura 10.1)

Figura 10.1

En el protocolo I2C el Arduino es considerado como dispositivo maestro


(master) y cada uno de los otros dispositivos externos I2C como esclavos (slaves).
Cada esclavo tiene su propia dirección expresada como un número hexadecimal
que permite al Arduino direccionarlo para comunicarse con él. Cada dispositivo
tiene un rango posible de direcciones dadas por su fabricante. La dirección
particular que escogemos es determinada a nivel de conexionado, estableciendo
el estado lógico de los pines de dirección como se verá más adelante.

213
Taller de Arduino

Para usar el bus I2C necesitamos, como en otras ocasiones, incluir en


nuestro sketch una librería. En este caso será: Wire.h (viene incluida en el IDE).

#include <Wire.h>

Después, en el bucle de configuración, activamos el bus I2C mediante la


función:

Wire.begin();

El dato es transmitido en paquetes de un byte. Para enviar un byte de datos


desde el Arduino al bus precisamos tres funciones:
La primera inicializa la comunicación con la dirección del dispositivo
esclavo.

Wire.beginTransmission(dirección);

La segunda función envía un byte (dato) desde nuestro Arduino al


dispositivo esclavo previamente direccionado.

Wire.write(dato);

Finalmente, una vez que hemos de enviar datos al esclavo, utilizamos la


siguiente función para acabar la trasmisión.

Wire.endTransmission();

Si ahora queremos solicitar datos desde el dispositivo esclavo al Arduino,


debemos escribir las siguientes dos funciones:

Wire.beginTransmission(dirección)
Wire.requestFrom(dirección,x)

Donde x es el número de bytes que deseamos leer. Para leer los datos que
vienen es necesario utilizar una variable de la siguiente manera:

Dentrada = Wire.read();

Donde Dentrada es la variable que almacenará ese dato. Finalizaremos la


trasmisión utilizando:

Wire.endTransmission();

214
10. Buses de datos

La mejor manera de entender y asimilar lo expuesto es realizar un proyecto


para clarificar el uso de este protocolo de comunicación tan extendido.

10.1.1 Práctica 32: utilización de la memoria I2C 24LC512


El Arduino tiene una memoria EEPROM interna para guardar datos de forma
segura. Sin embargo, esta memoria solo puede guardar 1.024 bytes como
máximo. En muchas aplicaciones esta capacidad es insuficiente. Por ello, podemos
echar mano de una memoria externa EEPROM de tipo I2C. En esta práctica
usaremos la EEPROM 24LC512 (Figura 10.2) fabricada por Microchip Technology.
Presenta una capacidad de 64 kB (65,536 bytes) que es más que suficiente en
proyectos de nivel básico o medio.

Figura 10.2

Utilizaremos esta memoria para guardar y recuperar posteriormente 20


datos aleatorios. Se trata de observar simplemente cómo funciona este protocolo.
En cuanto al hardware que necesitamos:

 Una memoria I2C EEPROM 24LC512.


 Dos resistencias de 4.7 kΩ (pull-up).
 Un condensador cerámico de 100 nF.

Las resistencias pull-up son necesarias siempre que utilicemos este tipo de
bus.
Antes de nada, vamos a echar un vistazo al esquema (Figura 10.6) porque
en este caso es importante estudiarlo antes de examinar el sketch.
En el circuito diseñado bajo Proteus observamos que hemos añadido dos
instrumentos virtuales que nos permiten profundizar en el funcionamiento del
bus I2C. Se trata de un instrumento virtual (Figura 10.3) para visualizar en tiempo
real el estado lógico del bus, lo que simplifica mucho su lectura. El analizador del
protocolo I2C te permite controlar e interactuar con el bus I2C. El analizador tiene
dos propósitos: primero, permitir que veamos los datos enviados por el bus I2C; y
segundo, proporciona una forma de enviar datos al bus, ya sea como maestro o
como dispositivo esclavo. Esto hace que sea muy valioso, tanto como instrumento

215
Taller de Arduino

de depuración sino también, para desarrollar y probar nuestras propias rutinas de


I2C.

Figura 10.3

Figura 10.4

Como segundo instrumento virtual tenemos el terminal virtual serie (Figura


10.4) que conectado a las líneas serie TX y RX, visualiza mensajes de
comprobación de funcionamiento del programa. La localización de estos dos
instrumentos virtuales se detalla en la siguiente figura 10.5.

Figura 10.5

Por otra parte, durante la elaboración del presente libro, ha aparecido en la


red un nuevo modelo del Arduino (versión 3) para usar con Proteus. Este modelo
presenta importantes mejoras gráficas con respecto a la librería anterior. Se
puede descargar gratuitamente del siguiente enlace:

216
10. Buses de datos

http://blogembarcado.blogspot.com.es/2012/02/
simulino-simulando-arduino.html
Te recomiendo que te los descargues y lo integres en Proteus
reemplazando la otra librería. Sin duda, está bastante bien elaborado a nivel
gráfico. Aunque nuestra EEPROM externa puede almacenar hasta 64 kB de datos,
nuestra práctica tiene solo la intención de demostrar un poco su uso, así que
vamos a almacenar y recuperar bytes solo en las primeras 20 posiciones de
memoria de la EEPROM.

Figura 10.6

Práctica 32. Utilizando una memoria I2C


/* Ejemplo básico del uso de la EEPROM 24LC512 */
/* Aumentando la capacidad de la memoria interna del Arduino */
#include <Wire.h>
#define memoria 0x50
unsigned int pointer;
byte d=0;
void setup()
{
Serial.begin(9600);
Wire.begin();
}

217
Taller de Arduino

void writeDato(int dispo, unsigned int address, byte dato)


{
Wire.beginTransmission(dispo);
Wire.write((byte)(address >> 8));
Wire.write((byte)(address & 0xFF));
Wire.write(dato);
Wire.endTransmission();
delay(10);
}
byte readDato(int dispo, unsigned int address)
{
byte result;
Wire.beginTransmission(dispo);
Wire.write((byte)(address >> 8));
Wire.write((byte)(address & 0xFF));
Wire.endTransmission();
Wire.requestFrom(dispo,1);
result = Wire.read();
return result;
}
void loop()
{
Serial.println("Escribiendo datos...");
for (int a=0; a<20; a++)
{
writeDato(memoria,a,a);
}
Serial.println("Leyendo datos...");
for (int a=0; a<20; a++)
{
Serial.print("Posición de la EEPROM ");
Serial.print(a);
Serial.print(" Guarda ");
d=readDato(memoria,a);
Serial.println(d, DEC);
}
}

218
10. Buses de datos

Examinamos el listado anterior. Primero activamos la librería y definimos la


dirección del bus I2C de la EEPROM como memoria.

#include <Wire.h>
#define memoria 0x50 // 0101 0000

Las entradas A0, A1 y A2 son utilizadas por la 24LC512 para establecer la


dirección única del dispositivo dentro del bus I2C. Los niveles lógicos de estos
pines definen parte de la dirección elegida por el usuario. La otra parte de la
dirección viene establecida de fábrica. En nuestro caso, la parte fija es 1010 y
como los pines A0, A1 y A2 están a cero (porque así lo cableamos), la dirección
completa es: 1010 000. En la figura 10.7 se observa el formato completo.

Figura 10.7

También vemos que utiliza un bit de comienzo (Star Bit): bit que indica si
queremos leer o escribir en el dispositivo (R/W). Otro bit llamado de
reconocimiento nos indicará si la trasmisión ha ido bien (Acknowledge Bit).
Por si te pierdes un poco, o para profundizar más en este tipo de protocolo,
te recomiendo que acudas al siguiente enlace:

http://www.comunidadelectronicos.com/articulos/i2c.htm

Las dos funciones personalizadas WriteDato() y readDato() se incluyen para


ahorrar tiempo y las podremos reutilizar siempre que utilicemos este tipo de
memorias. Sirven para escribir y leer datos. La función WriteDato() inicia la
transmisión con la EEPROM y envía la dirección en donde almacenar el byte de
datos en la EEPROM. La función readDato() opera en el bus I2C de la misma
manera que WriteDato(), pero en lugar de enviar un byte de datos a la EEPROM,
se utiliza la función Wire.requestFrom() para consultar los datos. Por último, el
byte de datos enviado desde la EEPROM es recibido en una variable (result) y se
convierte en el retorno de la función.

219
Taller de Arduino

Prestar especial atención a estas dos líneas de código que actualizan


constantemente la dirección de la memoria:

Wire.write((byte)(address >> 8));


Wire.write((byte)(address & 0xFF));

En el bucle principal se escribe 20 veces el valor o dato en direcciones


consecutivas de la memoria EEPROM. A continuación, se realiza un bucle de
nuevo, recuperando los valores y mostrándolos en el instrumento terminal virtual
(Figura 10.8).
En la figura 10.9 se observa al analizador I2C funcionado. Nos presenta
mucha información valiosa de la comunicación I2C. Es una herramienta fabulosa
para analizar este tipo de circuitos. No quiero pensar en lo que tendríamos que
gastarnos para adquirir su equivalente en hardware.

Figura 10.8

Figura 10.9

220
10. Buses de datos

Por último, bajo Proteus tenemos la posibilidad de examinar el contenido


de la memoria EEPROM y comprobar si los 20 datos se han guardado
correctamente (Figura 10.10).

Figura 10.10

10.1.2 Práctica 33: expandiendo los puertos con el I2C MCP23017


Un «expansor» de puertos es otro integrado útil que se controla a través del bus
I2C. Está diseñado para ofrecer más salidas digitales. En este proyecto, vamos a
utilizar el MCP23017 (Figura 10.11) que permite expandir las salidas digitales de tu
Arduino (y así no te gastarás dinero en comprarte un Arduino Mega).

Figura 10.11

En esta práctica, vamos a conectar el MCP23017 a nuestro Arduino y


demostrar cómo controlar las 16 salidas de expansión del puerto. Cada una de las
salidas del expansor de puertos puede ser tratada como un pin digital normal de
salida del Arduino. En cuanto al hardware que necesitamos:

 Un MCP23017 (es barato: < 3 Euros).


 Dos resistencias de 4.7 kΩ.
 Algunos diodos leds y resistencias de 200 Ω.

221
Taller de Arduino

Antes de nada, vamos a echar un vistazo al esquema (Figura 10.12).

Figura 10.12

Los dieciséis puertos de E/S se distribuyen en dos puertos A y el B. Las


resistencias pull-up externas de 4.7 K deben utilizarse en el bus I2C
obligatoriamente. Por otra parte, tenemos la dirección de hardware de los tres
pines (15 a 17). Estos se utilizan para determinar la dirección del bus I2C. Si todos
ellos se conectan a GND, la dirección del dispositivo que nosotros elegimos es:
0×20 (hexadecimal).
Ahora examinaremos cómo utilizar este integrado. La mayoría de los
dispositivos I2C tienen varios registros que se pueden configurar. Cada dirección
contiene un byte de datos que determina varias opciones. Así que antes de usarlo
necesitamos establecer si cada puerto es una entrada o una salida. Vamos a
establecer los dos puertos como salidas. Para ello escribimos:

Wire.beginTransmission(0x20);
Wire.write(0x00); // Acceso Registro A IODIRA.
Wire.write(0x00); // Pone todos los pines del puerto A
como salidas.
Wire.endTransmission();

222
10. Buses de datos

Wire.beginTransmission(0x20);
Wire.write(0x01); // Acceso Registro B IODIRB.
Wire.write(0x00); // Pone todos los pines del puerto B
como salidas.
Wire.endTransmission();

Dentro del bucle principal controlamos directamente los pines de cada


puerto utilizando el siguiente trozo de programa:

Wire.beginTransmission(0x20);
Wire.write(0x12); // Dirección del puerto A.
Wire.write(valor); // Valor de envío.
Wire.endTransmission();

Wire.beginTransmission(0x20);
Wire.write(0x13); // Dirección del puerto B.
Wire.write(valor); // Valor de envío.
Wire.endTransmission();

Las direcciones de los dos registros internos A y B son la 0x12 y 0x13


El siguiente sketch reúne todo lo anterior para realizar un encendido
secuencial y curioso de los 16 diodos leds conectados a nuestro Arduino tal y
como se observa en la figura 10.12.
Práctica 33. Ampliando los pines digitales del Arduino
/* Utilización básica del MCP23017. */
/* Por pines que no sea... */
#include "Wire.h"
void setup()
{
Wire.begin();
Wire.beginTransmission(0x20);
Wire.write(0x00);
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x01);
Wire.endTransmission();
}

223
Taller de Arduino

void ContajeBina()
{
for (byte a=0; a<256; a++)
{
Wire.beginTransmission(0x20);
Wire.write(0x12);
Wire.write(a);
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x13);
Wire.write(a);
Wire.endTransmission();
}
}
void loop()
{
ContajeBina();
delay(500);
}

Como podrás observar el código muestra un contaje secuencial en los


diodos LED mediante la estructura for.

10.1.3 Práctica 34: midiendo el tiempo con el I2C DS1307


Cuando necesitemos utilizar el dato del tiempo en nuestros proyectos con
Arduino tendremos que usar un integrado especializado en esta tarea. Se me
ocurre plantear una medida de temperaturas que se muestre junto al tiempo en
que se ha realizado para proporcionar una mayor información y contrastarla en
un histograma.

EL integrado RTC DS1307 es un reloj de tiempo real con batería de respaldo


(RTC = Real Time Clock) que permite al Arduino mantener tiempo; hora y fecha,
aun si el circuito electrónico en el que se encuentra se queda sin energía. Es
perfecto para llevar registro de datos, de tiempo, temporizadores y alarmas, etc.
Un reloj de tiempo real (RTC) es básicamente un reloj que funciona con una
batería y mantiene la hora, incluso cuando hay un corte de energía. El uso de un
RTC puede realizar un seguimiento durante largos plazos de tiempo.

224
10. Buses de datos

Arduino tiene incorporado un reloj interno llamado millis que es utilizado por
la función millis(). Esta función solo realiza un seguimiento del tiempo transcurrido
desde la última vez que se usó Arduino. Esto significa que cuando la alimentación se
enciende, el temporizador de milisegundos se ajusta a 0. Nuestro Arduino no sabe
que es «lunes» o «09 de abril»; lo único que puede decir es «Hace 14.000
milisegundos desde la última vez que me encendí». Si deseamos ajustar la hora en
el Arduino sin tener el módulo DS1307, tendríamos que establecer y programar la
fecha y hora para que empiece a contar desde ese momento. Pero dejamos sin la
alimentación al Arduino, no nos quedaría más remedio que reajustar la hora. Al
igual que los relojes de alarma muy baratos: cada vez que pierden la alimentación
quedan parpadeando con la hora en 12:00. Si bien este tipo de cronometraje básico
está bien para algunos proyectos, algunos proyectos tales como registradores de
datos, relojes, etc. tendrán que tener un cronometraje consistente que no se
desprograme cuando dejamos al Arduino sin alimentación. El integrado RTC se
especializa en mantener la noción del tiempo. Se pueden contar años bisiestos y
saber en qué día o mes estamos. Una desventaja es que no puede registrar el
cambio de hora por el horario de verano o invierno. En la figura 10.12 y 10.13 se
muestra una plaquita que trae incorporada el integrado DS1307
(www.bricogeek.com) junto con la batería necesaria (la pila dura unos 9 años con lo
que no debemos preocuparnos demasiado por ella). Es muy útil adquirirla de esta
manera para evitar conexionado.

Figura 10.12 Figura 10.13

Vamos con la práctica que consistirá en mostrar la fecha y la hora en un LCD


utilizando nuestro Arduino. Lo primero que tenemos que hacer es descargarnos e
instalar la librería RTClib para hacernos la vida más fácil.

https://github.com/adafruit/RTClib

225
Taller de Arduino

El siguiente paso es configurar nuestro RTC con la fecha y hora actual. En este
punto, es necesario tener la fecha correcta de nuestro PC, ya que será la que se
establecerá en el RTC. Para esto, compilaremos y cargaremos el siguiente código. Es
de vital importancia que compilemos y carguemos el código con la mayor rapidez
posible entre un paso y otro, porque cuando compilamos se genera un archivo “.hex”
con su fecha de modificación y es esta fecha la que se cargará en el RTC.

Práctica 34.a. Ajuste del RTC


/* Ajuste de la fecha actual en el RTC DS1307. */
/* Igualito que en el despertador de nuestro dormitorio.*/
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 RTC;
void setup ()
{
Wire.begin();
RTC.begin();
RTC.adjust(DateTime(__DATE__, __TIME__));
}
void loop ()
{
}

La función RTC.adjust(DateTime(__DATE__, __TIME__)) es la que toma la


fecha de tu PC y al ajusta en el DS1307. Una vez cargado el código anterior,
cargamos lo que es código de funcionamiento propiamente dicho.

Práctica 34.b. El DS1307 mostrando la fecha y la hora en un LCD


/* Mostrando la fecha y la hora actual en el LCD. */
/* Ya tenemos construido un reloj básico. */
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal.h>
RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

226
10. Buses de datos

void setup ()
{
lcd.begin(16, 2);
Serial.begin(9600);
Wire.begin();
RTC.begin();
}
void loop ()
{
lcd.clear();
DateTime now = RTC.now();
lcd.setCursor(1,1);
lcd.print(now.year(), DEC);
lcd.print ('/');
lcd.print (now.month(), DEC);
lcd.print ('/');
lcd.print (now.day(), DEC);
lcd.print (' ');
lcd.print (now.hour(), DEC);
lcd.print (':');
lcd.print (now.minute(), DEC);
lcd.print (':');
lcd.print (now.second(), DEC);
lcd.println ();
delay(1000);
}

Como vemos en el listado anterior, todo se reduce a utilizar la función


RTC.now() que nos averigua la fecha actual contenida en el DS1307 para después
mostrarla ordenadamente en el LCD.

El esquema en Proteus se muestra en la Figura 10.14.

Diseña un proyecto que muestre en un LCD, la temperatura medida


con un sensor LM35 junto con la fecha y la hora en que se ha
realizado.

227
Taller de Arduino

Figura 10.14

10.2 El bus SPI


El bus SPI difiere del bus I2C en que se puede utilizar para enviar los datos y
recibirlos desde un dispositivo de forma simultánea y a diferentes velocidades. La
comunicación, sin embargo, es también del tipo maestro-esclavo. El Arduino actúa
como maestro y determina qué dispositivo (el esclavo) se comunicará con él a la
vez. Cada dispositivo SPI utiliza cuatro pines (Figura 10.15) para comunicarse con
un maestro: MOSI (Master-Out, Slave-In), MISO (Master-In, Slave-Out), SCK
(reloj), y SS o CS (Slave Select o Selección de chip). Estos pines SPI están
dispuestos en el Arduino como se muestra en la Figura 10.16.

Figura 10.15

228
10. Buses de datos

Figura 10.16

Una típica conexión de un dispositivo SPI con el Arduino es las que se


muestra en la Figura 10.7. Los pines D11, D12 y D13 están reservados para la
comunicación SPI, pero el pin SS se puede utilizar como cualquier otro pin digital.
Veamos ahora cómo implementar este protocolo en Arduino. En primer
lugar, añadimos la librería SPI.h (incluida con el IDE de Arduino).

#include "SPI.h"

A continuación, tenemos que elegir un pin que se utilizará para SS y


configurarlo como un pin digital de salida. Debido a que estamos utilizando solo
un dispositivo SPI en nuestro ejemplo, vamos a utilizar D10 y configurarlo HIGH
primero, porque la mayoría de los dispositivos SPI tienen un pin SS activo LOW.

pinMode (10, OUTPUT)


digitalWrite (10, HIGH)

Esta es la función para activar el bus SPI:

SPI.begin ()

Por último, tenemos que establecer la forma de enviar y recibir datos.


Algunos dispositivos SPI requieren que sus datos sean enviados junto con el bit
más significativo (MSB) en primer lugar, y otros requieren que este bit MSB se
envíe al final del dato. Por lo tanto, usaremos la siguiente función después
SPI.begin():

SPI.setBitOrder (orden)

Aquí, el parámetro orden es bien MSBFIRST o MSBLAST.


Para enviar datos a un dispositivo SPI, primero establecemos el pin SS en
bajo (LOW) que advierte al Arduino que desea comunicarse con él. A

229
Taller de Arduino

continuación, enviaremos bytes de datos al dispositivo utilizando la función


siguiente:

SPI.transfer(byte)

Después de que se haya terminado la comunicación con el dispositivo,


establecemos el pin SS a HIGH para indicar al dispositivo SPI que el Arduino ha
finalizado la comunicación con él.

10.2.1 Práctica 35: utilizando el potenciómetro digital SPI AD5206


Los potenciómetros digitales son útiles cuando se necesita variar la resistencia en
un circuito electrónicamente, en lugar de manualmente. Existen multitud de
aplicaciones como el acondicionamiento de señales de audio y de generación de
tonos en las que se utilizan los potenciómetros digitales. En esta práctica vamos a
utilizar un potenciómetro digital de seis canales para controlar el brillo de seis
LED. Los pasos que cubriremos para implementar la comunicación SPI pueden ser
modificados para su uso con la mayoría de los otros dispositivos SPI.

El AD5206 es un potenciómetro digital de 6 canales. Esto significa que tiene


seis resistores variables (potenciómetros) en un circuito integrado. Hay tres pines
en el circuito integrado por cada uno de los seis resistores variables internos. Los
pines de cada resistor variable están etiquetados como AX. BX y WX. Ejemplo: A1,
B1 y W1
En esta práctica usaremos cada resistor variable como un divisor de
tensión; en un lado se conecta el pin de tensión alta (pin B), en el otro lado el pin
de tensión baja (pin A). El pin central (pin W) se conexiona como salida de la
tensión variable.

Figura 10.17

230
10. Buses de datos

El AD5206 (Figura 10.17) es controlado digitalmente usando SPI. El


dispositivo es habilitado poniendo el pin Chip Select (CS) a nivel bajo. Las
instrucciones se envían en códigos de operaciones (opcodes) de 10 bits con los
tres bits más significativos (10-8) definiendo la dirección del potenciómetro a
ajustar y los ocho bits menos significativos (7-0) estableciendo qué valor poner al
potenciómetro entre 0 y 255. La transferencia del código de operación empieza
con el bit más significativo MSB en el flanco de subida de la señal de reloj. En este
caso, el AD5206 proporciona una resistencia máxima de 10 kΩ, entregados en 255
pasos (255 siendo el máximo, siendo 0 el mínimo).
En esta práctica vamos a variar el brillo de seis leds de forma secuencial,
cambiando el valor de la resistencia de las patillas W1,W2,W3,W4,W5 y W6 del
integrado AD5206. En cuanto al hardware necesario:

 Un potenciómetro SPI AD5206 de 10 kΩ.


 6 diodos LED.

Práctica 35. Manejando un potenciómetro digital


/* El potenciómetro SPI y arduino */
/* Una manera de esquivar las resistencias */
#include <SPI.h>
const int slaveSelectPin = 10;
void setup()
{
pinMode (slaveSelectPin, OUTPUT);
SPI.begin();
SPI.setBitOrder(MSBFIRST);
}
void loop()
{
for (int channel = 0; channel < 6; channel++)
{
for (int level = 0; level < 255; level++)
{
digitalPotWrite(channel, level);
delay(10);
}

231
Taller de Arduino

delay(10);
for (int level = 0; level < 255; level++)
{
digitalPotWrite(channel, 255 - level);
delay(10);
}
}
}
void digitalPotWrite(int address, int value)
{
digitalWrite(slaveSelectPin,LOW);
SPI.transfer(address);
SPI.transfer(value);
digitalWrite(slaveSelectPin,HIGH);
}

Después de incluir e inicializar la librería Spi.h, entramos en dos bucles for


que van seleccionado cada canal y, progresivamente primero, envían valores
entre 0 y 255 y, después, entre 255 y cero. Con ello, la resistencia aplicada a los
diodos varía en intervalos de 10 ms. La función clave de este programa es la que
se muestra a continuación:

void digitalPotWrite(int address, int value)

Activamos el chip mediante la patilla 10 del Arduino conectada al pin SS del


AD5206. A continuación, le enviamos por SPI la dirección del canal sobre el que
deseamos actuar y el valor que debe tener su resistencia asociada. Finalmente
cerramos comunicación con el dispositivo enviando un nivel bajo por el pin SS.
El esquema de la práctica simulada con Proteus se muestra en la figura
10.18.

Diseña un proyecto basado en el sensor de temperatura SPI TC72 y


un LCD Serial. Puedes encontrar su hoja de características en el
siguiente enlace:

http://ww1.microchip.com/downloads/en/DeviceDoc/21743B.pdf

232
10. Buses de datos

Figura 10.18

233
CAPÍTULO

COMUNICACIONES
INALÁMBRICAS

Llegó la hora de ponerse serios y divertirse al mismo tiempo. Empezamos a


abordar el tema de comunicar nuestro Arduino con dispositivos
inalámbricamente, es decir, sin cables de por medio. Es realmente fascinante
poder controlar un robotito de esta manera. Y, de hecho, es el primer paso que
tenemos que dar, antes de aventurarnos con la programación en Android que
tanto está de moda hoy en día para controlar el Arduino desde nuestro teléfono
inteligente o tableta. Comencemos.

11.1 Comunicaciones inalámbricas XBee


Los módulos XBee son dispositivos que integran un transmisor-receptor del
protocolo de comunicaciones inalámbricas ZigBee y un procesador en un mismo
módulo, lo que le permite a los usuarios desarrollar aplicaciones de manera
rápida y sencilla. ZigBee es un protocolo de comunicaciones inalámbrico basado
en el estándar de comunicaciones para redes inalámbricas IEEE_802.15.4.
ZigBee permite que dispositivos electrónicos de bajo consumo puedan
realizar sus comunicaciones inalámbricas. Es especialmente útil para redes de
sensores en entornos industriales, médicos y, sobre todo, domóticas.
Las comunicaciones ZigBee se realizan en la banda libre de 2.4GHz. A
diferencia de bluetooth no utiliza FHSS (frequency hooping), sino que realiza las
comunicaciones a través de una única frecuencia, es decir, de un canal.
Normalmente puede escogerse un canal de entre 16 posibles. El alcance depende
de la potencia de emisión del dispositivo, así como el tipo de antenas utilizadas. El
alcance normal con antena en visión directa suele ser de aproximadamente 100 m
y en interiores de unos 30 m. La velocidad de transmisión de datos de una red
ZigBee es de hasta 256 kbps. Una red ZigBee la pueden formar, teóricamente,
hasta 65535 equipos, es decir, el protocolo está preparado para poder controlar
en la misma red esta cantidad enorme de dispositivos.

234
11. Comunicaciones inalámbricas

Los módulos XBee pueden tener distintos tipos de antenas (Figura 11.1), lo
cual incidirá directamente en la máxima distancia de trasmisión y recepción.
Los módulos XBee son económicos, potentes y fáciles de utilizar. Existen
dos series de estos módulos. La serie 1 y la serie 2. Los módulos de la serie 1 y la
serie 2 tienen el mismo patillaje e incluso la misma apariencia, sin embargo, NO
son compatibles entre sí, ya que utilizan distintos chipsets y trabajan con
protocolos diferentes.

Figura 11.1

Un tipo de módulo XBee que está de moda, en estos momentos, es el


que se muestra en la figura 11.2. Se referencia por: XBee Pro XBP24-AWI-00 y su
principal característica es su potencia de 60 mW. Pertenece a la Serie 1 (S1) y
trabaja a 2,4 GHz. Está fabricado por Digi Maxstream y produce una alta potencia
de salida. Los modelos Pro tienen el mismo patillaje y comandos AT que la serie
básica, pero ofrecen una salida con más potencia (60 mW). Funciona con la pila de
protocolo de protocolos 802.15.4 (la base de ZigBee) y trabaja mediante un simple
protocolo serial. Además, permite una comunicación bidireccional entre
microcontroladores, ordenadores o prácticamente cualquier cosa que disponga
de un puerto serie o Serie/USB.
Para la comunicación en parejas (punto a punto), es necesario
asegurarse de utilizar dos modelos de series iguales. Como es de la serie 1 no se
comunicará con modelos de la serie 2. Su precio ronda los 30 euros y claro está,
necesitamos dos módulos para establecer la comunicación a nivel de trasmisión y
recepción. Si adquirimos otro modelo distinto, hay que tener cuidado de que sea
de la serie 1 por el problema de incompatibilidad antes expuesto.
Características
 Alimentación: 3.3 V @ 215 mA.
 Velocidad de transferencia: 250 kbps Max.

235
Taller de Arduino

 Potencia de salida: 60 mW (+18 dBm).


 Alcance: 1500 metros aprox.
 Antena integrada.
 Certificado FCC.
 6 pines ADC de 10-bit.
 8 pines digitales IO.
 Encriptación 128-bit.
 Configuración local o de forma inalámbrica.
 Comandos AT o API.

Figura 11.2

Para comunicar el módulo XBee con nuestro Arduino recomiendo utilizar


una shield especifica (Arduino XBee Shield) mostrada en la figura 11.3. Además,
nos servirá, también, para utilizar los módulos bluetooth que abordaremos más
adelante.

Figura 11.3

236
11. Comunicaciones inalámbricas

11.1.1 Configuración de los módulos XBee


Antes de empezar cualquier proyecto de comunicación con estos módulos es
necesario configurarlos apropiadamente para que puedan comunicarse entre sí.
Para ello, utilizaremos el software X-CTU que proporciona el fabricante y que
podemos descargar gratuitamente del siguiente enlace:

http://www.digi.com/support/productdetail?pid=3352&type=utilities

Una vez descargado, lo ejecutamos y nos va a pedir su actualización en


línea. Aceptamos, y tras un cierto tiempo que tarda en descargar dicha
actualización, ya estamos preparados para trabajar con él.
Ahora cogemos nuestra placa Arduino y le quitamos el microcontrolador
con cuidado tal como se muestra en la figura 11.4.

Figura 11.4

Le insertamos la shield con el módulo XBee colocada y configuramos los dos


jumpers de la shield en posición USB tal y como se muestra en la figura 11.5. Estos
jumpers tienen dos posiciones: XBee/USB. La primera (XBee) hace trabajar al
módulo con la comunicación serie utilizando para ello los pines TX y RX. En la
segunda posición (USB) utiliza los pines TX y RX para comunicarse con el PC a través
del Arduino de tal manera que la trasmisión-recepción XBee queda inoperativa.

Figura 11.5

237
Taller de Arduino

Ahora conectamos el Arduino con la shield montada al PC y ejecutamos el


software X-CTU. Debería aparecer una pantalla como la figura 11.6 en la que
elegimos establecer comunicación serie con la placa Arduino situada en el COM
determinado por nuestro PC. Presionamos el botón: Test/Query y apuntamos el
número de serie (direcciones) de este módulo para utilizarlo más adelante.
A continuación, sacamos el primero de los módulos XBee e insertamos el
segundo realizando los mismos pasos para leer su número de serie que,
lógicamente, al venir de fábrica será diferente.
En mi caso, los dos números de serie son los siguientes:

XBee 1 : 13A20040331966 (dirección 1).


XBee 2 : 13A200403353b8 (dirección 2).

Figura 11.6

En un último paso haremos que ambos módulos «se vean», es decir, que se
puedan encontrar en la red inalámbrica y se puedan comunicar punto a punto.
Para ello, presionamos la opción: modem configuración y después: read (Figura
11.7).

238
11. Comunicaciones inalámbricas

Figura 11.7 Figura 11.8

Sobre la pantalla (Figura 11.8) tenemos que modificar tres cosas: primero,
debemos elegir un identificador de la red, para ello optamos por un ID cualquiera
con la obligatoriedad que sea el mismo en los dos módulos XBee (yo he elegido
«1234»). Después, debemos escribir en cada módulo la dirección destino del otro
módulo XBee. Es decir, en la configuración del módulo XBee 1 le ponemos la
dirección destino del módulo XBee 2, y viceversa. Obsérvese que la dirección está
compuesta de dos campos: uno es la parte alta de la dirección (es la misma en las
dos XBee) y otra es la parte baja de dicha dirección completa (aquí es donde es
diferente para cada uno de los módulos).
Por último, debemos elegir cuál de los módulos va a ser el coordinador de la
red y cuál va a ser router/end de la misma. Ello se hace como se muestra en la figura
11.9 teniendo en cuenta que se debe elegir la opción AT. Es decir, en la configuración
de un módulo, pondremos: coordinator AT y en el otro: router/end AT.
Como consejo para no confundirse, es conveniente pegar una etiqueta en
cada módulo con su dirección particular y su función de coordinador o de router.
Ahora ya tenemos los dos módulos XBee conectados interna e
inalámbricamente. A nivel, por así decirlo de software, todo lo que uno de los
módulos envíe con la fución: serialprint(), lo recibirá el otro de forma serial, como
veremos más adelante en las prácticas. Por último, volvemos a insertar el
microcontrolador en su placa Arduino.

239
Taller de Arduino

Figura 11.9

Es conveniente advertir que existen muchas más posibilidades de


configuración de los módulos XBee, dependiendo del tipo de red que deseemos
implementar. La que os he mostrado es una de las más simples denominada
punto a punto. Otro tipo de redes quedan fuera de alcance de este libro.

11.1.2 Práctica 36: aviso sonoro inalámbrico


En esta práctica vamos a probar la comunicación entre dos módulos XBee.
Necesitaremos dos Arduinos y dos módulos XBee con sus correspondientes
mochilas. Se trata de colocar en uno de ellos, al que llamaremos EMISOR, un
pulsador conectado a la patilla 2. Este Arduino emitirá una orden al terminal
RECEPTOR, en el que colocaremos un zumbador en la patilla o pin 5 y un led en la
patilla 13. El hardware que necesitamos es el siguiente:
 2 módulos XBee Pro XBP24-AWI-00 de 60 mW (configurados según el
apartado anterior).
 2 Arduinos.
 2 Shields XBee.
 Un diodo led.
 Una batería externa para alimentar el Arduino lejano.
 Un zumbador.
 Un pulsador.

240
11. Comunicaciones inalámbricas

 Una resistencia de 10 k.
 Una resistencia de 220 ohmios.

Los esquemas del circuito emisor y del circuito receptor se muestran en las
figuras 11.10 y 11.11, respectivamente.

Figura 11.10

Figura 11.11

241
Taller de Arduino

El listado de programa de ambos Arduinos se muestra a continuación:

Práctica 36a. Aviso sonoro con XBee. Parte del emisor


/* Aviso sonoro con XBee. Parte del emisor. */
/* Que corra el aire entre los dos Arduinos... */
int pulsador = 2;
void setup()
{
Serial.begin(9600);
pinMode(pulsador,INPUT);
}
void loop()
{
if(digitalRead(pulsador)==LOW)
{
Serial.print('A');
delay(100);
}
}

Examinado el listado, observamos que cuando presionamos el pulsador,


enviamos la letra «A» a través de la comunicación serial. Este dato viajará
inalámbricamente hasta el otro módulo XBee que está situado a cierta distancia
de nuestro PC (Figura 11.12).

Figura 11.12

Es decir, la comunicación entre los dos módulos XBee, se realiza de manera


serie utilizando sus propias funciones.

242
11. Comunicaciones inalámbricas

Serial.print('A')

Por ello, tras subir los diferentes sketch a los dos arduinos, es necesario
cambiar las posiciones de los jumpers al estado XBee para que se liberen los pines
TX y RX del arduino y los módulos puedan establecer dicha comunicación serie.

Práctica 36b. Aviso sonoro con XBee. Parte del receptor


/* Aviso sonoro con XBee. Parte del receptor. */
/* Que corra el aire entre los dos arduinos… */
int buzzer=5;
int led= 13;
void setup()
{
Serial.begin(9600);
pinMode(buzzer,OUTPUT);
pinMode(led,OUTPUT);
}
void loop()
{
if(Serial.available()>0)
{
if(Serial.read() == 'A')
{
digitalWrite(buzzer,HIGH);
delay(10);
digitalWrite(buzzer,LOW);
digitalWrite(led,HIGH);
delay(20);
digitalWrite(led,LOW);
}
}
}

En el programa del Arduino receptor, y tras la configuración, se testea si el


canal serie está disponible mediante la función:

if(Serial.available()>0)

243
Taller de Arduino

Si es así, lo leemos y averiguamos si lo que nos ha llegado es el carácter


«A». En caso de que sea verdadero, activamos el zumbador y encendemos el LED
durante 100 ms; en caso de que sea falso, regresamos al principio del bucle para
volver a testear el dato que nos llega.

if(Serial.read() == 'A')
{
digitalWrite(buzzer,HIGH);
delay(10);
digitalWrite(buzzer,LOW);
digitalWrite(led,HIGH);
delay(100);
digitalWrite(led,LOW);
}

En la figura 11.13 se observa el circuito completo simulado con Proteus.


Aprovechamos que este software puede simular dos Arduinos a la vez para
realizar este proyecto. Cada uno de los Arduinos tiene cargado su sketch
correspondiente al emisor y receptor. Se ha añadido un componente denominado
terminal virtual, para visualizar el envío a través de la comunicación serial. Los dos
Arduinos se comunican a través de dos conectores RX y TX teniendo en cuenta
que deben estar cruzados.

Figura 11.13

244
11. Comunicaciones inalámbricas

11.1.3 Práctica 37: visualización remota de temperaturas


En esta práctica registraremos temperaturas a través de un sensor LM35
conectado a un Arduino que puede estar perfectamente en la terraza de nuestra
vivienda. Visualizaremos dichas temperaturas en otro Arduino que está situado,
por ejemplo, en el salón de nuestra casa. Ambos Arduinos están alimentados
independientemente con dos baterías externas. Utilizaremos un LCD serial para
observar las temperaturas. El hardware que necesitamos es el siguiente:

 2 módulos XBee Pro XBP24-AWI-00 de 60mW.


 2 Arduinos.
 2 Shields XBee.
 Un LM35.
 Dos baterías externas para alimentar los arduinos.
 Un LCD serial.

Los esquemas del circuito emisor y del circuito receptor se muestran en las
figuras 11.14 y 11.15. El Arduino emisor está en el exterior, midiendo temperatura
que envía a través de XBee al Arduino receptor, que nos las muestra
cómodamente en un LCD.
El listado de programa de ambos Arduinos se muestra a continuación:

Figura 11.14

245
Taller de Arduino

Figura 11.15

Práctica 37a. Visualización remota de temperaturas. Parte del emisor


/* Visualización remota de temperaturas usando un LM35 y
XBee. */
/* Proyecto apropiado para no pasar frío. */
float tempC;
int tempPin = 0;
void setup()
{
Serial.begin(9600);
}

void loop()
{
tempC = analogRead(tempPin);
tempC = (5.0 * tempC * 100.0)/1024.0;
Serial.print(tempC);
delay(5000);
}

246
11. Comunicaciones inalámbricas

El tratamiento del LM35 ya se ha visto anteriormente. Solo aclarar que la


temperatura procedente del sensor se capta a través de la entrada A0 del
Arduino.

Práctica 37b. Visualización remota de temperaturas. Parte del receptor


/* Visualización remota de temperaturas usando un LCD y XBee. */
/* Proyecto apropiado para no pasar frío. */
#include <SoftwareSerial.h>
#include <serLCD.h>
serLCD miLcd(9);
float tempC;
void setup()
{
Serial.begin(9600);
miLcd.clear();
}
void loop()
{
if(Serial.available()>0)
{
tempC= Serial.read()
miLcd.setCursor(1,1);
miLcd.print(tempC);
delay(10);
}
}

Utilizamos la librería SoftwareSerial porque los pines TX y RX están


ocupados en la comunicación serie. Esta librería nos permite habilitar un pin
digital cualquiera de nuestro Arduino para realizar la trasmisión serie con el LCD.
Puedes utilizar la nueva librería NewSoftwareSerial en su lugar, sin mayores
cambios de código.

En la figura 11.16 se observa el circuito completo simulado con Proteus.


Aprovechamos que este software puede simular dos Arduinos a la vez, para
realizar este proyecto. Cada uno de los Arduinos tiene cargado su sketch

247
Taller de Arduino

correspondiente al emisor y receptor. Los dos Arduinos se comunican a través de


dos conectores RX y TX teniendo en cuenta que deben estar cruzados.

Figura 11.16

Te propongo realizar un proyecto que controle inalámbricamente un


motor DC. Deberás regular la velocidad y gobernar el sentido de giro
del motor a través de interruptores y de un potenciómetro.

11.2 Comunicaciones inalámbricas bluetooth


Bluetooth es un estándar de tecnología inalámbrica. Proporciona una manera de
intercambiar datos en distancias cortas utilizando las transmisiones de radio de
onda corta en la banda de 2400 a 2480 MHz. Permite crear PAN (Personal Área
Networks) con un cierto nivel de seguridad. Se lleva a cabo en varios tipos de
dispositivos, como ordenadores, teléfonos inteligentes, sistemas de sonido que
pueden leer audio digital desde una fuente remota, etc.
Existe un tipo de Arduino que implementa nativamente esta tecnología. Se
le denomina Arduino BT y se suministra ahora con un ATmega328 y un módulo

248
11. Comunicaciones inalámbricas

Bluegiga WT11 Bluetooth. La página de referencia es http://www.arduino.cc/


en/Main/ArduinoBoardBluetooth.
En mi opinión, la mejor manera de proceder en muchos proyectos es
utilizar un tipo de arduino «base» como el Arduino UNO o Mega e ir añadiendo
funcionalidades a medida que crezcan nuestras necesidades. Por ello, creo que es
mejor adquirir módulos y shields en este sentido. Es por ello que vamos a utilizar
el Arduino UNO con un módulo bluetooth externo. Además, el Arduino BT es
bastante caro (ronda los 70 euros).
El módulo que vamos a utilizar es el llamado Bluetooth Bee (Figura 11.17). Es
un pequeño módulo bluetooth que es compatible con los zócalos de la shield XBee y
que está diseñado para transmitir datos de forma inalámbrica de un punto a otro.

Figura 11.17

El módulo respeta los pines originales de los XBee por lo que se puede
conectar directamente como sustituto. Tiene una antena incorporada que
permite un alcance de unos 10 metros aproximadamente o hasta un máximo de
30 metros en espacio abiertos. Se comporta como un puerto serial y dispone de
comandos AT para cambiar el baudrate.
Características
 Chip Bluetooth: CSR BC41714
 Protocolo Bluetooth: Bluetooth v2.0 + EDR.
 Protocolo USB: v1.1/2.0.
 Frecuencia de funcionamiento: 2.4 ~ 2.48GHz.
 Modulación: GFSK.
 Potencia: 4dBm, Clase 2.
 Distancia: 20 a 30 m en espacios abiertos (normalmente 10 m).
 Seguridad: Autenticación y encriptación.
 PIN para emparejamiento: 1234.
 Alimentación: 3.3 V (50 mA).

249
Taller de Arduino

El módulo inalámbrico Bluetooth BEE es adaptable con las shields XBEE. El


patillaje es compatible con XBEE y es adecuado para todo tipo de sistemas de
microcontroladores que proporcionan 3.3 V. Los módulos Bluetooth BEE vienen
con una antena integrada que proporciona una mejor calidad de señal. Actúa
como un puerto serie transparente que trabaja como una variante de un
adaptador de bluetooth como, por ejemplo, un teléfono bluetooth. El BTBEE es
solo un módulo esclavo. La comunicación entre los dos BTBEE no funcionará.
BTBEE tiene un pequeño interruptor utilizado para configurarlos con
comandos AT. Para esta versión actual el modo AT solo se puede utilizar para
comprobar si el módulo BTBEE es capaz de comunicarse o no. La velocidad de
comunicación por defecto, cuando viene de fábrica, es de 38400 bps. Para testear
los módulos BTBEE es necesario establecer el pequeño interruptor del módulo
BTBEE al modo AT tal que como muestra en la Figura 11.8.

Figura 11.18

Los comandos AT son instrucciones codificadas que conforman un


lenguaje de comunicación entre el hombre y un terminal modem.
En un principio, el juego de comandos AT fue desarrollado en 1977
por Dennis Hayes como un interfaz de comunicación con un módem
para así poder configurarlo y proporcionarle instrucciones, tales
como marcar un número de teléfono. Más adelante, con el avance
del baudio, fueron las compañías Microcomm y US Robotics las que
siguieron desarrollando y expandiendo el juego de comandos hasta
universalizarlo. Los comandos AT se denominan así por la
abreviatura de attention. Aunque la finalidad principal de los
comandos AT es la comunicación con módems, la telefonía móvil
GSM también ha adoptado como estándar este lenguaje para poder
comunicarse con sus terminales. De esta forma, todos los teléfonos
móviles GSM poseen un juego de comandos AT específico que sirve

250
11. Comunicaciones inalámbricas

de interfaz para configurar y proporcionar instrucciones a los


terminales. Este juego de instrucciones puede encontrarse en la
documentación técnica de los terminales GSM y permite acciones
tales como realizar llamadas de datos o de voz, leer y escribir en la
agenda de contactos y enviar mensajes SMS, además de muchas
otras opciones de configuración del terminal. Queda claro que la
implementación de los comandos AT corre a cuenta del dispositivo
GSM y no depende del canal de comunicación a través del cual
estos comandos sean enviados, ya sea cable de serie, canal
infrarrojos, bluetooth, etc.

11.2.1 Configuración de los módulos bluetooth Bee


En este apartado vamos a ver cómo configurar estos módulos. No disponemos de
una aplicación similar a X-CTU que nos facilitaba mucho el trabajo con los
módulos XBee. Sin embargo, vamos a abordar este asunto de una forma sencilla y
abreviada.
Tan pronto la conectamos al ordenador y por USB, la shield con el
módulo Bluetooth Bee insertado, abrimos el icono Bluetooth de nuestro PC y
agregamos un dispositivo tal y como se muestra en la figura 11.19. Si pulsamos
en el icono que representa nuestro módulo, nos aparece otra ventana en la
que elegimos el código de emparejamiento (Figura 11.20) que es necesario,
igual que en los teléfonos móviles, para establecer la comunicación entre el PC
y dicho módulo. Este código es, por defecto, el 1234. Hecho esto, se nos
mostrará una ventana de confirmación (Figura 11.21). A continuación,
presionamos en la ventana de propiedades del dispositivo para cambiar
algunas características (Figura 11.22).

Figura 11.19 Figura 11.20

251
Taller de Arduino

Figura 11.21

Figura 11.22

En las propiedades de hardware (Figura 11.23) observamos el puerto serie


al que está conectado y que debemos recordarlo para el futuro. Cambiamos
también aquí la velocidad de comunicación del bluetooth del PC para emparejarla
con la del módulo Bluetooth Bee.
Finalmente, utilizamos el programa Hyperterminal que podemos descargar
de la red para establecer la comunicación con comandos AT. Para probar si el
BTBEE está funcionando o no (asegúrate de que el interruptor del módulo está en

252
11. Comunicaciones inalámbricas

la posición AT), envía la palabra AT al módulo BTBEE desde el Hyperterminal. Si


todo es correcto, observarás un OK (Figura 11.24).

Figura 11.23

Figura 11.24

Ya hemos comprobado el correcto funcionamiento del módulo. Ahora ya


podemos usarlo en nuestros proyectos. Solo debemos cambiar la posición del
interruptor (Figura 11.25) y la velocidad de trasmisión, que será de 9600 baudios.
Un LED se encenderá en este modo de trabajo.

253
Taller de Arduino

Figura 11.25

Evidentemente, ahora se nos abre todo un mundo de posibilidades. Tanto


los teléfonos móviles como las tabletas, tan de moda hoy en día, disponen de una
conexión bluetooth. Si dispones del sistema operativo Android podemos diseñar
aplicaciones para gobernar el Arduino con todo lo que ello conlleva. Este tema es
tan amplio que sobrepasa las expectativas de este libro, pero si quieres
profundizar en ello, existen en la red multitud de tutoriales al respecto.

254
CAPÍTULO

ARDUINO Y EL
INTERNET DE
LAS COSAS

En los capítulos anteriores, se mostró cómo se puede recibir información visual


con Arduino mediante la comunicación con las pantallas LCD. Imagínate si se
pudiese enviarla a lo largo de Internet para que todo el mundo la pudiese ver. ¿Y
si pudieras controlar tu Arduino de forma remota? O incluso, que tu Arduino de
forma remota pudiera hablar con tu PC. En la sección previa observamos la
comunicación de Arduino a través de I2C, Bluetooth y el SPI. Ahora abordaremos
proyectos de la comunicación a través de Internet.
El Internet de las Cosas (IOT), consiste en que las cosas tengan conexión a
Internet en cualquier momento y lugar. En un sentido más técnico, consiste en la
integración de sensores y dispositivos en objetos cotidianos que quedan
conectados a Internet a través de redes fijas e inalámbricas. De esta manera,
cualquier objeto es susceptible de ser conectado y «manifestarse» en la red.
Además, el IOT implica que todo objeto puede ser una fuente de datos. Esto está
empezando a transformar la forma de hacer negocios, la organización del sector
público y el día a día de millones de personas.
Tomar una taza de café con solo poner un tweet no es ciencia ficción, es
una realidad. Las películas de ciencia ficción que nos trasladaban a futuros lejanos
donde todo era controlado por pequeños dispositivos son ya un reflejo, en parte,
de situaciones que experimentamos en nuestra vida cotidiana. Esto es debido al
concepto «Internet de las cosas» (Internet of Things) gracias al cual nuestros
gadgets más apreciados como un smartphone, un ordenador portátil, una tableta
y, como no, nuestro Arduino, se convierten en un control remoto o un pequeño
monitor de actividades que refleje y manipule las acciones de los objetos que se
encuentran a nuestro alrededor.
Internet de las cosas está cada vez más presente en nuestro día a día. En
el entorno laboral ha tenido aplicaciones tan peculiares e imaginativas como la

255
Taller de Arduino

del frigorífico Drink Time Sheet de la empresa JWT Brasil. Los empleados de
dicha empresa vieron cómo tomaba una nueva dimensión tener completado su
registro de horas dedicadas a sus proyectos, cuando al completarlo en su
totalidad, el frigorífico desbloqueaba su cierre y les ofrecía bebidas gratuitas
para celebrarlo.
La conexión e interacción con dispositivos es uno de los puntos fuertes de
Arduino ya que permite crear prototipos que interactúen con el ordenador, con
un smartphone, con una impresora, etc. No hace falta ser un programador o
desarrollador experimentado para utilizar nuestro Arduino en el nuevo entorno
de Internet de las cosas. Por otra parte, Internet de las cosas y la tecnología
Arduino están abriendo un cúmulo de posibilidades que aportan una nueva
dimensión a los recursos y conversaciones que generan los medios sociales.
Arduino y los medios sociales han hecho buenas migas. De hecho, muchos de los
proyectos desarrollados con tecnología de código abierto con Arduino han
incluido una parte de interacción con Twitter o Facebook.
Unos ejemplos serían, por ejemplo, una máquina expendedora de refrescos
que funciona con la publicación de un tweet o con un hashtag predeterminado
por la propia empresa de bebidas o una mano construida con Lego que se ilumina
cuando se realiza un like en Facebook. También se han creado dispositivos
orientados a negocios como la hostelería, que permiten crear vínculos con la
comunidad en medios sociales, como un dispositivo adaptado a una panadería
con el cual es posible conocer mediante Twitter cuándo salen del horno las
hornadas de pan, pasteles… El panadero selecciona cuál es el producto que ha
sido recién horneado y, al pulsar el botón correspondiente, se tuitea. De esta
forma, el cliente conoce cuándo puede comprar en su panadería preferida su
producto recién hecho.
En definitiva, el objetivo ideal de la IOT sería lograr que cualquier
objeto tenga «vida propia» y, con ello, una identidad. Si todos los objetos
cotidianos estuvieran equipados con etiquetas de radio, podrían ser
identificados y gestionados de forma automática de la misma manera que si
lo hiciesen seres humanos. Básicamente, si los objetos pasan a estar
conectados pueden interactuar en red, entre ellos o con personas, ya sea
enviando y recibiendo información o realizando determinadas acciones en
función de los datos disponibles. Algo que abre posibilidades ilimitadas, y no
solo en el marketing.
Pero regresemos al principio del tema. Empecemos por lo básico: cómo conectar
nuestro Arduino a la red utilizando una shield muy cómoda: la Ethernet shield.

256
12. Arduino y el Internet de las cosas

12.1 Características de la Arduino Ethernet shield


Uno de los medios de comunicación más potentes disponibles con Arduino es
Ethernet. Ethernet es un estándar de red que permite que todos los tipos de
dispositivos se comuniquen entre sí mediante el envío y la recepción de flujos de
datos (llamados paquetes). Ethernet es extremadamente rápido y robusto, la
transmisión de los datos de ida y vuelta a través de la red se realiza sin apenas
errores. Cada dispositivo de la red obtiene un identificador único llamado
dirección IP que permite que los dispositivos se comuniquen a través de los
diferentes protocolos de Internet. Arduino facilita la configuración de la
comunicación por Internet usando la shield Ethernet y la librería Ethernet. Pero
antes de exponeros los aspectos de esta librería, vamos a echar un vistazo a
algunos conceptos claves de redes (Tabla 12.1).

Término Descripción

Ethernet es una tecnología de red estandarizada que describe


una forma de comunicación entre ordenadores y otros
Ethernet
dispositivos de red para enviarse información de ida y vuelta
a través de una red física cableada.

Los protocolos establecen el lenguaje de comunicación


propiamente dicho. Para que dos dispositivos se comuniquen,
ambos deben estar hablando el mismo lenguaje o protocolo.
Por ejemplo, el Protocolo de transferencia de hipertexto
(HTTP) es un protocolo común que vamos a usar para
Protocolo
configurar el Arduino como un servidor web. La utilización del
protocolo HTTP establecerá un lenguaje que permite al
servidor web de Arduino comprender mensajes y atender a
las solicitudes de los clientes web como el navegador web
(Mozilla, Explorer, etc.) de tu ordenador.

Una dirección Media Access Control (MAC) es un identificador


único asignado a Ethernet y a otros dispositivos de red. La
dirección MAC permite que los dispositivos se identifican de
Dirección MAC
forma única con el fin de comunicarse con otros dispositivos.
Tu shield Ethernet para Arduino vendrá con una etiqueta
proporcionándole una dirección MAC exclusiva.

257
Taller de Arduino

Término Descripción

Protocolo de control de transmisión (TCP) y Protocolo de


TCP/IP
Internet (IP) son protocolos de Internet.

Una dirección IP es una dirección única que los dispositivos y los


servidores utilizan para identificarse a través de Internet. Por
Dirección IP ejemplo, cuando vas a un sitio web como www.arduino.com,
Internet utiliza el servicio de nombres de directorio (DNS) para
traducirlo en una dirección IP numérica: 209.84.148.39.

Las direcciones IP locales son similares a las direcciones IP


normales, pero están utilizando, específicamente, la
Dirección Local IP comunicación entre ordenadores y dispositivos en una red
local. Por ejemplo, cuando configuras una red en casa, a cada
equipo de esa red casera se le asigna una IP local.

Tabla 12.1

La Shield Ethernet original fue un hito para la plataforma Arduino,


permitiendo proyectos de comunicación a través de redes y a través de Internet.
Implementada con el chip W5100 Wiznet Ethernet, proporciona una pila de
protocolos de red con TCP y UDP a través de una Ethernet de 10/100 Mb. La
mochila tiene un conector estándar RJ45 que permite una conexión estándar con el
módem, router u otros dispositivos de red. La versión más moderna de esta shield
(Figura 12.1 y Figura 12.2) añade una ranura para la tarjeta microSD. Esto significa
que se pueden leer y almacenar archivos. Pero es importante observar que el chip
W5100 y la tarjeta SD se comunican con el Arduino mediante el bus SPI. Esto es
importante porque significa que no pueden usar ambos a la vez.

Figura 12.1

258
12. Arduino y el Internet de las cosas

La shield actual tiene una alimentación a través de Ethernet (PoE) que es un


módulo diseñado para extraer energía de un tipo de cable Ethernet de par
trenzado Categoría 5. También dispone de un conector RJ45 para conectarse a
una red Ethernet. El botón de reinicio sirve para reiniciarla. Añade una serie de
LED informativos que son muy útiles cuando las cosas no funcionan.

Figura 12.2

Estos LED son los siguientes:

 PWR: indica que Arduino y la mochila están alimentados.


 LINK: indica la conexión a una red y parpadea cuando la mochila
transmite o recibe datos.
 FULLD: indica que la conexión de red es full-duplex.
 100M: indica la presencia de una conexión de red 100 Mb/s (en lugar
de 10 Mb/s).
 RX: parpadea cuando recibe datos.
 TX: parpadea cuando envía datos.
 COLL: parpadea cuando se detectan colisiones de red.

El puente de soldadura INT puede conectarse para permitir que la placa


Arduino reciba interrupciones y sean notificadas desde W5100, pero esta opción
no está en la librería estándar de Ethernet. El puente conecta el pin INT del
W5100 para pin digital 2 de Arduino.

259
Taller de Arduino

Figura 12.3

Para usar la shield solo hay que montarla sobre nuestro Arduino (Figura
12.3). Para cargar el sketch se conecta al ordenador por el cable USB. Una vez que
este ha sido cargado, se puede desconectar del ordenador y alimentarla desde el
exterior. También podemos conectarla a un ordenador, a un switch o a un
enrutador utilizando un cable ethernet estándar (CAT5 o CAT6 con conectores
RJ45).

12.1.1 La librería Ethernet


La librería Ethernet viene incluida con el IDE de Arduino y te permite configurar tu
mochila Ethernet para comunicarte con el mundo exterior. Puedes configurar
hasta cuatro servidores concurrentes y clientes (en total). El servidor se configura
de tal manera que primero acepta conexiones entrantes de clientes, y luego envía
y recibe datos. Por otra parte, un cliente primero hace conexiones salientes al
servidor y luego puede enviar datos y recibirlos desde el servidor. Vamos a echar
un vistazo a la Tabla 12.2 que proporciona una visión general de las funciones
disponibles en esta librería Ethernet.

Término Descripción

Ethernet.begin(mac) Inicializa la librería con la dirección MAC de la


Ethernet.begin(mac, ip) shield y la dirección IP obtenida automática-
Ethernet.begin(mac, mente mediante DHCP. En caso de que nuestro
ip, gateway) router no disponga de servicio DHCP, se puede
Ethernet.begin(mac, añadir la IP manualmente, así como la dirección
ip, gateway,subnet) de la puerta de enlace.

Crea un servidor para escuchar en un


Server(port)
determinado puerto.

260
12. Arduino y el Internet de las cosas

Término Descripción

Server.begin() Inicializa el servidor.

Obtiene un cliente que esté conectado al


Server.available()
servidor y posea datos disponibles para lectura.

Server.write() Envía datos a todos los clientes conectados.

Imprime datos a todos los clientes conectados al


servidor. Imprime números como secuencia de
Server.print() dígitos, cada uno como carácter ASCII (ejemplo:
el número 34 es enviado como los dos
caracteres '3' y '4').

Imprime datos, como en la función anterior,


Server.println()
pero añade una línea nueva.

Crea un cliente que pueda conectarse a la IP


Client(ip, port)
especificada por su dirección y el puerto.

Devuelve verdadero si el cliente está conectado.


Si la conexión está cerrada, pero algunos datos
Client.connected()
están todavía sin leer, sigue devolviendo
verdadero.

Inicializa la conexión. Retorna verdadero si se


Client.connect() estableció la conexión, en caso contario
devuelve falso.

Client.write() Escribe datos en el servidor.

Imprime datos al servidor. Imprime números


como secuencia de dígitos, cada uno como
Client.print()
carácter ASCII (ejemplo: el número 34 es
enviado como los dos caracteres '3' y '4').

Imprime datos, como en la función anterior,


Client.println()
pero añade una línea nueva.

Devuelve el número de bytes disponibles para


Client.available() ser leídos (el número de bytes enviados desde el
servidor).

261
Taller de Arduino

Término Descripción

Client.read() Lee el siguiente byte recibido desde el servidor.

Client.stop() Desconecta del servidor.

Tabla 12.2

Con los fundamentos de Ethernet, la librería de Ethernet y su


correspondiente shield, ya estamos casi preparados para iniciar nuestro primer
proyecto de conexión de Arduino a Internet. Sin embargo, como vamos a
construir un servidor web bajo Arduino, debemos exponer antes algunos
conceptos relativos a esto, para no perdernos más adelante cuando
profundicemos en la práctica.
Lo que vamos a crear con el Ethernet Shield es un servidor web. Nos
proporcionará el código HTML para poder verlo en nuestro navegador y poder así,
interactuar con él. Pero ¿qué es un servidor web? En Internet, un servidor (Figura
12.4) es un ordenador remoto que provee los datos solicitados por parte de los
navegadores de otros ordenadores. En redes locales (LAN), se entiende como el
software que configura un PC como servidor para facilitar el acceso a la red y sus
recursos.

Figura 12.4

Los servidores almacenan información en forma de páginas web y, a través


del protocolo HTTP, lo entregan a petición de los clientes (navegadores web) en
formato HTML. Un servidor sirve información a los ordenadores que se conecten a
él. Cuando los usuarios se conectan a un servidor, pueden acceder a programas,
archivos y otra información del servidor. En la web, un servidor es un ordenador
que usa el protocolo HTTP para enviar páginas web al equipo de un usuario
cuando este las solicita (Figura 12.5).

262
12. Arduino y el Internet de las cosas

Figura 12.5

12.1.2 Práctica 38: implementando un Arduino web Server


En primer lugar, necesitamos saber la dirección MAC de tu Ethernet Shield (Figura
12.6). Debería estar impresa en una etiqueta en la parte posterior de la placa.

Figura 12.6

En el código del programa vamos a guardar la dirección MAC en una matriz


de bytes de la siguiente manera:

byte mac [] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED};

Esta es realmente la dirección de hardware de la mochila que se utiliza para


comunicarse y protegerse a través de Ethernet y que será única en toda la red.

263
Taller de Arduino

A continuación, precisaremos de una dirección IP. Desde la versión 1.0 del IDE
de Arduino, la librería Ethernet soporta el Protocolo de Configuración Dinámica del
Host (DHCP), lo que permite a Arduino descubrir automáticamente tu dirección IP.
Ello configurará automáticamente tu dirección IP siempre y cuando el router de tu
casa esté configurado para tener el DHCP activado (lo que suele ser habitual).

El enrutador (router) que te instaló tu ISP (Provedor de Servicios de


Internet) cuando contrataste el acceso a Internet ya vino configurado
con una serie de características. Una de ellas es la de proporcionar
una IP dinámica a cualquier ordenador o dispositivo de red que se
conecte a él, bien sea por cable o por WIFI. Este servicio acostumbra
a estar habilitado por defecto. Si no es así, deberías poder activarlo
en la configuración de tu router. En caso contrario, ponte en contacto
con la empresa contratada.

Si por alguna razón no pudiésemos activar el servicio DHCP, siempre podemos


averiguar la IP manualmente. Hay diferentes técnicas para hacerlo, dependiendo de la
configuración. Si tu Arduino está conectado directamente por cable al router
podemos encontrar la dirección IP local acudiendo al panel de administración del
router (Figura 12.7). Normalmente, accediendo mediante un navegador web a la IP
del router, que por lo general tiene el formato http://192.168.0.1. En ese caso, cada
ordenador o dispositivo de red conectado posee una dirección del tipo
http://192.168.1.x donde x es cualquier número entre 1 y 255.

Figura 12.7

264
12. Arduino y el Internet de las cosas

Cada ordenador o dispositivo de red en la red tendrán una única dirección


del tipo 192.168.1.x en el que el número final identifica el dispositivo en la red,
por lo que asegúrate de que tu Ethernet Shield no entra en conflicto con esos
dispositivos. Le asignaremos, por tanto, una dirección IP libre (por ejemplo:
192.168.1.2) de la siguiente manera:

IPAddress manualIP (192, 168, 1, 2);

Por último, a veces, también tenemos que especificar el router como


gateway (puerta de enlace). Creamos una matriz de bytes y almacenamos en ella
la dirección IP del router para ser usado como la puerta de enlace. Por ejemplo:

penlace byte [] = {192, 168, 1, 1};

Ahora ya podemos escribir el sketch que nos servirá como plantilla principal
para todos los proyectos en los que diseñemos un Arduino web server. El
siguiente listado pone en práctica todo lo que hemos discutido antes mediante la
creación de un servidor en el Arduino. Al servidor se le encomendó la tarea de
aceptar conexiones de clientes entrantes (enviados a través de un navegador
web) y de responder con un mensaje personalizado.

Práctica 38a. Servidor Web con Arduino


/* Servidor web con la Ethernet shield. */
/* Arduino como servidor de páginas Web, increíble, pero
cierto... */
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x61};
IPAddress manualIP(192,168,1,15);
EthernetServer server(80);
boolean dhcpConnected = false;
void setup()
{
if (!Ethernet.begin(mac))
{
Ethernet.begin(mac, manualIP);
}
server.begin();
}

265
Taller de Arduino

void loop()
{
EthernetClient client = server.available();
if (client)
{
boolean currentLineIsBlank = true;
while (client.connected())
{
if (client.available())
{
char c = client.read();
if (c == '\n' && currentLineIsBlank)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.println("Funcionando el Servidor");
break;
}
if (c == '\n')
{
currentLineIsBlank = true;
}
else if (c != '\r')
{
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}

En primer lugar, incluimos dos librerías necesarias:

#include <SPI.h>
#include <Ethernet.h>

266
12. Arduino y el Internet de las cosas

A continuación, se inicializa el servidor HTTP en el puerto 80 y definimos


algunos parámetros propios del hardware vistos anteriormente.

byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x61};


IPAddress manualIP(192,168,1,195);
EthernetServer server(80);
boolean dhcpConnected = false;

Una vez que se ha inicializado el servidor, el sketch intentar conectar el


Arduino a la red Ethernet usando DHCP; si no puede, se configura manualmente
con una dirección IP libre (192.168.1.15).

void setup()
{
if (!Ethernet.begin(mac))
{
Ethernet.begin(mac, manualIP);
}
server.begin():
}

Una vez que se ha conectado a un cliente, se reciben los datos


continuamente del servidor mostrándose en el terminal serie hasta que le llega un
carácter de nueva línea que delimita el final del mensaje. Este es el indicador que
nos cierra la comunicación.

if (c == '\n')
{
currentLineIsBlank = true;
}

Una vez que haya cargado el código y se está ejecutando, se puede


conectar el conjunto Arduino-Shield al router mediante el cable de red. Ahora,
tenemos que averiguar la dirección IP dinámica que ha asignado el router a la
shield Ethernet. Para ello, abrimos el panel de administración de nuestro router y
observamos algo parecido a esto (Figura 12.8). Tenemos la conexión Ethernet del
Arduino a través de la IP: 192.168.0.195. Esa es la dirección dinámica que ha sido
asignada. En tu caso, y dependiendo de tu router, puede ser otra; pero siempre
comprendida en el rango de direcciones IP dinámicas que proporciona el
enrutador.

267
Taller de Arduino

Abrimos cualquier navegador web (el cliente) y tecleando la dirección IP


anterior, se envía una petición de conexión al servidor web de Arduino y este
responderá enviando el mensaje: “Funcionado el servidor” (Figura 12.9).
Vamos a modificar el programa para que, con la misma plantilla anterior,
testemos remotamente las entradas analógicas del Arduino que está funcionando
como servidor.

Figura 12.8

Figura 12.9

Práctica 38b. Lectura remota de los canales analógicos


/* Servidor web con la Ethernet shield para leer datos. */
/* Arduino enviando datos de sus pines analógicos. */
#include <SPI.h>
#include <Ethernet.h>
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x61};
IPAddress manualIP(192,168,1,195);
EthernetServer server(80);
boolean dhcpConnected = false;

268
12. Arduino y el Internet de las cosas

void setup()
{
if (!Ethernet.begin(mac))
{
Ethernet.begin(mac, manualIP);
}
server.begin();
}
void loop()
{
EthernetClient client = server.available();
if (client)
{
boolean currentLineIsBlank = true;
while (client.connected())
{
if (client.available())
{
char c = client.read();
if (c == '\n' && currentLineIsBlank)
{
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println();
client.print("ENTRADAS ANALOGICAS ");
client.println("<br />");
client.println("<metahttp-equiv=\"refresh\"
content=\"5\">");
for(int analogChannel = 0; analogChannel < 6;
analogChannel++)
{
int sensorReading =
analogRead(analogChannel);
client.print("Entrada analogica: ");
client.print(analogChannel);
client.print(" es ");
client.print(sensorReading);
client.println("<br />");
}
client.println("</html>");

269
Taller de Arduino

break;
}
if (c == '\n')
{
currentLineIsBlank = true;
}
else if (c != '\r')
{
currentLineIsBlank = false;
}
}
}
delay(1);
client.stop();
}
}

Hemos añadido a la plantilla el trozo de código que está recuadrado.


Observamos unas etiquetas del lenguaje HTML cuya compresión requieren
algunos conocimientos básicos de este lenguaje que pueden estudiarse en el
siguiente link: http://roble.pntic.mec.es/apuente/html/
El resultado en el navegador se puede visualizar en la Figura 12.10.

Figura 12.10

Diseña un proyecto que adquiera temperaturas con un sensor LM35


y las muestre en un navegador web.

270
12. Arduino y el Internet de las cosas

12.1.2 Práctica 39: comunicándose con Twitter


Un servicio que es genial hoy en día es Twitter. Una vez que nos hemos registrado
y tenemos una cuenta de Twitter, podemos difundir los tuits (mensajes) de hasta
140 caracteres a toda la red Twitter. La gente puede suscribirse a su feed y recibir
automáticamente las actualizaciones del tuit. Además, Twitter ofrece otros
servicios, lo que significa que se puede tener, de forma automática, sus tuits
agregados a su cuenta de Facebook.
¿No sería estupendo si se pudiera crear un feed de Twitter que se actualice
automáticamente cuando suceda algo en nuestro Arduino? Por ejemplo, que
cuando el sensor de temperatura LM35 de nuestro dormitorio llegue a los 200
grados, nos envíe un tuit avisándonos de que vayamos pensando en mudarnos de
domicilio (Figura 12.11).
En esta sección aprenderemos cómo configurar nuestro Arduino y su shield
Ethernet para enviar automáticamente un tuit cuando pulsemos un botón
conectado a la placa Arduino, lo que está claro que nos abre un campo enorme de
posibilidades. Ahí dejo que tu imaginación se ponga a trabajar…

Figura 12.11

Si aún no tienes una cuenta en Twitter, o si deseas crear una nueva para
este proyecto, vete al siguiente enlace: http://www.twitter.com y crea una.
Después, necesitaremos obtener un token especial que autorizará al Arduino para
enviar mensajes a nuestra cuenta de Twitter.
Este token es una especie de clave de seguridad que permite mediar entre
tu placa Arduino y Twitter. Para obtener tu token, es necesario acudir al siguiente
enlace:

http://arduino-tweet.appspot.com/

Primero debemos autorizar a nuestro Arduino para que utilice una cuenta
tal y como se muestra en la Figura 12.12.

271
Taller de Arduino

Figura 12.12

Figura 12.13

Tras unos momentos, se nos mostrará en la ventana del navegador la clave


de seguridad o token que debemos apuntar (Figura 12.13). Pasamos al segundo
punto y nos descargamos desde la misma web la librería correspondiente a
Twitter. Posteriormente la añadimos desde el IDE de Arduino para poder usarla en
nuestra práctica. Ahora es el momento de echar un vistazo más de cerca a las
funciones de esta librería y que se muestran en la Tabla 12.3.

Función Descripción

Twitter(string token) Se envía la clave o token al servidor de Twitter.

Comienza la publicación de un mensaje.


bool post(const char *message) Devuelve true si la conexión se establece con
Twitter, false si hay un error.

272
12. Arduino y el Internet de las cosas

Función Descripción

Comprueba si el proceso de solicitud de


boolcheckStatus(Print *debug)
publicación aún está realizándose.

Devuelve la respuesta de código del estado


HTTP de Twitter.
int status()
El estado solo está disponible después de que
la publicación del mensaje ha terminado.

Tabla 12.3

Ahora que Twitter y nuestro Arduino se comunican, vamos a construir un


circuito simple para enviar los tuits cada vez que presionamos un botón. El
circuito se muestra en la figura 12.14. El código del sketch es el siguiente:

Práctica 39. Enviando mensajes a Twitter


/* Enviando tweets desde arduino a Twitter. */
/* Sencillamente muy interesante... */
#include <SPI.h>
#include <Ethernet.h>
#include <Twitter.h>
byte mac[] = {0x90, 0xA2, 0xDA, 0x0D, 0xF4, 0x61};
IPAddress manualIP(192,168,1,195);
int b1Pin = 2;
Twitter twitter("124837782-TGASC1BgjexTyezzxxxxxxxxxxxxxxxx");
void setup()
{
delay(1000);
if(!Ethernet.begin(mac))
{
Ethernet.begin(mac, manualIP);
}
Serial.begin(9600);
}
void enviarTweet(const char msgenviar[])
{
Serial.println("Conectando ...");

273
Taller de Arduino

if (twitter.post(msgenviar))
{
int estado = twitter.wait(&Serial);
if (estado == 200)
{
Serial.println("OK.");
}
else
{
Serial.print("fallo : code ");
Serial.println(estado);
}
}
else
{
Serial.println("La conexión ha fallado.");
}
}
void loop()
{
if(digitalRead(b1Pin) == HIGH)
{
presCt++;
enviarTweet ("Tú Casa está en llamas”);
delay(2000);
}
}
En primer lugar, tratamos de conectar el Arduino a la red Ethernet usando
DHCP (automáticamente) o mediante la dirección IP manual. Una vez conectado,
iniciamos una conexión en serie para que podamos observar los mensajes en
monitor serie del IDE. Twitter envía el código 200 si la conexión es correcta; en
caso contrario devuelve el código de error. Después, utilizamos la función
enviarTweet() para formatear y enviar tuits correctamente.
Por seguridad, he tapado parte de mi clave o token. Sustitúyela por la tuya.
Twitter twitter("124837782-TGASC1BgjexTyezzxxxxxxxxxxxxxxxx");

274
12. Arduino y el Internet de las cosas

Figura 12.14

En la Figura 12.15 observamos el resultado en Twitter. Revisa


cuidadosamente esta plantilla en caso de que no te funcione la conexión. Varía las
plantillas para modificar los mensajes y no envíes repetitivos e idénticos tuits
porque Twitter se da cuenta y puede bloquearlos.

Figura 12.15

Twitter bloquea el mismo mensaje que se envía, de forma


consecutiva, dentro de un corto período de tiempo. Para evitar que
esto pueda sucederte, añade una variable al mensaje, que se
autoincremente, cada vez que se envíe.

275
Taller de Arduino

Realiza una práctica en la que muestres en Twitter la temperatura de


tu dormitorio.

12.2 Características de la Arduino wifi shield


La shield Ethernet necesita estar conectada físicamente al router para trabajar.
Esto puede ser una limitación importante en muchas aplicaciones. Aquí es donde
entra en juego la comunicación inalámbrica tan de moda hoy en día. Y es que
disponemos en el mercado de una shield wifi que convierte al Arduino en un
poderoso instrumento para independizarnos del cableado del router y no
depender de una ubicación concreta para conectarnos a él.
La shield wifi (Figura 12.16) te permitirá conectarte a cualquier red
inalámbrica 802.11b/g. Esta shield (de momento un poco cara) es capaz de
comunicarse con UDP y TCP y su uso es fácil ya que contamos con una librería
muy documentada y testeada. Sus pines libres en la parte superior te permiten
añadir sin problemas sensores y actuadores. Además de soportar la especificación
802.11b/g, la mochila wifi soporta encriptación WEB y WPA2 para proporcionar
seguridad a tus conexiones. Por si fuera poco, también proporciona una ranura
microSD que puede ser utilizada tanto con el Arduino UNO como el Mega, a través
de la librería SD. También cuenta con una serie de LED de estado que nos
informan del estado de la conexión.

Figura 12.16

El Arduino Shield wifi y lector de tarjetas SD se comunican mediante el bus


SPI. En la Arduino UNO, la comunicación SPI se admite en los pines digitales 11, 12

276
12. Arduino y el Internet de las cosas

y 13. El pin 10 se utiliza para seleccionar la HDG104 y el pin 4 se utiliza para el


lector de tarjetas SD.
Como el chip de la protección wifi (HDG104) y lector de tarjetas SD utilizan
el Bus SPI, solo uno puede estar activo en un momento dado. Si ambos están en
uso, el SD y librería wifi se entienden perfecta y automáticamente. Si estás
utilizando uno solo de estos dos recursos, debes deseleccionar explícitamente. Se
verá en el código de ejemplo.

12.2.1 La librería wifi


Para comenzar a utilizar esta shield, vamos a usar la librería wifi. La librería wifi se
encarga de toda la comunicación de red de bajo nivel para nosotros y también
proporciona soporte para muchos de los comandos y la funcionalidad
proporcionada por la shield. En este punto, sería bueno familiarizarse con la Tabla
12.4, que proporciona una visión general de las funciones principales que vamos a
usar. Una vez que hayas revisado esta tabla, estarás listo para seguir adelante con el
proyecto de ejemplo donde se van a testar los parámetros de tu red inalámbrica.
La librería wifi es parecida a la Ethernet. En todo caso la shield wifi puede
actuar como cliente de un servidor o como servidor mismo. Una aplicación de
esto último es su funcionamiento como servidor HTML o de páginas web.

Término Descripción

Inicializa la librería WiFi y comienza


WiFi.begin() la comunicación con el dispositivo.
WiFi.begin(char[] ssid)
Podemos unirnos a cualquier red
WiFi.begin(char[] ssid, char[] pass)
abierta o proporcionar la
WiFi.begin(char[] ssid, int keyIndex,char[]key)
contraseña con cifrado.

WiFi.disconnect() Se desconecta de la red actual.

Obtiene el SSID de la red actual y


WiFi.SSID()
devuelve un String.

Obtiene la dirección MAC del


router conectado y lo almacena
WiFi.BSSID(bssid)
en una matriz de 6 bytes que se
pasa como un argumento.

277
Taller de Arduino

Término Descripción

Devuelve la intensidad de señal


WiFi.RSSI() de la conexión como tipo de
variable Long.

Devuelve el tipo de cifrado de la


corriente de un router
especificado. Retorna con un
WiFi.encryptionType(wifiAccessPoint)
byte, donde: TKIP (WPA) = 2,
WEP = 5, CCMP, (WPA) = 4,
NINGUNO = 7, AUTO = 8.

Devuelve el número de redes


WiFi.scanNetworks()
presentes en un byte.

Devuelve una matriz de 6 bytes


WiFi.macAddress() que representa la dirección MAC
de la shield WIFi.

Devuelve la dirección IP
WiFi.localIP()
asignada a la shield WiFi.

Devuelve la máscara de subred


WiFi.subnetMask()
de la shield WiFi.

Devuelve la dirección IP de
WiFi.gatewayIP()
puerta de enlace.

Crea un servicio de servidor para


WiFiServer(int port) que escuche en un puerto
específico.

WiFiServer.begin() Inicia el servidor.

Interroga si un cliente tiene


WiFiServer.available()
datos listos para ser enviados.

Envía datos a todos los clientes


WiFiServer.write(data) conectados (ya sea de tipo byte
o char).

278
12. Arduino y el Internet de las cosas

Término Descripción

Imprime datos en todos los


WiFiServer.print()
clientes como secuencia de
WiFiServer.println()
dígitos ASCII.

Crea un cliente que pueda


conectarse a la dirección IP y el
WiFiClient()
puerto definido en la función
connect ().

Interroga si el cliente está


WiFiClient.connected()
conectado.

Inicia la conexión mediante la


WiFiClient.connect(ip, port)
dirección IP y puerto
WiFiClient.connect(URL, port)
especificado mediante una URL.

Escribe datos en el servidor


WiFiClient.write(data)
(byte o char).

WiFiClient.print()
Imprime datos en el servidor
WiFiClient.println()
como secuencia de dígitos ASCII.

Devuelve el número de bytes


disponibles para ser leídos (el
WiFiClient.available()
número de bytes enviados desde
el servidor).

Lee el siguiente byte recibido


WiFiClient.read()
desde el servidor.

WiFiClient.stop() Desconecta del servidor.

Tabla 12.4

12.2.2 Práctica 40: escaneando tu red inalámbrica WiFi


En este ejemplo vamos a poner a funcionar la shield para comprobar que funciona
bien y no tenemos que devolverla al vendedor. Realizaremos un sencillo barrido
de la red inalámbrica de nuestra casa observando los routers que están presentes

279
Taller de Arduino

alrededor, la potencia de señal que nos llega y la dirección IP dinámica que nos
asigna nuestro enruteador. Lo primero que hacemos es abrir el ejemplo
denominado: ScanNetworks.ino que está dentro de la librería.

Práctica 40. Probando la WiFi


/* Probando la shield WIFI. */
/* Veremos si no nos tangaron los 80 Euros…. */
#include <SPI.h>
#include <WiFi.h>
void setup()
{
Serial.begin(9600);
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println("WiFi shield no existe");
while (true);
}
String fv = WiFi.firmwareVersion();
if ( fv != "1.1.0" )
Serial.println("Actualiza el firmware");
printMacAddress();
}
void loop()
{
delay(10000);
Serial.println("Escanenado redes existentes...");
listNetworks();
}
void printMacAddress()
{
byte mac[6];
WiFi.macAddress(mac);
Serial.print("MAC: ");
Serial.print(mac[5], HEX);
Serial.print(":");

280
12. Arduino y el Internet de las cosas

Serial.print(mac[4], HEX);
Serial.print(":");
Serial.print(mac[3], HEX);
Serial.print(":");
Serial.print(mac[2], HEX);
Serial.print(":");
Serial.print(mac[1], HEX);
Serial.print(":");
Serial.println(mac[0], HEX);
}
void listNetworks()
{
Serial.println("** Lista de Redes **");
int numSsid = WiFi.scanNetworks();
if (numSsid == -1)
{
Serial.println("No puedo encontrar nada");
while (true);
}
Serial.print("Redes disponibles");
Serial.println(numSsid);
for (int thisNet = 0; thisNet < numSsid; thisNet++)
{
Serial.print(thisNet);
Serial.print(") ");
Serial.print(WiFi.SSID(thisNet));
Serial.print("\tSignal: ");
Serial.print(WiFi.RSSI(thisNet));
Serial.print(" dBm");
Serial.print("\tEncryption: ");
printEncryptionType(WiFi.encryptionType(thisNet));
}
}
void printEncryptionType(int thisType)
{
switch (thisType)

281
Taller de Arduino

{
case ENC_TYPE_WEP:
Serial.println("WEP");
break;
case ENC_TYPE_TKIP:
Serial.println("WPA");
break;
case ENC_TYPE_CCMP:
Serial.println("WPA2");
break;
case ENC_TYPE_NONE:
Serial.println("None");
break;
case ENC_TYPE_AUTO:
Serial.println("Auto");
break;
}
}

Las dos primeras líneas incluyen las librerías necesarias. Date cuenta del
cambio con respecto a la librería Ethernet.

#include <SPI.h>
#include <WiFi.h>

Con la siguiente línea comprobamos si la shield está bien conectada a la


placa de Arduino y está operativa. En caso contrario, te avisa por medio del
programa monitor de que algo falla.

if (WiFi.status() == WL_NO_SHIELD)

La siguiente comprobación es muy importante ya que testea el firmware de


la shield. Si no viene actualizada tienes un problema porque que no te funcionará.

String fv = WiFi.firmwareVersion();
if (fv != "1.1.0" )
Serial.println("Actualiza el firmware");

282
12. Arduino y el Internet de las cosas

No es que esté dañada físicamente. Lo que sucede es que su firmware es


obsoleto y le impide establecer comunicación con los protocolos de red actuales.
Necesitas «modernizar» su firmware. En la página oficial de Arduino explica cómo
hacerlo, aunque yo recomiendo seguir las instrucciones que vienen muy bien
detalladas en el siguiente enlace:

http://www.dfrobot.com/community/how-to-upgrade-arduino-wifi-
shield-firmware-on- windows.html

A mí, personalmente, no me ha funcionado el método expuesto en la


página oficial. La verdad es que es un poco extraño adquirir una wifi shield de
paquete y encontrarte con este berenjenal, pero las cosas son así.

Una vez superado este «trámite engorroso» el código realiza una espera de
diez segundos para dar tiempo a inicializarse y continúa llamando a tres funciones
que realizan todo el trabajo.

printMacAddress();
listNetworks();
printEncryptionType(int thisType);

La primera te muestra la MAC de tu shield; la segunda te proporciona una


lista de redes de tu entorno y la tercera te suministra el tipo de encriptación de
cada una de ellas. Todo ello a través del programa monitor del IDE de Arduino.

Figura 12.17

283
Taller de Arduino

Es importante ejecutar este programa de testeo para asegurarse de que


todo está bien, y que si algo no funciona en las prácticas que vienen ahora en
adelante, no es debido a un mal funcionamiento del hardware o una falta de
actualización de la shield.

En la figura 12.17 se puede observar un correcto funcionamiento.

En este momento vamos a sacarle más jugo a las shields anteriores y vamos
a entrar de lleno en el Internet de las cosas para que observéis hasta qué punto
podemos llegar con la conectividad de las redes.

12.3 El servidor de datos Xively


Xively (originalmente llamada Pachube, más tarde Cosm y finalmente Xively,
debido a una marca previamente registrada) consiste en un servicio online
desarrollado específicamente para el Internet de las cosas (Internet Of Things –
IOT). La plataforma permite publicar los datos recogidos por distintos sensores
(como pueden ser sensores de humedad, temperatura, gases, luminosidad,
radiación, etc.) mediante gráficas en tiempo real y widgets.

Es decir, que funciona como un servidor colector de datos procedentes de


diferentes tipos de dispositivos; entre ellos, nuestro Arduino. Entramos de lleno
en el mundo de Internet de las cosas, porque estamos conectando el Arduino
directamente al servidor Xively para que este reciba los datos, los procese y nos
los visualice ordenadamente a través de unas gráficas muy personalizables. Y todo
ello, utilizando un navegador web y desde cualquier sitio con conexión a Internet.

Lo primero que tenemos que hacer es registrarnos con una cuenta gratuita
(pero limitada) en su página web: http://www.xively.com y obtener una clave
denominada: API Key. La clave API es personal y es lo que te da acceso para crear,
eliminar, recuperar, editar y actualizar tus datos en el servidor. Por no olvidar que
es una medida de seguridad importante para que nadie usurpe tu cuenta.

Una interfaz de programación (API) representa la capacidad de


comunicación entre componentes de software. Se trata del conjunto
de llamadas a ciertas librerías que ofrecen acceso a ciertos servicios
desde los procesos y representa un método para conseguir
abstracción en la programación, generalmente (aunque no
necesariamente) entre los niveles o capas inferiores y los superiores

284
12. Arduino y el Internet de las cosas

del software. Uno de los principales propósitos de una API consiste


en proporcionar un conjunto de funciones de uso general, por
ejemplo, para dibujar ventanas o iconos en la pantalla. De esta
forma, los programadores se benefician de las ventajas de la API
haciendo uso de su funcionalidad y se evitan el trabajo de programar
todo desde el principio.

Una vez que hayas creado una cuenta, inicia la sesión y vete a la
configuración (settings) para generar una llave que utilizarás más adelante en tu
sketch (Figura 12.18). A continuación, observarás que te ha generado una clave
alfanumérica muy larga que debes copiar.

Figura 12.18

De momento activa todos los permisos, con el tiempo podrás cambiarlos


(Figura 12.19). Xively ha creado una librería personalizada para su uso con
Arduino con el fin de ayudar a hacer la comunicación un poco más fácil. Esta
librería contributiva es necesaria descargarla y añadirla al IDE de Arduino como
estamos acostumbrados:

https://github.com/xively/xively_arduino/archive/master.zip

También es imprescindible descargar e instalar una segunda librería desde


el siguiente enlace:

https://github.com/amcewen/HttpClient/archive/master.zip

285
Taller de Arduino

Figura 12.19

Con las dos nuevas librerías añadidas en nuestro IDE, ahora vamos a
agregar un nuevo dispositivo al entorno de trabajo de Xively. Comenzamos por ir
a la pestaña de desarrollo (Develop) dentro de su web (Figura 12.20).

Figura 12.20

Al descargar la librería observaremos que su nombre es:


xively_arduino-master.zip. El IDE de Arduino no permite añadir
librerías que contengan guiones en el nombre del fichero. Por tanto,
va a dar error. Es necesario renombrar la librería (por ejemplo:
xively.zip) y también la carpeta que contenga el zip. Para ello, es
necesario que descomprimas la librería, renombres y la vuelvas a
comprimir. De esta manera podemos añadirla sin problemas.

286
12. Arduino y el Internet de las cosas

Dentro de las opciones que nos aparecen (Figura 12.21) debemos, en


primer lugar, darle un nombre descriptivo a la aplicación que vamos a desarrollar.
Esto es importante, ya que este será la referencia que nos presentará el servidor
Xively cuando esté funcionado. Además, rellenamos el campo de información que
nos recuerda la finalidad del proyecto.

Figura 12.21

Figura 12.22

287
Taller de Arduino

Finalmente, decidimos si queremos que nuestros datos en la nube puedan


ser públicos (vistos por cualquiera) o privados, si solo queremos consultarlos
nosotros. Después, nos aparece una ventana final de configuración que nos
proporciona información importante. Además de la API key o clave generada
anteriormente, nos muestra el identificador de datos con Arduino que es
particular para cada sensor que tengamos conectado. A este identificador se le
denomina ID feed y debe ser utilizado en el sketch al igual que la API key (Figura
12.22 y Figura 12.23).

Figura 12.23

12.3.1 Práctica 41: monotorizando temperaturas


con el servidor Xively
Llegó el momento de poner en práctica todo lo aprendido antes. Vamos a realizar
un proyecto que suba a Xively las temperaturas medidas en el salón de mi casa.
Más tarde, las visualizaremos en un navegador web por medio de una gráfica. El
hardware que precisamos es el siguiente:

 Una shield WiFi.


 Un sensor LM35.
 Un diodo led.
 Una resistencia de 220 Ω.

El esquema se muestra en la figura 12.24. Ahora que todos los


componentes están listos, podemos conectar el Arduino a Xively. Esto
permitirá la comunicación bidireccional entre el Arduino y Xively. Su lectura de
las temperaturas estará disponible en la web y seremos capaces de encender o
apagar el LED desde cualquier lugar. Ya sabemos que necesitamos su
identificador ID feed y la API Key. El sensor LM35 está conectado al pin A0 del
Arduino. El sketch que debemos cargar en el Arduino se muestra a
continuación.

288
12. Arduino y el Internet de las cosas

Figura 12.24

Práctica 41. Monotorizando temperaturas con xively y

/* Trabajando con el servidor xively en la nube. */


/* Sensor de temperatura, Arduino e internet. ¿Quién da más? */
#include <SPI.h>
#include <WiFi.h>
#include <HttpClient.h>
#include <Xively.h>
char ssid[] = "vodafoneB372";
char pass[] = "PLYVUIFLXDFY7I";
int keyIndex = 0;
int status = WL_IDLE_STATUS;
char xivelyKey[] = " CopDYFzUkoXIfKm7i7jMSJ9Wla5p9XL3NlZEzVqmK70HEKNC";
char sensorID[] = "CANAL DEL SENSOR DE TEMPERATURA";
#define sensorPin A0
XivelyDatastream datastreams[] =
{
XivelyDatastream(sensorID, strlen(sensorID), DATASTREAM_FLOAT),
};
XivelyFeed feed(1063065004, datastreams, 1);
WiFiClient client;
XivelyClient xivelyclient(client);

289
Taller de Arduino

void printWifiStatus()
{
Serial.print("SSID: ");
Serial.println(WiFi.SSID());
IPAddress ip = WiFi.localIP();
Serial.print("IP Dirección: ");
Serial.println(ip);
long rssi = WiFi.RSSI();
Serial.print("intensidad de la señal (RSSI):");
Serial.print(rssi);
Serial.println(" dBm \n");
}
void setup()
{
Serial.begin(9600);
pinMode(sensorPin, INPUT);
pinMode(ledPin, OUTPUT);
Serial.println("Conectando a wifi...");
Serial.println();
while ( status != WL_CONNECTED)
{
Serial.print("Conectada al SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, keyIndex, pass);
delay(10000);
}
Serial.println("Connectado a wifi");
printWifiStatus();
}
void loop()
{
float tempC;
int tempPin = 0;
tempC = analogRead(tempPin);
tempC = (5.0 * tempC * 100.0)/1024.0;
datastreams[0].setFloat(tempC);

290
12. Arduino y el Internet de las cosas

Serial.print("Lee temperatura");
Serial.println(datastreams[0].getFloat());
delay(15000);
}

Las primeras líneas del código incluyen las librerías necesarias.

#include <SPI.h>
#include <WiFi.h>
#include <HttpClient.h>
#include <Xively.h>

Definimos las variables de conexión a nuestro router con los datos que solo
debemos saber nosotros. De hecho, he tapado, a propósito, parte de mi clave
WPA2. Además, debemos declarar la variable que contiene la API KEY de xively.

char ssid[] = "vodafoneB372";


char pass[] = "PLYVUIFLXDFY7I";
int keyIndex = 0;
int status = WL_IDLE_STATUS;
char xivelyKey[] =
" CopDYFzUkoXIfKm7i7jMSJ9Wla5p9XL3NlZEzVqmK70HEKNC";

Definimos el canal de datos (datastream) entre Arduino y Xively. En este


caso, es el sensor LM35 el que está definido así. Es importante introducir
directamente el identificador numérico 1063065004 en la función XivelyFeed() y
no como variable.

char sensorID[] = "CANAL DEL SENSOR DE TEMPERATURA";


#define sensorPin A0
#define sensorPin A0
#define ledPin 3
XivelyDatastream datastreams[] =
{
XivelyDatastream(sensorID, strlen(sensorID),
DATASTREAM_FLOAT),
}
XivelyFeed feed(1063065004, datastreams, 1);

291
Taller de Arduino

WiFiClient client;
XivelyClient xivelyclient(client);

La función que figura a continuación se utiliza solo por motivos de


depuración, ya que lo único que hace es mostrarnos a través del programa
monitor una serie de mensajes relativos a las características de la conexión WiFi.

void printWifiStatus()

El primer bloque de línea del bucle setup espera a establecer la conexión


WiFi con tu router utilizando los datos privados. Es importante no cambiar el
nombre de la variable status porque si no da errores al compilar el código.

while (status != WL_CONNECTED)


{ Serial.print("Conectada al SSID: ");
Serial.println(ssid);
status = WiFi.begin(ssid, keyIndex, pass);
delay(10000);
}

Las primeras líneas del bucle loop realmente son las que tenemos que
programar. Adquieren las temperaturas del sensor y la formatean en la variable
tempC cuyo contenido subimos a Xively.
float tempC;
int tempPin = 0;
tempC = analogRead(tempPin);
tempC = (5.0 * tempC * 100.0)/1024.0;

La función que acaba enviando la temperatura, cada 15 segundos, por el


canal (datastreams[0]) al servidor, es la siguiente:

datastreams[0].setFloat(tempC);

Tan pronto como compilamos el sketch observamos en la página web un


gráfico (Figura 12.25) que nos muestra la evolución de la temperatura con el
tiempo. Este histórico lo podemos configurar con varias opciones que dejo al
criterio del lector.

292
12. Arduino y el Internet de las cosas

Figura 12.25

Xively es un servidor que ofrece muchas más prestaciones. De hecho,


ofrece una versión de pago que no es barata precisamente. Sin embargo,
podemos jugar e investigar con las prestaciones gratuitas que nos brinda.

12.4 El servidor de datos Plotly


Plotly es un servidor datos que te brinda la posibilidad de «iluminar» tus datos a
través de gráficos profesionales y de presentarlos de mil formas diferentes.
Cuenta con una interfaz gráfica de usuario para importar y analizar los datos en
una cuadrícula y usa herramientas estadísticas de gran potencia. Es, por así
decirlo, la hermana presumida de este tipo de servidores.

El procedimiento general es muy similar a Xively. Primero tenemos que


abrir una cuenta (gratuita de momento) mediante nuestro correo electrónico y
bajarnos la librería para comunicar nuestro Arduino con este servidor (Figura
12.26).

Esta librería se puede descargar a través del siguiente enlace:

https://github.com/plotly/arduino-api

Después de descomprimirla, observarás que existen varios


subdirectorios con varias posibilidades hardware (Figura 12.27). Vamos a
conectarnos a través de una shield WiFi, por tanto, elegimos la librería
correspondiente a ella. La añadimos al IDE; no olvidando que debemos
eliminar el guion del nombre del fichero y tenemos que volver a comprimirla.
En este caso, la renombré de esta manera: plotlyw.zip. En la figura 12.28 se
observa esta librería instalada.

293
Taller de Arduino

Figura 12.26

Figura 12.27

Figura 12.28

294
12. Arduino y el Internet de las cosas

A continuación, apuntamos el número de API Key que se ha generado


cuando hemos confirmado el registro en Plotly, y el nombre de usuario que le
hemos dado (Username).

Ahora ya podemos empezar a trabajar con este servidor. Así de sencillo.

12.4.1 Práctica 42: adquisición y visualización de datos en Plotly


El propósito de esta práctica es demostrar cómo conectar un Arduino WiFi Shield
a los servidores de Plotly para crear gráficos muy atractivos. Vamos a utilizar un
sensor de humedad y temperatura (DHT22) que proporcione datos numéricos a
las gráficas. Pero, antes de nada, vamos a echar un vistazo a este tipo de sensor
que está cogiendo tanta popularidad hoy en día.

12.4.1.1 El sensor de temperatura/humedad DHT22


El sensor de humedad/temperatura DHT22 (Figura 12.29) se presenta en un
cuerpo de plástico ideal para montar sobre un panel o similar. Utiliza un sensor
capacitivo que devuelve una señal digital con la medición (no se necesitan pines
analógicos). Es muy sencillo de utilizar, aunque solo permite una lectura cada 2
segundos.

Figura 12.29

Simplemente aliméntalo de 3 a 5 V el cable amarillo a un pin de entrada y el


cable negro a GND. Usa un protocolo de un solo cable, pero no es directamente
compatible con la librería de Dallas: One-Wire. Si necesitas utilizar varios sensores
al mismo tiempo, cada uno necesita su propio pin de datos. Es bastante sensible y
preciso y funciona en un amplio rango de humedades.
Características
 Alimentación: 3 a 5 V.
 Consumo: 2.5 mA máx (en captura.)
 Rango: 0-100 % (±2-5 %).

295
Taller de Arduino

 Capaz de leer temperatura de -40 a 80 °C (±0.5 °C).


 Tiempo de sensado: 1 vez cada 2 segundos.

Del montaje realizado que se muestra en la Figura 12.30, destacamos que


no utilizamos el pin 3, y que la resistencia de 10 kΩ tiene que conectarse entre la
alimentación y el pin de salida de datos. También es interesante ver que, aunque
el sensor entrega señales de naturaleza analógica, como son la humedad y la
temperatura, estas señales las leemos por un pin digital de Arduino. Este hecho
revela que con un solo pin somos capaces de obtener dos lecturas. Por ello nos
damos cuenta de la ventaja que aportan las señales digitales frente a las
analógicas: menos cables y más simplicidad en los montajes.

Figura 12.30

Procedemos, como es habitual, a descargarnos la librería asociada a este


sensor para que trabaje con nuestro Arduino. Lo hacemos desde el siguiente
enlace:

https://github.com/adafruit/DHT-sensor-library/

En cuanto al hardware que necesitamos:

 Un sensor DHT22 (< 6 euros si buscas bien en la red).


 Una shield WiFi.
 Una resistencia 10 kΩ.
 Un Arduino UNO.

296
12. Arduino y el Internet de las cosas

Antes de conectarte a Plotly deberías probar el ejemplo que trae la librería


para asegurarte de que tu sensor funciona perfectamente. Este ejemplo se llama:
DHTtester.ino. Lo he simulado en Proteus (Figura 12.31) para que observes lo que
te debe aparecer en el programa monitor.

Ahora vamos a examinar el código que cargaremos en el Arduino para que


envíe estos datos a Plotly. Ten a mano tu API Key y tu nombre de usuario.

Figura 12.31

Práctica 42. Adquisición y visualización de datos en Plotly


/* Utilizando el sensor DHT22 */
/* Embellezcamos nuestros datos para impresionar... */
#include <SPI.h>
#include <WiFi.h>
#include "plotly_wifi.h"
#include "DHT.h"
#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
plotly plotly;
char layout[]="{}";

297
Taller de Arduino

char filename[] = "Temp_humed";


int status = WL_IDLE_STATUS;
char ssid[] = "nombre de wifi";
char pass[] = "contraseña";
void wifi_connect()
{
Serial.println("Intentando conectar al router.");
status = WiFi.begin(ssid, pass);
if (status != WL_CONNECTED)
{
Serial.println("No puedo conectar");
while(true);
}
else
{
Serial.println("Connectado");
}
}
void setup()
{
Serial.begin(9600);
wifi_connect();
dht.begin();
plotly plotly;
plotly.VERBOSE = true;
plotly.DRY_RUN = false;
plotly.username = "Tu nombre de usuario";
plotly.api_key = "Tu API Key";
}
void loop()
{
float h = dht.readHumidity();
float t = dht.readTemperature();
plotly.open_stream(1, 2, filename, layout);
plotly.post(millis(),t);

298
12. Arduino y el Internet de las cosas

delay(150);
plotly.post(millis(),h);
for(int i=0; i<300; i++)
{
delay(1000);
}
}

Después de inicializar las librerías necesarias definimos un objeto del sensor


DHT22 que va a estar conectado al pin 2 del Arduino.

#define DHTPIN 2
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

Definimos también un objeto Plotly de su librería, así como sus variables de


inicialización.
plotly plotly;
char layout[]="{}";
char filename[] = "Temp_humed";

Establecemos la configuración, ya vista, de la conexión de la shield WiFi al


router de nuestra casa y la testeamos. En el bucle setup() comenzamos la
conexión y le enviamos al servidor nuestros datos privados.
wifi_connect();
dht.begin();
plotly plotly;
plotly.VERBOSE = true; // Siempre con este valor.
plotly.DRY_RUN = false; // Siempre con este valor.
plotly.username = "Tu nombre de usuario";
plotly.api_key = "Tu API Key";

En el bucle loop() abrimos una cadena de datos parametrizada del tipo


plotly con las lecturas de humedad y temperatura. Además, le subimos los
tiempos en los que se han hecho las medidas.

float h = dht.readHumidity();
float t = dht.readTemperature();

299
Taller de Arduino

plotly.open_stream(1, 2, filename, layout);

Con el programa monitor abierto puedes ver lo que enviamos al servidor


Plotly y sus respuestas en tiempo real. Ahora solo nos queda abrir nuestra cuenta
en Plotly y ver los datos graficados. Con ellos, la verdad es que podemos hacer
maravillas visuales (Figura 12.32 y 12.33).

Figura 12.32

Figura 12.33

12.5 Arduino Yun


Es una novedosa placa que implementa un Arduino y un pequeño Linux corriendo
cada uno en un procesador distinto y con una conexión serie entre ellos. Lo que
hace grande al producto es sin duda el gran desarrollo software que se ha llevado
a cabo mediante las librerías e implementación para que los entornos se
entiendan y sobre todo buscando que desde la parte de Arduino sea fácil hacer
uso del linux. Arduino Yun (Figura 12.34) salió al mercado para hacer la
competencia a la conocida tarjeta raspberry pi que tanto auge estaba adquiriendo
en el mercado de los sistemas integrados.

El proyecto YUN (yun significa ‘nube’ en chino) está orientado a utilizar el


entorno de Arduino con todas las funcionalidades de un Linux. En este caso la

300
12. Arduino y el Internet de las cosas

distribución es linino que se deriva de OpenWRT. Se ha diseñado para que no


estemos obligados a trabajar con Linux para realizar proyectos. Es decir, es como
un Arduino normal, con su mismo tipo de IDE, su mismo tipo de acceso a las
patillas digitales/analógicas, su mismo lenguaje de programación, etc. Sin
embargo, es mucho más caro; por algo será.

Una de las primeras características es el poder cargar los sketch vía WiFi.
Esto es tremendamente útil, sobre todo si nos olvidamos el cable USB en casa. El
funcionamiento es simple:

Figura 12.34

El IDE de Arduino muestra entre los puertos disponibles la IP del YUN para
enviarle programas. En el linino, cuando se recibe la petición se levanta el proceso
que hace que el sketch sea transmitido al entorno Arduino vía el puerto serie que
los conecta. En los IDE más actuales (1.5.5), ya aparece la librería bridge que es la
encargada de gestionar de forma transparente para el usuario todos los servicios
y clases que proporcionan la conectividad.

301
Taller de Arduino

El trabajo realizado con esta librería puente o bridge es vital ya que permite
interactuar desde nuestro sketch a nivel de línea de comandos del. Se puede
interactuar a nivel de ficheros, escribiendo y leyendo datos en ficheros existentes
o crearlos. Implementa funciones de red avanzadas permitiendo el acceder a
información de la web vía servicios HTTP. También permite publicar información
vía web en este caso haciendo uso del servidor web que corre en el Linux
proporcionando, incluso por medio de REST, el acceso a los pines del Arduino
tanto para lectura como para escritura. Esta implementación posibilita conectarse
a una dirección web y desde un navegador en otra máquina distinta, interactuar
con los pines del Arduino leyendo o escribiendo información. Existen otro tipo de
recursos que da información de los procesos de la parte del Linux o que crean
clientes y servidores para compartir la información, así como clases de más bajo
nivel que se encargan de la mensajería. Por último, y no menos importante,
proporciona ejemplos de interacción de alto nivel con plataformas como Temboo
(lo veremos más adelante en profundidad) o Xively, para leer o publicar
información de sensores de todo tipo.

Linino es una distribución Linux basada en openWRT que es habitualmente


usada en sistemas Linux integrados y que consume pocos recursos. La
característica más sobresaliente, en este caso, es el acierto de seleccionar la
implementación de la interfaz con el sistema LuCi, que es una capa web sobre el
sistema operativo y podamoss gestionar Linino desde cualquier navegador web.
Conectarnos al servidor de la placa y gestionamos la parte linux sin tener que
utilizar la cónsola es una ventaja muy importante sobre todo si se tiene poca
experiencia con Linux. Las tareas habituales de instalar y desinstalar paquetes, la
configuración de red (si se desea modificar) y la de programas de arranque, así
como la supervisión del rendimiento y revisión de log está disponible con una
interfaz clara vía web y preconfigurada. Ni que decir tiene que podemos
conectarnos vía ssh y por consola, hacer lo que haríamos en cualquier Linux,
aunque con las limitaciones de una distribución de estas características (no
soporta la x gráficas).

Como resumen, sus prestaciones más importantes se relacionan


continuación:

 Incorpora un GNU/Linux al cual tenemos acceso desde la shell y


desde un entorno web.
 Dispone de un módulo WiFi integrado, capaz de funcionar como
cliente o como AP.

302
12. Arduino y el Internet de las cosas

 La comunicación Linux-Arduino es sencilla, rápida, cómoda y


bidireccional: desde Arduino podemos ejecutar comandos en el Linux
y desde este, podemos activar pines u otras operaciones en la placa
de Arduino.
 Permite la carga de los sketches de forma inalámbrica y también usar
el puerto serie remotamente.
 Si prescindimos de todo lo demás, podemos usar esta placa como si
fuera un Arduino normal (tipo Arduino Leonardo).

En definitiva: la YUN une dos maravillosos mundos abiertos, el de Linux y el


de Arduino con todas las posibilidades que ofrece uno multiplicadas por las que
ofrece el otro. Su mayor inconveniente es su precio (ronda los 70 euros).
Sus prestaciones de hardware son las siguientes:

 Procesador: Atheros AR9331.


 Arquitectura: MIPS @400 MHz.
 Alimentación: 3.3 V.
 Puerto Ethernet: IEEE 802.3 10/100 Mbit/s.
 Conexión WiFi: IEEE 802.11b/g/n.
 USB Type-A: 2.0 Host/Device.
 Lector de tarjetas: Micro-SD
 RAM: 64 MB DDR2.
 Memoria Flash: 32 MB.
 Soporte para PoE tipo 802.3af.

Si deseas más información debes consultar el siguiente enlace:


http://arduino.cc/en/Guide/ArduinoYun
Ahora vamos a configurar nuestro Arduino YUN, recién desempaquetado,
para empezar a trastear con él. Lo primero que tenemos que hacer es
descargarnos e instalar una versión del IDE mayor que la 1.5.4, para que pueda
soportarlo a nivel de drivers.
http://arduino.cc/en/Main/Software
YUN tiene la capacidad de actuar como un punto de acceso, pero también
puede conectarse a una red existente. Estas instrucciones te guiarán a través de la
conexión de tu YUN a una red inalámbrica. Puede conectarse a redes sin
encriptar, así como las redes que soportan WEP, WPA y WPA2.

303
Taller de Arduino

La primera vez que lo encendamos, y tras unos instantes, se creará una red
WiFi llamada ArduinoYun-XXXXXXXXXXXX. Debemos conectar nuestro ordenador
a esa red (Figura 12.35). Claro está, nos desconectaremos de Internet (no
podemos tener todo).

Figura 12.35

Figura 12.36

Abrimos el navegador web e introducimos la dirección local: 192.168.240.1


en la barra de direcciones. Después de unos momentos, aparece una página web
que te pedirá una contraseña. Rellena ese campo con la palabra: arduino y pincha
en el botón: LOG IN (Figura 12.36).

304
12. Arduino y el Internet de las cosas

Figura 12.37

Figura 12.38

La primera cosa que tenemos que hacer tan pronto entramos en esta
ventana es cambiar la clave por otra personal y reiniciar el YUN (Figura 12.37 y
Figura 12.38). Si algún aciago día, no recuerdas el password, siempre puedes
recuperar la configuración por defecto de fábrica presionando el botón de reset
de WiFi durante unos 30 segundos (Figura 12.39). El siguiente paso es seleccionar
la red WiFi a la que conectaremos el YUN. Elegimos, claro está, el router de
nuestra casa o trabajo, y escribimos la contraseña que posee este router. De esta
forma, el YUN accederá sin problemas al router (Figura 12.40). Autómaticamente,
y tras un reseteo del Arduino, conecta de nuevo nuestro ordenador al router y
volvemos a disponer de conexión a Internet si este fuera el caso.
Cuando nuestro YUN esté en la misma red que el ordenador, podemos
conectarnos de manera inalámbrica y programarlo. Para comprobarlo, abrimos el
IDE y bajo el menú Herramientas > Puerto, deberíamos observar el nombre de
YUN y su dirección IP. En el menú placa, seleccionamos Arduino YUN (Figura
12.41).
Hagamos una prueba. Abrimos el ejemplo Blink (Archivo > Ejemplos >
01Basics > Blink) y cargamos el sketch. Se nos pedirá una contraseña de
administrador. Utilizamos la que escribimos en la pantalla de configuración. Una

305
Taller de Arduino

vez que el programa se carga, tras haber introducido la contraseña de acceso


(Figura 12.42), el procesador 32U4 se reiniciará. Finalmente, se debería ver
parpadear el LED conectado al pin 13.

Figura 12.39

Figura 12.40

Figura 12.41

306
12. Arduino y el Internet de las cosas

Figura 12.42

12.5.1 Arduino Yun y el servidor Temboo


El Arduino Yun viene cargado con el poder de Temboo, por lo que es fácil de
conectar con una amplia gama de recursos y servicios basados en la web. Temboo
es una interfaz de desarrollo que provee, una serie de APIS, para conectar nuestro
Arduino YUN a casi cualquier cosa que os imaginéis. Una de sus características
más sobresalientes es que puedes realizar increíbles proyectos sin apenas
programar nada utilizando sus plantillas ya diseñadas.
Un diagrama explicativo se muestra a continuación (Figura 12.43):

Figura 12.43

Temboo hace que sea sencillo y fácil para el Arduino Yun conectarse a más
de 100 recursos y servicios (por ejemplo, Facebook, Dropbox, Gmail, etc.)
mediante la estandarización de la forma de interactuar con sus interfaces de
programación de aplicaciones (API). No te preocupes si no estás familiarizado con
la programación de APIs; con Temboo no tienes que preocuparte por los detalles.

12.5.2 Práctica 43: envío de correos electrónicos con Temboo


En esta te mostraré cómo enviar un correo electrónico a través de Gmail desde tu
Arduino Yun.

Imagínate todos los tipos de mensajes que puedes enviar: recordatorios,


alertas, palabras dulces, etc. En primer lugar, lo que tenemos que hacer es

307
Taller de Arduino

registrarnos gratuitamente en la página web: http://temboo.com/ y crear, si no la


tenemos, una cuenta en Google, imprescindible para trabajar con Temboo (y casi con
cualquier cosa). La práctica consiste en utilizar el servicio de correo electrónico para
avisarte de que la temperatura de dormitorio indica que tu casa está ardiendo y hace
falta avisar a los bomberos. El hardware que necesitamos es el siguiente:

 Un Arduino Yun.
 Un sensor de temperatura LM35.
 Conexión a Internet.

El sketch de la práctica se muestra a continuación:

Práctica 43. Utilización del correo electrónico como indicador de alarma


/* Envío de correos con arduino Yun */
/* Por si los vecinos no se enteran del incendio */
#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h"
const String GMAIL_USER_NAME = "germantojeiro@gmail.com";
const String GMAIL_PASSWORD = "xxxxxxxxxx";
const String TO_EMAIL_ADDRESS = "germantojeiro@gmail.com";
boolean success = false;
float LM35 = A0;
void setup()
{
Serial.begin(9600);
delay(4000);
while(!Serial);
Bridge.begin();
}
void loop()
{
if (!success)
{
float tempC;
tempC = analogRead(LM35);
tempC = (5.0 * tempC * 100.0)/1024.0;

308
12. Arduino y el Internet de las cosas

Serial.println(tempC);
if (tempC>35)
{
Serial.println("Empezando con SendAnEmail...");
TembooChoreo SendEmailChoreo;
SendEmailChoreo.begin();
SendEmailChoreo.setAccountName(TEMBOO_ACCOUNT);
SendEmailChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
SendEmailChoreo.setAppKey(TEMBOO_APP_KEY);
SendEmailChoreo.setChoreo("/Library/Google/Gmail/
SendEmail");
SendEmailChoreo.addInput("Username",
GMAIL_USER_NAME);
SendEmailChoreo.addInput("Password",
GMAIL_PASSWORD);
SendEmailChoreo.addInput("ToAddress",
TO_EMAIL_ADDRESS);
SendEmailChoreo.addInput("Subject","Alarma");
SendEmailChoreo.addInput(“MessageBody",
"Tu casa está ardiendo”);
unsigned int returnCode = SendEmailChoreo.run();
if (returnCode == 0)
{
Serial.println("El Email se ha enviado");
success = true;
}
else
{
while (SendEmailChoreo.available())
{
char c = SendEmailChoreo.read();
Serial.print(c);
}
}
SendEmailChoreo.close();
delay(60000);
}
}
}

309
Taller de Arduino

Las primeras líneas del código incluyen las librerías necesarias y definen los
datos de tu cuenta de correo electrónico en Gmail y la dirección de correo a quien
deseas enviar el mensaje. En este caso a mí mismo.
#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h"
const String GMAIL_USER_NAME = "germantojeiro@gmail.com";
const String GMAIL_PASSWORD = "xxxxxxxxxx";
const String TO_EMAIL_ADDRESS = "germantojeiro@gmail.com";

En el bucle de configuración setup() habilitamos la comunicación serie solo


con el propósito de depurar el código con el programa monitor. Si al final funciona
bien, puedes eliminar las líneas relativas al serial.

void setup()
{
Serial.begin(9600);
delay(4000);
while(!Serial);
Bridge.begin();
}

En el bucle loop() comprobamos si ya hemos enviado el correo con la


variable succes (no vaya a ser que nos llenemos del mismo correo nuestra bandeja
de entrada). Conectamos con Temboo como cliente y le enviamos nuestras
credenciales.

TembooChoreo SendEmailChoreo;
SendEmailChoreo.begin();
SendEmailChoreo.setAccountName(TEMBOO_ACCOUNT);
SendEmailChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
SendEmailChoreo.setAppKey(TEMBOO_APP_KEY);

Estos datos personales son accesibles una vez que nos hemos logeado en
Temboo. Debemos crear un fichero.h con el siguiente contenido:

#define TEMBOO_ACCOUNT "rastman"


#define TEMBOO_APP_KEY_NAME "myFirstApp"
#define TEMBOO_APP_KEY "b69b163d-ce91-44f0-a"

310
12. Arduino y el Internet de las cosas

Donde “rastman” es el nombre de mi cuenta y “b69b163d-xxx-xxxx-a” es la


clave Key que me ha generado Temboo automáticamente. Al fichero que contiene
estas tres líneas le damos el nombre: TembooAccount.h, el cual hemos incluido al
principio del sketch. Debes guardar este fichero en el directorio de librerías de
Arduino, justo donde está temboo.h

Comprobamos si el sensor LM35 ha superado una determinada


temperatura. He puesto 35 °C con el propósito exclusivamente de depuración. Si
se supera este valor se lanza el código para enviarme el correo electrónico. Si no
se supera, no hace nada.

float tempC;
tempC = analogRead(LM35);
tempC = (5.0 * tempC * 100.0)/1024.0;
if (tempC>35)

Con la siguiente función identificamos la librería que envía el mensaje y le


pasamos los datos de la cuenta de correo de Gmail.

SendEmailChoreo.setChoreo("/Library/Google/Gmail/SendEmail");
SendEmailChoreo.addInput("Username", GMAIL_USER_NAME);
SendEmailChoreo.addInput("Password", GMAIL_PASSWORD);

Finalmente, dirección destino del correo Gmail, la línea que contiene el


asunto y el contenido del mensaje.

SendEmailChoreo.addInput("ToAddress", TO_EMAIL_ADDRESS);
SendEmailChoreo.addInput("Subject","Alarma");
SendEmailChoreo.addInput(“MessageBody","Tú casa está ardiendo”);

El código de retorno (returnCode) nos indicará si hemos sido capaces de


enviar nuestra petición al servidor Temboo. En caso de error le pedimos a Temboo
que nos muestre el tipo de error cuando el servidor esté disponible.
if (returnCode == 0)
{
Serial.println("El Email se ha enviado");
success = true;
}

311
Taller de Arduino

else
{
while (SendEmailChoreo.available())
{
char c = SendEmailChoreo.read();
Serial.print(c);
}
}

Nota: la primera vez que ejecutamos el sketch, podemos recibir una


advertencia de Google que nos pide autorizar el acceso por parte de Temboo.
Sigue sus instrucciones para darle acceso a tu cuenta de Google.

Probemos el código calentando el LM35 con un mechero y comprobando


cuándo me llega el correo a Gmail.

En la Figura 12.44 observamos como la temperatura al subir por encima de


35 °C envía el mensaje. En la Figura 12.45 vemos el mensaje que me ha mandado
Temboo a mi cuenta de Gmail.

Figura 12.44

Figura 12.45

312
12. Arduino y el Internet de las cosas

Prueba esta plantilla para que Temboo te envíe un correo a tu cuenta


de correo si alguien entra en tu dormitorio cuando estás en el
instituto. Utiliza un sensor de presencia PIR y, si quieres, un RTC para
añadir la hora en que invadieron tu espacio.

12.5.3 Práctica 44: utilizando el sensor DHT22


y una hoja de cálculo con Temboo
Te mostraré un ejemplo sencillo para hacer que tu Arduino Yun rellene filas con
datos procedentes de un sensor de humedad/temperatura DHT22, en una hoja de
cálculo de Google. Para ello crearemos una hoja de cálculo de Google:
http://docs.google.com. Las columnas de la hoja de cálculo deberán tener
etiquetas para que este ejemplo funcione. En ese caso, definimos dos columnas
con la etiqueta de temperatura y humedad (Figura 12.46) en la primera línea. Es
importante darle un nombre a esta hoja de cálculo porque lo utilizaremos más
tarde.

Analicemos el sketch que debemos subir al Arduino Yun. En realidad, es una


plantilla que podemos reutilizar para otro tipo de aplicaciones en las que usemos
otro tipo de sensores.

Es conveniente testear el funcionamiento del sensor DHT22 antes de


utilizarlo en la práctica. Nos aseguraremos, de esta manera, de excluir problemas
concernientes al sensor (Figura 12.47).

Figura 12.46

313
Taller de Arduino

Figura 12.47

El hardware que necesitamos es el siguiente:

 Un Arduino Yun.
 Un sensor de Humedad/temperatura DHT22.
 Conexión a Internet.

Práctica 44. Utilizando Temboo con el sensor DHT22


/* Envío de datos del sensor DHT22 a una hoja de cálculo en
google */
/* Realmente es fácil utilizar temboo... */
#include <Bridge.h>
#include <Temboo.h>
#include "TembooAccount.h"
#include "DHT.h"
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
#define DHTPIN 2
const String GOOGLE_USERNAME = "germantojeiro";
const String GOOGLE_PASSWORD = "tu contraseña en google";
const String SPREADSHEET_TITLE = "El título de la hoja de cálculo";
const unsigned long RUN_INTERVAL_MILLIS = 60000;
unsigned long lastRun = (unsigned long)-60000;

314
12. Arduino y el Internet de las cosas

void setup()
{
Serial.begin(9600);
delay(4000);
while(!Serial);
Serial.print("Incializando...");
Bridge.begin();
Serial.println("Hecho");
float h = dht.readHumidity();
float t = dht.readTemperature();
}

void loop()
{
unsigned long now = millis();
if (now - lastRun >= RUN_INTERVAL_MILLIS)
{
lastRun = now;
Serial.println("Adquiriendo valores del sensor...");
unsigned long sensorValue = getSensorValue();
Serial.println("Añadiendo valores a la hoja de
cálculo...");
TembooChoreo AppendRowChoreo;
AppendRowChoreo.begin();
AppendRowChoreo.setAccountName(TEMBOO_ACCOUNT);
AppendRowChoreo.setAppKeyName(TEMBOO_APP_KEY_NAME);
AppendRowChoreo.setAppKey(TEMBOO_APP_KEY);
}
AppendRowChoreo.setChoreo("/Library/Google/Spreadsheets/
AppendRow");
AppendRowChoreo.addInput("nombre usuario", GOOGLE_USERNAME);
AppendRowChoreo.addInput("contraseña", GOOGLE_PASSWORD);
AppendRowChoreo.addInput("SpreadsheetTitle", SPREADSHEET_TITLE);
String rowData(now);
rowData += ",";
rowData += sensorValue;

315
Taller de Arduino

AppendRowChoreo.addInput("RowData", rowData);
unsigned int returnCode = AppendRowChoreo.run();
if (returnCode == 0)
{
Serial.println("Listo! Appended " + rowData);
Serial.println("");
}
else
{
while (AppendRowChoreo.available())
{
char c = AppendRowChoreo.read();
Serial.print(c);
}
}
AppendRowChoreo.close();
}
unsigned long getSensorValue()
{
return dht.readHumidity();
return dht.readTemperature();
}

Si observas el código te darás cuenta de que tiene forma de plantilla y por


eso es reutilizable para otras aplicaciones que se te puedan ocurrir. No se trata de
entender todo, sino lo que tienes que personalizar.
Sírvete del programa monitor para depurar el código. Lo hacen la mayoría
de los programadores expertos que viven de esto.

12.5.4 Práctica 45: utilizando el YUN para controlar un LED


En esta práctica vamos a controlar el apagado o encendido de un LED desde un
navegador web con nuestro Arduino Yun. En la pantalla de administración básica
de Yun, vista anteriormente, donde lo habíamos unido a nuestra red WiFi,
debemos marcar los servicios rest como open. (Figura 12.48).

Ahora, asignamos una IP fija al Arduino Yun. Para poner una IP fija debemos
acceder a su panel de configuración, en concreto, al panel avanzado, llamado Luci.

316
12. Arduino y el Internet de las cosas

Una vez en el panel, y suponiendo que ya tenemos a Yun conectado a nuestra


WiFi doméstica con una IP dinámica, nos dirigimos a Network->Interfaces y
buscamos nuestra red WiFi. Pulsamos en Edit y en esa pantalla podremos
asignarle una IP estática. A partir del momento que grabemos nuestra nueva
configuración, recordad que para volver al panel de control tendréis que usar la IP
que le habéis puesto.

Figura 12.48

Nota: creo que no es imprescindible ponerle una IP fija, ya que cuando


invoquemos el servicio rest podemos usar la nomenclatura del tipo
http://nombre_arduino.local/… Aunque a mí me ha dado problemas, por eso
prefiero una IP estática a una dinámica.
Abrimos desde el IDE el ejemplo: Bridge. Este sketch de ejemplo es muy
interesante, ya que convierte a nuestro Arduino Yun en un servidor web capaz de
ofrecer servicios Rest. Para ello trabaja de manera coordinada con el «lado
Linino», es decir, el procesador que está ejecutando el sistema operativo Linux.
Cualquier petición http que hagamos, es atendida por el servidor web de Linino
(por ello podemos acceder al panel de configuración, por ejemplo). Sin embargo,
si la petición tiene la siguiente nomenclatura: http://nombre_arduino.local/es
atendida por el servidor web de Linino, y como detecta el sufijo “/arduino”, se
envía al procesador arduino 32u4. Básicamente, le pasa la llamada al sketch que
tengamos ejecutando en ese momento en nuestro Arduino.
Más información en http://arduino.cc/en/Tutorial/Bridge.

Práctica 45. Utilizando el Yun para controlar un Led


/* Apagado y encendido de un led con Yun */
/* La ventaja del Yun para controles inalámbricos. */
#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

317
Taller de Arduino

YunServer server;
void setup()
{
pinMode(13, OUTPUT);
digitalWrite(13, LOW);
Bridge.begin();
digitalWrite(13, HIGH);
server.listenOnLocalhost();
server.begin();
}
void loop()
{
YunClient client = server.accept();
if (client)
{
process(client);
client.stop();
}
delay(50);
}
void process(YunClient client)
{
String command = client.readStringUntil('/');
if (command == "digital")
{
digitalCommand(client);
}
if (command == "analog")
{
analogCommand(client);
}
if (command == "mode")
{
modeCommand(client);
}
}

318
12. Arduino y el Internet de las cosas

void digitalCommand(YunClient client)


{
int pin, value;
pin = client.parseInt();
if (client.read() == '/')
{
value = client.parseInt();
digitalWrite(pin, value);
}
else
{
value = digitalRead(pin);
}
client.print(F("Pin D"));
client.print(pin);
client.print(F(" puesto a "));
client.println(value);
String key = "D";
key += pin;
Bridge.put(key, String(value));
}
void analogCommand(YunClient client)
{
int pin, value;
pin = client.parseInt();
if (client.read() == '/')
{
value = client.parseInt();
analogWrite(pin, value);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" puesto a analogico "));
client.println(value);
String key = "D";
key += pin;
Bridge.put(key, String(value));
}

319
Taller de Arduino

else
{
value = analogRead(pin);
client.print(F("Pin A"));
client.print(pin);
client.print(F(" lee analogico "));
client.println(value);
String key = "A";
key += pin;
Bridge.put(key, String(value));
}
}
void modeCommand(YunClient client)
{
int pin;
pin = client.parseInt();
if (client.read() != '/')
{
client.println(F("error"));
return;
}
String mode = client.readStringUntil('\r');
if (mode == "input")
{
pinMode(pin, INPUT);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configurado como ENTRADA!"));
return;
}
if (mode == "output")
{
pinMode(pin, OUTPUT);
client.print(F("Pin D"));
client.print(pin);
client.print(F(" configurado como SALIDA!"));

320
12. Arduino y el Internet de las cosas

return;
}
client.print(F("error: mode INVÁLIDO"));
client.print(mode);
}

Vamos a analizar el código fuente del sketch Bridge un poco más de cerca.
El skech utiliza tres librerías.

#include <Bridge.h>
#include <YunServer.h>
#include <YunClient.h>

La librería bridge, como su nombre indica, es el puente que nos permite


establecer una comunicación entre los dos procesadores de la placa del Arduino
Yun. La WiFi, la conexión Ethernet, el conector USB y la tarjeta SD están
conectadas del «lado Linino». Por eso para acceder a estos recursos necesitamos
la librería Bridge.

La librería YunServer hace posible al Yun escuchar las conexiones de


clientes en el puerto 5555. Todas las peticiones HTTP que lleguen al puerto 80 del
«lado Linino» y que lleven la nomenclatura adecuada, son reenviadas al puerto
5555 y recibidas en nuestro sketch.

Cuando se recibe una petición, se parsea la cadena, y en función de su


estructura se hacen diferentes operaciones, tales como actuar sobre los pines
digitales, escribir un dato en los analógicos, etc. En detalle, podemos consultar el
enlace: http://arduino.cc/en/Tutorial/Bridge.

Una vez compilado y subido el sketch que por defecto tiene el control del
pin 13, pero podemos cambiarlo si queremos, abrimos el navegador web y
escribimos cualquiera de estas DIRECCIONES:

http://rastman.local/arduino/digital/13
Obtendrás la siguiente información: “Pin D13 a 1”.
http://rastman.local/arduino/digital/13/1
El led 13 se enciende.
http://rastman.local/arduino/digital/13/0
El led se apaga.

321
Taller de Arduino

Reemplaza “rastman” por el nombre que le diste a tu Arduino Yun. Puedes


observar las Figuras 12.49 y 12.50 para ver el resultado en el navegador.

Figura 12.49

Figura 12.50

Te habrás dado cuenta de que el código anterior también procesa los


pines analógicos del Arduino. Diseña un proyecto que tenga en
cuenta esto para leer el estado de un sensor y actuar en
consecuencia.

12.5.5 Utilizando el YUN y Temboo con el generador mágico de código


Elije un sensor. Elije la acción que deseas que se desencadene cuando un sensor
se active y Arduino Yun junto con Temboo te permiten realizarlo sin escribir casi
una sola línea de código. Podemos, por ejemplo, envíar textos cuando un sensor
de luz detecta la noche o cuando un sensor de presencia se activa porque un
intruso entra en tu casa.

Con el nuevo Sketch Builder (https://temboo.com/library/Library/Devices/)


proporcionado por Temboo, podemos programar nuestro Arduino Yun para hacer
todas estas cosas y más, en poco tiempo. Después de elegir, a partir de múltiples
tipos de sensores, se pueden establecer las condiciones y tener el código
generado de inmediato en el sitio web Temboo. Entonces solo tenemos que
copiar, pegar en el IDE y subirlo al YUN.

En este caso he escogido un sensor de temperatura LM35. Deseo que


cuando la temperatura suba por encima de 50 °C me envíe un mensaje
personalizado a mi teléfono móvil y que a través del teclado numérico del mismo

322
12. Arduino y el Internet de las cosas

pueda cortar la luz de mi casa utilizando el pin digital 13 de mi YUN. Ya sé que


esto puede parecer muy complicado, pero, ahora es sencillo, utilizando este
nuevo servicio de Temboo. Casi parece magia, pero no lo es.

Figura 12.51

En la figura 12.51 elijo el tipo de sensor de temperatura. A continuación, se


nos presenta una ventana (Figura 12.52) donde escojo el servicio que quiero
tener. En mi caso selecciono el de aviso por teléfono móvil.

Al presionar esta opción se nos abre la ventana de configuración


propiamente dicha (Figura 12.53). En ella y a golpe de ratón vamos rellenando las
casillas pertinentes. Evidentemente el SMS a tu móvil no es gratis; pero puede
disfrutar de un servicio gratuito y limitado que te servirá para realizar pruebas si
te registras en Nexmo. Además, tu casa no va a quemarse todos los días.

Figura 12.52

323
Taller de Arduino

A estas alturas ya debemos saber identificar lo que nos pide esta pantalla
de configuración. A continuación, solo debemos generar el código (generate),
copiarlo, añadir las líneas de código relativas a la gestión del sensor LM35, y
subirlo al YUN.

Figura 12.53

Explora otras posibilidades con esta plantilla mágica. Utiliza sensores


que hayas visto en este libro.

324
CAPÍTULO

ENTORNOS DE
PROGRAMACIÓN
GRÁFICA

13.1 Entorno gráfico de programación S4A


S4A (Scratch for Arduino) es una modificación de Scratch desarrollada por el
Grupo de Programación Smalltalk del Citilab, para programar de forma sencilla e
intuitiva la plataforma de hardware libre Arduino. S4A incluye nuevos bloques
para controlar sensores y actuadores conectados al sistema Arduino

La integración de estos dos entornos permitió el desarrollo de S4A (Figura


13.1). Esta plataforma nos permite entrar al mundo de la electrónica, la robótica y
programación, y desarrollar diferentes prototipos, sin necesidad de tener
conocimientos avanzados. Ha sido desarrollada para atraer a la gente al mundo de
la programación. Su objetivo es también proporcionar una interfaz de nivel alto
para programadores de Arduino con funcionalidades como la interacción de varias
placas a través de eventos de usuario.

Figura 13.1

Los programas desarrollados con Scratch están compuestos por objetos


sobre los que podemos actuar; podemos moverlos por el escenario, cambiará su
forma, su color y también podemos interactuar con ellos.

325
Taller de Arduino

Este maravilloso entorno de programación es gratuito y muy adecuado para


alumnos de todas las edades que quieran introducirse en el mundo de la
programación de Arduino sin conocimientos de programación. Sin embargo, no
nos engañemos, posee una potencia oculta que permite desarrollar proyectos
complejos que impliquen comunicaciones avanzadas, como XBee y Android.
¿Qué esperamos? Vamos a instalarlo. Los pasos a seguir son los siguientes:

• Descarga e instala el software de Scratch for Arduino S4A de la web de


Citilab según tu sistema operativo: Windows, Mac o Linux.
http://s4a.cat/
• Descarga el último firmware para Arduino para establecer la
comunicación de este con S4A. Esto se realiza cargando dicho fichero en
el IDE de Arduino y después subiéndolo a la placa (Figura 13.2). Con ello,
el Arduino se convierte es un dispositivo controlado completamente por
SA4 y, a partir de ahí, toda su programación se realiza desde este
entorno.
http://s4a.cat/downloads/S4AFirmware15.ino

El firmware es un bloque de instrucciones de máquina para


propósitos específicos, grabado en una memoria, normalmente de
lectura/escritura (ROM, EEPROM, flash, etc.), que establece la lógica
de más bajo nivel que controla los circuitos electrónicos de un
dispositivo de cualquier tipo. Está fuertemente integrado con la
electrónica del dispositivo, siendo el software que tiene directa
interacción con el hardware: es el encargado de controlarlo para
ejecutar correctamente las instrucciones externas. En resumen, un
firmware es un software que maneja físicamente al hardware.

Figura 13.2

326
13. Entornos de programación gráfica

• Finalmente ejecuta S4A (Figura 13.3) y realiza el diseño haciendo uso de


las librerías de bloques correspondientes. Una parte de las cuales se
encarga de la lectura y escritura de datos en la tarjeta de acuerdo
siempre con la configuración que establezca el firmware.

Figura 13.3

Por otra parte, la configuración de entrada/salida aún está siendo


desarrollada, así que por ahora los componentes tienen que conectarse de una
forma concreta. Dicha configuración no puede modificarse y se muestra a
continuación:

 Salidas digitales (pines digitales 10,11 y 13).


 Salidas analógicas (pines digitales 5, 6 y 9.)
 Entradas analógicas (todos los pines analógicos de entrada).
 Entradas digitales (pines digitales 2 y 3).
 Servomotores RC (pines digitales 4, 7, 8 y 12).

También se puede controlar una placa de manera inalámbrica si se añade


un módulo como, por ejemplo: XBee. Una característica importante es que se
puede crear un proyecto utilizando tantas placas como puertos USB haya
disponibles.

327
Taller de Arduino

SA4 puede trabajar con aplicaciones Android utilizando un protocolo muy


sencillo (HTTP API), por lo que también es posible interactuar desde un navegador
o cualquier otra aplicación habilitada para la red.

Vamos a abordar una serie de ejemplos sencillos que te demostrarán lo fácil


que es programar con este entorno. Empezaremos con una práctica que
simplemente encenderá y apagará un diodo led conectado en la salida pin 13 de
nuestro Arduino. Es importante recordarte que no todos los pines del Arduino son
directamente utilizables por SA4. Por eso, hay que tener presente la configuración
que te mostré hace un momento.

13.1.1 Práctica 46: intermitencia de un LED


Práctica 46. Intermitencia de un LED
/* Apagado y encendido intermitente de un LED con Sa4 */
/* La ventaja de SA4 es que no escribo una sola línea de
código */

Figura 13.4 Figura 13.5

Figura 13.6

328
13. Entornos de programación gráfica

Se han utilizado dos funciones (Figura 13.4 y Figura 13.6) «digital» de la


librería «movimiento» asociadas a la salida PI13; una en estado «encendido» y
otra en estado «apagado». Las temporizaciones se hacen con los bloques
«pensar» de la librería «apariencia» a los que les hemos quitado el texto que
muestran por defecto y en los que se ha colocado el valor del tiempo en
segundos; se pueden realizar también con el bloque «esperar … segundos» de la
librería «control».

En la figura anterior se observa la correspondencia entre las funciones


típicas del lenguaje de programación de Arduino y su equivalente en modo
gráfico. Por si se te ocurre pensarlo, no es posible, de momento, traducir el código
de un lenguaje a otro.

Si queremos que en la pantalla del escenario aparezca una imagen de un


diodo LED que simula su encendido y apagado, debemos crear con la herramienta
«disfraces» (Figura 13.7 y Figura 13.8) dos imágenes: una que llamamos led_off, y
otra led_on.

Figura 13.7

Figura 13.8

329
Taller de Arduino

En el programa utilizamos el bloque de función «cambiar el disfraz»


perteneciente a la librería «apariencia» que permite mostrar en el escenario una u
otra imagen. Es una función muy interesante porque nos permite simular, de
alguna manera, el funcionamiento real del Arduino.

13.1.2 Práctica 47: variación de la intermitencia de un LED

Práctica 47. Variando la frecuencia de la intermitencia del led


/* Intermitente controlada de un led con Sa4 */
/* Introducimos un potenciómetro */
/* Figuras 13.9, 13.10 y 13.11 */

Figura 13.9 Figura 13.10

Figura 13.11

Asociamos una variable al valor de una entrada analógica (Analog0) con el


objetivo de variar el retardo en el encendido y apagado de la salida digital en el
pin 13. Definimos la variable «frecuencia» que mediante la función «fijar
frecuencia a valor del sensor Analog0» asociamos a ella el valor leído del canal
analógico. El tiempo de encendido lo fijamos a 0.1 segundos, y en donde

330
13. Entornos de programación gráfica

actuamos es en el tiempo de apagado. El tiempo de apagado lo configuramos con


la función «esperar frecuencia/2000 segundos».

El valor leído del canal Analog0 se divide por 2000 con el fin de reducir el
rango de variación de la variable frecuencia. En este caso, podemos deducir que el
valor de frecuencia es:

• Frecuencia varía entre 0 y 0,512 segundos.


• Analog0 varía entre 0 y 1024.

Es importante destacar que, a la hora de construir nuestro programa,


debemos acostumbrarnos a introducir unos bloques dentro de otros.

13.1.3 Práctica 48: control de un LED con un interruptor

Práctica 48. Manejo de la función IF con un LED y un interruptor


/* Control del encendido/apagado de un led mediante un
interruptor */
/* La cosa se va complicando... */
/* Código en la Figura 13.12 */
/* Montaje en la Figura 13.13 */

Figura 13.12

331
Taller de Arduino

Figura 13.13

Queremos gobernar una salida digital 13 mediante el control de una


entrada digital 12 a la que le hemos colocado un pulsador (Figura 13.13).

Mediante el bloque de «sensor… presionado» averiguamos si el valor de la


entrada es «true» o «false», y en función del resultado, y mediante el bloque de
función «si… si no» (que se corresponde al típico IF... else) perteneciente la
librería «control», conseguimos la función de gobierno deseada de encender o
apagar el LED conectado a la patilla 13. Como consejo, fíjate en el color de los
bloques a la hora de encontrarlos en el menú correspondiente.

13.1.4 Práctica 49: gobierno de un LED mediante un pulsador virtual

Práctica 49. Gobierno de un LED mediante un pulsador virtual

/* Control del encendido/apagado de un led mediante un


interruptor virtual */
/* La cosa se va complicando más... */
/* Programa en Figura 13.14 */
/* Disfraces en las Figuras 13.15, 13.16 y 13.17 */
/* El montaje en la Figura 13.20 */

332
13. Entornos de programación gráfica

En este caso lo que vamos a añadir a la versión anterior es la visualización,


en la pantalla escenario, de un LED y un pulsador; pero en este caso el pulsador
será «virtual», es decir, que el diodo LED de la salida 13 se controlará desde la
pantalla del ordenador. Se trata de activar desde la pantalla «escenario» un botón
para activar el PIN 13 y otro botón para desactivarlo.
La activación y desactivación se lleva a cabo por la acción sobre dos objetos:
«led_off» y «led_on». La activación propiamente dicha es la que se asocia al
objeto Arduino1 que tiene también integrados los objetos: «led_on» y «led_off».
Cuando se presiona sobre el objeto «botón_on» se envía al «mensaje» ON (orden
«enviar a todos») que al recibirse en el script correspondiente al programa
Arduino1 activa la salida 13 mediante la orden «digital 13 encendido». Cuando se
presiona sobre el objeto «botón_off» se envía al «mensaje» OFF (orden «enviar a
todos») que al recibirse en el script correspondiente desactiva la salida 13
mediante la orden: «digital 13 apagado» (Figura 13.14).

Figura 13.14 Figura 13.15

Fijaos que el esquema mental de funcionamiento consiste en cambiar el


estado del led y su apariencia por medio del estado del pulsador. Las imágenes de
los diferentes «disfraces» las puedes insertar desde Internet o diseñar con una
pequeña utilidad de dibujo (Figuras 13.15, 13.16 y 13.17).

Los programas pulsacion_off y pulsacion_on se muestran a continuación


junto a los «disfraces» asociados a cada uno.

333
Taller de Arduino

Es importante que cojas práctica con el manejo del entorno, porque aunque
al principio puede parecer complicado, es realmente sencillo cuando lleves
algunas horas trasteando con él.

Figura 13.16 Figura 13.17

Figura 13.18 Figura 13.19

Los objetos descritos anteriormente: led, pulsador_off y pulsador_on, se


muestran en las Figuras 13.18 y 13.19.

Figura 13.20

En la figura 13.20 observamos la práctica en funcionado dentro del


escenario. En realidad, la programación utilizando los escenarios es divertida al
principio. Pero a medida que vamos adquiriendo práctica con la programación, y

334
13. Entornos de programación gráfica

ya que tenemos un Arduino real para comprobar si su comportamiento es


correcto, vamos dejándolo a un lado.

13.1.5 Práctica 50: control de un semáforo

Práctica 50. Control de un semáforo


/* Control de un semáforo */
/* Vete sacando una foto de tu calle. */
/* Código en las Figuras 13.21 y 13.22 */
/* Montaje en la Figura 13.24 */

Figura 13.21 Figura 13.22

En este ejemplo vamos a realizar un semáforo. Utilizaremos las siguientes


salidas:

 Lámpara roja PIN 13


 Lámpara ámbar PIN 11
 Lámpara verde PIN 10

Se han creado tres disfraces (figura para representar los tres estados del
semáforo). Estos se irán mostrando de acuerdo a la secuencia de encendido de las
salidas:

• Cambiar disfraz a Semáforo rojo.

335
Taller de Arduino

• Cambiar disfraz a Semáforo ámbar.


• Cambiar disfraz a Semáforo verde.

En la pantalla de «escenario» se ha colocado un fondo con la imagen de un


cruce de calles. Ello le da cierto realismo a la aplicación y queda bien delante de
tus amigos. Puedes incluso buscar, con el Google, Street view, un cruce de
semáforos cerca de donde vives y utilizar esa captura de la imagen para aplicarla
en esta práctica (Figura 13.23).

Figura 13.23

Figura 13.24

En el escenario (Figura 13.23) se ha incluido una foto de fondo con un


semáforo que está cerca de mi domicilio.

336
13. Entornos de programación gráfica

13.1.6 Práctica 51: control de un motor Servo

Práctica 51. Control de un motor Servo


/* Control de un motor Servo */
/* Programación por bloques para controlar un motor/
/* Programa en Figuras 13.25 y 13.26. */
/* Montaje en Figura 13.27. */

Figura 13.25

Figura 13.26

337
Taller de Arduino

S4A dispone de dos salidas dedicadas para el control de un motor


mediante las instrucciones:

• Motor apagado.
• Motor dirección horario/antihorario.

En esta práctica gobernamos el motor mediante tres letras del teclado del
ordenador. Tecla «a»: apagado. Tecla «b»: giro en sentido horario. Tecla «c»: giro
en sentido antihorario.

Figura 13.27

En el inicio del programa el motor se apaga, y a partir de ahí obedece a la


señal de control en cuanto al sentido de giro, ya que es un servo de rotación
continua.

13.1.7 Práctica 52: LM35 como termostato

Práctica 52. Aplicación de un sensor LM35 como termostato


/* Termóstato con un LM35 */
/* Programa en las Figuras 13.28 y 13.29 */
/* Montaje en la Figura 13.30 */
/* Simulación del escenario en la Figura 13.31 */

338
13. Entornos de programación gráfica

En esta práctica volvemos a usar el famoso LM35. Utilizaremos este sensor


para leer temperaturas por el canal analógico Analog1 y, en función de su valor,
controlaremos el encendido y apagado de dos leds conectados en los pines 10 y
11 del Arduino. Las condiciones que se establecen para el gobierno de los dos LED
vienen dadas por los siguientes rangos:

 Si 300 > Temperatura > 0: LED 1 Encendido.


 Si Temperatura > 300: LED 2 Encendido.

Figura 13.28 Figura 13.29

Figura 13.30 Figura 13.31

339
Taller de Arduino

Definimos una variable analógica que llamaremos Temperatura y se le


asignará el canal Analog1 de la Tarjeta Arduino mediante el bloque de función:
«fijar Temperatura a valor del sensor Analog1».
Se han creado tres «disfraces» que permiten indicar en la pantalla
«escenario» el estado real de las salidas. El tercer disfraz se ha puesto para indicar
que no se cumple alguna de las dos condiciones.

Con estos sencillos ejemplos te he querido exponer lo fácil que es


programar nuestro Arduino en un entorno gráfico de programación. Te animo a
que investigues y pruebes tus propios diseños. Es interesante que te sumerjas y
participes en la amplia comunidad de entusiastas de este estupendo software.

A continuación, vamos a dar un salto cualitativo para introducirnos en otro


entorno gráfico de mayor complejidad y potencia. Se denomina LabVIEW y es
todo un estándar en el control y procesado de señales electrónicas.
Evidentemente, no es mi intención abarcar todas sus posibilidades, sino mostrarte
su potencialidad con Arduino. Estoy seguro de que te quedarás asombrado de lo
que la extraña pareja labVIEW y Arduino pueden llegar a conseguir.

13.2 Entorno gráfico de programación LabVIEW


LabVIEW es un lenguaje de programación visual que emplea iconos en lugar de
líneas de código, para crear aplicaciones. Fue creado por National Instruments en
1976. La principal diferencia con lenguajes basados en texto es que, en lugar de
que una serie de instrucciones determinen la ejecución del programa, es el flujo
de datos el que la dicta, lo que viene a ser llamado dataflow programming.

En concreto, la ejecución viene supeditada a la estructura de un diagrama


de bloques, el cual se crea a partir de la interconexión de una serie de funciones a
través de cables. Estos se encargan de propagar tanto variables como código tan
pronto como se encuentren disponibles en las respectivas fuentes. Podemos
observar un programa realizado en LabVIEW en la Figura 13.32.

La metodología de trabajo de LabVIEW parte de la creación de programas


llamados VIs (Virtual Instruments), los cuales se encuentran constituidos por tres
elementos: un panel frontal, un diagrama de bloques y un panel de conexiones.

El panel frontal (Figura 13.33) es una interfaz de usuario en forma de


tablero de instrumentos virtual que contiene las interfaces de entrada y salida de
nuestro código. Se denominan mandos e indicadores y sirven para que el usuario

340
13. Entornos de programación gráfica

interactúe con el programa durante la ejecución del mismo. LabVIEW ofrece una
serie de funciones específicas (Figura 13.34) para tal cometido, contenidas en la
paleta de herramientas Controls, y accesible únicamente desde el panel frontal.

Figura 13.32

Figura 13.33

341
Taller de Arduino

Figura 13.34

La programación en sí (programación G) se realiza con diagrama de


bloques. Los bloques se introducen e interconectan mediante iconos gráficos que
representan las funciones propias de labVIEW. A través de la paleta de
herramientas Functions podremos acceder a las librerías de funciones disponibles,
así como buscar nuevas creadas por otros usuarios en el repositorio que mantiene
National Instruments en su página web.

Como vemos, Labview es un software de adquisición y procesado de datos


bastante complejo y su comprensión completa escapa a las pretensiones de este
libro. Sin embargo, sí que se pueden mostrar algunos ejemplos básicos de
programación utilizándolo en compañía de nuestro Arduino. En primer lugar,
debemos descargarnos la versión de estudiante llamada: LabVIEW Student Edition
que es suficiente para nuestros propósitos.

http://www.ni.com/trylabview/esa/

A continuación, debemos descargar e instalar un paquete de gestión de


controladores de la diversa instrumentación que maneja LabVIEW. Se denomina
NI-VISA y el link es:

http://www.ni.com/download/ni-visa-5.0.3/2251/en/

Hay que apuntar que son paquetes pesados en tamaño, por lo que nos
llevará su tiempo bajarlos de la red.

342
13. Entornos de programación gráfica

Después abrimos una utilidad llamada VI Package Manager (VIPM) que nos
permite instalar los Toolkits (kits de herramientas) que utilizan aplicaciones o
dispositivos externos que no están incluidos, por defecto, en labVIEW. Desde
VIPM buscamos con la palabra «arduino», la última versión de su conjunto de
herramientas, tal y como se muestra en la figura 13.35.

Figura 13.35

Automáticamente, empieza a descargar de Internet el paquete de interfaz y


es posible, aunque no seguro, que te aparezca un mensaje de error indicando que
no se puede conectar con labVIEW. (Figura 13.36). Lo que debemos hacer (y esto
no aparece en el manual de instalación) es crear una dirección local de conexión
entre ambos programas. Para ello dentro de labVIEW abrimos el menú de
Opciones->VI Server y añadimos la dirección IP local 127.0.0.1 para que se conecte
internamente con la aplicación VIPM (Figura 13.37).

Figura 13.36

343
Taller de Arduino

Figura 13.37

Por otra parte, en el mismo menú es conveniente comprobar que, además de la


dirección IP local, el puerto sea el mismo: 3363 (Figura 13.38).

Reiniciamos LabVIEW y al abrir VPIM comprobamos si todo es correcto bajo el


menú de sus opciones tal y como se muestra en la figura 13.39.

Figura 13.38

344
13. Entornos de programación gráfica

Figura 13.39

Ahora ya podemos instalar el tolkitt de Arduino que aparecerá en la lista tal


y como se muestra en la figura 13.40.

Figura 13.40

Por último, al igual que hicimos con SA4, debemos subir al Arduino el
firmware apropiado de conexión con labVIEW. Este se encuentra en la ruta o path
mostrado en las figuras 13.41 y 13.42.

Figura 13.41

345
Taller de Arduino

Figura 13.42

Compilamos y subimos el siguiente fichero LIFA_Base.ino (entre los


usuarios avezados se le conoce coloquialmente como LIFA).

Es importante que utilices la versión 1.0.X del IDE de Arduino para


compilar y cargar el fichero ya que las versiones superiores provocan
errores de compilación. Esto se debe, según los desarrolladores de
LIFA, a que el equipo oficial de programadores de Arduino ha
cambiado el nombre de algunas funciones y no han actualizado su
compatibilidad con labVIEW.

Si todo ha ido bien ya estamos preparados para utilizar el entorno labVIEW


con Arduino. Vamos a abordar algunos ejemplos para que comprendas mejor la
mecánica del proceso. Para un mejor seguimiento y compresión de lo que voy a
exponer, te aconsejo que eches un vistazo al siguiente enlace donde encontrarás
mucha información sobre el uso de labVIEW.

http://www.ni.com/academic/

13.2.1 Práctica 53: control simple de un LED


Se trata de encender o apagar un led conectado al pin 13 del Arduino desde el
panel visual de labVIEW.

Práctica 53. Control simple de un led


/* Control de un led con labVIEW */
/* Empezamos con labVIEW... */

Lo primero que tenemos que hacer es diseñar en panel frontal de


visualización desde el cual gobernamos el proceso de control del LED (Figura 13.43).

346
13. Entornos de programación gráfica

Figura 13.43

Todo lo que observas son controles insertados y etiquetados visualmente


desde el menú de control. Simplemente, los buscamos e insertamos
directamente, asignándoles una etiqueta de texto descriptiva. Es cuestión de
práctica conseguir «dibujar» lo que se observa en la figura. Es una técnica
moderna de programación habitual, cuya filosofía de trabajo consiste en diseñar
primero una ventana o panel de elementos gráficos, y después relacionarlos con
bloques de programación.

A continuación, desde el menú: Windows->Show Block Diagram (atajo:


Control E) abrimos la ventana de bloques de programa (Figura 13.44) que debe
contener realmente la programación propiamente dicha.

Figura 13.44

347
Taller de Arduino

Buscamos la librería de funciones de Arduino tal y como se muestra en la


figura 13.45. Para empezar, debemos configurar Arduino y lo hacemos poniendo
el bloque Init (Figura 13.46) al que le asignamos los parámetros:

 Puerto de comunicación.
 Velocidad de transmisión.
 Tipo de tarjeta Arduino.
 Numero de bits de los paquetes de comunicación.

Figura 13.45 Figura 13.46

Para asignar las constantes mencionadas basta ponerse sobre el terminal


(Figura 13.47) con la herramienta de edición en modo wire y pulsando el botón

348
13. Entornos de programación gráfica

derecho del ratón, podemos seleccionar el control a añadir con la opción Create
(Constante, Control, Indicador). Si pinchamos dos veces en el icono Init
desplegamos una ventana que permite realizar todo lo anterior de otra manera
(Figura 13.48).

Figura 13.47

Figura 13.48

A continuación, se coloca una estructura de tipo While loop (Figura 13.49).

Figura 13.49

Este bucle se ejecutará continuamente hasta que pulsemos el botón


«Cerrar puerto» (viene a ser el equivalente al loop de un programa escrito para

349
Taller de Arduino

Arduino). Dentro de esta estructura pondremos el bloque de configuración de E/S


y el de lectura de valor de entrada Arduino (figura 13.50).

Figura 13.50

En la entrada Pin Mode debemos seleccionar INPUT y la entrada Digital I/O


PIN deberemos unirla a un bloque PIN Digital que creará el control
correspondiente en el panel y que en modo de ejecución permitirá cambiar la
entrada a leer. Es muy importante que se sepa que los pines 0 y 1 digitales están
ocupados en la comunicación con LabVIEW, por lo tanto, nunca se deben
seleccionar ni para leerlos ni para escribir en ellos.

No debemos olvidarnos de realizar el cableado de los buses de conexión


entre módulos (Figura 13.51). Utilizando el ratón se unen los buses fácilmente ya
que el propio entorno nos avisa de errores en el caso de que no lo hagamos bien.

Figura 13.51

Observarás que los controles de color verde los ha insertado


automáticamente LabVIEW ya que dependen exclusivamente de los
correspondientes bloques del panel frontal.

El siguiente bloque realiza la acción de escribir en pin digital (Figura 13.52).

Figura 13.52

350
13. Entornos de programación gráfica

Para cerrar finalmente la comunicación con nuestro Arduino añadimos el


siguiente bloque (Figura 13.53):

Figura 13.53

Para correr la aplicación debes pulsar sobre el botón mostrado en la figura


13.54 una vez que has conectado físicamente el LED a la patilla 13 del Arduino
(Figura 13.55).

Figura 13.54

Figura 13.55

Tan pronto ejecutes el programa fíjate en tu placa Arduino. Deberás observar


que los LED de trasmisión serie están continuamente parpadeando indicando que
labVIEW ha tomado el control de nuestro Arduino. Ahora, si desde el panel frontal
accionas el botón del LED, este se encenderá o apagará a tu antojo.

Si al ejecutar el programa te aparece el típico error 502 tan


comentado en los foros, revisa la conexión del puerto de Arduino y la
configuración del bloque init.

351
Taller de Arduino

13.2.2 Práctica 54: lectura y escritura de valores en Arduino


Se trata de enviar un valor analógico a la salida PWM PIN 3 que obtendremos de
un elemento del panel. Se leerá el valor del canal de entrada analógica A0 y se
mostrará paralelamente en dos instrumentos del panel. Finalmente,
controlaremos el led conectado en el PIN 8 mediante un interruptor. El panel de
control diseñado para esta práctica se observa en la figura 13.56.

Figura 13.56

Tal y como se puede observar en el diagrama de funciones de la figura


13.57, procederemos de la siguiente manera.

En primer lugar, colocamos el bloque de inicialización Init y le asignamos el


parámetro de número de puerto, al resto le dejamos los que toma por defecto.
Seguidamente configuramos el PIN 8 como salida (Figura 13.58). Dentro del bucle
while insertamos el bloque de lectura analógica A0 (Figura 13.59). Este bloque
necesita que le pongamos el valor del canal de entrada analógica en su salida ya
que nos entrega un valor tipo Double que se corresponde con la lectura realizada.
La salida la encaminamos a los instrumentos de medida que se corresponden con
el medidor de aguja del panel.

352
13. Entornos de programación gráfica

Figura 13.57

Figura 13.58

Figura 13.59

El siguiente bloque (Figura 13.60) que debemos colocar es el


correspondiente a la salida digital en el PIN 8. El valor que representa el número
de PIN lo recibe de la correspondiente constante «8», y el valor que queremos
sacar en la salida lo tomamos de un interruptor (PIN 8) que a la vez también
sacamos a un led (LED 8). Ambos en el panel frontal.

Figura 13.60

353
Taller de Arduino

Figura 13.61

El último bloque de función (Figura 13.61) que colocaremos es el de


escritura del valor analógico PWM en el PIN 3. Lo haremos configurando el
número «3» y mediante un mando tipo potenciómetro designaremos el valor de
la entrada Duty Cycle, conectando también un indicador tipo termómetro vertical.

Finalmente, ya fuera del bucle colocamos el bloque de cierre del canal Close
y el bloque de tratamiento de error (Figura 13.62), que nos permita mostrar en la
pantalla una ventana con información sobre los posibles errores que se
produzcan.

Figura 13.62

13.2.3 Práctica 55: intermitencia de un LED

Abordamos en esta práctica el clásico ejemplo: una salida intermitente en uno de


los pines digitales de Arduino. Vamos a activar la salida digital PIN 13 de modo
intermitente con intervalos de tiempo ajustables, en tiempo de ejecución, desde
el Panel de control.

Como siempre inicializamos Arduino y después definimos el PIN 13 como


una salida.

Dentro del bucle while colocamos el bloque escritura Digital Write Pin. Este
bloque recibe la señal digital de la estructura que constituye la intermitencia de
frecuencia variable. El panel frontal diseñado se muestra en la figura 13.63.

En el bucle while añadimos un Shift Register simplemente pulsando el


botón derecho del ratón estando exactamente sobre el contorno del bucle
(opción: Add Shift Register). De esta forma conseguimos que se ejecute

354
13. Entornos de programación gráfica

sistemáticamente cada cierto tiempo (el indicado en el control: Tiempo del panel
frontal) la operación que hay dentro del bucle. Se trata de sacar TRUE y FALSE a
través de la señal de Reloj.

Figura 13.63

Se ha colocado un operador AND para habilitar mediante un interruptor la


salida del PIN 13. Se han colocado también un indicador: Reloj, que muestra la
intermitencia en el panel frontal. El panel de bloques se muestra en la figura 13.64

Figura 13.64

355
Taller de Arduino

13.2.4 Práctica 56: control de una salida analógica PWM


Sabemos que nuestro Arduino tiene la posibilidad de generar señales del tipo
PWM en algunos de sus pines digitales. Hemos visto anteriormente que esta
cualidad era muy importante para el control de la velocidad de los motores DC. De
momento, en esta práctica vamos a enviar a la salida PWM del PIN 9 un valor
comprendido entre 0 y 255. Más adelante, aplicaremos esta característica para
gobernar un motor DC desde el panel frontal de labVIEW. El panel frontal se
observa en la Figura 13.65.

Figura 13.65

Se comienza insertando el bloque Init fuera del while y se utiliza el bloque


PWM Write Pin en el que designamos el PIN 9 (PWM). La entrada de señal para
este bloque la cableamos con un objeto del tipo Slide (desplazamiento horizontal)
al que configuramos en la escala 0-255 (Figura 13.66).

Figura 13.66

356
13. Entornos de programación gráfica

13.2.5 Práctica 57: control de la velocidad y sentido de un Motor DC


En esta práctica vamos a controlar la velocidad y sentido de giro de un motor DC
desde labVIEW. Es muy interesante abordar este pequeño proyecto, por así
decirlo, ya que debemos recordar lo visto anteriormente relacionado con el
control de motores para implementarlo desde el panel frontal de labVIEW.
Utilizamos, como siempre en estos casos, un driver de corriente LD293 que estará
conectado a dicho motor. Recordando el patillaje de este circuito integrado, se
muestran las conexiones a continuación.

• El Pin 1 (CHIP INHIBIT 1) sirve para activar el motor. Si este pin está
conectado a una salida de Arduino del tipo PWM, se puede variar la
velocidad del motor haciendo variar el valor de esta patilla.
• Los Pines 2 (INPUT 1) y 7 (INPUT 2) permiten fijar el sentido de giro
del motor o la parada. Los pines 3 (OUT 1) y 6 (OUT 2) son los pines
de salida de potencia del motor.

Los pines 7 y 8 de la tarjeta Arduino se utilizan para controlar la dirección


del motor y el pin 11 para el modo PWM. La parte frontal de este ejemplo es muy
sencillo y se muestra en la figura 13.67.

Figura 13.67

Observamos el panel de bloques mostrado en la figura 13.68 Para empezar


se inicializa la conexión con Arduino. Seguidamente se configura el PIN digital 8

357
Taller de Arduino

como salida sentido Derecha y el PIN 9 como salida sentido Izquierda. Dentro del
bucle se ha colocado una estructura tipo Case Estructure que se encargará del
gobierno del motor. La ejecución del bucle se realiza en intervalos de 200 ms.

Los casos a tener en cuenta en esta estructura son dos, que se


corresponden con los dos posibles sentidos de giro del motor. En el primer caso,
True (Figura 13.68): el sentido de giro es a la Izquierda por lo que debemos sacar
los valores correspondientes en las salidas PIN 7 y PIN 8 de Arduino. La velocidad
se recoge del control tipo numérico de aspecto circular que he etiquetado como
Control de velocidad del motor. La Tabla 13.6 muestra el valor de los pines en este
caso.

Figura 13.68

Pin Arduino Valor Pin L293 PIN L293 VALOR


PIN 7 0 0 1 IZQUIERDA
PIN 8 1 0 1
Tabla 13.6

En el segundo caso: False (Figura 13.69): el sentido de giro es a la derecha y


la Tabla 13.7 recoge los valores en este caso.

Pin Arduino Valor Pin L293 PIN L293 VALOR


PIN 7 1 1 0 DERECHA
PIN 8 0 1 0
Tabla 13.7

358
13. Entornos de programación gráfica

Figura 13.69

La conmutación de la estructura Case Structure se realiza mediante un


operador del tipo Greater or Equal To 0. El signo de la condición sale directamente
del control rotatorio ya que tendrá valores positivos en un sentido de giro (0-100),
y negativos en el otro (-100-0).

La velocidad se genera en una escala de -100 a 100 por lo que se debe


multiplicar por 2.5 para alcanzar los 255 que es el valor máximo que se puede
sacar en una salida PWM en el PIN 11. El esquema completo se observa en la
Figura 13.70. La salida del multiplicador es un valor de tipo double (color
naranja) que es incompatible con el tipo de dato entero que debe recibir el
bloque write analog. Por ello, se intercala en medio un control conversor de tipo
de datos.

Figura 13.70

359
Taller de Arduino

13.2.6 Práctica 58: medida de temperatura con un LM35


En esta práctica vamos a adquirir temperaturas de un sensor de temperatura a
través del PIN A0 y las vamos a mostrar en dos indicadores en el panel frontal de
labVIEW. Dicho panel se muestra en la figura 13.71.

Si recordamos como se utiliza este sensor, debemos saber que entrega


10 mV por grado centígrado de temperatura, por lo que hay que utilizar el
bloque de la función de multiplicar para realizar una multiplicación por 100.
De esta manera tenemos la temperatura ajustada y podemos visualizarla
perfectamente en el panel frontal.

En la figura 13.72 se observa el diagrama de bloques de esta práctica.

Figura 13.71

Figura 13.72

360
13. Entornos de programación gráfica

Si activamos el modo depuración con el icono en forma de bombilla, la


ejecución del programa se realizará a cámara lenta, permitiéndonos ver los
valores a lo largo de todo el flujo de los bloques. Esto es interesante cuando algo
no funciona y no sabemos muy bien la razón.

13.2.7 Práctica 59: control de un motor paso a paso (PAP)


En esta práctica controlaremos un motor PAP bipolar desde labVIEW. Antes de
nada, es conveniente que visualicéis este vídeo en YouTube que he realizado para
una mayor compresión de lo que expongo a continuación.

http://www.youtube.com/watch?v=AHPQvV_AkqY

Para excitar suficientemente las bobinas del motor utilizo una Arduino
shield motor, como se observa en la figura 13.73.

Figura 13.73

Figura 13.74

Esta shield utiliza los dos pines 12 y 13 para el control del motor. La
alimentación del motor es de 9 V. El panel frontal es muy sencillo y se muestra en
la figura 13.74. Realmente solo controlamos la velocidad del motor y el número
de pasos que debe dar el motor. El diagrama de bloques correspondiente se
muestra completo en la figura 13.75.

361
Taller de Arduino

En primer lugar, definimos los pines del Arduino que van a controlar el
motor. La utilización de la shield nos obliga a usar los pines 13 y 12. También
establecemos cuántos cables posee nuestro motor, que, en este caso, como es
bipolar, tiene 4 hilos. El siguiente bloque simplemente obedece a los controles del
panel frontal y gira el número de pasos a la velocidad que le indiquemos. Es
importante reseñar que el motor solo realiza una acción y para; si quisiésemos
que se controlara continuamente, habría que utilizar una estructura while.

Figura 13.75

Si queremos manejar el motor inalámbricamente a través de XBee,


debemos apilar dos shields: la propia del control del motor bipolar (Arduino motor
shield) y la shield XBee. Aunque en principio parece imposible físicamente por la
falta de alimentación de la shield Xbee, se puede realizar un «apaño» tomando la
alimentación y la masa de los pines ICSP como expongo en el siguiente vídeo.

http://www.youtube.com/watch?v=oFl85qnZuTM

Además, como vemos en el vídeo, debemos cambiar el tipo de conexión de


labVIEW. En lugar de comunicarlo por el puerto USB/Serial, debemos utilizar
XBee.

13.2.8 Práctica 60: control de un LCD


En esta última práctica vamos a manejar un LCD paralelo desde labVIEW
mostrando un mensaje de texto. Realmente es muy sencillo implementarlo al
utilizar una serie de bloques funcionales que realizan todo el trabajo. Estos
bloques se muestran en las figuras 13.76, 13.77 y 13.78.

Lo único que tenemos que hacer es configurar apropiadamente estos


bloques para que haya una correspondencia entre el panel frontal (Figura 13.79) y

362
13. Entornos de programación gráfica

los pines de conexión de nuestro Arduino. El diagrama de bloques se muestra en


la figura 13.80 y el montaje real en la figura 13.81.

Figura 13.76

Figura 13.77

Figura 13.78

363
Taller de Arduino

Figura 13.79

Figura 13.80

Figura 13.81

364
13. Entornos de programación gráfica

That’s all!!! Ahora, tienes una visión profunda de las posibilidades actuales
de Arduino. Este será tu punto de partida para empezar a desarrollar proyectos
propios. Aspectos como Android y Processing podrían ser perfectamente temas
interesantes en los que podrías embarcarte de ahora en adelante. De todas
maneras, el mundo Arduino está en constante y vertiginoso crecimiento, por lo
que no te faltarán áreas donde practicar. Suerte en lo que sean tus próximas
“arduinoaventuras”.

365
APÉNDICE

PROTEUS Y
ARDUINO

PROTEUS es un entorno integrado diseñado para la realización completa de


proyectos de construcción de equipos electrónicos en todas sus etapas: diseño,
simulación, depuración y construcción. La suite se compone de cuatro elementos,
perfectamente integrados entre sí:

 ISIS es la herramienta para la elaboración avanzada de esquemas


electrónicos, que incorpora una librería de más de 6.000 modelos de
dispositivos digitales y analógicos.

 ARES es la herramienta para la elaboración de placas de circuito


impreso con posicionador automático de elementos y generación
automática de pistas, que permite el uso de hasta 16 capas. Con
ARES el trabajo duro de la realización de placas electrónicas recae
sobre el PC en lugar de sobre el diseñador.

 PROSPICE la herramienta de simulación de circuitos electrónicos


según el estándar industrial SPICE3F5.

 VSM (Virtual System Modelling) es la revolucionaria herramienta que


permite incluir en la simulación de circuitos el comportamiento
completo de los micro-controladores más conocidos del mercado.
PROTEUS es capaz de leer los ficheros con el código ensamblado para
los microprocesadores de las familias PIC, AVR, 8051, HC11,
ARM/LPC200 y BASIC STAMP y simular perfectamente su
comportamiento. Incluso puede ver su propio código interactuar en
tiempo real con su propio hardware pudiendo usar modelos de
periféricos animados tales como displays LED o LCD, teclados,
terminales RS232, simuladores de protocolos I2C, etc. Proteus es
capaz de trabajar con los principales compiladores y ensambladores
del mercado.

366
Apéndice 1. Proteus y Arduino

El distribuidor en España con abundante información y documentación


didáctica sobre el uso del programa es: http://www.hubor-proteus.es.

La versión más actual de este producto es 8.1 que trae integrado el modelo
de Arduino para poder simular y depurar nuestros diseños. Sin embargo, se puede
utilizar Arduino en versiones anteriores de Proteus descargando gratuitamente un
modelo del mismo:

http://blogembarcado.blogspot.com.es/2012/02/simulino-simulando-
arduino.html.

El archivo viene comprimido y contiene dos ficheros importantes llamados:


arduino.lib y arduino.idx. Ambos ficheros, una vez descomprimidos, deben copiarse
en la carpeta Library que está situada bajo el directorio donde está instalado Proteus.

Cuando abrimos Proteus y buscamos: «arduino» en el selector de


componentes nos debe aparecer el modelo tal y como se muestra en la figura xxx.
El segundo paso que realizamos es el de asignarle un fichero con extensión HEX
que hemos obtenido previamente al compilar el sketch con el IDE de Arduino. Sin
embargo, es necesario configurar la visibilidad del fichero compilado en el IDE
mediante su menú de preferencias (figura A1).

Cuando compilemos veremos la ruta del fichero HEX en cuestión como se


observa en la figura A2.

Figura A1

367
Taller de Arduino

Figura A2

Ahora copiamos la ruta del fichero HEX con la combinación de teclas:


Control+C, y lo insertamos con la combinación: Control+V, en las propiedades del
modelo de Arduino en Proteus (Figura A3).

Finalmente, ya podemos simular nuestros proyectos en Proteus. Como el


fichero HEX quedó asignado al modelo, cualquier cambio del sketch que hagamos
no nos obligará a que volvamos a repetir el proceso anterior.

Figura A3

368

Potrebbero piacerti anche