Documentos de Académico
Documentos de Profesional
Documentos de Cultura
open source
Con más de
80 ejemplos !!
INGENIERIA DE MICROSISTEMAS
PROGRAMADOS S.L.
C/ Alda. Mazarredo Nº 47 - 1º Dpto. 2
48009 BILBAO - BIZKAIA
Tel/Fax: 94 4230651
email: info@microcontroladores.com
www.microcontroladores.com
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
INDICE GENERAL
TEMA1: El Universo ARDUINO
1.- INTRODUCCIÓN
i-1
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
3.-EJEMPLO: INTERMITENCIA
3-1 Trabajo personal
5.- EXPRESIONES
5-1 Constantes
5-2 Variables
5-2-1 Tipos de variables
5-3 Operaciones
i-2
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
3.- SERVOMOTORES
3-1 Conexión de servos
3-2 La librería servo.h
3-2-1 Función: #include
3-2-2 Función: attach()
3-2-3 Función: writeMicroseconds()
3-2-4 Función: write()
3-2-5 Función: read()
3-2-6 Función: attached()
3-2-7 Función: detach()
i-3
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
i-4
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
i-5
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
RELACION DE MATERIALES
La siguiente relación se corresponde con los materiales y accesorios necesarios para realizar todos
los ejercicios y experimentos propuestos en el presente módulo 8. Se supone al lector en posesión del
entrenador “UNIVERSAL TRAINER” en cualquiera de sus versiones V1, V2 o V3.
i-6
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
“ARDUINO:la tecnología al alcance de todos”. Editorial: Creaciones Copyright. Autor: Mikel Etxebarria
Isuskiza. La obra se puede considerar como un complemento al contenido del presente módulo de
prácticas. Propone una importante colección de ejemplos que se resuelven con materiales y
componentes muy económicos.
i-7
ARDUINO: La tecnología al alcance de todos
INDICE GENERAL
www.microcontroladores.com
i-8
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Todas ellas tienen un coste bastante elevado que no está al alcance de todos. Únicamente las
Escuelas de formación profesional, Ingenierías, Universidades, así como empresas de diseño, montaje,
investigación y desarrollo (I+D) o similares, se lo pueden permitir.
Afortunadamente a día de hoy esto ya no tiene porqué ser así necesariamente. Gracias a plataformas
como ARDUINO es posible acercar el mundo de la tecnología a todas las personas, empezando por
estudiantes de Enseñanza Secundaria Obligatoria (ESO), bachiller, y módulos profesionales, como a todo tipo
de aficionados a la misma.
ARDUINO es una palabra de origen Germánico que se podría traducir como “El que ayuda a los
amigos”. Allá por el año 2005, en el instituto Italiano de Diseño Interactivo (IVRA), se reúne un equipo de
profesores y alumnos, procedentes de diferentes disciplinas, y liderados por Massimo Banzi, David Cuartielles,
Tom Igoe, Gianluca Martino, David Mellis y Nicholas Zambetti.
Apuestan por desarrollar una tarjeta electrónica sencilla y de muy bajo precio, que pueda ser utilizada
en cualquier tipo de proyecto y en cualquiera de las diferentes disciplinas y áreas del conocimiento. Que tenga
un lenguaje de programación sencillo y fácil de aprender y, sobre todo, ¡accesible y abierta a todo el mundo!.
Esto es ARDUINO.
Este módulo que tienes entre manos pretende acercarte a la tecnología. Para ello, en Ingeniería de
Microsistemas Programados (MSE), hemos diseñado un buen número de ejemplos de programación que
trataremos de presentar de forma ordenada y progresiva. Se trata de que tú, querido lector, puedas aprender a
utilizar la plataforma ARDUINO y su programación de una forma amena y eminentemente práctica.
Lo hemos dividido en una serie de temas que te van a permitir estudiar, analizar y utilizar los múltiples
recursos internos de que consta un controlador como ARDUINO. Al mismo tiempo, vas aprendiendo las
sentencias y funciones más importantes de que consta su lenguaje de programación. Ten en cuenta que todo
lo que aprendas sobre los recursos internos y el lenguaje de programación (muy similar al lenguaje C), lo
podrás utilizar en un futuro no muy lejano sobre controladores más potentes como los utilizados en
aplicaciones comerciales e industriales.
ARDUINO es básicamente una tarjeta electrónica. Con el paso del tiempo se han desarrollado
diferentes modelos que se diferencian en su aspecto y prestaciones. Aunque el lenguaje de programación es
similar para todas ellas, cada uno elige la que mejor se adapte a sus necesidades. En cualquier caso
recordemos que todas ellas son abiertas, por lo que se pueden obtener sus esquemas y toda la información
1-1
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
técnica disponible sobre las mismas. Vamos a echar un vistazo a las más representativas y a sus
características más relevantes.
En la figura 1-3 tenemos otro modelo de tarjeta de control, la ARDUINO NANO. Se trata de una versión
miniaturizada y mejorada de la tarjeta ARDUINO UNO. Viene encapsulada en un formato DIL de 0.6” con 30
pines distribuidos en dos filas de 15 pines, y unas
dimensiones de tan solo 0.73” x 1.70” (18.5 mm x
43.1). Este modelo se puede insertar directamente
sobre un zócalo, una tarjeta impresa o un módulo
board para el montaje sin soldadura, y conectar con
los periféricos que vamos a gobernar en la aplicación.
¡¡ ES LA QUE VAMOS A EMPLEAR EN EL
PRESENTE MÓDULO DE PRÁCTICAS !!
Aunque hemos mostrado las tres tarjetas de control más utilizadas, al menos hoy en día, basta con que
visites la página oficial de ARDUINO (www.arduino.cc), para que veas la variedad de tarjetas ARDUINO
existentes. Además de por su aspecto, las tarjetas se diferencian en sus prestaciones y características. En la
siguiente tabla se hace una breve comparación de las características más relevantes de los tres modelos de
tarjetas de control de ARDUINO que acabamos de presentar.
1-2
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Como ocurre con cualquier otro sistema, las diferentes tarjetas de control de ARDUINO no sirven de
gran cosa si no les conectamos los periféricos que vamos a gobernar: sensores, interruptores, indicadores,
altavoces, motores, displays, pantallas, relés, válvulas y un sinfín de dispositivos diferentes.
Algunos periféricos son de uso tan común y tan extendido, que muchas empresas fabrican las tarjetas
que los contienen. Reciben el nombre de “Shields”, y se pueden conectar o “pinchar” directamente sobre las
tarjetas de control ARDUINO UNO, MEGA 2560, o cualquiera que
sea compatible.
1-3
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Aunque no se trata de un Shield propiamente dicho, otra forma de conectar periféricos a nuestra tarjeta
de control ARDUINO para probar los programas, es mediante el uso de entrenadores de electrónica de
propósito general, como puede ser el de la figura 1-6.
ARDUINO es un controlador al que debemos programar para que realice una determinada tarea. Para
ello necesitamos una serie de herramientas software que nos permitan y faciliten la programación. Una de esas
herramientas es el propio lenguaje que vamos a emplear en el diseño de nuestros programas.
El lenguaje ARDUINO, como todos los lenguajes (incluidos los humanos), está en constante evolución.
Con el tiempo van apareciendo nuevas expresiones, reglas y sentencias. En este módulo de prácticas vamos a
construir nuestros programas y ejemplos usando las funciones principales. Ya tendrás tiempo de ir
profundizando conforme vayas adquiriendo más conocimientos. No olvides que el lenguaje de programación
ARDUINO ¡¡ es libre !!.
1-4
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Otra herramienta software que necesitamos es la conocida como “Entorno de trabajo de ARDUINO”
también conocido como “IDE”. Es una aplicación que se ejecuta en nuestro PC y la podemos conseguir, de
forma gratuita, para los sistemas operativos Windows, Mac OS X y Linux. Con ella podemos escribir nuestros
programas, verificarlos, guardarlos en un archivo, recuperarlos y grabarlos físicamente sobre la memoria
FLASH de programa del controlador ARDUINO. La figura 1-8 muestra el aspecto del IDE de ARDUINO.
Vemos una ventana sobre la cual escribiremos nuestro programa empleando el lenguaje ARDUINO. En
el argot de ARDUINO los programas reciben el nombre de “Sketch”. Mediante una serie de opciones y botones
podremos:
1-5
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Una vez más tenemos que repetir que el entorno IDE de trabajo de ARDUINO, y el lenguaje de
programación que incluye, son totalmente gratuitos y están disponibles en la página web oficial:
www.arduino.cc. Te lo puedes descargar libremente para los sistemas operativos Windows, Mac OS X y Linux.
Es más, recomendamos que periódicamente visites el sitio con objeto de descargar la última versión disponible.
Vamos a ir describiendo el equipo que necesitamos para poder realizar los múltiples ejemplos de
programación que vamos a proponer en el presente módulo de prácticas.
Es el que vamos a utilizar en todos los ejemplos. En la figura 1-9 tenemos la distribución de las patillas
de la tarjeta de control ARDUINO NANO. Te recomendamos que la tengas siempre a mano. Observa que todas
ellas tienen una, dos e incluso tres funciones diferentes que se pueden configurar por programa. Por ejemplo,
la patilla 9 se puede emplear como línea digital de entrada o salida (E/S) o bien como salida de señal PWM. Tal
y como se aprecia en la imagen, la patilla 1 es la primera del ángulo superior izquierdo. Se van contando de
forma correlativa en sentido contrario a las agujas del reloj.
1-6
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
FUNCION DESCRIPCIÓN
D0 – D13 Entradas o salidas digitales. Permiten leer o sacar niveles lógicos: “1” = tensión
(5V); “0” = No tensión (0V)l La línea 13 está conectada a un led situado en la
propia tarjeta.
TX/RX Señales de transmisión (TX) y recepción (RX) en las comunicaciones serie tipo
USART.
RESET Entradas para reiniciar el sistema. Es activa por nivel “0” y están también
conectadas con el pulsador que hay en la propia tarjeta.
GND Entradas de tierra de alimentación
INT0 / INT1 Entradas de interrupción externa. Se pueden configurar por programa para que
sean activas por nivel “0”, o por flanco ascendente o descendente o por cambio
de estado lógico.
PWM Salidas de señal modulada en anchura (PWM)
SDA / SCL Señales para la comunicación serie tipo I2C. Esta comunicación se gestiona
mediante las funciones incluidas en la librería “Wire”
SS / MOSI Señales para la comunicación serie tipo SPI. Esta comunicación se gestiona
MISO / SCK mediante las funciones incluidas en la librería “SPI”
AREF Entrada de tensión de referencia para los convertidores analógico / digital
A0 – A7 Entradas analógicas al convertidor. Este tiene una resolución de 10 bits por lo
que proporciona una escala de 1024 valores diferentes.
3V3 Salida de 3.3V.
+5V Entrada / Salida de la tensión interna de trabajo, estabilizada a 5V
VIN Entrada de tensión de alimentación. Puede estar comprendida entre 6 y 20V
como máximo.
U1
1 30
En lo sucesivo, con el fin de simplificar los esquemas eléctricos de los 2 D1 VIN 29
D0 GND
ejemplos propuestos, el símbolo de la tarjeta ARDUINO NANO lo vamos a 3
RESET RESET
28
4 27
representar como se muestra en la figura 1-10. GND +5V
ARDUINO NANO
5 26
6 D2 A7 25
7 D3 A6 24
Simplemente representamos el número de cada una de las patillas y la 8 D4 A5 23
D5 A4
función principal de las mismas: D0 - D13 (E/S digitales), A0 – A7 (entradas 9
D6 A3
22
10 21
analógicas), RESET, GND, 3V3, AREF, +5V y VIN. Hay que remitirse a la figura 1-9 11 D7 A2 20
D8 A1
anterior para conocer el resto de funciones que pueden estar asociadas a alguna de 12
D9 A0
19
13 18
esas patillas. 14 D10 AREF 17
15 D11 3V3 16
D12 D13
Figura 1-10. Símbolo eléctrico de ARDUINO NANO
Lo presentamos en la figura 1-6 anterior. Se trata de un laboratorio de propósito general para trabajar el
aspecto práctico de la electrónica en sus diferentes especialidades: semiconductores, digital, analógica, micro
programable, etc… Nos aprovecharemos de los recursos que dispone para trabajar con nuestro ARDUINO
NANO:
1-7
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Además, dispone de una amplia zona para el montaje sin soldadura. Esto nos permite insertar la tarjeta
de control ARDUINO NANO, así como montar todos los circuitos eléctricos que necesitemos para llevar a cabo
todo tipo de pruebas y experimentos.
+5Vcc
montaje es común a todos los que iremos haciendo en las sucesivas prácticas.
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
ARDUINO NANO Aunque tenemos dos patillas, la 4 y la 29, por las que podemos aplicar la
señal GND de alimentación, basta con que usemos una de ellas. En este caso
GND
D10
D11
D12
D2
D3
D4
D5
D6
D7
D8
D9
+5Vcc. Tanto GND como +5Vcc nos la suministra el entrenador Universal Trainer
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
V3
La tarjeta de control ARDUINO NANO se inserta a la derecha del módulo board del entrenador. De esta
forma se hace más fácil su conexión con el PC, a través del conector mini USB. También disponemos de una
amplia zona para el montaje de los circuitos y accesorios que precisemos en las diferentes prácticas.
Como se muestra en la figura, empleamos tres cables para la alimentación de +5Vcc (rojos), y otros
tres para la alimentación GND (negros). Ambas alimentaciones las suministra el entrenador Universat Trainer
V3. Al conectar el entrenador se ilumina un led azul que indica la correcta alimentación de la NANO. También
es posible que el led rojo, conectado con D13, parpadee. Esto es porque la NANO suele venir con un programa
de test.
IMPORTANTE: Aunque en este documento, todos los ejemplos se desarrollan sobre el entrenador
Universal Trainer V3, también es posible hacerlo sobre las versiones anteriores, la V1 y la V2, de dicho
entrenador.
1-8
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
En el momento de escribir este documento, la última versión disponible de las herramientas software
de Arduino, el entorno IDE de trabajo y el lenguaje de programación, es la 1.0.5. Se puede descargar de forma
gratuita desde:
www.arduino.cc/en/Main/Software
Recomendamos visitar este sitio con cierta frecuencia para obtener la última versión más actualizada.
Al seleccionar la versión Arduino 1.0.5 (o la que sea), tenemos la opción de elegir para qué sistema
operativo la deseamos: Windows, Mac OS X y Linux. En nuestro caso vamos a trabajar con Windows. Aunque
todos los ejemplos los hemos realizado bajo W XP, también los hemos probado bajo W 7 y W8 de 64 bits.
Funciona todo correctamente.
En la versión 1.0.5 se puede descargar un único archivo ejecutable de instalación llamado “arduino-
1.0.5-windows.exe” y que también lo adjuntamos en el CDROM que acompaña a este módulo de prácticas. Al
ejecutarlo, automáticamente se instala el entorno de trabajo (IDE), el lenguaje, los archivos auxiliares y los
drivers. Basta con ir aceptando las diferentes preguntas que se realizan durante el proceso de instalación.
En el escritorio aparecerá un icono de acceso directo. Al hacer doble click sobre él, se abre la ventana
de trabajo de Arduino, como la mostrada en la figura 1-13.
1-9
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Se trata de un entorno muy sencillo. La mayor parte de tareas las podemos realizar mediante los
botones: verificar, grabar, nuevo, cargar y salvar Sketchs. El área destinada a la escritura de los programas o
sketchs se comporta como un editor de textos convencional.
Las opciones del menú principal permiten realizar las típicas operaciones de Windows relacionadas con
los Archivos (“Archivo”), Edición de textos (“Editar”), Programas (“Sketch”), Selección de herramientas y
configuración (“Herramientas”) y opciones de ayuda (“Ayuda”).
Una de las primeras tareas a realizar es seleccionar con qué tipo de tarjeta de control vamos a trabajar.
En nuestra caso, como se muestra en la figura 1-14, seleccionamos: Herramientas Tarjeta Arduino
Nano w/ Atmega328
Ahora podemos conectar la tarjeta Arduino NANO en uno de los puertos USB de nuestro PC. En
pantalla nos aparece un “globo” indicando que se ha detectado un nuevo dispositivo USB, concretamente el
ARDUINO NANO. Transcurrido un cierto tiempo el sistema nos informa de que el dispositivo está instalado y
listo para usarse.
1 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
Cuando se conecta la tarjeta NANO y se instala sobre un puerto USB, se crea un canal serie virtual
COMx. El siguiente paso es establecer la comunicación entre el entorno de trabajo IDE y dicho canal serie
COMx. Para ello seleccionamos: Herramientas Puerto Serial COMx, como se muestra en la figura 1-15.
Es posible que en nuestro PC tengamos más de un canal serie COM. Si deseamos conocer en cuál de
ellos quedó instalado nuestra tarjeta controladora Arduina NANO cuando la conectamos al puerto USB,
podemos recurrir al administrador de dispositivos de Windows:
Como se muestra en la figura 1-16, el puerto serie virtual se asignó, en nuestro caso, al COM23.
1 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 1: El Universo ARDUINO
www.microcontroladores.com
¡Por fin! ya tenemos todo lo necesario para empezar a trabajar. Podemos hacer un pequeño programa,
a modo de test, para comprobar el correcto funcionamiento de todo el sistema. Puede servir como ejemplo el
que se muestra en la figura 1-17 que, como todos los demás ejemplos, se incluye en el CDROM que acompaña
al módulo de prácticas.
Puedes hacer también la siguiente comprobación. Desconecta el cable USB de la tarjeta Arduino
NANO. Desconecta la alimentación del entrenador y la vuelves a conectar. El led sigue realizando la secuencia
de intermitencia. Esto demuestra que, una vez has transferido un programa a la tarjeta, este permanece en ella
indefinidamente, Arduino NANO es independiente del PC.
Ya estás listo para empezar a realizar los múltiples ejemplos que vamos a ir proponiendo. En Ingeniería
de Microsistemas creemos que te vas a divertir, al mismo tiempo que te vas introduciendo en la tecnología y la
programación. Esperamos que te “enganches”.
1 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
En el mundo digital todas las cosas u objetos se contemplan como si únicamente pudieran tener dos
estados diferentes y opuestos. A esto se le conoce como estados “binarios”. Por ejemplo, una bombilla puede
estar encendida o apagada, pero nunca se pueden dar ambas situaciones al mismo tiempo. Ejemplos como
este podemos poner muchos:
Un interruptor o un pulsador puede estar accionado o no, pero no ambas cosas al mismo tiempo
El motor está girando (no importa a qué velocidad) o puede estar parado.
La sirena de una alarma está activada o no lo está.
Un relé puede estar activado o no, lo mismo que por ejemplo, una electro válvula.
Podemos tener pulsada una tecla del teclado de nuestro ordenador, o no tenerla.
Un sensor detecta la presencia de un objeto o su ausencia.
Tu mismo, puedes reír o llorar, vivir o morir, pero nunca ambas cosas al mismo tiempo.
“nivel 1” cuando hay tensión (+V). También se le denomina “nivel alto”, “high”, “ON” o, simplemente, “1”
“nivel “0” cuando no hay tensión (0V). También se le denomina “nivel bajo”, “low”, “OFF” o,
simplemente, “0”
Quizá a partir de este momento entiendas un poquito más el funcionamiento del programa de Test que
viste en el tema anterior. Al led conectado en la patilla D13 de E/S se le aplicaba un nivel alto (HIGH) y se
iluminaba. Luego se le aplicaba nivel bajo (LOW) y se apagaba. El proceso se repetía de forma indefinida con
un intervalo de tiempo de 1 segundo para cada caso.
El eje horizontal representa el tiempo T. Muestra el intervalo de tiempo en que la señal digital
permanece a “0”, luego a “1” y vuelta a valer “0”. Ahora fíjate en el diagrama de tiempos de la figura 2-2.
Representa a tres señales digitales de otros tantos dispositivos: un interruptor, un motor y una bombilla.
El interruptor está abierto (sin accionar) durante un segundo. Luego se cierra (acciona) durante otro
segundo. Se abre durante tres segundos y, finalmente, se cierra durante dos.
El motor está parado durante dos segundos, en movimiento durante cuatro y parado durante uno.
La bombilla se apaga y enciende a intervalos de un segundo. ¿Te suena?
2-1
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
Son señales binarias que se introducen al controlador (p.e. a la tarjeta Arduino NANO) a través de
determinadas patillas, y procedentes de determinados periféricos de entrada como pueden ser interruptores,
pulsadores, sensores, detectores, teclados, etc…Sea cual sea el periférico empleado, solo puede introducir
señales con niveles lógicos binarios: “0” (no tensión) o “1” (tensión).
2-2
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
No importa cuál de los dos circuitos empleemos. Lo realmente importante es saber cómo leer la entrada
del controlador a la que está conectado ese pulsador, e interpretar correctamente el valor binario leído.
Son señales binarias de nivel “0” (no tensión) o de nivel “1” (tensión) que, es esta ocasión, proporciona
el controlador por algunas de sus patillas. En esas patillas conectamos los periféricos de salida que vamos a
gobernar tales como: bombillas, relés, motores, válvulas, alarmas, etc.. El controlador puede por tanto
activarlos o desactivarlos.
Uno de los periféricos de salida más sencillos y económicos son los llamados diodos “Led”. Son
pequeños dispositivos que cuando se activan emiten luz. El led tiene dos patillas: ánodo (A) y cátodo (K). Para
que se ilumine es necesario aplicarles una tensión de “polarización directa”. Se consigue cuando el ánodo (A)
es positivo respecto al cátodo (K). Los hay de diferentes formas, tamaños y colores y se emplean mucho como
pilotos de señalización o indicadores.
Nuevamente no es importante cuál de los dos circuitos empleemos. Lo que realmente importa es saber
qué hay que hacer para que el controlador saque por sus patillas de salida, cualquiera de los dos
niveles lógicos.
RECORDAR: Lo mismo que leemos el estado de un pulsador, podemos leer el estado de una tecla, un
interruptor, un sensor, un final de carrera, etc… Igualmente, si que somos capaces de activar o desactivar un
led, podremos activar o desactivar un relé, un motor, una válvula, etc..
IMPORTANTE. La corriente que es capaz de entregar un controlador por cualquiera de sus patillas de salida,
es limitada. En el caso de Arduino NANO es una corriente de 40mA, suficiente para activar directamente leds o
cargas de consumo similar. Si se quiere controlar dispositivos con un mayor consumo, las líneas de salida
deben conectarse a circuitos que amplifiquen en corriente y/o en tensión la señal. De no hacerlo es muy posible
que estropeemos el controlador.
2-3
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
Ya va siendo hora de que estudiemos las funciones del lenguaje Arduino encargadas de controlar las
líneas de entrada o salida (E/S) de nuestra tarjeta Arduino NANO. Fundamentalmente son tres y muy sencillas:
Configura una línea digital (patillas D0 - D13) para que actúe como entrada o como salida.
Normalmente se suele poner al principio de un programa. Por defecto, al iniciar el sistema, todas las líneas de
E/S quedan configuradas como entradas.
Sintaxis:
pinMode(pin,modo)
Ejemplos:
Lee y devuelve el estado (“1” o “0”, “HIGH” o “LOW”) de cualquiera de las patillas digitales.
Sintaxis:
digitalRead(pin)
Ejemplos;
Escribe o saca por una patilla digital de salida el valor binario “1” o “0”, “HIGH” o “LOW”.
Sintaxis:
digitalWrite(pin,valor)
Ejemplos
2-4
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
¡Manos a la obra! Vamos a resolver íntegramente nuestro primer proyecto al que llamaremos “Función
SI”. Será una cosa muy sencilla pero que nos permitirá utilizar las tres funciones anteriores y observar el
aspecto general de un programa escrito en el lenguaje Arduino.
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
“0”. Fíjate en el esquema eléctrico de conexiones de la figura 2-7.
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
3V3
VIN
GND
RESET RESET
AREF
5-1 Montaje práctico
ARDUINO NANO
GND
D10
D11
D12
como ya sabemos, dispone de múltiples dispositivos de prueba. Conectamos el
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
led S0 con la señal D2 de la tarjeta Arduino NANO (patilla 5). El interruptor E0 lo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
conectamos con la señal D3 (patilla 6).
La fotografía de la figura 2-8 muestra el montaje práctico realizado sobre el entrenador. Procura
emplear cablecillos de diferentes colores para, por ejemplo, distinguir entre las entradas y las salidas.
2-5
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
En primer lugar vamos a ver qué aspecto tiene un programa escrito en el lenguaje Arduino, sobre su
entorno IDE de trabaja. Observa la figura 2-9.
Vallamos por partes. Ya ves que hemos dividido la pantalla de trabajo en tres secciones. Vamos a
detallarlas.
Sección 1
Aunque no solemos hacerlo por pura pereza, es una muy buena práctica documentar los programas.
Los comentarios sirven para informar de quien es el autor, la empresa, versión del programa, fecha de creación
y todo aquello que se considere oportuno. También se puede indicar qué herramientas hardware o software se
necesitan para ejecutar el programa y, lo más importante, explicar brevemente qué es lo que hace.
2-6
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
Podemos escribir cualquier tipo de texto siempre y cuando vaya encerrado entre los signos /* ……… */.
También se puede documentar cada sentencia o grupo de sentencias del programa, para explicar qué es lo
que hacen. Se suele hacer mediante textos sencillos que van precedidos de los signos //.
En, general podemos poner cualquier texto en cualquier lugar del programa. Si es un texto de varias
líneas, se encierra entre /* …. */, y si es de una única línea, suele ir precedido de //.
Sección 2
En el lenguaje Arduino es necesario incluir la función setup(). Normalmente suele ir al principio del
programa. Todas las sentencias que estén incluidas dentro de las llaves, se ejecutan una única vez, al iniciar el
sistema. Por este motivo aquí suelen ponerse las funciones de configuración, como por ejemplo:
void setup()
{
pinMode( 2 , OUTPUT );
}
La señal D2 queda configurada como salida y no es muy probable que esta situación cambie a lo largo
de un mismo programa. Puedes poner cualquier tipo de función, pero recuerda: sólo se ejecutan una vez. En
ocasiones quizá no necesites configurar nada. En este caso, aunque vacía, también es necesario ponerla:
void Setup()
{
}
Sección 3
Esta función también es imprescindible y contiene el cuerpo principal de nuestro programa. Todas las
funciones que lo componen deben estar cerradas entre las llaves. En nuestro ejemplo:
Void loop()
{
digitalWrite( 2, digitalRead(3));
}
Todas las funciones que estén incluidas entre las llaves {……} se ejecutan de forma indefinida, desde
la primera a la última y de nuevo la primera. En nuestro ejemplo, la lectura de la entrada D3 y la escritura sobre
la salida D2, se ejecutan constantemente a la velocidad propia del controlador.
En otros lenguajes de alto nivel como el C, está función también es imprescindible y suele recibir el
nombre de “main()”.
Una vez tenemos escrito nuestro programa, el siguiente paso es transferirlo a la memoria Flash del
controlador. Es una tarea muy sencilla. Basta con pulsar el botón “Cargar” del entorno de trabajo IDE de
Arduino. Transcurrido un cierto tiempo, nos aparecerá un mensaje de “Carga terminada”, así como un resumen
de la memoria que consume nuestro programa sobre el total disponible. Ver de nuevo la figura 2-9.
Es importante que sepas que, una vez que cargas un programa en el controlador, este se mantiene por
tiempo indefinido aunque desconectes la alimentación. La única forma de borrarlo es cargando otro programa
nuevo.
2-7
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
5-4 Comprobación
Es el último paso. Es la hora de comprobar si todo, tanto el hardware como el software, funciona
correctamente. Nuestro actual ejemplo es muy sencillo de verificar. Basta que introduzcas un nivel “1” con el
interruptor E0 (interruptor hacia arriba). El led S0 se debe iluminar. Cuando introduces un nivel “0” (interruptor
E0 hacia abajo), el led se apaga.
Debes tener en cuenta que a la velocidad que el controlador ejecuta nuestro programa, cualquier
cambio que se produzca en la entrada D3 (interruptor E0), repercute inmediatamente sobre la salida D2 (Led
S0).
En este instante seguro que te estás cuestionando si es necesario utilizar un controlador para iluminar
una simple bombilla mediante un interruptor. Tiempo al tiempo, ya se irán complicando los programas e irás
viendo las casi infinitas posibilidades que posee.
Por ejemplo, puedes modificar tanto el esquema eléctrico como el programa anterior para controlar el
encendido de varios leds mediante varios interruptores.
Te propongo controlar cuatro leds de salida conectados con las señales D2, D3, D3 y D4, mediante 4
interruptores conectados con las señales D5, D6, D7 y D8 del controlador. Dibuja a continuación el esquema
eléctrico y escribe el programa correspondiente.
2-8
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
En el mundo digital es muy frecuente hacer ciertas operaciones llamadas “Funciones lógicas”.
Realmente, el ejemplo anterior respondía a una de ellas: la función “SI”. En la figura 2-10 su resume el
funcionamiento.
La “tabla de la verdad” resume el valor
binario de la salida S, en función del
valor binario de la entrada E. Es muy
sencillo. Si E=0 S=0, si E=1 S=1.
También se representa el diagrama de
tiempos. Si lo miras con cuidado verás
que equivale a la tabla de la verdad. Por
último se muestra el símbolo eléctrico
que se emplea para esta función.
Figura 2-10 La función lógica SI
El funcionamiento del programa “Función_SI” del ejemplo anterior respondía exactamente a esta tabla
de la verdad. También podemos establecer la ecuación lógica para esta función:
=
6-1 Función lógica NO
Se trata de lo contrario a la función SI. También se le suele llamar función “NOT”. En la figura 2-11 se
resume su funcionamiento.
El símbolo “ ! ” se emplea para expresar la función NO al escribir nuestros programas. Dicha función
responde a la siguiente ecuación lógica:
=
Estudia el siguiente programa, “Función_NO”. Lo escribes y lo grabas.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, ! digitalRead(3)); //D2 e la función NO con D3
}
Comprueba que cuando el interruptor E0 está a “0” (hacia abajo), el led S0 está …………………………………
Comprueba que cuando el interruptor E0 está a “1” (hacia arriba), el led S0 está …………………………………
………………………………………………………………………………………………………………………………….
2-9
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16 3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
Realizar el montaje representado en el esquema eléctrico de la figura 2- ARDUINO NANO
13. Este mismo montaje lo vamos a emplear en los siguientes ejemplos con los
GND
D10
D11
D12
que vamos a finalizar el presente tema.
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
La patilla 5 de la tarjeta de control Arduino NANO se corresponde con la señal
D2 y se conecta con el led S0 del entrenador.
S0 E2 E1
2 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, digitalRead(3) & digitalRead(4)); //Función AND entre D3 y D4
}
Comprueba que si cualquier entrada está a “0”, la salida se mantiene a nivel lógico…………….
La salida es de nivel lógico ……………… cuando ambas entradas están a nivel ………………..
6-3 Función O
Emplearemos el mismo esquema eléctrico y el mismo montaje práctico que se mostraba en las figuras
2-13 y 2-14.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, digitalRead(3) | digitalRead(4)); //Función OR entre D3 y D4
}
Comprueba que la salida es “0” cuando las entradas están a nivel ………………………….
2 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
Como consecuencia de combinar entre sí las funciones lógicas anteriores, podemos obtener otras
funciones lógicas derivadas. Vamos a estudiarlas a continuación.
Se trata de una función AND (&) a cuya salida se le aplica una función NOT (!). El programa
“Función_NAND” puede ser algo así como esto.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, ! (digitalRead(3) & digitalRead(4))); //Función NAND entre D3 y D4
}
Observa con cuidado los paréntesis. Siempre se ejecutan las funciones que estén en los paréntesis
más internos. En este caso se leen las entradas D3 y D4 y se realiza la función AND (&) con ellas. A
continuación, con el resultado obtenido, se realiza la función NOT (!) y el resultado se escribe sobre la salida
D2. Escribe y carga el programa sobre la tarjeta Arduino NANO. Comprueba el funcionamiento.
= +
Figura 2-17. Función NOR
Se trata de una función OR (|) a cuya salida se le aplica una función NOT (!). Realiza una suma lógica
(que no aritmética) invertida. El programa “Función_NOR” que resuelve esta ecuación puede ser el siguiente.
2 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, ! (digitalRead(3) | digitalRead(4))); //Función NOR entre D3 y D4
}
Observa con cuidado los paréntesis. Siempre se ejecutan las funciones que estén en los paréntesis
más internos. En este caso se leen las entradas D3 y D4 y se realiza la función OR (|) con ellas. A
continuación, con el resultado obtenido, se realiza la función NOT (!) y el resultado final se escribe sobre la
salida D2. Escribe y carga el programa, y comprueba el funcionamiento.
=( )∙ )+( ∙( )
Figura 2-18. La función XOR
Una función AND realiza el producto lógico de las entradas E1 invertida y E2. Otra función AND realiza
el producto de E1 y E2 invertida. Con el resultado de ambas funciones AND se realiza una suma lógica (que no
aritmética) mediante una función OR que ofrece el resultado final. Fíjate en los paréntesis del programa de
ejemplo “Función_XOR”, que resuelve la ecuación.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, (( ! digitalRead(3) & digitalRead(4)) | (digitalRead(3) & ! digitalRead(4)))); //Función XOR
}
Lee e invierte (!) el estado de la entrada D3 y realiza la función AND (&) con D4. Luego lee e invierte (!)
D4 y realiza la función AND (&) con D3. Con los resultados de ambas funciones AND se realiza una función OR
(|), cuyo resultado final se escribe sobre la salida D2.
2 - 13
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
=( )∙ + ∙( )
Figura 2-19. La función XNOR
Una función AND realiza el producto lógico de las entradas E1 invertida y E2. Otra función AND realiza
el producto de E1 y E2 invertida. Con el resultado de ambas funciones AND se realiza una suma lógica (que no
aritmética) mediante una función OR. El resultado de esta función OR se invierte para obtener el resultado final.
Fíjate en los paréntesis del programa de ejemplo “Función_XNOR”, que resuelve la ecuación.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2, ! (( ! digitalRead(3) & digitalRead(4)) | (digitalRead(3) & ! digitalRead(4)))); //Función
XNOR entre D3 y D4
}
Lee e invierte (!) el estado de la entrada D3 y realiza la función AND (&) con D4. Luego lee e invierte (!)
D4 y realiza la función AND (&) con D3. Con los resultados de ambas funciones AND se realiza una función OR
(|). El resultado de esta función OR se vuelve a invertir (!) para obtener el resultado final que se escribe sobre la
salida D2.
Hasta el momento, todas las líneas de entrada o salida de nuestro controlador Arduino NANO, se han
manipulado de forma individual. Mediante las sentencias pinMode(), digitalRead() y digitalWrite() podemos
configurar, leer y escribir cualquiera de las 14 líneas de E/S digitales numeradas de la D0 a la D13.
Es una forma muy sencilla de controlar ciertos periféricos como pueden ser pulsadores, interruptores,
leds, relés, etc…, pero SIEMPRE de forma individual. Se lee o se escribe sobre una determinada línea, valores
de un único bit: el “0” o el “1”.
Sin embargo, hay ocasiones en que necesitaremos poder leer o escribir en algún periférico, varios bits
AL MISMO TIEMPO: una pantalla, un display de 7 segmentos o, por ejemplo, un conjunto de relés que deben
reaccionar al unísono. Hacerlo mediante las funciones que conocemos no es recomendable ya que solo
pueden manipular un bit cada vez.
2 - 14
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
De las 14 líneas de E/S que dispone Arduino NANO, 8 de ellas se encuentran en el Puerto D. Se trata
de las líneas digitales D0-D7 y se encuentran en las patillas 1, 2, 5, 6, 7, 8, 9 y 10 del controlador
respectivamente. Las 6 patillas de E/S restantes se encuentran en el Puerto B. Corresponden a las líneas
digitales D8-D13 y se encuentran en las patillas 11 a la 16. Se recomienda repasar la figura 1-9.
Los 8 bits del Puerto C se corresponden con las 8 entradas analógicas A0-A7. Se corresponden con las
patillas 19-26 respectivamente. Se recomienda repasar la figura 1-9.
A partir de este momento, si conseguimos leer o escribir en cualquiera de esos puertos, estaremos
haciendo transferencias de datos de 8 bits simultáneamente, y no de un solo bit como lo hemos venido
haciendo hasta ahora.
Cada puerto se controla mediante 3 registros a través de los cuales podemos configurarlo como
entrada o salida, leer un valor de 8 bits procedentes de las patillas de un puerto de entrada o escribir un valor
de 8 bits sobre las patillas de un puerto de salida. La siguiente tabla resume dichos registros.
El lenguaje de programación Arduino permite manejar esos registros en forma de variables. Podemos
leer el valor que contienen en un momento dado y también escribir nuevos valores en ellos. Un ejemplo vale
más que mil palabras.
Ejemplos:
DDRD = B00001111; Escribe el valor binario (B) sobre el registro DDRD. Esto configura las líneas D0-D3
como salida y las líneas D4-D7 como entradas.
PORTD = B00000110; Saca el valor binario por las líneas de salida D0-D3. D1 y D2 se ponen a nivel “1”; D0 y
D3 se ponen a nivel “0”.
DDRB = 0; Las líneas D8-D13 del Puerto B se configuran como entradas.
A = PINB; La variable A se carga con el valor presente en las líneas de entrada del Puerto B
Ya ves que es muy sencillo. Basta con expresar qué valores quieres almacenar en cada registro para
que puedas, bien configurarlo, o bien sacar un determinado valor por sus correspondientes patillas. Dicho valor
lo puedes expresar en binario (B00001111), en hexadecimal (0xF) o bien en decimal (15). Todos ellos son
equivalentes. La opción en binario es especialmente útil en estos casos.
2 - 15
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
NOTA:
El uso de esta técnica nos permite actuar simultáneamente sobre varias líneas de entrada o salida, pero
puede provocar ciertos problemas. Ten en cuenta que algunas líneas tienen otras funciones. Por ejemplo, D0
y D1 pueden ser usadas como recepción (Rx) y transmisión (Tx) en serie. D5 y D6 pueden ser salidas PWM,
la línea D4 puede ser la señal SDA en comunicaciones I2C, etc… Estas funciones son gestionadas por
ciertas sentencias del propio lenguaje Arduino. Ahora bien, si cambiamos sus configuraciones esas
sentencias pueden no funcionar correctamente.
+5Vcc
Observa el esquema del montaje de la figura 2-21. Tenemos 4
interruptores, E3:E0, conectados con las líneas D11:D8
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
AREF
VIN
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
S0
S2
S3
E0
Figura 2-21. Esquema de montaje
void setup()
{
DDRD = B00001111; //D3:D0 salidas
DDRB = 0; //D11:D8 entradas
}
void loop()
{
PORTD = PINB; //Lee las entradas D11:D8 y lo guarda en las salidas D3:D0
}
En la función void setup() configuramos las entradas y salidas. En DDRD se configura que las líneas
D3:D0 actúan como salidas. En DDRB se configuran todas las líneas como entradas. Aunque en este caso sólo
se emplean las líneas D11:D8, siempre es recomendable configurar también como entradas, aquellas líneas
que no se usen.
La función void loop() es el programa principal. Simplemente carga en PORTD (salidas D3:D0) el
resultado de leer PINB (entradas D11:D8). Tanto la lectura de las cuatro entradas como la escritura sobre las
cuatro salidas se hace simultáneamente.
Si hubiéramos empleado las sentencias digitalRead() y digitalWrite() el programa hubiera sido bastante
más largo y menos eficiente. Tendríamos que hacer tantas lecturas y escrituras como líneas queramos
explorar. Además, esas lecturas y escrituras se harían de una en una, no de forma simultánea.
2 - 16
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
+5Vcc
Realiza el montaje correspondiente al esquema de la figura 2-
22. Los interruptores E3:E0 se conectan con las líneas
D11:D8 respectivamente. Se configurarán como entradas.
Con ellos vamos a introducir, a modo de dato variable, un
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
número binario de 4 bits que puede ir desde 0000 (0) hasta
D13
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
RESET RESET
AREF
VIN
GND
1111 (15).
ARDUINO NANO
Los 8 leds S7:S0 del laboratorio Universal Trainer se
GND
D2
D3
D4
D5
D6
D7
D8
D9
S0
S2
S3
S4
S5
S6
S7
void loop()
{
PORTD = (PINB & B00001111) + 5; //Suma 5 al valor de las entradas D11:D8
}
Al leer el Puerto B (PINB) se obtiene el estado lógico de TODAS sus líneas de entrada (que son 6). Sin
embargo en este ejemplo solo nos interesa el estado de las líneas D11:D8 (las 4 de menos peso), a las que
hemos conectado los 4 interruptores. Para evitar leer valores impredecibles en las líneas no conectadas, es
muy frecuente emplear una función lógica, en este ejemplo la función AND, con objeto de descartarlas (PINB &
B00001111). El resultado de la lectura de esas entradas siempre será B0000XXXX.
Modifica convenientemente el programa para realizar las operaciones que se proponen en la siguiente
tabla. Anota en ella los diferentes resultados de salida.
2 - 17
ARDUINO: La tecnología al alcance de todos
TEMA 2: Las entradas y salidas Digitales
www.microcontroladores.com
2 - 18
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
velocidad a la que trabajan los controladores. Nuestro Arduino NANO no podía
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
3V3
RESET RESET
VIN
GND
AREF
ser menos. Monta el circuito de prueba según el esquema mostrado en la figura
3-1. ARDUINO NANO
GND
De momento únicamente vamos a emplear el led S0 del entrenador,
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
que lo conectaremos con la señal D2 (patilla 5) del controlador Arduino NANO.
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
S0
Figura 3-1. Esquema del circuito de prueba
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2,HIGH); //La salida D2 se pone a "1"
digitalWrite(2,LOW); //La salida D2 se pone a "0"
}
Es muy sencillo. La salida D2 se pone a nivel “1” (el led S0 se enciende) y luego la salida D2 se pone a
nivel “0” (el led S0 se apaga). Ambas funciones están dentro de la función principal void loop(), por lo que se
ejecutan de forma indefinida y el led se estará apagando y encendiendo constantemente.
Ahora bien, ¿cómo ves el led S0 de salida? Lo ves permanentemente encendido. ¿Por qué? Porque a
la velocidad que trabaja el controlador, el encendido y apagado es tan rápido que la retina de nuestros ojos ve
al led siempre encendido. ¡Es una sensación óptica! El led sí que se apaga, pero no lo vemos.
Un controlador como el Arduino NANO es capaz de ejecutar cientos de miles de instrucciones por
segundo. Es una velocidad tan rápida que, en ocasiones, vamos a tener que obligarle a que realice ciclos de
espera o “temporizaciones”.
Una función de temporización en un programa, detiene la ejecución del mismo durante un determinado
tiempo. El tiempo que deseamos “perder” se puede expresar en microsegundos o en milisegundos. El lenguaje
Arduino de programación dispone de dos funciones para ello.
Realiza una temporización de tantos microsegundos (µS) como se indiquen. Recuerda que: 1 segundo
= 1000 mS, y 1 mS = 1000 µS. Así que: 1 segundo = 1.000.000 µS.
Sintaxis:
delayMicroseconds(n)
3-1
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
n: Expresa el número de microsegundos que se desea temporizar. Se trata de un número entero (16 bits)
sin signo (“unsigned int”). Actualmente el número más grande que se puede indicar para realizar una
temporización con precisión es de 16.383 (aproximadamente 16 mS). Esto puede variar en futuras
versiones del lenguaje. Para realizar temporizaciones mayores se recomienda emplear la función
delay().
Ejemplos:
A=100;
delayMicroseconds(A); //Temporiza 100 µS = 0.1 mS = 0.0001 segundos
delayMicroseconds(1000); //Temporiza 1000 µS = 1 mS = 0,001 segundos
Realiza una temporización de tantos milisegundos (mS) como se indiquen. Recuerda que: 1 segundo =
1000 mS, y 1 mS = 1000 µS.
Sintaxis:
delay(n)
n: Expresa el número de milisegundos que se desea temporizar. Se trata de un número que puede ser un
entero largo (32 bits) sin signo (“unsigned long”). Un número entero largo, con sus 32 bits, ocupa 4
32
bytes y puede representar un valor desde 0 hasta 4.294.967.295 (2 -1).
Ejemplos:
A=100;
delay(A); //Temporiza 100 mS = 0,1 segundo
delay(1000); //Temporiza 1000 mS = 1 segundo
delay(60000); //Temporiza 60000 mS = 60 segundos = 1 minuto
El programa “Intermitencia” es una versión mejorada del ejemplo anterior. Observa que se intercala
una temporización cada vez que se enciende o apaga el led. Se parece al programa “Test” que vimos en el
Tema 1.
void setup()
{
pinMode( 2 , OUTPUT); //D2 Salida
}
void loop()
{
digitalWrite(2,HIGH); //La salida D2 se pone a "1"
delay(Tiempo); //Temporiza
digitalWrite(2,LOW); //La salida D2 se pone a "0"
delay(Tiempo); //Temporiza
}
Cuando lo cargues sobre el controlador Arduino NANO, ahora sí que puedes apreciar perfectamente
que el led se enciende y apaga a intervalos de un segundo.
3-2
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
El ejemplo crea una variable, “Tiempo”, a la que se le carga con el valor de temporización deseado, en
este caso 1000 mS = 1 seg. El valor de esa variable se puede modificar para hacer una intermitencia más o
menos rápida. Cada vez que se cambie, debes volver a cargar el programa sobre el controlador.
Puedes modificar el valor de la variable “Tiempo” tanto como desees. Proponemos que lo vayas
reduciendo de forma sucesiva hasta que no se aprecie la intermitencia del led. Anota aquí el valor de “Tiempo”
a partir del cual el led lo ves permanentemente iluminado.
Valor: ……………………………….…………………………………………………………………………………
Mediante una serie de ejemplos, vamos a seguir jugando con las temporizaciones. Puedes usar tu
imaginación para realizar programas cada vez más complejos y llamativos.
4-1 El “Faro”
Se trata de un ejemplo muy sencillo que trata de simular el funcionamiento de un faro o baliza que
señala su posición, mediante una serie de destellos regulares. En el ejemplo se producen tres destellos rápidos
seguidos de una pausa de 1.5 segundos.
Más adelante aprenderás funciones y técnicas de programación que te permitirán escribir este mismo
programa con muchas menos instrucciones, haciendo que sea más óptimo y consuma menos memoria del
controlador.
+5Vcc
4 27
S3:S0, que se conectan respectivamente con las salidas D2:D5 S3 5 GND +5V 26
D2 A7
de nuestro controlador, tal y como se muestra en el esquema
ARDUINO NANO
6 25
7 D3 A6 24
de la figura 3-2. S2 8 D4 A5 23
9 D5 A4 22
10 D6 A3 21
El programa enciende secuencialmente, de derecha a S1 11 D7 A2 20
D8 A1
izquierda, desde S0 a S3, cada uno de los leds, dando una 12
D9 A0
19
13 18
sensación de movimiento. Ver el montaje en la figura 3-3. S0 14 D10 AREF 17
15 D11 3V3 16
D12 D13
Figura 3-2. Esquema del “Juego de luces”
3-3
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
+5Vcc
4 27
VERDE S2 5 GND +5V 26
D2 A7
ARDUINO NANO
6 25
El led S2 se conecta con la señal D2 y emula a la 7 D3 A6 24
AMBAR S1 8 D4 A5 23
luz verde. El led S1 se conecta con D3 y emula a la luz 9 D5 A4 22
ámbar. S0 se conecta con D4 y emula a la luz roja. 10 D6 A3 21
ROJO S0 11 D7 A2 20
12 D8 A1 19
D9 A0
El pulsador E10 se conecta con la entrada de 13
D10 AREF
18
14 17
RESET. Se emplea para iniciar la secuencia de 15 D11 3V3 16
D12 D13
funcionamiento del semáforo.
Si te fijas en el programa verás un detalle importante. Todas las funciones que lo componen están
incluidas en la función void setup(). Esto quiere decir que sólo se van a ejecutar una única vez: cada vez que
se reinicie el sistema. Por su parte, la función void loop() está vacía. No contiene ninguna instrucción para
ejecutar. Cuando el controlador entra en ella, se queda sin hacer nada en un bucle infinito. En otras palabras,
la secuencia del semáforo sólo se produce cuando pulses el botón RESET de reinicio.
Modifica los tiempos en que cada luz permanece encendida y/o apagada.
Si te fijas en un semáforo convencional, verás que antes de que la luz verde pase a ámbar, y la
ámbar pase a roja, ambas luces realizan una serie de destellos de aviso. ¡Date prisa!
5.- EXPRESIONES
A estas alturas habrás observado que las instrucciones que hemos visto hasta el momento, y la
mayoría de las instrucciones del lenguaje Arduino, necesitan uno o más parámetros u operandos para su
correcto funcionamiento. Estos van cerrados entre paréntesis y separados por “,”. De momento hemos
estudiado:
Esos parámetros los podemos indicar de diferentes formas. Es más, algunas de ellas ya las hemos
usado en los diferentes programas de ejemplo propuestos.
3-4
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Constante: El valor del parámetro se proporciona directamente en la propia función. Por ejemplo:
delay(1000). Temporiza directamente 1000 mili segundos.
Variable: El valor del parámetro está previamente definido y guardado en una variable. Por
ejemplo: delay(Tiempo). El valor a temporizar está guardado en la variable “Tiempo” y el controlador
debe ir a buscarlo.
Operación: El valor del parámetro se obtiene como consecuencia de realizar cualquier tipo de
operación aritmético/lógica entre variables y/o constantes. Por ejemplo: delay((Tiempo+1000)/3).
Temporiza tantos milisegundos como resulten de calcular el valor de la variable “Tiempo” más 1000 y
todo ello dividido entre 3.
No se puede decir cuál de estas formas de expresar los parámetros o datos es la mejor. Las
usaremos en cada caso según mejor nos convenga.
5-1 Constantes
Cuando en un programa se utiliza un valor que siempre es fijo y nunca varía, se emplea como un dato
“constante”. Si en un momento dado tienes que realizar una temporización que siempre es igual, por ejemplo
de 1 segundo, emplearás delay(1000).
El controlador ejecuta esa instrucción siempre con el mismo parámetro (1000). NO se puede variar
dinámicamente durante la ejecución del programa. La única forma de cambiarlo es modificando el programa
y grabándolo nuevamente en la memoria del controlador.
Otro ejemplo. Imagina que debes realizar un programa para calcular la longitud de una circunferencia
en función de un diámetro dado. La ecuación a resolver sería: = ∙ , donde:
Los datos constantes forman parte del propio programa y se encuentran como parámetros en las
propias instrucciones o funciones del mismo. Se guardan por tanto en la memoria FLASH de programa del
controlador. Se trata de una memoria NO VOLATIL de sólo lectura. No se puede modificar (salvo cuando se
graba el programa) y su contenido se mantiene incluso cuando se desconecta la alimentación.
En algunos de los ejemplos que ya hemos hecho se han empleado palabras como: HIGH o LOW,
INPUT u OUTPUT o TRUE o FALSE. Son palabras “clave” del lenguaje Arduino tratadas como “constantes”.
5-2 Variables
3-5
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Como ya hemos hecho en alguno de los ejemplos anteriores, las variables han de ser declaradas
previamente para luego poder ser utilizadas, según la siguiente sintaxis:
tipo: Establece qué tipo de información va a contener la variable. Puede ser números, letras o textos.
nombre: Es el nombre que vamos a asignar a la variable y con el que la vamos referenciar en lo sucesivo a
lo largo del programa. Lo ideal es que se empleen nombres no muy largos y que recuerden un
poco su contenido. El nombre de una variable debe empezar siempre por una letra, no por un
número y no debe contener espacios en blanco.
valor: Es el valor que metemos en la variable o recipiente. Es opcional. Podemos crear una variable
vacía, sin introducir ninguna información en su interior. Simplemente le hacemos una reserva en la
memoria RAM del controlador para cuando la necesitemos.
La siguiente tabla resume algunos de los tipos más corrientes para la declaración de variables.
En función del tipo de variable que vayamos a crear, debemos saber que se consume una mayor o
menor cantidad de memoria RAM. Es conveniente definir adecuadamente una variable según el tipo de
información que vaya a contener. Por ejemplo, una variable tipo “long” consume 4 bytes de memoria RAM. Su
uso es bastante poco recomendable si la información que va a contener es, supongamos, de tipo byte. La
memoria RAM es limitada y un uso inadecuado de variables la puede terminar agotando.
Por ejemplo, imagina que a una variable tipo byte que contiene el valor 253, se le suma 6. El
resultado debiera ser 259, sin embargo vemos que es 3. ¿Por qué? Porque en una variable tipo byte el valor
8
máximo que cabe es de 0 a 255 (2 -1). Luego se desborda, vuelve a 0 y empieza de nuevo.
3-6
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Otro tipo de variables son los llamados Arrays. Un array es una colección de variables de cualquiera
de los posibles tipos estudiados. Para acceder a una variable en particular dentro de una colección, se debe
indicar el índice de la misma. Mira estos ejemplos:
int Tabla[4]
Crea un array llamado “Tabla” capaz de almacenar 4 números de tipo
int. Ocupa por tanto 8 bytes de la memoria RAM. Ver la figura 3-7
Valores[4] = 12345
En la variable 4 del array “Valores” se introduce el número 12345
char Letra=Texto[2]
Extrae la variable 2 del array “Texto” (letra D) y la almacena sobre la variable “Letra”
3-7
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Una vez que finaliza la ejecución de una función, todas sus variables locales desaparecen hasta que
volvamos a usarla. Según la figura, en la función Mi_función_1(), las variables “Tiempo”, “Hora” y
“Resultado” son locales. Observa las variables locales del resto de las funciones de la figura 3-10 de ejemplo.
5-3 Operaciones
Como ya habrás adivinado, tanto los parámetros que acompañan a las sentencias del lenguaje
Arduino, como los valores que cargamos en las variables, pueden obtenerse como resultado de hacer todo
tipo de operaciones aritméticas entre variables y/o constantes.
= Asignación
+ Suma
- Resta
* Multiplicación
/ División
% Módulo (el resto de una división entre dos números enteros)
Al igual que cuando operamos nosotros, cualquier expresión se calcula de izquierda a derecha. La
multiplicación y la división tienen prioridad sobre la suma y la resta. Se pueden usar los paréntesis para
establecer la prioridad deseada en la operación. Mira estos ejemplos:
3 +5 – 2 = 6 (12 – 2) + 5 * 3 = 25 y no 45
20 - 2 * 3 = 14 y no 54 ((12 – 2) + 5) * 3 = 45 y no 25
(20-2) * 3 = 54 y no 14 13 % 4 = 1
20 / 2 * 3 = 30 7%5=2
24 / (2 * 3) = 4 5%5=0
Teniendo en cuenta todo lo visto en esta sección, a partir de ahora podrás determinar los parámetros
que usan las funciones del lenguaje Arduino, de una forma mucho más flexible y potente. Fíjate en los
siguientes ejemplos y trata de responder a las preguntas.
byte Luz = 3;
pinMode(Luz+1,OUTPUT);
digitalRead(Luz);
digitalWrite((1+Luz)*2,HIGH);
byte A = 250;
byte B;
byte C;
unsigned int D;
A = A + 3;
B = (A-200) * 2 / 4;
C = A * 2 + 20;
D = (A * 100) % 2;
byte A=10;
delay((A+2) * 1000 / 5):
3-8
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
6.- SONIDO
Aprovechando que ya sabemos manejar las entradas y salidas digitales, es el momento de ver cómo
podemos generar sonido con nuestro controlador Arduino NANO. Al fin y al cabo una señal de sonido no es
otra cosa que una señal eléctrica que varía a una determinada frecuencia produciendo diferentes tonos. Mira
la figura 3-11.
Esta señal la podemos aplicar a un transductor como puede ser un altavoz. Este traduce la señal
eléctrica en una serie de movimientos mecánicos que producen cambios de presión, vibraciones u ondas en
el aire, llegando así hasta nuestro oído. El oído humano es capaz de percibir y escuchar vibraciones que van
desde los 20Hz (Hertzios) has los 20000Hz (o 20KHz).
Las vibraciones por debajo de los 20Hz reciben el nombre de “infrasonidos”, y por encima de los
20KHz, “ultrasonidos”. Teóricamente el oído humano no es capaz de percibir ninguno de esos sonidos,
aunque algunos animales sí.
Según la figura anterior, vamos a generar señales audibles compuestas de niveles lógicos: “1” y “0”.
Esto ya lo sabemos hacer. Solo nos queda por calcular la frecuencia que deseamos para esa señal. Es fácil:
1. A partir de la frecuencia F deseada (por ejemplo 1000Hz), calculamos lo que debe durar un ciclo. Un
ciclo es la parte que se repite de la señal (nivel “1” y nivel “0”). También se le llama “periodo” o T.
= = = . = =
2. Ahora calculamos el semiperiodo S, o lo que es igual, el tiempo que la señal va a estar a nivel “1” y a
nivel “0”.
.
= = = . = . =
Observa el siguiente programa, “Tonos_1”, y verás que no tiene mayor dificultad. Estamos aplicando
todo lo que hemos aprendido hasta el momento:
Creamos diferentes variables. “F” contiene la frecuencia de la señal sonora deseada. En “C” se
calcula la duración del ciclo o periodo en segundos, según la fórmula anterior. En “T” tenemos la duración del
ciclo o periodo convertida en microsegundos. Finalmente, la variable “S” se carga con la duración del
semiperiodo. Todas estas variables están fuera de las funciones void setup() y void loop(), por lo que son
variables globales.
3-9
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Por lo demás, el cuerpo principal del programa no nos enseña nada nuevo:
void loop()
{
digitalWrite(12,HIGH); //El altavoz se activa
delayMicroseconds(S); //Temporiza
digitalWrite(12,LOW); //El altavoz se desactiva
delayMicroseconds(S); //Temporiza
}
La salida digital 12 se pone a “1”, se temporiza según el valor calculado para el semiperiodo (S), se
pone a nivel “0” y se vuelve a temporizar según S.
Para probar este ejemplo necesitamos del altavoz que se incluye en el presente
módulo. Como se muestra en la figura 3-12, le vamos a colocar o soldar dos cablecillos
que nos permitan a su vez conectarlo con la tarjeta de control Arduino NANO.
+5Vcc
Ahora veamos el
esquema eléctrico de
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
conexiones que se
muestra en la figura 3-13.
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
Prueba a variar la frecuencia modificando en el programa el valor de la variable F. Oirás sonidos con
diferentes tonos. A frecuencia bajas, tonos graves; a frecuencias altas, tonos agudos. También puedes hacer
un análisis de tus propias capacidades auditivas. Completa la siguiente tabla.
Como no podía ser menos, el lenguaje de programación Arduino dispone de sus propias funciones o
instrucciones para generar todo tipo de sonidos. Esto facilita enormemente la programación ya que no
tendremos que calcular ni periodos ni semiperiodos para una frecuencia deseada. Lo hará el propio lenguaje.
3 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Genera una señal de onda cuadrada con la frecuencia y la duración deseada. La frecuencia mínima
que puede generar es de 31Hz. La señal de salida es simétrica. El nivel “1” dura lo mismo que el nivel “0”.
Sintaxis:
tone(pin,frecuencia,duración)
Ejemplos:
tone(12,1000,1000); Genera una señal o tono de 1000Hz durante 1 segundo por la patilla 12
tone(3, A + 100,300); Genera una señal cuya frecuencia resulta de sumar el contenido de la variable “A”
con 100, por la patilla 3. La duración del tono es de 300mS (0.3s).
tone(6,2500); Genera una señal de 2500 Hz por la patilla 6 de forma permanente hasta que se
ejecute la función noTone().
Detiene la generación de la señal audible producida por la última función tone() ejecutada en el
programa.
Sintaxis:
noTone(pin)
pin: Indica la patilla por donde se está generando la señal audible que se desea detener.
Ejemplo:
Graba y prueba el funcionamiento del programa “Tonos_V2”. Se comporta exactamente igual que el
programa “Tonos_V1” del ejemplo anterior, pero estarás de acuerdo en que es mucho más sencillo:
void loop()
{
tone(12,F); //Genera una señal de frecuencia F por la patilla 12
}
No solo eso, también es mucho más eficiente. Efectivamente, en el programa “Tonos_V1”, mientras
el controlador está temporizando para activar o desactivar la patilla por donde sale la señal audible (la 12),…
¡NO PUEDE ESTAR HACIENDO NINGUNA OTRA TAREA! Sin embargo, si empleamos la función tone(), el
controlador realiza los ajustes internos necesarios para sacar la señal deseada y a continuación continúa
ejecutando las instrucciones de nuestro programa.
3 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
Vamos ahora con el ejemplo “Tonos_V3” para corroborar lo que acabamos de decir. En la función
void setup() se ha incluido la función tone(12,F). Sabemos por tanto que solo se ejecuta una vez y el
controlador queda ajustado para producir permanentemente una señal audible por la patilla 12.
D13
3V3
VIN
GND
RESET RESET
AREF
D10
D11
D12
D2
D3
D4
D5
D6
D7
D8
D9
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
D2
D3
D4
D5
D6
D7
D8
de RESET (patilla 3) después de grabar el programa, para D9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
RESET
Figura 3-16. Esquema del ejemplo “Tonos_V4”
Naturalmente, con la función tone() del lenguaje Arduino también puedes crear tus propias melodías.
Este ejemplo te lo demostrará. Ten en cuenta que a cada nota musical le corresponde una frecuencia. Si
sabes solfeo te basta con buscar la relación entre las notas de la partitura con sus correspondientes
frecuencias, para poder así reproducir una melodía.
Según el sistema latino de notación musical, las notas básicas son siete: “do, re, mi, fa, sol, la, si”. En
el sistema inglés de notación, también denominado “denominación literal”, se corresponden con “C, D, E, F,
G, A, B” respectivamente. A partir de ellas se obtienen los sostenidos, bemoles y una combinación de todos
ellos.
Además de las notas (o frecuencias), en una melodía también se debe establecer la duración de cada
una así como el intervalo entre una nota y la siguiente. La duración se suele establecer en 1/4, 1/8, etc… de
segundo, es decir: 1000 mS / 4, 1000 mS / 8, etc… La duración de una nota se puede establecer en la misma
función tone().
El intervalo entre una nota y la siguiente suele ser un 30% de la duración de la misma. Dichos
intervalos se pueden conseguir fácilmente mediante la función delay().
3 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
El programa del ejemplo reproduce 8 conocidas notas. Todas ellas, salvo en frecuencia, duración e
intervalo, son similares. Observa las funciones tone() y delay() de la primera nota. Se corresponde con la nota
C4 (262Hz), con una duración de 250 mS y un intervalo de espera del 30% de la duración (325 mS).
Te sirve el mismo circuito de la figura 3-16. Acuérdate de grabar el programa antes de conectar el
pulsador E10 con la señal de RESET (patilla 3).
Aquí tienes una segunda versión mejorada del ejemplo del semáforo, el “Semáforo_V2”.
Aprovechando lo que ya sabemos sobre el sonido, el programa emula el funcionamiento de un semáforo con
señales acústicas para invidentes. La secuencia se inicia al activar la señal de RESET. El encendido
secuencial de las diferentes luces va acompañado de sus correspondientes señales acústicas de aviso.
Si te fijas, todas las instrucciones del programa se encuentran incluidas en la función void setup(),
por lo que únicamente se ejecutan tras reiniciar el sistema mediante el RESET. El programa te puede parecer
largo pero no complicado. Con lo que sabemos de momento es lo único que podemos hacer. En el próximo
tema vamos a estudiar y a emplear sentencias de control. Con ellas vamos a poder hacer programas mucho
más cortos y eficientes. Tiempo al tiempo.
En la figura 3-17 se muestra el esquema de conexiones para este ejemplo. No hay mucho que
explicar ya que es similar al empleado en ejemplos anteriores. Recuerda que es aconsejable grabar el
programa antes de conectar el pulsador E10 con la entrada RESET (patilla 3).
E10
RESET 1 30
2 D1 VIN 29
3 D0 GND 28
RESET RESET
+5Vcc
4 27
VERDE1 S2 5 GND +5V 26
D2 A7
ARDUINO NANO
6 25
7 D3 A6 24
AMBAR1 S1 8 D4 A5 23
9 D5 A4 22
10 D6 A3 21
ROJO1 S0 11 D7 A2 20
12 D8 A1 19
13 D9 A0 18
14 D10 AREF 17
15 D11 3V3 16
D12 D13
3 - 13
ARDUINO: La tecnología al alcance de todos
TEMA 3: Temporizaciones, expresiones y sonido
www.microcontroladores.com
3 - 14
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Los seres humanos somos capaces de analizar nuestro entorno y situación y, en función de nuestros
intereses, sentimientos, capacidad, intuición, obligación, etc…, tomamos decisiones que nos llevan a realizar
una tarea u otra con mayor o menor éxito.
Los programas que hemos desarrollado hasta el momento eran programas muy secuenciales. Las
instrucciones se van ejecutando una tras otra, desde la primera hasta la última y sin ninguna otra
consideración.
Sin embargo Arduino, al igual que cualquier otro controlador, también tiene capacidad de tomar
decisiones y ejecutar los programas o tareas apropiadas en caso. Ahora bien, Arduino no tiene sentimientos, ni
intuición, ni tan siquiera es inteligente. Es una máquina que solo sabe manejar números, y como tal, sus
decisiones se toman en base a ellos: cálculos aritméticos/lógicos, comparaciones entre números, estados de
las señales digitales de entrada, valores analógicos leídos de un sensor, etc…
Ya sabemos que Arduino puede realizar operaciones aritméticas como sumar y restar diferentes
números o datos que podemos expresar en forma de “constantes”, “variables” o combinación de ambas cosas.
También puede hacer comparaciones entre datos o entre los resultados que ofrecen a su vez otras funciones.
Los operadores de comparación, así como los símbolos que los representan, son los siguientes:
Igualdad (==)
Distinto de (¡=)
Menor que (<)
Mayor que (>)
Menor o igual que (<=)
Mayor o igual que (>=)
Como resultado de una comparación, sea del tipo que sea, solo se obtienen dos resultados posibles:
verdadero (true) o falso (false). Mira y analiza los siguientes ejemplos:
Suponiendo que …
Entonces …
4-1
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Incluso es posible relacionar entre sí varias de las comparaciones o expresiones anteriores. Para ello,
Arduino dispone de tres operadores lógicos o “booleanos” que, seguro que te recuerdan algo. Aquí los tienes
junto con los símbolos que los representan:
Y (&&)
O (||)
NO (¡)
De igual forma, como consecuencia de relacionar dos o más expresiones mediante estos operadores
lógicos, también se generan dos posibles resultados: verdadero (true) o falso (false). Observa los siguientes
ejemplos. Cada expresión que relacionamos va encerrada entre paréntesis para evitar errores.
2.- SENTENCIA IF (… )
Debemos recordar que una expresión puede estar formada por operaciones aritméticas entre
constantes y/o variables relacionadas entre sí por operadores de comparación, que a su vez, se relacionan
mediante operadores lógicos o booleanos. Repasa los ejemplos anteriores.
Sintaxis:
if(expresión)
{
….
….
}
expresión: Establece la condición que Arduino debe evaluar. Puede ser la comparación entre datos
constantes y/o variables. Puede haber una o más comparaciones relacionadas entre sí
mediante los operadores lógicos. También se pueden comparar los resultados obtenidos al
ejecutar operaciones aritméticas u otras funciones del propio lenguaje Arduino.
llaves: Como en un bocadillo, encierran las sentencias que el controlador debe ejecutar en caso de
que se cumpla la condición (true). No hacen falta si únicamente se va a ejecutar una instrucción
o sentencia.
4-2
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
D13
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
RESET RESET
AREF
VIN
GND
D10
D11
D12
D2
D3
D4
D5
D6
D7
D8
D9
ejemplos.
E10
void loop()
{
if(digitalRead(2)==0) //Si la entrada D2 está a "0" ...
{
tone(12,400); //Genera una frecuencia de 400Hz...
delay(300); //... durante 0.3"
tone(12,300,300); //Genera una frecuencia de 300Hz durante 0.3"
}
}
Si la entrada D2 está a nivel “0” (true) se generan los dos tonos que simulan el timbre. Uno es de
400Hz y el otro de 300Hz. Ambos tienen una duración de 0.3 s.
Si la entrada D2 está a nivel “1”, la condición no se cumple (false) y las instrucciones encerradas entre
las llaves no se ejecutan.
Consejo: Cuando emplees sentencias condicionales en tus programas, es una buena costumbre alinear las
llaves de forma que se vea claramente el emparejamiento de la que abre, con la llave que cierra. En el ejemplo
se distingue claramente las llaves que abren y cierran la función void loop() principal, y las que corresponden a
las de la función if().
Se trata de otra sentencia de control que se derivada de la sentencia if() anterior. Permite establecer
claramente qué hacer si no se cumple la condición (else). La figura 4-3 puede ayudar a entender su
funcionamiento.
4-3
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Sintaxis:
if(expresión)
{
….
….
}
else
{
….
….
}
expresión: Establece la condición que Arduino debe evaluar. Puede ser la comparación entre datos
constantes y/o variables. Puede haber una o más comparaciones relacionadas entre sí
mediante los operadores lógicos. También se pueden comparar los resultados obtenidos al
ejecutar operaciones aritméticas u otras funciones del lenguaje Arduino.
llaves: Engloban a todas las sentencias que el controlador debe ejecutar tanto en caso de que se
cumpla la condición (if), como si no se cumple (else). Las llaves no hacen falta si únicamente
se necesita ejecutar una instrucción en cada caso, por ejemplo:
if (A > 13)
A = A + 25;
else
A = B;
+5Vcc
Una nueva versión del juego de luces que hicimos en el tema anterior.
Mediante un interruptor se controla si el desplazamiento es a la izquierda o
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
AREF
VIN
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
izquierda a derecha.
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
S2
S1
S0
En la figura 4-5 se muestra el esquema para una nueva versión del ejemplo del semáforo,
“Semáforo_V3”.
Las líneas D3:D5 actúan como salidas y se conectan con los leds S2:S0 que simulan las luces verde,
ámbar y roja del semáforo respectivamente.
El pulsador E10 del entrenador Universal Trainer se conecta con la línea D2 que actúa como entrada.
El pulsador es accionado por el peatón cada vez que desea cruzar la vía.
4-4
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
y se generan unos tonos de 1000 Hz, con una duración de 0.4” y
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
3V3
VIN
GND
RESET RESET
AREF
una cadencia de 0.7”. Son tonos más breves y rápidos para darle
al peatón la sensación de que debe darse prisa al cruzar.
ARDUINO NANO
Finalmente, se enciende la luz roja con un tono permanente de 2
segundos. Finaliza el tono pero la luz roja se mantiene encendida
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
hasta iniciar una nueva secuencia.
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
En el programa se distingue claramente qué instrucciones
se ejecutan si NO se pulsa E10 (else). Se enciende la luz roja y se
apagan las otras dos. En el instante que se detecta la pulsación de
E10 (if) se inicia la secuencia de funcionamiento.
VERDE2 S2
AMBAR2 S1
ROJO2 S0
E10
PASAR
Figura 4-5. Esquema del “Semáforo_V3”
En cuanto veamos esta sentencia, inmediatamente le buscarás utilidad en alguno de los programas
que hemos visto anteriormente, con objeto de hacerlo más pequeño y eficiente.
Se trata de una sentencia para realizar bucles controlados. Un bucle es un conjunto de instrucciones
cuya ejecución se repetirá un número determinado de veces.
Sintaxis:
inicio: Es una expresión que permite cargar una variable con un valor inicial. Solo se ejecuta una vez,
al principio del bucle.
condición: Es una expresión condicional. Si se cumple la condición (true), se ejecutan todas las
instrucciones o sentencias del bucle. Si no se cumple la condición (false), el bucle finaliza y la
ejecución del programa sigue su curso. Esta expresión se evalúa cada vez que se repite el
bucle.
modificador: Es una expresión que permite modificar el valor de la variable con objeto de alcanzar la
condición. Este modificador se ejecuta cada vez que se repite el bucle.
llaves: Encierran, a modo de “bocadillo”, a todas las instrucciones que forman el bucle y que deben
ejecutarse un número determinado de veces.
Ejemplo:
4-5
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Una imagen vale más que mil palabras. Observa el diagrama de flujo de la figura
4-6. Se declara la variable “N”, de tipo byte, y se le carga con el valor inicial 1
(byte N = 1). Se evalúa y, si es menor que 5 (N < 5), se ejecutan todas las
sentencias cerradas entre las llaves. El valor de la variable “N” se modifica
automáticamente y, en este caso, se incrementa en una unidad (N = N + 1).
Vuelve a repetirse la evaluación de la condición. Si es cierta se vuelven a ejecutar
las sentencias y el proceso se repite hasta que la condición sea falsa. En el
ejemplo de la figura, las sentencias encerradas entre las llaves se ejecutan 4
veces: mientras “N” sea menor de 5.
Para establecer el inicio, la condición y el modificador de cualquier bucle for(), se pueden emplear todo
tipo de expresiones aritméticas, booleanas o lógicas y de comparación entre variables y/o constantes. Por
ejemplo:
int A = 5;
for(byte N=A+3); N <= A*2+8; N=N+3)
{
….
}
En ocasiones realizamos operaciones sencillas con una variable, cuyo resultado va a parar a esa
misma variable. Para ello existen los llamados “operadores compuestos” que simplifican esas expresiones:
Son muy utilizados en los modificadores de la sentencia for(): for(byte N=1; N<5; N++)
+5Vcc
4-2 Ejemplo: Faro_V2
AREF
VIN
GND
Aquí tienes una versión muy mejorada del programa “Faro” del tema ARDUINO NANO
anterior, el programa “Faro_V2”. El funcionamiento de ambos programas es
GND
idéntico. Consiste en hacer una baliza que parpadea tres veces seguidas
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
4-6
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Ya tenemos la última y definitiva versión del ejemplo del semáforo, el “Semáforo_V4”. Su circuito es el
mismo que el del esquema de la figura 4-5, y tiene idéntico funcionamiento que el ejemplo “Semáforo_V3”. Si
comparas ambos observarás que el empleo de la función for() reduce notablemente el tamaño del programa,
ocupa menos memoria del controlador y es por tanto más eficiente.
+5Vcc
Los bucles for() se pueden anidar. Esto es, dentro de un bucle for() puede haber
uno o más bucles for(), y dentro de cada uno de estos, puede haber otros y así
sucesivamente. Este programa es una pequeña demostración de anidamiento de
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
dos bucles.
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
3V3
RESET RESET
VIN
GND
AREF
ARDUINO NANO Se trata de emitir dos ráfagas luminosas sobre los leds S1 y S0 conectados con
las señales D3 y D4 respectivamente. La secuencia se inicia al pulsar E10
GND
D10
D11
D12
D2
D3
D4
D5
D6
D7
D8
D9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
Cada vez que se produce una ráfaga de 5 destellos en el led S1, se produce un
destello en el led S0. La secuencia finaliza cuando se hayan producido 6 de
estos destellos en S1.
S1
S0
E10
INICIO
Figura 4-8. Circuito del programa “Ráfagas”
void loop()
{
if(!digitalRead(2)) //Si la entrada D2 es verdad (nivel "0") ...
{
for(byte A=1; A<=6;A++) //Mientras A <= 6
{
for(byte B=1;B<=5;B++) //Mientras B <= 5 ...
{
digitalWrite(3,HIGH); //Activa el led S1
delay(80); //Temporiza
digitalWrite(3,LOW); //Desactiva el led S1
delay(100); //Temporiza
}
digitalWrite(4,HIGH); //Activa el led S0
delay(100); //Temporiza
digitalWrite(4,LOW); //Desactiva el led S0
delay(120); //Temporiza
}
}
}
Dentro de la función if(), si se cumple que la entrada D2 está a activada (“0”), se encuentran dos bucles
for(). El más interno se controla desde la variable “B” que evoluciona desde 1 hasta 5. Produce una ráfaga de 5
destellos en el led S1 conectado a la línea D3.
El bucle for() externo se controla mediante la variable “A” que evoluciona desde 1 hasta 6. Envuelve al
bucle for() interno, por lo que este se repite 6 veces. Por cada una de ellas el led S0 conectado en la línea D4
produce un destello.
4-7
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Cuando se anidan dos o más bucles for(), se resuelve primero el más interno siguiendo en orden hasta
resolver, por último, el bucle más externo.
Es una variante de la sentencia for(), y también se emplea para realizar bucles en donde un conjunto
de instrucciones se ejecutan un número determinado de veces.
Sintaxis:
while (condición)
{
….
….
}
condición: Es una expresión condicional. Mientras la condición sea cierta (true) se ejecutan las sentencias
del bucle. En caso contrario el bucle finaliza.
llaves: Encierran a todas las sentencias que forman el bucle y que se ejecutarán siempre que la
condición sea cierta (true). Si únicamente se debe ejecutar una instrucción, no es necesario
cerrarla entre llaves. Si la sentencia while() finaliza con “;” se ejecuta así misma mientras se dé
la condición.
Vamos a emplear el mismo circuito que el mostrado en el esquema de la figura 4-2. El cuerpo principal
del programa se muestra a continuación:
void loop()
{
while(digitalRead(2)); //Esperar mientras D2=1
while(! digitalRead(2)); //Esperar mientras D2=0
tone(12,400); //Genera una frecuencia de 400Hz...
delay(300); //... durante 0.3"
tone(12,300,300); //Genera una frecuencia de 300Hz durante 0.3"
}
Ambas funciones while() finalizan con “;”. La primera se ejecuta constantemente mientras la entrada D2
esté a nivel “1” (pulsador S0 sin accionar). La segunda while() se ejecuta constantemente mientras la entrada
D2 esté a nivel “0” (pulsador S0 accionado).
En otras palabras, el programa espera a que accionemos el pulsador (nivel “0”) y luego lo soltemos
(nivel “1”), para ejecutar el tono de nuestro timbre. Hay que hacer ambas cosas: pulsar y soltar.
Conviene recordar que los pulsadores del laboratorio Universal Trainer trabajan con lógica invertida. Si
no se accionan ofrecen un nivel “1””. Cuando se accionan ofrecen un nivel “0”.
Un ejemplo práctico. Deseamos un sistema que cuente un número de piezas, por ejemplo 10, y genere
una señal sonora de aviso. El pulsador E10 del laboratorio simula a un sensor que detecta las piezas, se
conecta con la línea de entrada D2.
El altavoz se conecta con la salida D12 y emite un tono de 1KHz durante 1 segundo cada vez que se
detecta el paso de las 10 piezas (10 pulsaciones en E10). Se emplea por tanto el mismo esquema de montaje
que el mostrado en la figura 4-2.
4-8
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Void loop()
{
byte Contador=1; //Contador =1
while (Contador <=10) //Mientras el contador no llegue a 10 ...
{
while(digitalRead(2)); //Esperar mientras D2 vale "1"
while(!digitalRead(2)); //Esperar mientras D2 vale "0"
Contador++; //Pulso recibido, Contador+1
}
Se inicia la variable “Contador” con el valor 1. Mientras dicha variable sea menor de 10, se ejecuta un
bucle while() formado por tres instrucciones. La primera de ellas espera mientras la entrada D2 (pulsador E10)
esté a nivel “1”. La segunda espera mientras la entrada D2 esté a “0”. Cuando se haya cumplido ambas
condiciones (el pulsador se accione y se suelte), se ejecuta la tercera instrucción: incrementar la variable
“Contador” en una unidad. Cuando la variable “Contador” alcance el valor 10, el bucle finaliza y se ejecuta la
instrucción tone().
Quizá hayas observado en el ejemplo anterior que en ocasiones, en lugar de contar 10 impulsos,
cuenta menos. No es que el programa esté mal diseñado, es un problema debido al conocido “efecto rebote”
típico de los dispositivos electromecánicos como son los pulsadores e interruptores.
Una forma de evitarlos es intercalar una pequeña temporización. Observa la modificación que hemos
hecho en el ejemplo “Contador_V2”.
4-9
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Al igual que la sentencia if(), la sentencia switch() controla el flujo de un programa haciendo que se
ejecuten unas instrucciones u otras en función de determinadas condiciones. En el caso de la sentencia
switch() se compara el valor de una variable con el valor indicado en múltiples sentencias “case”. Cuando
coincide con una de ellas, se ejecutan las instrucciones correspondientes.
La palabra clave “break” finaliza la sentencia switch() y normalmente se usa al final de cada caso o
“case”.
Sintaxis:
switch(var)
{
case 1:
….
….
break;
case n:
…..
break;
default:
….
}
var: Es la variable cuyo contenido se va a comparar con los valores indicados en los diferentes
“case”.
case: Establecen todos los valores (1-n) con los que se va a comparar el contenido de la variable
“var”. Cuando coincide con uno de ellos, se ejecutan todas las instrucciones comprendidas
entre ese “case” y la expresión “break”.
default: Es opcional. Si se usa, en caso de que no haya ninguna “case” que coincida con el valor de la
variable “var”, se ejecutan todas sus instrucciones.
D13
3V3
RESET RESET
VIN
GND
AREF
Los leds S3:S0 del laboratorio se conectan con las líneas D3:D0 que
ARDUINO NANO se configuran como salidas. Su valor dependerá de las entradas de
acuerdo a la siguiente tabla de la verdad:
GND
D10
D11
D12
ENTRADAS SALIDAS
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
E1 E0 S3 S2 S1 S0
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
0 0 0 0 0 0
0 1 1 1 1 1
1 0 1 0 1 0
1 1 0 1 0 1
E1
S1
S0
S2
S3
E0
Figura 4-10. Decodificador de 2 x 4
4 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
void loop()
{
A = PINB & B00000011; //Lee el valor de E1 y E0
switch(A)
{
case 0: //Si vale 00 (0)
PORTD = 0; //Saca 0000
break;
case 1: //Si vale 01 (1)
PORTD = B00001111; //Saca 1111
break;
case 2: //Si vale 10 (2)
PORTD = B00001010; //Saca 1010
break;
default: //Entonces vale 11 (3)
PORTD = B00000101; //Saca 0101
}
}
Se lee el Puerto B (PINB) y se hace la función AND con los dos bits de menos peso (& B00000011). El
valor que se deposita en la variable “A” solo puede ser 00 (0), o 01 (1), o 10 (2) o bien 11 (3). La función
switch(A) compara la variable con los posibles casos expuestos (case). Si es 0, por el Puerto D se saca el valor
0 (PORTD = 0,); si es 1, se saca el valor 1111; si es 2, se saca el valor 1010 y, por último, si no es ninguno de
esos tres, por defecto se saca el valor 0101.
Un tipo de decodificador muy empleado es el llamado “decodificador selector”. Por cada código de
entrada solo se debe activar una y solo una salida. Responde a la siguiente tabla de la verdad:
ENTRADAS SALIDAS
E1 E0 S3 S2 S1 S0
0 0 0 0 0 1
0 1 0 0 1 0
1 0 0 1 0 0
1 1 1 0 0 0
Con el mismo esquema de la figura 4-10 anterior, este ejemplo propone realizar cuatro juegos
diferentes de luces. Cada juego se selecciona mediante los dos interruptores E1:E0 conectados a las líneas
D9:D8 de entrada.
El programa se presta a muchas modificaciones: échale imaginación. Puedes modificar los tiempos y
las secuencias. Incluso puedes emplear más señales de entrada y salida para realizar secuencias más
complejas y llamativas.
4 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
Hablando de decodificadores, otro muy utilizado en los circuitos digitales es el llamado “BCD a 7
segmentos”. Se trata de un circuito capaz de controlar el clásico dígito numérico o display como el mostrado en
la figura 4-11.
Basta con sacar por ese Puerto D las combinaciones binarias que iluminen los leds necesarios para
representar un número, letra o símbolo. La siguiente tabla representa las combinaciones binarias que han de
aplicarse para visualizar los número 0 al 9 y las letras A a la F, suponiendo que el punto decimal (dp) está
desactivado. Recordemos que los leds del display de la Universal Trainer se activan al aplicarles un nivel “0”.
ENTRADAS SALIDAS
DIGITO BIN. DEC. D7 D6 D5 D4 D3 D2 D1 D0 HEX. DEC.
(dp) (g) (f) (e) (d) (c) (b) (a)
0 0000 0 1 1 0 0 0 0 0 0 0xC0 192
1 0001 1 1 1 1 1 1 0 0 1 0xF9 249
2 0010 2 1 0 1 0 0 1 0 0 0xA4 164
3 0011 3 1 0 1 1 0 0 0 0 0xB0 176
4 0100 4 1 0 0 1 1 0 0 1 0x99 153
5 0101 5 1 0 0 1 0 0 1 0 0x92 146
6 0110 6 1 0 0 0 0 0 1 0 0x82 130
7 0111 7 1 1 1 1 1 0 0 0 0xF8 248
8 1000 8 1 0 0 0 0 0 0 0 0x80 128
9 1001 9 1 0 0 1 1 0 0 0 0x98 152
A 1010 10 1 0 0 0 1 0 0 0 0x88 136
B 1011 11 1 0 0 0 0 0 1 1 0x83 131
C 1100 12 1 1 0 0 0 1 1 0 0xC6 198
D 1101 13 1 0 1 0 0 0 0 1 0xA1 161
E 1110 14 1 0 0 0 0 1 1 0 0x86 134
F 1111 15 1 0 0 0 1 1 1 0 0x8E 142
Monta el circuito de la figura 4-12. De los tres displays disponibles en el entrenador Universal Trainer,
vamos a emplear el de la derecha. Representa a las unidades y se identifica como dígito AC3. Como es de
ánodo común, su patilla AC3 se conecta con +5Vcc de alimentación. Los 7 segmentos (a-g) y el punto decimal
(dp) se conectan con las líneas D0-D7 del Puerto D, que se configuran como salidas.
Los interruptores E3:E0 se conectan con las líneas D11:D8 del Puerto B que se configuran como
entradas. Mediante esos interruptores se introducen los códigos binarios para cada dígito o símbolo que
queremos visualizar.
4 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
+5Vcc
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16 3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
11
a 7
b 4 ARDUINO NANO
c 2
d 1
GND
e
D10
D11
D12
10
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
f 5
g 3
10
11
12
13
14
15
AC1
AC2
AC3
1
2
3
4
5
6
7
8
9
dp
E3
12
E2
E1
+5Vcc E0
¡IMPORTANTE! Las líneas D0 y D1 del controlador Arduino NANO también se emplean como señales Rx y Tx
durante la transferencia o carga de un programa. Se recomienda conectarlas a los segmentos del display una
vez que se haya grabado el programa.
void loop()
{
A = PINB & B00001111; //Lee el valor de E3:E0
switch(A)
{
case 0: //Si vale 0000 (0)
PORTD = B11000000; //Saca 11000000
break;
case 1: //Si vale 0001 (1)
PORTD = B11111001; //Saca 11111001
break;
…..
…..
El ejemplo sin embargo, no es un programa realmente eficiente. Lo hemos resuelto con las funciones
switch() / case porque es lo que tocaba. También se puede resolver mediante el empleo de “Arrays” como se
estudió en el tema anterior. Echa un vistazo al ejemplo “Decodificador_BCD_7_segmentos_V2” que
proponemos.
En primer lugar se crea un Array de tipo byte llamado “Display”. Contiene, en decimal, los 16 valores
posibles que hay que sacar a los segmentos. Para obtener cualquiera de ellos basta con indicar en qué
posición dentro del Array se encuentra. Por ejemplo, Display[4] contiene el valor 153, que es precisamente al
valor que hay que sacar a los segmentos para que visualicen el dígito 4.
byte Display[16]={192,249,164,176,153,146,130,248,
128,152,136,131,198,161,134,142}; //Valores de salida
4 - 13
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
void loop()
{
A = PINB & B00001111; //Lee el valor de E3:E0
PORTD = Display[A]; //Saca el valor de salida
}
Se lee el valor que proporcionan los interruptores de entrada E3:E0. Este valor estará comprendido
entre 0 y 15 y se emplea como índice del Array para obtener el valor de salida (PORTD=Display[A]).
¡Qué diferencia de programa! La conclusión que debes de sacar de todo esto es que un mismo
programa se puede resolver de varias formas diferentes. El lenguaje Arduino nos proporciona las sentencias y
recursos necesarios para que, usados debidamente, podamos hacer programas muy eficientes. Es cuestión de
tiempo y práctica.
Completa la siguiente tabla con objeto de visualizar en el display ciertos símbolos y/o letras que tú
mismo vas a diseñar. Luego modificas adecuadamente el programa para visualizarlos en función del valor que
introduces con los interruptores de entrada.
ENTRADAS SALIDAS
SIMBOLO BIN. DEC. D7 D6 D5 D4 D3 D2 D1 D0 HEX. DEC.
(dp) (g) (f) (e) (d) (c) (b) (a)
= 0000 0
“ 0001 1
- 0010 2
º 0011 3
P 0100 4
r 0101 5
t 0110 6
u 0111 7
g 1000 8
H 1001 9
i 1010 10
J 1011 11
L 1100 12
n 1101 13
ñ 1110 14
o 1111 15
Otro programa de carácter eminentemente práctico. Se trata de un dispositivo digital capaz de contar,
de 0 a 9, el número de pulsos que se le aplican. Recibe el nombre de “Década” y su esquema de montaje se
muestra en la figura 4-13.
Los segmentos del display se conectan con las líneas D0:D7 del controlador, como en el ejemplo
anterior. El display visualizará el número de pulsos aplicados.
El pulsador E10 del entrenador Universal Trainer se conecta con la línea D8 que actúa como entrada.
Con este pulsador vamos introduciendo los pulsos a contar.
4 - 14
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
+5Vcc
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16 3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
11
a 7
b 4 ARDUINO NANO
c 2
d 1
GND
e
D10
D11
D12
10
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
f 5
g 3
10
11
12
13
14
15
AC1
AC2
AC3
1
2
3
4
5
6
7
8
9
dp
12
E10
+5Vcc
Una vez que grabes y pruebes el programa, puedes usar el generador lógico del entrenador, para aplicar los
pulsos a contar en lugar del pulsador.
Para empezar retiras la conexión del pulsador E10 y conectas la patilla D8 con la salida del generador. Modifica
el programa y anula las dos funciones delay() que eliminaban los rebotes. El generador está libre de ellos.
Vuelve a grabar el programa recién modificado.
Un ejemplo de carácter lúdico. Se trata de emular un dado electrónico que visualice sobre el display un
número aleatorio entre 1 y 6. Aprovechamos la ocasión para estudiar dos nuevas funciones del lenguaje
Arduino.
Función random()
Genera y nos devuelve un número aleatorio de entre una gran secuencia de números.
Sintaxis:
random(min,max)
4 - 15
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
min: Establece el valor mínimo del número aleatorio que nos va a devolver. Es opcional. Si no se indica el
valor mínimo será 0.
Ejemplo:
Función randomSeed()
El sistema que emplea Arduino para generar número aleatorios, consiste en una secuencia muy larga
de números diferentes, pero siempre es la misma secuencia. Los números son por tanto “pseudo-aleatorios”.
Con el empleo de esta sentencia se inicia internamente el sistema generador, haciéndole empezar en un punto
arbitrario de la secuencia.
Sintaxis:
randomSeed(int o long)
int o long: Es un valor cualquiera, bien sea entero (16 bits), o entero largo (32 bits). Se emplea como
“semilla” con la que se inicia el sistema generador de números aleatorios.
Ejemplo:
Monta el circuito según el esquema de la figura 4-13 anterior. Una vez que cargues el programa,
comprueba su funcionamiento. Inicialmente el display aparece apagado con el punto decimal (dp) iluminado.
Está a la espera de recibir un pulso por D8, e iniciar la jugada.
Se obtiene un número comprendido entre 1 y 6 que se visualiza sobre el display durante 2 segundos.
Luego este se apaga y comienza una nueva partida.
Hemos visto las sentencias o funciones de control más importantes y utilizadas. De todas formas el
lenguaje Arduino dispone de alguna más. Su empleo queda a criterio del programador.
Esta sentencia es muy similar a la sentencia while() ya estudiada. La diferencia es que la condición
para repetir o no el bucle se establece al final del mismo, no al principio.
Sintaxis:
do
{
…
…
} while(condición);
condición: Es una expresión condicional. Mientras la condición sea cierta (true) se ejecutan las sentencias
del bucle, las comprendidas entre do y while(). En caso contrario el bucle finaliza.
4 - 16
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
llaves: Encierran a todas las sentencias que forman el bucle y que se ejecutarán un determinado
número de veces mientras la condición sea cierta (true).
Esta función es una forma de finalizar o “romper” cualquier bucle fo(), while() o do…while() aunque no
se dé la condición establecida. También la hemos usado para salir o finalizar la función switch() / case.
Sintaxis:
break;
Retorna o finaliza cualquier función creada por el usuario. Si se desea puede devolver un valor al
programa que hizo uso o llamó a esa función.
Sintaxis:
return
rteturn valor;
valor: Es el valor que devuelve la función en su retorno. Es opcional y puede ser una variable o una
constante.
Sintaxis:
prueba:
…
…
…
goto prueba; //Salta incondicionalmente al punto del programa en el que se encuentre la etiqueta indicada.
4 - 17
ARDUINO: La tecnología al alcance de todos
TEMA 4: Toma de decisiones y sentencias de control
www.microcontroladores.com
4 - 18
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
1.- INTRODUCCIÓN
En el Tema 1 se explicó que algunas de las 14 patillas de entrada o salida digitales que dispone la
tarjeta Arduino NANO, podían actuar como salidas de señales del tipo PWM. Concretamente son 6 patillas: D3,
D5, D6, D9, D10 y D11. Consulta la figura 1-9.
La figura 5-2 muestra una secuencia de cuatro señales PWM: A, B, C y D. Todas tienen en común el
mismo periodo T de 2 mS o, lo que es lo mismo, una frecuencia de 500 Hz. Sin embargo la duración del nivel
“1”, es decir del ciclo útil, varía.
La señal A tiene un ciclo útil del 0%. Durante la duración total del periodo T, los 2 mS, la señal
permanece a nivel “0”. La señal B se corresponde con una señal PWM cuyo ciclo útil es del 25% de la
duración del periodo. Esto es, el nivel “1” se mantiene durante 0.5 mS y el nivel “0” los 1.5 mS restantes del
periodo (75%).
5-1
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
La señal C representa una señal PWM cuyo ciclo útil es el 75% de la duración total del periodo. El
nivel “1” dura 1.5 mS y el nivel “0” los 0.5 mS restantes (25%).
Por último, la señal D representa a una señal cuyo ciclo útil es del 100% de la duración del periodo. El
nivel “1” dura los mismos 2 mS.
La mayor parte de los controladores actuales, entre los que se encuentra nuestro Arduino NANO,
integran la electrónica necesaria para generar, si se desea, una o varias señales PWM por algunas de sus
patillas. En nuestro caso esas patillas son: D3, D5, D6, D9, D10 y D11. Cuando se habilitan, la frecuencia F
de las señales es fija. Para las patillas D5 y D6 es aproximadamente de 980 Hz (T=1mS) y de 490 Hz (T=2
mS) para el resto.
Las señales PWM se pueden usar para controlar y regular la potencia que aplicamos a ciertos
periféricos de salida como puede ser un led, un motor, un servo, etc…, ya que podemos ajustar la duración o
el tiempo en que se mantiene el nivel “1” (ciclo útil), en cada periodo.
Según este razonamiento, si se le aplica una señal con un ciclo útil del 25% (figura 5-2-B), el led
brillará la ¼ parte de su potencia. Si la señal fuera del 75% (figura 5-2-C), brillará las ¾ partes de su potencia.
Con una señal PWM del 0% (figura 5-2-A), el led se apagará. Tenemos por tanto un rango que va del 0%
hasta el 100% de la señal PWM para ajustar el brillo deseado.
De la misma manera que podemos regular el brillo de un led o de una lámpara, también podemos
regular la velocidad a la que gira un motor o el posicionamiento de un servo. El principio es el mismo.
Permite determinar la duración de la anchura del pulso o el ciclo útil de una señal PWM de salida.
Sintaxis:
analogWrite(pin,valor)
pin: Es la patilla por donde se va a generar la señal PWM. En el controlador Arduino NANO puede ser 3,
5, 6, 9, 10 u 11.
valor: Es el valor que determina la duración del ciclo útil. Está comprendido entre 0 y 255, donde 0
corresponde con un ciclo útil del 0% de duración, y 255 con un ciclo útil del 100%.
Ejemplo:
La patilla elegida para sacar la señal PWM no necesita ser configurada como salida. La propia función
analogWrite() lo hace automáticamente. La señal PWM de salida se mantiene indefinidamente hasta que
indiquemos un ciclo útil de valor diferente o bien se ejecute una función del tipo digitalRead() o digitalWrite()
sobre esa misma patilla. En este caso la salida de señal PWM se anula.
5-2
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Vamos a realizar una serie de ejemplos que permitan sacar una o +5Vcc
varias señales PWM por algunas de las patillas disponibles al efecto: D3, D5,
D6, D9, D10 y D11.
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
2-1 Ejemplo: PWM
D13
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
AREF
RESET RESET
VIN
GND
Es el ejemplo más sencillo que se puede realizar. Monta el circuito ARDUINO NANO
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
El led S0 del entrenador Universal Trainer se conecta con la patilla D6
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
del controlador Arduino NANO. Esta patilla se empleará como salida PWM y
nos permitirá controlar la potencia que se aplica al led, regulando así su brillo.
La función void setup() está vacía. En este caso no vamos a configurar nada, pero es obligatorio
poner la función.
void loop()
{
analogWrite(6,Ciclo); //Genera la señal PWM
while(1); //Bucle sin fin
}
Al cargar el programa y ejecutarlo, veremos que el led S0 brilla bastante menos que como lo ha
venido haciendo en ejemplos anteriores. Puedes probar a modificar el programa variando el valor de la
potencia deseada.
Con este programa de ejemplo sí que podrás apreciar claramente el efecto de “regulación” del brillo
de un led, al que se le aplica una señal PWM variable. Emplea el mismo esquema de conexiones que el de la
figura 5-4.
Efectivamente, mediante un bucle for() el ciclo útil de la señal PWM va creciendo desde un mínimo
(0) hasta un máximo (255) en pasos de 5 en 5.
5-3
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
La variable “Ciclo” empieza con 0 y evoluciona hasta llegara a 255 en incrementos de +5 (0, 5, 10,
15,…). Los distintos valores de esta variable se emplean para generar una señal PWM cuyo ciclo útil va
aumentando hasta llegar al 100% (255). El brillo del led irá aumentando.
Luego, mediante otro bucle for() y de forma parecida, la señal va decreciendo desde un máximo (255)
hasta un mínimo (0) en iguales pasos. El brillo del led irá disminuyendo.
+5Vcc
Monta el circuito del esquema de la figura 5-5. Consiste en un vistoso
juego de luces en el que los leds S0-S3 lucen con un brillo aleatorio.
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
Estos leds se conectan con las patillas D6, D9, D10 y D11 que, como
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
3V3
RESET RESET
VIN
GND
AREF
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
AREF
RESET RESET
VIN
GND
ARDUINO NANO
El led S0 se conecta con la patilla D6 desde donde se le
aplica la señal PWM. La patilla D2 se conecta con el pulsador
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
E10. Con cada pulsación, la señal PWM en D6, va aumentando
de 10 en 10 hasta un máximo de 250 (máximo brillo). La patilla
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
3.- SERVOMOTORES
Los servomotores, también conocidos como “servos”, son dispositivos similares a un motor de
corriente continua (DC) pero con la capacidad de realizar giros de forma controlada a cualquier posición y en
cualquier sentido, dentro de su rango de acción. Por ejemplo, podemos indicar que su eje realice un giro de
34º en sentido horario, y se mantenga en esa posición indefinidamente hasta que se indique otra nueva.
5-4
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Desde el punto de vista de su conexión, la mayor parte de los servos precisan únicamente de tres
cables como se muestra en la figura 5-9. El cable negro para la tensión GND o 0V de alimentación. Por el rojo
se aplica una tensión de +5V. Por el blanco se aplica la señal
PWM de control. Debes tener en cuenta que esto puede cambiar
de un modelo a otro de servo. Lo ideal es consultar y cerciorarse
mediante la documentación que facilita el fabricante.
5-5
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Para nuestras prácticas y ejemplos vamos a usar el servo modelo S3003 de la firma Futaba, que se
incluye en el presente módulo. Sus características fundamentales son:
Como se muestra en la figura 5-11, vamos a emplear una tira de pines macho.
Esta tira, a la que cortaremos un trozo con tres pines, también se incluye en el
lote de materiales del presente módulo.
Por un lado estos tres pines se insertan en el conector hembra del servo,
también de tres vías. Posteriormente podremos insertar todo el conjunto sobre
el módulo board del entrenador Universal Trainer y hacer así las conexiones.
900-00008
Servo
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16 3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
AREF
RESET RESET
VIN
GND
En la figura 5-12 tenemos el esquema de conexiones que
ARDUINO NANO
vamos a emplear en los próximos ejemplos. El servo únicamente
necesita tres conexiones. El cable negro se conecta con GND de
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
alimentación. El cable rojo se conecta con +5Vcc de alimentación.
PWM
GND
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
Mediante el cable blanco se le aplica la señal PWM que controla su
Vdd
5-6
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
El lenguaje Arduino, al igual que cualquier otro lenguaje, es algo vivo que con el paso del tiempo se
va enriqueciendo incluyendo nuevas palabras y acepciones. En nuestro caso el lenguaje Arduino va
adquiriendo nuevas funciones y sentencias.
Cuando se añaden sentencias de propósito general, que no tienen una aplicación en concreto, estas
se incluyen en el propio lenguaje, como si fuera una ampliación del mismo. Por eso es aconsejable que,
periódicamente, descargues la última versión disponible. Sin embargo, si se crean nuevas sentencias para un
fin específico, estas se suelen incluir en lo que se denomina una “librería”, que no es otra cosa que un fichero
auxiliar con extensión “.h” que contiene el código necesario para implementarlas.
Podemos encontrar librerías para el control de pantallas, robots, servos, comunicaciones, tarjetas de
memoria, internet y mucho más. Algunas librerías están diseñadas por la propia organización de Arduino.
Otras librerías las suministran los propios fabricantes de hardware y accesorios. En otros casos tú mismo
puedes crear tus propias librerías para un determinado objetivo.
En estos momentos nos vamos a centrar en la librería “Servo”. Se trata de un fichero, “Servo.h”, que
se instala junto con el sistema Arduino. Una vez incluido en nuestro programa podemos pensar que nuestro
lenguaje se ha enriquecido con las nuevas sentencias que incluye ese fichero.
3-2-1 #include
Sintaxis:
Ejemplo:
#include <Servo.h> Incluye en nuestro programa la librería “Servo”. Esto nos permite hacer uso de todas
las funciones y sentencias que contiene y que veremos a continuación.
3-2-2 attach()
Asocia un servo a cualquiera de las líneas digitales disponibles. A diferencia de las señales PWM,
que únicamente estaban disponibles en seis de las patillas del controlador, las señales PWM para el control
de servos se pueden generar por cualquier patilla. Son señales que se generan por software.
Sintaxis:
servo.attach(pin);
servo.attach(pin,min,max);
servo: Es una variable tipo servo que asigna un nombre al servo que vamos a controlar (lo veremos
enseguida).
pin: Número de patilla a la que se conecta el servo.
min (opcional): Establece, en micro segundos, la anchura mínima del pulso correspondiente a un ángulo de
0º. Por defecto es de 544. Revisar la documentación del fabricante.
max (opcional): Establece, en micro segundos, la anchura máxima del pulso correspondiente a un ángulo de
180º. Por defecto es de 2400. Revisar la documentación del fabricante.
5-7
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Ejemplo:
3-2-3 writeMicroseconds()
Genera una señal PWM cuya anchura o ciclo útil, expresado en microsegundos, se aplica al servo
indicado. Esta señal origina por tanto el desplazamiento del eje un determinado número de grados.
Sintaxis:
servo.writeMicroseconds(valor);
Ejemplo:
Suponiendo el servo modelo S3003 de Futaba, como el que se incluye en este módulo de prácticas…
3-2-4 write()
Genera una señal PWM cuya anchura o ciclo útil se obtiene a partir de los grados que indicamos en la
propia función. Esta señal origina por tanto el desplazamiento del eje del servo un determinado número de
grados.
Sintaxis:
servo.write (valor);
Ejemplo:
Suponiendo el servo modelo S3003 de Futaba, como el que se incluye en este módulo de prácticas…
5-8
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
3-2-5 read()
Lee el ángulo actual en el que se encuentra el servo, que no es otro que el valor que se le ha pasado
en la última función write().
Sintaxis:
servo.read();
Ejemplo:
3-2-6 attached()
Sintaxis:
servo.attached();
Ejemplo:
3-2-7 detach()
Sintaxis:
servo.detach();
Ejemplo:
5-9
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Es el momento de proponer una serie de ejemplos que nos permitan aprender a usar un servo como
el que se incluye en el lote de materiales del presente módulo de prácticas.
Recuerda que los servos son periféricos con una gran cantidad de aplicaciones. Se utilizan en
aquellos casos en que sea necesario controlar con cierta exactitud el posicionamiento del eje de un motor: el
timón de una embarcación, la dirección de un vehículo, los alerones de un avión, el posicionamiento de un
objeto, robótica, automatismos, y un largo etcétera.
Un buen ejemplo para tener una primera toma de contacto con un servo motor. Necesitas montar el
esquema mostrado en la anterior figura 5-12, en la que el servo se controla mediante la patilla D3 del
controlador Arduino NANO.
El programa empieza incluyendo la librería “Servo.h” que contiene las funciones que usaremos
posteriormente para controlar el servo.
También se crea la variable “pwm”. En ella introducimos, en micro segundos, la duración del ciclo útil
de la señal PWM que se aplicará al servo. Según las especificaciones del modelo Futaba S3003, la duración
mínima es de 300 µS y la máxima 2300 µS, lo que provoca desplazamientos del eje de un extremo al otro con
un giro de 180º de recorrido en total.
En la función de configuración indicamos, mediante la sentencia attach(), que el servo S3003 está
conectado o vinculado con la patilla D3 del controlador.
void setup()
{
S3003.attach(3); //Conecta el servo
}
void loop()
{
S3003.writeMicroseconds(pwm); //El servo se posiciona según "pwm"
while(1); //Fin del programa
}
Se puede calcular cuántos µS de ciclo útil son necesarios para girar 1º. En nuestro modelo Futaba
S3003 será:
− −
⁄º = = = . μ
5 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
Ahora será fácil determinar la duración que debe tener el ciclo útil de la señal PWM, para que el eje
gire un determinado número de grados (g).
= −( ∗ . )
Por ejemplo:
Para girar 0º (un extremo del servo), PWM = 2300 – (0 * 11.11) = 2300
Para girar 90º (servo centrado), PWM = 2300 – (90 * 11.11) = 1300
Para girar 180º (el otro extremo del servo), PWM = 2300 – (180 * 11.11) = 300
Completa la siguiente tabla calculando los valores necesarios para realizar giros de diferentes grados.
Luego modificas la variable “pwm” del programa para comprobar el correcto funcionamiento.
ANGULO 15º 30º 45º 75º 90º 105º 120º 135º 150º 165º 180º
PWM
Es la propia función write() quien calcula la duración del ciclo útil de la señal PWM, a partir de los
grados que deseamos girar. Ahora bien, para ello es necesario que conozca la duración mínima y máxima de
ése ciclo útil, según el modelo de servo que estemos utilizando. Por este motivo, en la función attach()
indicamos ahora estos dos parámetros:
void setup()
{
S3003.attach(3,300,2300); //Conecta y ajusta el servo
}
Si no se indican, se toman por defecto los valores de 544 µS y 2400 µS para la duración mínima y
máxima respectivamente. El efecto que esto puede producir es que el servo se vea excedido o limitado en su
recorrido.
Este ejemplo es una consecuencia de todo lo visto hasta el momento. El servo realiza una maniobra
consistente en desplazarse de un extremo al otro (180º en total) en intervalos de 5º. Luego vuelve a la
posición inicial y el ciclo se repite constantemente.
3V3
D13
VIN
GND
AREF
RESET RESET
D10
D11
D12
D2
D3
D4
D5
D6
D7
D8
D9
PWM
GND
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
Vdd
DISMINUY E
E11
5 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 5: Las señales PWM y el control de servo motores
www.microcontroladores.com
5 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Entendemos por comunicar al hecho de compartir información. Entre los humanos podemos transmitir y
recibir ideas, sensaciones, pensamientos, conocimientos, sentimientos, etc… En el mundo de los ordenadores
en general y de Arduino en particular, también se puede compartir información. Un Arduino se puede
comunicar con otro Arduino, con un ordenador tipo PC, con otro controlador, con un periférico, etc… Estamos
hablando de transmitir y recibir datos numéricos.
Imagina un Arduino que, bajo el control de tu programa, es capaz de recoger información del entorno
que le rodea a través de sensores de luz, presión, temperatura, humedad, velocidad, posición, presencia, etc…
Esta información se transmite, por ejemplo, a un PC. Este a su vez, bajo su propio programa de control, recoge
la información recibida para manipularla, registrarla, visualizarla gráficamente, imprimirla y, en definitiva,
realizar cualquier tipo de tratamiento con ella.
De igual forma, te puedes imaginar a un PC transmitiendo a nuestro Artduino una serie de órdenes o
instrucciones. Ordenes que al ser recibidas por nuestro Arduino, se procesan y se traducen en tareas tales
como activar / desactivar una bombilla, un led, un motor, un servo, un relé, o cualquier cosa que sea necesario
controlar. Ordenes con las que generar señales PWM, frecuencias de diferentes valores, realizar cálculos o
iniciar diferentes procesos dentro de Arduino.
En definitiva, las posibilidades de comunicar nuestro controlador Arduino NANO, abren una ventana
con el mundo exterior. Arduino no se queda en una simple tarjeta electrónica que ejecuta una determinada
tarea. Arduino es ahora capaz de “dialogar” con otros periféricos o sistemas, algunos de los cuales más
grandes y potentes que él mismo, y compartir información.
Al hablar de comunicar Arduino con cualquier otro sistema, estamos hablando de una comunicación
digital donde los datos transferidos son siempre códigos binarios compuestos de bits. Es más, la cantidad
mínima de información que se puede transferir es un byte que, como ya sabes, está compuesto de 8 bits.
Las personas nos podemos comunicar de diferentes formas: oral, escrita o visual. De la misma
manera, los sistemas digitales también tienen diferentes formas de trasferir información. Probablemente, una
de las más extendidas y utilizadas, sea la comunicación “serie asíncrona”. Observa la figura 6-1.
Es un tipo de comunicación que está disponible en cualquiera de las plataformas Arduino (UNO,
NANO, MEGA, DUE, etc…). Se emplean únicamente dos patillas o líneas: transmisión de datos (Tx) y
recepción de datos (Rx). Bajo el punto de vista del Arduino de la figura, éste transmite datos a través de la
línea Tx y son recibidos por el PC a través de su línea Rx. También a la inversa. El PC transmite datos a
través de su línea Tx, que son recogidos por la línea Rx de Arduino. Es decir, lo que es transmisión (Tx) en un
extremo, es recepción (Rx) en el opuesto y viceversa.
6-1
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Una transferencia de datos puede estar compuesta de decenas, cientos o miles de bytes. Un byte
está compuesto de 8 bits que van “circulando” uno tras otro por las líneas Tx y/o Rx, dependiendo de quién
trasmita o quién reciba.
Según el tiempo “t” en que cada uno de esos bits se mantenga en la línea Tx o Rx, se determina la
velocidad de la transferencia. Por ejemplo, si cada bit de cada byte se mantiene 1 segundo en las líneas Tx o
Rx, se dice que la comunicación es de 1 bit por segundo. Esto recibe el nombre de “baudio”. Un byte
completo tardará como mínimo 8 segundos en transferirse. Si lo multiplicas por el número total de bytes a
transferir, obtienes el tiempo que tarda en realizarse la comunicación.
Arduino es capaz de realizar comunicaciones desde los 300 hasta los 115200 baudios. Es decir,
115200 bits por segundo, o lo que es lo mismo, aproximadamente 14000 bytes por segundo (115200 / 8). En
este caso, cada bit se transmite o recibe en tan solo 8.6 µS (1 / 115200).
La velocidad a la que vamos a realizar las comunicaciones en los próximos programas de ejemplo, es
de 9600 baudios. Se trata de una velocidad muy segura y fiable. La admiten la mayor parte de dispositivos
con los que vayamos a comunicar, por ejemplo, un PC.
Sea cual sea el tipo de comunicación que vayamos a realizar, debemos conocer qué patillas de
nuestro controlador Arduino NANO son empleadas por esas señales. Se resumen en la siguiente tabla:
TIPO PATILLA
D0 D1 D4 D5 D10 D11 D12 D13
UART Rx Tx
I2C SDA SCL
SPI SS MOSI MISO SCK
Las patillas D0 y D1 se emplean como señales de recepción (Rx) y transmisión (Tx) respectivamente.
Se pueden conectar directamente con otra tarjeta Arduino o con cualquier otro tipo de dispositivo que admita
este mismo tipo de comunicación serie, y cuyas señales se adapten a las especificaciones eléctricas “TTL”.
6-2
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Quizá recuerdes que estas dos patillas (D0 y D1) las hemos empleado en algún ejemplo anterior,
como líneas de E/S para el control de periféricos, al igual que el resto de patillas. Sin embargo, si ahora
vamos a utilizarlas como líneas de comunicación, no debemos usarlas con ningún otro fin.
Dentro del sistema Arduino NANO, estas líneas (D0=Rx y D1=Tx), también están conectadas con
unos circuitos electrónicos que las adaptan a las especificaciones USB. En realidad las hemos estado
usando, sin saberlo, cada vez que el Arduino se comunica con el PC cuando grabamos un programa.
En resumidas cuentas, las patillas D0 (Rx) y D1 (Tx), o su equivalente a través del conector USB, las
podemos usar a partir de ahora para realizar nuestros propios programas de comunicación tipo UART.
Cualquier programa que vayamos a realizar a partir de ahora, y que emplee comunicaciones serie
tipo UART, necesita ser configurado y activado convenientemente. Para ello, el lenguaje Arduino dispone de
dos sentencias muy sencillas y fáciles de utilizar.
Activa la comunicación serie tipo UART y establece, en baudios, la velocidad de la misma. Una vez
ejecutada esta función, las líneas D0 y D1 se configuran como líneas de recepción (Rx) y transmisión (Tx)
respectivamente. A partir de este momento no deben ser usadas como líneas de entrada / salida digital.
Sintaxis:
Serial.begin(baudios);
baudios: Establece la velocidad deseada en la comunicación. Los valores posibles son: 300, 1200,
2400, 4800, 9600, 14400, 28800, 38400, 57600 o 115200.
Ejemplo:
void setup()
{
Serial.begin(9600); //Activa la comunicación serie a una velocidad de 9600 baudios
}
Desactiva la comunicación serie. Ejecutada esta sentencia, las patillas D0 (Rx) y D1 (Tx) pueden
volver a usarse como patillas de entrada / salida digital.
Sintaxis:
Serial.end();
Ejemplo:
Una vez establecida la comunicación podemos comenzar a realizar programas en los que, como se
muestra en la figura 6-2, Arduino transmite información al mundo exterior: un PC, otro Arduino, una
impresora, etc… Basta conocer las sentencias o funciones oportunas.
6-3
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Transmite datos vía serie y puede tener varias formas. Los valores numéricos se transmiten mediante
sus equivalentes caracteres ASCII, uno por cada dígito. En el caso de los números en coma flotante (“float”),
se transmiten con dos decimales por defecto. Los datos de tipo byte se transmiten como un único carácter
ASCII. Los caracteres o cadenas de caracteres (“strings”) se transmiten tal cual. Van cerrados entre comillas
simples o dobles respectivamente.
Sintaxis 1:
Serial.print(valor);
Ejemplos:
int A = 78;
Serial.print(A*2); //Transmite “156”
float PI = 3.141592;
Serial.print(PI); //Transmite “3.14”
Sintaxis 2:
Serial.print(valor,formato);
Ejemplos:
int A = 78;
Serial.print(A,BYTE); //Transmite “N” (en ASCII 78=N)
Serial.print(A,DEC); //Transmite “78” (en decimal, base 10). Por defecto
Serial.print(A,HEX); //Transmite “4E” (en hexadecimal, base 16)
Serial.print(A,BIN); //Transmite “01001110” (en binario, base 2)
Serial.print(A,OCT); //Transmite “116” (en octal, base 8)
float PI = 3.141592;
Serial.print(PI,0); //Transmite “3” (sin decimales)
Serial.print(PI,2); //Transmite “3.14” (con 5 decimales, por defecto)
Serial.print(PI,5); //Transmite “3.14159” (con 5 decimales)
6-4
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Tiene las mismas formas que la función anterior. La única diferencia es que tras transmitir los datos,
automáticamente transmite un código de “retorno de carro” (\r o 0x0D) y un “avance de línea” (\n o 0x0A).
Sintaxis:
Serial.println(valor);
Serial.println(valor,formato);
Ya basta de teoría. Hemos visto las sentencias fundamentales para establecer una comunicación
serie y transmitir datos. Es hora de hacer algunos sencillos programas que nos permitan introducirnos al
fascinante mundo de la transmisión de datos en serie.
+5Vcc
4-3-1 Ejemplo: Saludos
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
posibles. Consiste en transmitir un mensaje cada vez que se
D13
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
RESET RESET
AREF
VIN
GND
acciona un pulsador E10 conectado en la patilla D4, según
el esquema de la figura 6-3. Aunque aparece en el
ARDUINO NANO
esquema, lo concerniente al interface USB no va con
nosotros. Simplemente representa que las líneas D0 y D1
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
enlazan con el PC a través del interface USB. Ya hemos
comentado que estas líneas no debemos usarlas con otros
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
fines en aquellos programas que realicen comunicaciones
Tx
serie. Interface USB
con el PC Rx
E10
Figura 6-3. Circuito del ejemplo Saludos
void setup()
{
pinMode(4,INPUT); //D4 es entrada
Serial.begin(9600); //Ajusta velocidad de la comunicación a 9600 baudios
}
Como novedad del programa principal, en la función void loop(), comentar la presencia de la función
Serial.println() que transmite vía serie la cadena indicada (“Saludos desde Arduino …”) y que añade
automáticamente los caracteres de control /r y /n (retorno de carro y avance de línea).
¿Cómo verificar el funcionamiento del programa? Si tenemos en cuenta que el programa del Arduino
trata de transmitir un mensaje al PC, hemos de suponer que dicho PC también deberá tener un programa
para recibir ese mensaje y, por lo menos, visualizarlo. A este tipo de programas se les llama “programas de
comunicaciones”. Para ordenadores PC bajo plataformas Windows podemos encontrar un buen número de
6-5
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
ellos: HyperTerminal (incluido en Windows), Docklight, Procomm, Smartcomm, etc… Incluso, el propio
entorno de trabajo de Arduino, incluye un sencillo programa de comunicaciones llamado “Serial monitor”, que
nos facilita la comprobación de programas y ejemplos de éste tipo. Para activarlo basta con pulsar el icono
representado mediante una lupa. Ver la figura 6-4.
Cada vez que se acciona el pulsador E10 conectado con la patilla D4, Arduino transmite el mensaje
que será visualizado en la ventana de ese monitor.
6-6
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
3V3
D13
+5V
VIN
GND
RESET RESET
AREF
El programa es muy sencillo. Se van leyendo cada una de las
ARDUINO NANO
entradas D4:D7. Si están a nivel “1” se transmite el carácter ‘1’.
Si están a nivel “0” se transmite el carácter ‘0’.
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
Mediante las funciones oportunas del lenguaje de programación Arduino, tenemos la posibilidad de
conocer si se ha recibido o no algún byte, es decir, si hay alguno almacenado en el buffer. También podemos
leerlos en el mismo orden en que fueron llegando.
6-7
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Observa la figura 6-11. Muestra un portátil conectado con una tarjeta Arduino cualquiera (la UNO en
la figura), mediante el puerto USB. Desde él se transmiten los caracteres de la cadena “HOLA”, que son
recibidos por Arduino y almacenados en su buffer interno de memoria RAM.
Devuelve el número de bytes que se han recibido y están por tanto almacenados en el buffer de
memoria. Si devuelve el valor 0 es que no se ha recibido ningún byte y el buffer está vacío. El valor máximo
que puede devolver es de 64.
Sintaxis:
Serial.available();
Ejemplo:
byte A;
A=Serial.available(); //A se carga con el valor 4 suponiendo el ejemplo de la figura 6-11
….
while(¡Serial.available()); //Espera mientras no se reciba ningún byte
Lee del buffer los bytes según se han recibido. Si no se ha recibido nada, devuelve el valor de -1.
Sintaxis:
Serial.read();
Ejemplo:
Lee del buffer un número entero con signo recibido por el canal serie. El número recibido únicamente
puede estar compuesto de los caracteres 0 al 9, y del signo (+ o -). No se admite ningún otro carácter. Estará
comprendido entre -32768 y +32768.
6-8
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Sintaxis:
Serial.parseint();
Ejemplo:
Lee del buffer el número en coma flotante (número real) recibido vía serie. El número recibido
únicamente puede estar compuesto de los caracteres 0 al 9, del punto decimal (.) y del signo (-). No se
admite ningún otro carácter.
Sintaxis:
Serial.parsefloat();
Ejemplo:
Con las funciones o sentencias que acabamos de ver, ya estamos listos para presentar y trabajar con
una serie de ejemplos que reciben datos desde un PC, otro Arduino o cualquier otro tipo de dispositivo o
periférico cualquiera. Los datos recibidos serán procesados y tratados por nuestro controlador Arduino NANO
de acuerdo a las necesidades. En resumidas cuentas, tenemos lo necesario para que nuestro Arduino pueda
transmitir y/o recibir datos, e interaccionar con el mundo exterior mediante las comunicaciones serie tipo
UART.
+5Vcc
3V3
D13
VIN
GND
RESET RESET
AREF
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
S2
S3
Figura 6-12. Control remoto
En función del comando recibido, uno de los leds de salida cambia de estado: comando ‘0’ S0, ‘1’
S1, ‘2’ S2 y ‘3’ S3. Observa y estudia el siguiente fragmento del programa:
6-9
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Si se recibe el comando ‘0’, se lee el estado de la patilla D4 (led S0) y se invierte (¡digitalRead(4)). El
resultado se escribe sobre la misma patilla D4 (digitalWrite()). Es decir, si la patilla D4 está a nivel “0”, pasa a
nivel “1” y viceversa. Se emplea la misma técnica de “cambio de estado” para el resto de comandos y patillas.
El ejemplo emula el funcionamiento de una calculadora capaz de realizar las cuatro operaciones
básicas (suma, resta, multiplicación y división) entre dos números enteros. Ambos números se transmiten
desde el PC al Arduino vía comunicación serie. Así mismo, el resultado obtenido por Arduino, se transmite
ahora al PC vía serie. Tenemos por tanto una comunicación en ambos sentidos: Arduino ↔ PC .
La novedad principal del programa reside en que vamos a crear y usar nuestra primera función. Una
función es a su vez un conjunto de funciones o sentencias que se deben ejecutar varias veces. En lugar de
escribirlas tantas veces como se necesiten, se escriben una única vez y se usan las veces que sea necesario.
En este caso hemos creado la función Dato(). Está formada a su vez por otras tres funciones:
While(), Serial.parseInt() y return(). Cada vez que nuestro programa llame a la función Dato(), se ejecutarán
todas las funciones que ésta contiene devolviendo el número entero que se reciba vía serie.
int Dato()
//Esta función espera a recibir un nº int por el canal serie
{
while(!Serial.available()); //Esperar si no se recibe nada
int N=Serial.parseInt(); //Lee el nº int
return(N); //Devuelve el nº int
}
Se aconseja que las funciones creadas por el usuario se definan y escriban al principio del programa,
antes incluso que la función void loop().
No se puede usar una función que no haya sido previamente declarada.
El nombre de la función debe empezar siempre por una letra.
Todas las sentencia que contiene una función deben estar encerradas entre llaves ({ }).
Si la función, como en este caso, devuelve un valor de tipo int, se debe declarar como tal (int Dato()).
La sentencia return() finaliza la función y puede devolver el valor que le indiquemos (return(N) en el
ejemplo).
Una función puede tener también parámetros de entrada con los que operar. Se “pasan” desde el
programa principal.
Una función puede “llamar” a otra función.
Al finalizar una función se retorna al programa principal o a la función que la llamó.
El programa principal hace uso o “llama”· a una función, ejecutando las instrucciones que contenga,
tantas veces como haga falta:
Nuestro ejemplo espera a que introduzcamos vía serie, desde el PC, el primer operando (A=Dato()).
Luego debemos introducir el símbolo de la operación a realizar (+, -, *, /). Por último introducimos el segundo
operando (B=Dato()). Calcula el resultado según la operación deseada, y lo transmite vía serie al PC:
Serial.print(" = ");
Serial.println(R); //Retransmite el resultado
6 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
ocasión vamos a hacer un programa amigable que, de forma
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
AREF
VIN
GND
interactiva, nos pregunte por el porcentaje de potencia que
deseamos aplicar a un led de salida. Nos devuelve la duración ARDUINO NANO
del ciclo útil y genera la señal PWM correspondiente. Monta el
circuito de la figura 6-14.
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
El led S0 del laboratorio Universal Trainer se conecta
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
con la patilla D4. Su brillo se regulará de forma remota
Tx
mediante el terminal serie del entorno Arduino. Interface USB
con el PC Rx S0
Figura 6-14. Control remoto de la señal PWM
Trabajo personal
Proponemos que diseñes un programa amigable e interactivo que permita controlar la potencia que
se aplica a los leds S3:S0 conectados respectivamente con las patillas D4:D7 del controlador Arduino NANO.
6 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
En la misma línea que el ejemplo anterior, se trata de controlar de forma remota el posicionamiento
de un servo. De forma interactiva, mediante el terminal serie del entorno Arduino, se pregunta el número de
grados que el servo debe girar (entre 0º y 180º).
+5Vcc
La figura 6-16 muestra el esquema de las
conexiones a realizar.
900-00008
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
Servo
El servo se controla mediante una señal
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
AREF
VIN
GND
RESET RESET
PWM desde la patilla D3, al igual que en los
ejemplos del tema anterior. ARDUINO NANO
GND
D10
D11
D12
Como ya sabemos, las patillas D0 y D1 se
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
emplean como líneas de recepción (Rx) y
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
transmisión (Tx) respectivamente. Van a parar al
PWM
GND
Vdd
interface USB que conecta Arduino NANO con el
PC. Desde éste, transmitimos en grados el Tx
2
3
Interface USB
desplazamiento que deseamos que gire el servo. con el PC Rx
Trabajo personal
Imagina una máquina herramienta cuyo usillo debe realizar diferentes desplazamientos. Proponemos
diseñar un programa mediante el cual el servo realice una secuencia de cinco maniobras consecutivas. En la
pantalla del PC recibiremos los mensajes oportunos para que, de forma sencilla, cualquier usuario pueda
definir las diferentes maniobras. Por ejemplo:
VALORES MANIOBRA
1 2 3 5 5 6
GIRO 10º 90º 45º 135º 180º
TEMPORIZACION 5” 3” 5” 2” 6”
REPETICION 10
Esto se puede pude traducir como que en la maniobra nº 1, el servo gira 10º y espera 5”, en la
maniobra nº 2 gira 90º y espera 3”, etc… La repetición representa el número de veces que se han de repetir
las maniobras anteriores.
Una vez que finaliza toda la secuencia, el sistema queda disponible para iniciar una nueva.
Ahora que ya sabemos comunicar nuestro Arduino NANO con el PC (o con cualquier otro equipo), y
transferir datos en ambos sentidos mediante la comunicación serie tipo UART, quizá sea un buen momento
para estudiar nuevas funciones y posibilidades del lenguaje Arduino.
No vamos a necesitar tener conectado ningún periférico en el controlador. Nos basta con mantener la
conexión USB con el PC.
6 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Aunque los programas que proponemos son sencillos e interactivos con el usuario, siempre son
susceptibles de ser mejorados. Te animamos a ello.
min(A,B);
max(A,B);
abs(A);
pow(base,exponente);
6-1-4 Ejemplo:Raiz
sqrt(A);
6 - 13
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
sin(A);
cos(A);
tan(A);
El lenguaje Arduino dispone, además de las ya conocidas, otras funciones para el control del tiempo y
también para realizar ciertas operaciones especiales con las entradas y salidas digitales. Ahora que sabemos
comunicarnos vía serie con el exterior, es un buen momento para estudiarlas, usarlas y transmitir sus
resultados al PC a través del terminal serie del entorno Arduino.
Gracias a la función millis() es posible conocer el tiempo que lleva Arduino ejecutando un programa
desde que se conectó la alimentación o se reinició mediante el RESET. Esta función devuelve un número
largo sin signo, “unsigned long” (4 bytes), que representa el tiempo en milisegundos. Este número puede ir
32
desde 0 mS hasta 4.294.967.295 mS (2 -1), que representa
aproximadamente a unos 50 días de funcionamiento. En el ejemplo (figura
6-22) se visualiza en segundos el tiempo trascurrido desde el reinicio, y se
intercala una temporización de 5000 mS entre una visualización y la
siguiente.
Sintaxis:
millis();
De forma similar, la función micros() también nos permite conocer el tiempo que lleva Arduino
ejecutando un programa desde que se conectó la alimentación o se reinició mediante el RESET. En esta
ocasión la función devuelve un número largo sin signo, “unsigned long” (4 bytes), que representa el tiempo en
microsegundos. Este número puede ir desde 0 µS hasta 4.294.967.295 µS
32
(2 -1), que representa aproximadamente a unos 70 minutos de
funcionamiento. En el ejemplo (figura 6-23) se visualiza en microsegundos
el tiempo trascurrido desde el reinicio, y se intercala una temporización de
5000 mS entre una visualización y la siguiente.
Sintaxis:
micros();
6 - 14
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
En el tema anterior se estudiaron las señales PWM que se generaban mediante la función
analogWrite(). La duración del ciclo útil se establecía mediante un valor comprendido entre 0 y 255. En este
ejemplo vamos a ver la relación que hay entre ese valor y el tiempo real en µS que dura un ciclo útil o nivel
“1”.
Para ello vamos a emplear una nueva función: pulseIn(). Esta función es capaz de medir el tiempo
que dura un pulso a “1” o un pulso a “0” de una señal aplicada por cualquier patilla de entrada digital.
32
Devuelve un valor entero grande sin signo (“unsigned long”) comprendido entre 0 µS y 4.294.967.295 µS (2 -
1), equivalente a unos 70 minutos de duración.
Sintaxis:
3V3
+5V
A7
A6
A5
A4
A3
A2
A1
A0
D13
RESET RESET
VIN
GND
AREF
Arduino El brillo del led S0 varía en función de
ese valor. ARDUINO NANO
GND
D10
D11
D12
D1
D0
D2
D3
D4
D5
D6
D7
D8
D9
La patilla D11 se conecta a su vez con la
patilla de entrada D2. Mediante pulseIn()
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
En la figura 6-25 se muestra el resultado obtenido para diferentes valores del ciclo útil. Recordemos
que el sistema Arduino genera una señal PWM de aproximadamente 490 Hz de frecuencia F con un periodo
T de 2040 µS. Todos los valores indicados son aproximados y pueden variar ligeramente en función de
múltiples factores.
Se aprecia que con la anchura mínima del ciclo útil (0) la duración es,
evidentemente, de 0 µS. Con una anchura de 254, la duración es de 2010
µS. La máxima posible sería 255, el 100%, pero esto nos daría una
duración de 0 µS, ya que en este caso la señal PWM es fija a nivel “1”. No
es un pulso. Desborda el tiempo (Time-Out) de la función pulseIn() y
devuelve el valor 0.
La figura 6-26 muestra la señal PWM capturada mediante un osciloscopio. Se aprecia claramente la
lectura que ofrecen los cursores que miden la anchura del nivel “1” de una señal PWM, cuyo ciclo útil es de
100. El resultado de la medida es de 800 µS, muy cercano a los 788 µS ofrecido en la figura 6-25 para una
misma señal.
6 - 15
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Tx
Monta el esquema de la figura 6-28. Por
Interface USB 1
D1 VIN
30 primera vez vamos a utilizar el generador
con el PC Rx 2 29
3 D0 GND 28 lógico del entrenador Universal Trainer. Nos
RESET RESET
4
GND +5V
27 +5Vcc va a proporcionar la señal de onda cuadrada
Up Sel . 1 5 26
DIG 1-50Hz 6 D2 A7 25 cuya frecuencia el Arduino será capaz de
D3 A6
Dn Adj.
7
D4 A5
24 medir mediante pulseIn().
F = 1H z 8 23
9 D5 A4 22
D6 A3
10
D7 A2
21 Si dispones de la versión V1 o V2 del
E10 11 20
MEDIR 12 D8 A1 19 entrenador, debes usar el generador lógico y
D9 A0
13
D10 AREF
18 NO el generador de funciones. Selecciona la
14 17
15 D11 3V3 16 frecuencia más baja de las disponibles.
D12 D13
Si estás usando la última versión del Universal Trainer, la V3, debes seleccionar la señal de salida de
tipo digital (DIG), la escala más baja (1-50 Hz) y ajustar, mediante el potenciómetro, la frecuencia de salida
más baja posible.
6 - 16
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Puedes probar con cualquier frecuencia que el generador lógico de tu entrenador sea capaz de
suministrar. Quizá observes que cuanto mayor sea esta, menor precisión se obtiene en la medida. Esto es
debido a que el pulso mínimo que la función pulseIn() puede medir es de aproximadamente unos 10 µS, lo
que hace un periodo mínimo de 20 µS que equivale a una frecuencia máxima de unos 50 KHz.
La función pulseIn() tiene un parámetro que expresa el tiempo que debe esperar a que se produzca
el pulso que queremos medir. Se trata de un entero largo sin signo (“unsigned long”) que está comprendido
32
entre 0 µS y 4.294.967.295 µS (2 -1). Equivale a una espera máxima de unos 70 minutos de duración.
Si transcurre dicho tiempo sin que llegue el pulso (Time-Out), la función devuelve el valor 0. En este
ejemplo el valor de espera se establece en la variable “TO” que se carga con el valor 10000000 (10
segundos). En la figura 6-31 se muestra algunos resultados:
Trabajo personal
Prueba a cambiar el pulsador E10 por el interruptor E0. Cuando lo mueves de nivel “1” a nivel “0” y de
nuevo a “1”, ¿qué observas en las diferentes medidas?. El error se debe al efecto “rebote” del que ya hemos
hablado. Los interruptores del entrenador Universal Trainer, al igual que dispositivos similares, presentan
dicho efecto. ¿Por qué no ocurría con el pulsador?
Los pulsadores E10 y E11 del entrenador están dotados de un circuito anti rebote como el que se
muestra en la figura 6-32. Por la línea E10 se obtiene un pulso “limpio” con transición 1-0-1 cada que se
pulsa.
6 - 17
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
+5Vcc
Hemos visto las funciones más importantes empleadas en las comunicaciones serie, y también
hemos practicado con ellas. Sin embargo, el lenguaje Arduino tiene más funciones relacionadas con la
comunicación serie tipo UART. En este apartado vamos a hacer un resumen de ellas, dejando que seas tú
mismo quien experimentes con las mismas y las utilices según te convenga.
Lee los datos que hay en el buffer de recepción serie en busca de la cadena de caracteres indicada.
La función devuelve “true” (verdad) si la cadena se encuentra efectivamente en el buffer. Si devuelve “falso”
es porque la cadena no se ha encontrado y no hay más datos en el buffer.
Sintaxis:
Serial.find(cadena);
Es similar a find(), pero la búsqueda se detiene si no se encuentra el final indicado. Es útil para
encontrar una cadena con un final determinado, por ejemplo, retorno de carro (\r).
Sintaxis:
Serial.findUntil(cadena,final);
Devuelve el siguiente byte o carácter que haya en el buffer de recepción, pero sin sacarlo del mismo
como hacía la función Serial.read().
Sintaxis:
Serial.peek();
6 - 18
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Lee caracteres del puerto serie y los almacena en el buffer indicado. La función finaliza si se ha leído
el número de caracteres indicado, o se excede el tiempo de espera establecido (Time-Out). Devuelve el
número de caracteres almacenados en el buffer. Un valor 0 indica que no se recibió ninguno.
Sintaxis:
Serial.readBytes(buffer,número);
buffer: Buffer donde se reciben y guardan los caracteres (p.e. char recibir[ ])
número: Número de bytes a recibir (int)
Lee caracteres del puerto serie y los va almacenando en el buffer indicado. La función finaliza cuando
se detecte un determinado carácter, o se hayan recibido el número de caracteres indicado, o bien se excede
el tiempo de espera establecido (Time-Out). Devuelve el número de caracteres recibidos y almacenados en el
buffer. Un valor 0 indica que no se recibió ninguno.
Sintaxis:
Serial.readBytesUntil(carácter,buffer,número);
Permite ajustar el tiempo de espera que emplean ciertas funciones como Serial.parseInt(),
Serial.readBytes() o Serial.readBytesUntil(), para que se den por finalizadas.
Sintaxis:
Serial.setTimeout(tiempo);
tiempo: Es un número entero largo (long) que expresa, en milisegundos, el tiempo de espera. Por
defecto es de 1000 mS (1 segundo).
Escribe uno o más bytes sobre el puerto serie. Para enviar bytes que representan dígitos o caracteres
se aconseja el empleo de Serial.print().
Sintaxis:
Serial.write(byte);
Serial.write(cadena);
Serial.write(buffer,número);
6 - 19
ARDUINO: La tecnología al alcance de todos
TEMA 6: Las comunicaciones
www.microcontroladores.com
Es una función a la que se le llama cada vez que se recibe un byte, ejecutándose así todas las
sentencias que contenga. Se debe emplear la función Serial.read() para leer el dato recibido.
Sintaxis:
void serialEvent()
{
….
….
}
6 - 20
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Es probable que en algún momento hayamos hablado de señales o entradas “analógicas”, pero ¿qué
son?, ¿para qué sirven?, ¿dónde están?, ¿cómo se manejan? Vamos a dedicar este tema a explicarlas tanto
de forma teórica como práctica a base de diferentes ejemplos.
Hasta el momento hemos visto a nuestro controlador Arduino como un sistema digital que únicamente
entiende y manipula señales digitales compuestas de niveles “1” y “0”. Con estos niveles lógicos o bits
podemos realizar cualquier tipo de operación aritmético / lógica, operaciones de control, temporizaciones,
sonidos, regulación y hasta comunicaciones, como hemos estudiado en los temas precedentes.
En el mundo “digital” todo se contempla como si únicamente hubiera dos posibles valores. Un
interruptor o pulsador puede estar activado (“1”) o desactivado (“0”). Un led se puede encender o apagar. El
sonido se puede generar a partir de una señal de onda cuadrada, compuesta de “1”s y “0”s, con diferentes
frecuencias. La regulación en el brillo de un led, la velocidad de un motor o el posicionamiento de un servo, se
puede realizar mediante señales PWM, que también son señales compuestas de “1”s y “0”s.
Sin embargo el mundo “real” es diferente. En la naturaleza nos podemos encontrar con parámetros o
magnitudes que pueden adquirir múltiples valores, no sólo “1”s y “0”s. Pensemos por ejemplo en la
temperatura. Se trata de una magnitud física que constantemente está variando en el tiempo. No hace la
misma temperatura de madrugada, que al mediodía o a la noche. Si dispusiéramos de un sensor capaz de
capturar la temperatura y ofrecernos una tensión proporcional a la misma, veríamos que esa tensión puede
tener multitud de valores posibles, como se muestra
en la figura 7-1. La temperatura es una magnitud
analógica. Gracias al sensor obtenemos una
tensión de 2V a las 5h de la mañana. A las 9h la
tensión es de unos 4V y sube a unos 5V a las 15h.
A partir de las 16h la temperatura va disminuyendo
y, por la tanto, la tensión que ofrece el sensor
también. Únicamente nos hace falta establecer una
relación entre tensión (V) y temperatura (ºC).
Piensa en las múltiples magnitudes físicas analógicas que nos rodean. Mediante los sensores o
“transductores” apropiados podemos convertir esas magnitudes a sus tensiones analógicas equivalentes:
Humedad y/o humedad relativa. Nos permite conocer la cantidad de vapor de agua que hay en la
atmósfera terrestre.
Presión atmosférica. Con el sensor oportuno podemos conocer la presión que ejerce el aire sobre la
tierra.
Peso. Podemos medir la fuerza con la que un cuerpo actúa sobre un punto de apoyo.
Velocidad. Con los sensores apropiados podemos medir la velocidad a la que se desplaza el aire, una
persona, un vehículo, etc…
Luz. Podemos medir la luz ambiente o la luz que incide sobre un objeto. Hay sensores que detectan luz
visible, infra roja, ultra violeta, etc…
Sonido. Con los transductores existentes se puede medir, conocer y/o detectar ruidos, sonido
ambiente, volumen, etc…
Hoy en día existen en el mercado todo tipo de sensores y transductores capaces de ofrecer una
tensión analógica equivalente a la magnitud física que están midiendo. Sin embargo, ningún sistema digital es
capaz de manipular ni procesar directamente esas tensiones analógicas. Nuestro controlador Arduino tampoco.
7-1
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Primero es necesario convertir las tensiones analógicas a sus equivalentes valores digitales. Para ello
se emplean unos circuitos electrónicos llamados “Convertidores Analógicos Digitales o Analog Digital
Converters”, abreviadamente “ADC”.
La figura 7-2 resume los elementos necesarios para poder procesar una magnitud analógica como
puede ser la temperatura.
1. El sensor o transductor, en este caso de temperatura, capta la magnitud física a medir. A su salida
ofrece una tensión analógica proporcional a esa temperatura.
2. Esa tensión se introduce al convertidor analógico/digital ADC. Este circuito ofrece a su salida un valor
binario equivalente a esa tensión.
3. El valor binario puede ser leído por el sistema digital, que puede ser nuestro Arduino o cualquier tipo de
controlador.
4. El sistema digital es ahora capaz de realizar cualquier tratamiento con ese valor binario: registrarlo en
memoria, realizar operaciones aritmético / lógicas, visualizarlo, transferirlo a otro sistema, etc…
Casi todos los microcontroladores actuales llevan integrado el circuito convertidor ADC. Básicamente
solo hace falta conectarle el sensor o transductor correspondiente a la magnitud física que queremos medir y
tratar. El controlador Arduino NANO, como no podía ser menos, es uno de ellos.
7-2
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Si tuviéramos una señal analógica cuya frecuencia F es de 500 Hz y su periodo T de 2000 µS,
podremos hacer una total de 20 muestreos (2000 µS / 100 µS). Es decir, tendríamos una “digitalización” más
precisa de esta nueva señal.
No siempre es necesario tomar tantas muestras por segundo de una determinada señal analógica.
Pensemos de nuevo en un sensor que mide la temperatura ambiente. Se trata de una magnitud que varía muy
lentamente. La temperatura no pasa de -10 ºC a +15 ºC en 0.0001 segundos. Lo mismo pasa con la luz natural.
No pasamos de la noche al día cada 100 µS. También ocurre con el peso. Nadie pesa 60 Kg ahora y 85 Kg 100
µS después. Por todo ello podemos afirmar: ¡¡ La velocidad de conversión de Arduino NANO es más que
suficiente para medir la mayor parte de magnitudes físicas analógicas !!
Para establecer una relación entre el valor digital o binario de salida, y la tensión analógica de entrada
que estamos midiendo, necesitamos conocer una constante llamada “Tensión de referencia” (VREF). Es la
tensión que emplea el convertidor para hacer sus operaciones. La resolución por bit se calcula según la
siguiente ecuación, y depende tanto de la VREF como del número de bits del convertidor. Suponiendo que VREF
= 5 V:
ó = = = . / ≅ = .
Conocido esto podemos predecir el valor binario de salida que nos ofrecerá el convertidor, en función
de la tensión analógica de entrada que estamos midiendo. Observa y analiza la siguiente tabla:
SALIDA SALIDA
TENSION BINARIO DEC. HEX. TENSION BINARIO DEC. HEX.
0.000 0000000000 0 0x0 2.500 1000000000 512 0x200
0.005 0000000001 1 0x1 3.000 1001100110 614 0x266
0.010 0000000010 2 0x2 4.000 1100110011 819 0x333
0.015 0000000011 3 0x3 4.985 1111111100 1020 0x3FC
0.020 0000000100 4 0x4 4.990 1111111101 1021 0x3FD
1.000 0011001100 204 0xCC 4.995 1111111110 1022 0x3FE
2.000 0110011000 408 0x198 5.00 1111111111 1023 0x3FF
7-3
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Basta dividir la tensión de entrada analógica entre la resolución por bit del convertidor, en este caso
0.00488. Por ejemplo: 3 V / 0.00488 = 614 = 0x266 = 1001100110.
¡¡ IMPORTANTE !!. La tensión analógica a medir nunca debe ser superior a la tensión de referencia VREF
que emplea el convertidor en sus operaciones internas. Por ejemplo, si VREF = 5V la tensión analógica
máxima de entrada será también de 5 V.
Para el control y empleo del convertidor ADC integrado en Arduino NANO únicamente se necesitan dos
sentencias del lenguaje de programación Arduino. Son muy sencillas y seguro que les encuentras un sinfín de
posibles aplicaciones.
Permite determinar la tensión de referencia (VREF) que va a emplear el convertidor ADC, para realizar la
conversión de una tensión analógica en su equivalente valor digital o binario. Esto es importante ya que
conocida ésta podremos calcular la resolución por bit del convertidor.
La tensión VREF no debe ser mayor que la tensión general que alimenta al controlador Arduino NANO
(normalmente 5 V). Por su parte, la tensión analógica que se desea convertir, no debe ser mayor que la tensión
VREF.
Sintaxis:
analogReference(tipo);
DEFAULT: Es la tensión de referencia por defecto. VREF es la misma que la tensión con la que se
alimenta el controlador: 5 V o 3.3 V según el tipo de controlador.
INTERNAL: Es una tensión de referencia fija que se genera en el interior del propio controlador. En el
caso de Arduino NANO es de 1.1 V.
EXTERNAL: Se usa como tensión VREF de referencia la aplicada por la patilla AREF del controlador.
Ejemplo:
En este ejemplo, teniendo en cuenta que el convertidor es de 10 bits, la resolución por bit es de:
.
ó = = = . / ≅ = .
Es la sentencia que vamos a emplear para realizar una conversión analógico/digital. Cada vez que se
ejecuta toma una muestra de la tensión presente en el canal analógico indicado, y realiza la conversión de la
misma.
Sintaxis:
analogRead(pin);
7-4
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
pin: Es el número de la patilla correspondiente al canal analógico que deseamos convertir. En el caso de
Arduino NANO son 8: A0-A7.
Ejemplo:
int V;
V=analogRead(A3); //Realiza la conversión de la tensión presente en la patilla A3.
Ya sabemos que el convertidor de nuestro Arduino tiene una resolución de 10 bits, por lo que el
10
resultado puede ser un valor numérico comprendido entre 0 y 1023 (2 ). Sin embargo, nos puede interesar
8
usar dicho valor como si fuera de 8 bits (byte), comprendido entre 0 y 255 (2 ), ya que es un formato mucho
más estándar y más empleado por múltiples funciones.
Sintaxis:
valor:Es el valor que se desea reasignar. Normalmente es de tipo int (16 bits) o de tipo long (32 bits). No
debe usarse con valores tipo float.
min: Expresa el límite mínimo del valor actual.
max: Expresa el límite máximo del valor actual.
Nmin: Expresa el límite mínimo del nuevo valor.
Nmax: Expresa el límite máximo del nuevo valor.
Ejemplo:
int V;
V=readAnalog(A3); //Realiza la conversión de la tensión presente en la patilla A3
v=map(V,0,1023,0,255); //Reasigna el valor leído convirtiéndolo a un byte
El valor analógico leído desde la patilla A3, está comprendido entre 0 y 1023 y se almacena en la
variable V. Dicho valor se reasigna a otro equivalente comprendido entre 0 y 255. Esta sentencia, según
Arduino, responde a la siguiente función matemática:
( − )∗( − )
=
( − )+
Ya se ha comentado que en el mercado existe una gran variedad de sensores y dispositivos capaces
de proporcionar una tensión analógica, comprendida entre un mínimo y un máximo, en función de una
determinada magnitud física. Para desarrollar las siguientes prácticas hemos elegido a tres de ellos por su
facilidad de uso, por ser asequibles y fáciles de localizar.
7-5
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
4-1 El potenciómetro
En la figura 7-7 puedes ver el aspecto de uno de estos potenciómetros así como su símbolo eléctrico.
Dispone de tres terminales o patillas. La 1 y la 2 se corresponden con los extremos de la resistencia y
representan el valor total de la misma. La patilla 3 es el cursor
y está asociado mecánicamente con el eje o mando que
permite deslizarlo por el cuerpo de la resistencia. Cada vez que
lo movemos variamos el valor de la resistencia. Si lo
colocamos justo en el centro de su recorrido, entre las patillas
1 y 3 tenemos la mitad de la resistencia total, en las patillas 2 y
3 la otra mitad. Por el mismo motivo se aplicamos una tensión
en sus extremos 1 y 2, por ejemplo de 5 V, entre la patilla 3 y
cualquiera de las otras dos tendremos una tensión que varía
entre 0 y 5V en función de dónde coloquemos el cursor.
El programa espera a recibir un pulso procedente de la entrada digital D2. La única novedad en este
ejemplo se encuentra en las siguientes dos funciones:
La función AN0=analogRead(A0) toma una muestra de la tensión analógica presente en la patilla A0, y
que suministra el potenciómetro. El resultado digital se almacena en la variable “AN0”. A continuación se
calcula la tensión real aplicada, como si fuera un voltímetro. Basta con multiplicar el valor digital por la
constante 0.00488. Recuerda que esta constante representa la resolución por bit.
7-6
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Es posible que notes que es francamente difícil ajustar ambas tensiones V1 y V2 a un mismo valor y
que se active así el led S4 (V1=V2). Los convertidores suelen tener una precisión de ± 1 bit. Si además
tenemos en cuenta que los potenciómetros son dispositivos electromecánicos, resultará muy difícil obtener dos
conversiones idénticas. La igualdad en ambas tensiones V1 y V2 se aprecia perfectamente cuando los
potenciómetros se mueven a ambos extremos (0V o 5V).
7-7
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
ARDUINO NANO
Figura 7-12. Control de brillo
Como novedad en el ejemplo usamos la función map(). Se emplea para trasladar un número de un
rango a otro rango diferente de forma proporcional. En este programa el valor obtenido de la conversión, que
está en el rango comprendido entre 0 y 1023, se pasa a otro rango comprendido entre 0 y 255 con el que se
genera la señal PWM.
1
D1 VIN
30 De forma similar, también podemos ajustar, por ejemplo, la
2 29
3 D0 GND 28 frecuencia de una señal. Monta el circuito de la figura 7-13. Se
RESET RESET
4
GND +5V
27 +5Vcc trata de un generador de frecuencias que puede tener un buen
5 26
6 D2 A7 25 número de aplicaciones prácticas como la comprobación de
D3 A6
7
D4 A5
24
+5Vcc
amplificadores B.F. (Baja Frecuencia), equipos de audio,
8 23
9 D5 A4 22 ecualizadores, etc…
10 D6 A3 21
11 D7 A2 20
12 D8 A1 19 REG. 1K A partir del valor analógico que proporciona el potenciómetro de
13 D9 A0 18
LS7
14 D10 AREF 17
1K conectado en la patilla A0, se genera una frecuencia audible
15 D11 3V3 16 comprendida entre 100 y 5000 Hz (5 KHz).
D12 D13
SPEAKER
ARDUINO NANO Figura 7-13. El generador de BF
7-8
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
El programa se limita a medir la tensión que genera el sensor BPW40 en función de la luz que incide
cobre él. Transmite vía serie al terminal del entorno Arduino, el resultado de la conversión, la intensidad que
circula por el sensor y la resistencia, y la caída de tensión en ésta.
Trabajo personal
7-9
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
1
D1 VIN
30 Aquí tienes un ejemplo con una buena utilidad práctica. Se
2 29
3 D0 GND 28 trata de controlar un sistema de alumbrado de forma que,
RESET RESET
4
GND +5V
27 +5Vcc cuando la luz ambiente baje por debajo de un valor mínimo
5 26
6 D2 A7 25 (p.e. se hace de noche), se active una salida que simula la
7 D3 A6 24
S0 8 D4 A5 23
activación de una bombilla, farola, etc…
9 D5 A4 22
10 D6 A3 21
11 D7 A2 20
Monta el circuito de la figura 7-19. El led S0 se conecta con
12 D8 A1 19 la patilla D3 de salida. Simula la activación o no del sistema
13 D9 A0 18
14 D10 AREF 17
E de alumbrado.
15 D11 3V3 16 10K
D12 D13 C
BPW40
El ejemplo muestra cómo “filtrar” una señal analógica que, como en este caso, nos suministra el sensor
de luz. Basta con tomar un número determinado de muestras haciendo las conversiones analógico/digitales
que sean necesarias. Luego se calcula la media aritmética con todas ellas.
Para realizar esta tarea se ha creado una función llamada Medir_luz(). Devuelve un valor entero con el
valor medio de las 10 conversiones que se realizan con un intervalo de 2 mS entre muestra y muestra.
Se comprueba si el valor medio obtenido es menor que el valor mínimo establecido, en cuyo caso se
activa la salida D3 simulando el alumbrado.
Trabajo personal
Consideremos el control de alumbrado anterior. Es de noche y las farolas están activadas. ¿Qué pasa
si en una noche de tormenta se produce un rayo o un relámpago cuya luz incide sobre el sensor? Seguramente
las farolas se apagan ya que, en ese instante, el sistema piensa que es de día. Luego se volverán a encender.
Esto es real y puede ocurrir, pero ¿es deseable? Encuentra una solución para corregir este tipo de casos.
Estamos seguros de que se te van a ocurrir gran cantidad de aplicaciones basadas en la detección y
tratamiento de la luz ambiente. Por ello te vamos a proponer un último ejemplo que, como todos los demás, es
susceptible de ser mejorado. Se trata de un sistema automático para regular el alumbrado de, por ejemplo, un
recinto.
Imagina una habitación con una bombilla de alumbrado y un sensor de luz colocado estratégicamente
en el exterior. Según la luz que reciba, la bombilla brillará más o menos. Cuando es un día claro y luminoso la
bombilla permanece apagada o con muy poca intensidad. Si por el contrario es un día nublado, o es de noche,
la bombilla brillará con mucha intensidad.
Te sirve el mismo esquema que el de la figura 7-19 anterior. El programa es muy sencillo y como tal no
aporta nada nuevo salvo la idea propia de la aplicación. Se realiza una conversión analógica/digital y se toma
una muestra de la luz ambiente actual. Para ello empleamos la función Medir_luz() desarrollada en el ejemplo
anterior.
El valor obtenido estará comprendido entre 0 y 1023 y se mapea en otro valor comprendido entre 255 y
0 mediante:
Observa que si la luz medida es de 0 (oscuridad total), tras el mapeado tenemos el valor 255. Si se
recibe la luz máxima, el valor de la conversión es de 1023 tras el mapeado tendremos el valor 0. Es decir, con
poca luz tenemos un valor alto y viceversa.
7 - 10
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Este valor mapeado es el que vamos a usar para generar una señal PWM por la patilla D3, y que
controlará el brillo del led S0 (o la bombilla). Cuanto menor sea la luz ambiente (de noche), mayor es la
duración del ciclo útil. El led se ilumina con más intensidad. Si la luz ambiente es mayor (de día), menor es la
duración del ciclo útil. El led se ilumina con menos intensidad.
La figura 7-21 muestra su esquema de conexiones. Tiene tres patillas. Dos de ellas
se conectan con la alimentación, +5V y GND. Por la tercera patilla circula una
intensidad (I) proporcional a la temperatura. Esta intensidad atraviesa la resistencia
(R) creando en ella una tensión (Vout) que la aplicaremos a la entrada del
convertidor analógico digital, desde donde la podremos leer y procesar.
10 mv / ºC
Figura 7-21. Conexiones del sensor de temperatura
Para calcular la temperatura ambiente en grados centígrados (ºC), a partir del resultado de la tensión
Vout que suministra el sensor, podemos aplicar la siguiente ecuación:
× × ×
º = =
D2 A7
Vdd
6 25
conectado con la patilla D2. Ver el esquema de la E10 7 D3 A6 24
D4 A5
figura 7-22. 8 23
1
9 D5 A4 22
10 D6 A3 21
D7 A2
La salida Vout del sensor de temperatura se 11
D8 A1
20
12 19
conecta con la patilla de entrada analógica A0. 13 D9 A0 18
14 D10 AREF 17
15 D11 3V3 16 100K
El resultado se transmite vía serie al terminal D12 D13
del entorno de programación de Arduino.
ARDUINO NANO
7 - 11
ARDUINO: La tecnología al alcance de todos
TEMA 7: Las señales analógicas
www.microcontroladores.com
Acabamos el tema con otro ejemplo de una importante utilidad práctica. Vamos a simular un sencillo
sistema de climatización. Monta el circuito de la figura 7-24.
+5Vcc
El led S7 simula la activación o no de un
Tx LM35DZ
sistema de refrigeración, mientras que el led S0 Interface USB 1 30
Rx 2 D1 VIN 29
simula a un sistema de calefacción. Ambos se con el PC
3 D0 GND 28 tª
conectan con las patillas D2 y D3 respectivamente. 4 RESET RESET 27
5 GND +5V 26
GND
Vout
D2 A7
Vdd
6 25
El ejemplo toma la temperatura actual S7 7 D3 A6 24
REFRIGERADOR 8 D4 A5 23
mediante el sensor analógico conectado con A0. Si
3
9 D5 A4 22
D6 A3
sobrepasa unos límites máximos y mínimos se activa 10
D7 A2
21
11 20
el sistema correspondiente. En cualquier caso, la S0 12 D8 A1 19
D9 A0
temperatura actual, que se toma cada dos segundos, CALEFACTOR 13
D10 AREF
18
14 17
se transmite vía serie al terminal del entorno Arduino. 15 D11 3V3 16 100K
D12 D13
ARDUINO NANO
7 - 12
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Vamos a acabar este módulo de prácticas presentando una serie de ejemplos adicionales que,
esperamos, puedan tener una valiosa utilidad práctica, te sirvan definitivamente para asentar todo lo aprendido
hasta el momento y te proporcionen una visión de las múltiples aplicaciones que puedes realizar con un
controlador como nuestro Arduino NANO.
Queremos hacer una mención especial a la pantalla LCD que vamos a emplear. Sobre ella vamos a
poder visualizar todo tipo de información. En realidad, todos aquellos ejemplos que hemos realizado, y cuyos
resultados se trasmitían vía serie al PC, podemos visualizarlos ahora sobre la pantalla LCD. Esto nos permitirá
realizar aplicaciones totalmente autónomas e independientes.
Se trata de uno de los periféricos más potentes y versátiles. Es capaz de visualizar todo tipo de
mensajes compuestos de texto, números y símbolos, y producir además diferentes efectos de visualización
como desplazamientos a izquierda y derecha, parpadeos, scrolls, etc… Una pantalla LCD tiene su propio
controlador que la gestiona.
La figura 8-1 muestra la pantalla LCD que vamos a utilizar y que se incluye
en el módulo. Se trata de una pantalla compuesta de 2 filas y 16 caracteres
por fila (2x16). Las hay con diferentes configuraciones: 1 x 16, 4 x 20, 2 x
20, 2 x 40, etc… En la figura también se aprecia cómo hemos soldado una
tira de 14 pines macho, que nos permitará insertar la pantalla sobre el
módulo board del entrenador Universal Trainer. De esta forma podremos
hacer rápidamente las conexiones con el controlador. Observa la posición
en que se encuentra la patilla número 1.
10
11
12
13
14
1
2
3
4
5
6
7
8
La figura 8-2 muestra el conexionado típico de estas pantallas. 9
RS
D0
D1
D2
D3
D4
D5
D6
D7
GND
VCC
VLC
R/W
NOMBRE Nº DESCRIPCION
GND 1 Conexión con GND de alimentación
VCC 2 Conexión con +5 V de alimentación
VLC 3 Tensión variable de entrada de entre 0 y 5 V para ajustar el contraste de la
pantalla.
RS 4 Entrada de control. A nivel “1” la pantalla recibe los códigos ASCII de los
caracteres a visualizar. A nivel “0” recibe códigos de control.
R/W 5 Entrada de lectura / escritura. A nivel “1” podemos leer el estado interno de la
pantalla. A nivel “0” podemos escribir los distintos caracteres a visualizar o los
distintos códigos de control.
E 6 A nivel “1” la pantalla queda habilitada para recibir caracteres y/o códigos de
control. A nivel “0” queda desconectada.
D0:D7 7 – 14 Son las líneas de datos por donde la pantalla recibe los caracteres y/o códigos
de control. Se conectan con las salidas de nuestro controlador. El interface
puede ser de 8 bits (se emplean a D0:D7) o de 4 bits (se emplean a D4:D7)
8-1
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
8 23
9 D5 A4 22
patillas D4:D7 del Arduino se conectan
D6 A3
10
D7 A2
21 con las patillas D4:D7 de la pantalla.
11 20
12 D8 A1 19
10
11
12
13
14
D9 A0
1
2
3
4
5
6
7
8
9
13
D10 AREF
18 Las patillas D2 y D3 controla las señales
14 17
RS
D0
D1
D2
D3
D4
D5
D6
D7
R/W
15 D11 3V3 16
D12 D13
directamente a GND (modo escritura).
ARDUINO NANO
Con la resistencia de 4K7 conectada
entre VLC y GND se consigue un buen
LCD2x16 contraste. Su valor se puede variar para
aumentarlo o disminuirlo.
Figura 8-3. Conexión de Arduino con la pantalla LCD
La fotografía de la figura 8-4 muestra el montaje final sobre el entrenador Universal Trainer.
Ya estamos familiarizados con el concepto de “librería” y el manejo de las múltiples funciones que
contiene. Acuérdate de la librería “Servo.h” que usamos en su momento para el control de servomotores.
De las muchas librerías creadas por el equipo de Arduino, vamos a hablar ahora de la librería
“LiquidCrystal.h”. Contiene un buen número de funciones dedicadas al control y manejo de pantallas LCD
basadas en el controlador Hitachi HD44780 o compatible.
8-2
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
De todas esas funciones, vamos a estudiar las más representativas e importantes. En cualquier caso,
te invitamos a que visites el sitio www.arduino.cc donde encontrarás abundante información y ejemplos con
todas ellas.
Crea una variable tipo LiquidCrystal y establece las conexiones entre la pantalla y el controlador
Arduino. El interface entre ambos puede ser de 8 o de 4 bits, en cuyo caso las líneas D0-D3 no se emplean.
Igualmente podemos determinar si se emplea o no la señal R/W de la pantalla. En caso de no usarse, dicha
señal debe conectarse con GND.
Sintaxis:
var: Nombre de una variable que se asigna a la pantalla LCD que vamos a controlar.
RS: Patilla del Arduino que se conecta con la señal RS de la pantalla.
RW: Patilla del Arduino que se conecta con la señal R/W de la pantalla (si es que se va a usar).
E: Patilla del Arduino que se conecta con la señal E de la pantalla.
D0-D7: Patillas de Arduino que se conectan con las líneas de datos D0-D7 de la pantalla. Si no se indican las
patillas para D0-D3, se supone un interface de 4 bits y únicamente se emplean las señales D4-D7.
Ejemplo:
LiquidCrystal lcd(2,3,4,5,6,7); //Establece la conexión de una pantalla llamada “lcd”. Las patillas D2 a D7 del
//Arduino se conectan con las señales RS,E,D4,D5,D6 y D7 de la pantalla. La
//señal R/W se debe conectar con GND
Inicia la pantalla LCD y le asigna el número de filas y el número de caracteres por fila según el modelo
de que se trate. En nuestro caso usamos una pantalla de 16 x 2 caracteres.
Sintaxis:
var.begin(c,f);
Ejemplo:
LiquidCrystal lcd(2,3,4,5,6,7);
lcd.begin(16,2); //La pantalla “lcd” es de 16 x 2
Coloca el cursor de la pantalla LCD en la posición deseada. A partir de ella se irán visualizando los
posteriores caracteres.
Sintaxis:
var.setCursor(c,f);
8-3
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Ejemplo:
LiquidCrystal lcd(2,3,4,5,6,7);
lcd.setCursor(3,0); //Coloca el cursor en la posición 3 (4º carácter) de la fila 0 (la 1ª)
Coloca el cursor en la primera posición de la pantalla, el ángulo superior izquierdo (posición 0 de la fila
0). No se borra el contenido de la misma.
Sintaxis:
var.home();
Borra la pantalla LCD y coloca el cursor en el ángulo superior izquierdo (posición 0 de la fila 0).
Sintaxis:
var.clear();
Ejemplo:
LiquidCrystal lcd(2,3,4,5,6,7);
lcd.clear(); //Borra la pantalla
Sintaxis:
var.write(char);
Ejemplo:
Sintaxis:
var.print(dato);
var.print(dato,base);
8-4
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Ejemplos:
int A=19;
float PI=3.1416;
lcd.print(A,HEX); //Imprime A en hexadecimal (1910 = 1316)
lcd.print(“Hola”); //Imprime “Hola”
lcd.print(PI*2,4); //Imprime 6.2832
Sintaxis:
var.cursor();
Sintaxis:
var.noCursor();
Sintaxis:
var.blink();
Sintaxis:
var.noBlink();
Apaga la pantalla LCD sin perder ni el texto que hubiera ni la posición actual del cursor.
8-5
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Sintaxis:
var.noDisplay();
Sintaxis:
var.display();
Desplaza el contenido que visualiza la pantalla (texto y posición del cursor) una posición a la izquierda.
Sintaxis:
var.scrollDisplayLeft();
Desplaza el contenido que visualiza la pantalla (texto y posición del cursor) una posición a la derecha.
Sintaxis:
var.scrollDisplayRight();
Establece la dirección de escritura de izquierda a derecha sobre la pantalla (por defecto). Esto implica
que los caracteres se van escribiendo de izquierda a derecha sin afectar a los que ya están escritos.
Sintaxis:
var.LeftToRight();
Establece la dirección de escritura de derecha a izquierda sobre la pantalla. Esto implica que los
caracteres se van escribiendo de derecha a izquierda sin afectar a los que ya están escritos.
Sintaxis:
var.RightToLeft();
8-6
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Sintaxis:
var.autoscroll();
Sintaxis:
var.noAutoscroll();
Crea un carácter personalizado por el usuario. Se pueden crear un total de 8 caracteres de 5 x 8 pixels
y numerados del 0 al 7. La apariencia o diseño de un carácter se determina en una matriz de 8 bytes, uno por
cada fila. Los 5 bits de menos peso de cada byte se corresponden con los 5 pixels que forman cada fila del
carácter. Una vez creado un carácter, se puede visualizar en la pantalla indicando simplemente su número.
Sintaxis:
var.createChar(n,dato);
Ejemplo:
byte flecha[8] ={
B00100,
B01110,
B10101,
B00100,
B00100,
B00100,
B00100,
B00100 }; //Crea la matriz “flecha” con 8 bytes que definen el nuevo carácter personalizado
8-7
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
En este apartado vamos a presentar una serie de ejemplos que utilizan las funciones anteriores, con
objeto de controlar la pantalla LCD y realizar diferentes efectos de visualización. La mayor parte de ellos se han
realizado a partir de los ejemplos incluidos en Arduino, no sin antes modificarlos y adaptarlos a nuestras
condiciones.
Para probarlos, y salvo que se indique otra cosa, vamos a emplear el esquema de conexiones que se
mostró en la figura 8-3.
Emplea las funciones display() y noDisplay() para habilitar o no la pantalla LCD. Cuando se
deshabilita la pantalla se apaga, pero su información se mantiene. De esta forma, cuando se vuelve a habilitar
la pantalla visualiza exactamente lo mismo que tenía.
Las funciones cursor() y noCursor() permite activar o no la visualización del cursor. El cursor se
presenta como el símbolo de un guión bajo ( _ ) y en todo momento indica la posición donde se visualizará el
siguiente carácter que escribamos en la pantalla.
El cursor también se puede representar como un símbolo sólido ( ▓ ) intermitente, que indica la
posición donde se visualizará el siguiente carácter que escribamos en la pantalla. Para ello podemos emplear
las funciones blink() y noBlink().
El ejemplo escribe un mismo texto “Microsystems” en las dos líneas que dispone la pantalla LCD. En la
línea superior se escribe de izquierda a derecha, lo normal. En la línea inferior se escribe de derecha a
izquierda.
8-8
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
El ejemplo visualiza dos textos, uno en cada línea de la pantalla. En la línea superior se visualiza sin
desplazamiento, en la línea inferior se visualiza con un desplazamiento automático hacia la izquierda (por
defecto).
La mayor parte de las pantallas LCD compatibles con el controlador Hitachi HD44780 permiten diseñar
o personalizar hasta un máximo de 8 caracteres numerados del 0 al 7. De esta forma podemos construir
símbolos gráficos o incluso caracteres de un determinado idioma que no están definidos en la propia pantalla.
Cada carácter se construye en torno a una matriz de 5x8 pixels o puntos, por lo que se necesitan los 5
bits de menos peso de 8 bytes consecutivos. En la figura 8-6 tenemos el diseño de dos caracteres: una sonrisa
y un corazón. Cada uno de ellos precisa de 8 bytes que se codifican según se muestra. Un bit a nivel “1”
implica que su correspondiente pixel se activa.
El programa crea cinco matrices o arrays de 8 bytes cada una, donde se definen otros tantos
caracteres personalizados: “corazon”, “alegre”, “serio”, “abajo” y “arriba”. Mediante la función createChat() se
numeran (del 0 al 4) y se almacenan en la memoria interna de la pantalla.
Por último, para visualizarlos en la posición actual del cursor, basta con emplear la función write(n),
donde n expresa el número de carácter (del 0 al 4 en el ejemplo) que se desea visualizar.
Aquí tienes un ejemplo de indudable interés práctico. Se trata de crear un nexo de unión entre el canal
serie de, por ejemplo, un ordenador tipo PC, y nuestra pantalla LCD. En medio se encuentra nuestro
controlador Arduino NANO. Monta el circuito de la figura 8-7.
8-9
ARDUINO: La tecnología al alcance de todos
TEMA 8: La pantalla LCD
www.microcontroladores.com
Tx
Interface USB 1 30
+5Vcc Rx 2 D1 VIN 29
con el PC D0 GND
3 28
4 RESET RESET 27
El Arduino hace de puente. Por un lado se
GND +5V +5Vcc
5
D2 A7
26 conecta, mediante el interface USB con
6 25
7 D3 A6 24
un PC. Por otro lado se conecta con la
D4 A5
4K7
8
D5 A4
23 pantalla LCD como lo hemos venido
9 22
10 D6 A3 21 haciendo hasta ahora.
11 D7 A2 20
12 D8 A1 19
10
11
12
13
14
4
5
6
7
8
9
13 18
D10 AREF
14 17 de mensajes que serán recibidos por el
RS
D0
D1
D2
D3
D4
D5
D6
D7
GND
VCC
VLC
R/W
15 D11 3V3 16
D12 D13 Arduino. Este a su vez los trasmitirá a la
ARDUINO NANO pantalla LCD.
LCD2x16
Figura 8-7. Comunicación PC / LCD
Llegamos al final del presente módulo de prácticas. Como trabajo personal te proponemos que
modifiques aquellos ejemplos en los que se usaba la comunicación serie para recibir los distintos resultados
que se obtenían en la ejecución.
Ahora ya sabes manejar una pantalla LCD. Se trata de un periférico de salida muy potente y versátil
capaz de visualizar cualquier cosa. No te hace falta un ordenador tipo PC que reciba los resultados que se
obtienen en las diferentes aplicaciones. Ahora puedes emplear la pantalla para visualizarlos. Con ello
conseguirás aplicaciones mucho más autónomas, portátiles y económicas.
8 - 10