Está en la página 1de 136

Tema 1

Introducción a Arduino
1.- ¿Qué es Arduino?

En primer lugar debes tener claro que Arduino NO es un microcontrolador. Arduino


es una plataforma de hardware y software libre, basada en una placa que usa un
microcontrolador de la empresa Atmel y un entorno de desarrollo, diseñada para
facilitar el uso de la electrónica en proyectos multidisciplinares.

Dicho de otra manera, Arduino es una tarjeta electrónica que integra básicamente a
un microcontrolador y un conjunto de pines de conexión de entradas y salidas que
permiten, mediante un determinado programa, interaccionar con el medio físico
mediante sensores y actuadores electrónicos. Los proyectos creados con Arduino
pueden ser autónomos o comunicarse con un programa que se ejecute en un ordenador.

El hardware consiste en una placa con un microcontrolador Atmel AVR y puertos de


entrada/salida. Los microcontroladores más usados son el Atmega168, Atmega328,
Atmega1280 y el ATmega2560, dependiendo del modelo de Arduino. Por otro lado, el
software consiste en un entorno de desarrollo (IDE) que implementa un lenguaje
de programación basado en C y un cargador de arranque (bootloader) que es
ejecutado en la placa.

Desde octubre de 2012, algunos modelos de Arduino (los más potentes) usan
microcontroladores CortexM3 ARM de 32 bits. Estos microcontroladores no son
compatibles a nivel binario con los AVR, pero se pueden programar con el mismo IDE
de Arduino y por tanto con el mismo lenguaje de programación. Eso sí, los
microcontroladores CortexM3 usan 3,3V, a diferencia de la mayoría de las placas con
AVR que generalmente usan 5V.

2.- Modelos de Arduino

A la hora de analizar los modelos que existen de Arduino en la actualidad, hay que
diferenciar entre dos tipos de productos bien distintos: las placas de Arduino y los
shields de Arduino. Las primeras son las placas electrónicas que contienen el
microcontrolador junto con una serie de conectores en los pines de entrada/salida. Estas
placas se diferencian principalmente por el tipo de microcontrolador que incorporan, y
por tanto por el número de entradas y salidas que disponen. Por otro lado, las “shields”
o escudos de Arduino son placas que se conectan a una placa de Arduino y le
otorgan una determinada funcionalidad. Por ejemplo, hay una shield que permite que
Arduino pueda conectarse a Internet, otra que le otorga funcionalidad GSM, etc.

En la página siguiente se muestran las principales placas de Arduino que existen en la


actualidad:
Arduino UNO Arduino MEGA 2560

Microcontrolador: ATmega328P (8 bits) Microcontrolador: ATmega2560 (bits)


Entradas/salidas digitales: 14 (6 PWM) Entradas/salidas digitales: 54 (15 PWM)
Entradas analógicas: 6 Entradas analógicas: 16
UART: 1 UART: 4
Reloj: 16MHz Reloj: 16MHz

Arduino LEONARDO Arduino MICRO

Microcontrolador: ATmega32u4 (8 bits) Microcontrolador ATmega32u4 (8 bits)


Entradas/salidas digitales: 20 (7 PWM) Similar a Arduino Leornardo, pero de un
Entradas analógicas: 12 tamaño muy reducido (48mmx18mm)
Comunicación USB integrada
Reloj: 16MHz

Arduino DUE Arduino YUN

Micro: SAM3X8E ARM Cortex-M3 (32 bits) Microcontrolador ATmega32u4 (8 bits)


Entradas/salidas digitales: 54 (12 PWM) Similar a Arduino Leonardo
Entradas analógicas: 12 Procesador: Atheros AR9331
UART: 4 Soporta una distribución de Linux
Comunicación USB integrada Conexión Wifi y Ethernet
Reloj: 84MHz Ranura para tarjeta SD
Convertidor digital/analógico: 2
En cuanto a las shields de Arduino, las
principales que se encuentran
actualmente son:
2
Ethernet shield
WIFI shield

Permite conectar una placa Arduino a Permite conectar una placa Arduino a
internet a través de un conector RJ45 Internet de forma inalámbrica por wifi
Compatible con Arduino UNO y Mega Compatible con UNO, Mega y DUE.

GSM shield Motor shield

Proporciona funcionalidad GSM/GPRS Permite conectar a Arduino cargas inductivas


a una placa Arduino. como relés, motores de continua o paso a paso.
Permite realizar/recibir llamadas y SMS Basado en el driver de potencia L298
Permite conexión a internet GPRS

Estos son “shields” de la tienda oficial de Arduino. No obstante, existen múltiples


empresas que elaboran sus propias shields para Arduino, por lo que el número de
posibilidades se multiplica. A continuación se muestran shields de la empresa DFRobot:

LCD shield Motor 2A shield

Permite conectar una pantalla LCD Permite controlar motor DC de hasta 2ª


Compatible con Arduino UNO y Mega Compatible con Arduino UNO y Mega

Board shield
GPS shield

3
Permite incorporar una placa de prototipos a Receptor GPS y GALILEO capaz de
Arduino para realizar montajes propios. comunicarse con Arduino por UART, USB o
Compatible con UNO, Mega y DUE I2C

3.- Descripción de la placa Arduino UNO_

De todos los modelos de Arduino que existen actualmente, nos centraremos en la placa
Arduino UNO, en concreto en su revisión 3, que es la última versión que ha salido. El
motivo para elegir esta placa es que se trata del modelo más sencillo, pero a la vez es
suficientemente potente como para hacer proyectos de envergadura con ella. Además,
prácticamente todas los shields y sensores son compatibles con ella, por lo que resulta
ideal como primera toma de contacto con el mundo de los microcontroladores.

En concreto existen dos modelos diferentes de Arduino UNO: uno de ellos lleva el
microcontrolador en formato PDIP (inserción) y el otro lo lleva en formato SMD
(superficial), como se observa en las siguientes imágenes:

Nosotros nos decantaremos por la primera opción por dos motivos: en primer lugar,
porque si el microcontrolador se estropea se puede sustituir por otro fácilmente. En
segundo lugar, porque esta placa nos permite programar el microcontrolador sobre la
propia placa y después extraerlo y emplearlo en otros montajes independientes.

A continuación analizaremos uno a uno los diferentes elementos de la placa Arduino


UNO:

4
 Alimentación de la placa:

Para alimentar la placa de Arduino UNO tenemos dos opciones: a través de un cable
USB conectado a un ordenador o a través de una fuente de alimentación externa.

0.- Conector USB: mediante este conector se pueden


hacer dos cosas: alimentar la placa y cargar un
programa en la memoria del microcontrolador. Sin
embargo, esto último puede parecer extraño, ya que el
microcontrolador empleado en esta placa (el
ATMega328p) no dispone de un puerto de
comunicación USB. Por ello se emplea otro microcontrolador, el Atmega16U2
(elemento 18 en el dibujo), programado como un conversor de USB a serie. Por tanto,
cuando conectamos la placa Arduino al ordenador, ésta aparecerá como un puerto COM
virtual, es decir, un puerto serie virtual. Dicho de otro modo, aunque la comunicación en
el lado del PC se hace a través del puerto USB, para el microcontrolador de Arduino se
trata de una comunicación serie estándar.

5
1.- Conector de alimentación: se trata de un
conector plug hembra de 2.1mm, para conectar una
fuente de alimentación externa. Se recomienda que la
tensión de dicha fuente esté comprendida entre los
7V y los 12V. En ningún caso debe superar los 20V,
puesto que podría destruir los componentes
electrónicos de la placa, ni ser inferior a 6V.

 Pines de alimentación (power pins):

Cuando alimentamos nuestra placa de Arduino, ya sea


mediante la conexión USB o mediante una fuente externa,
vamos a tener en la placa una serie de salidas de tensión
continua debido a unos reguladores de tensión y condensadores
de estabilización que posee la placa. Esas salidas de tensión
las tenemos disponibles en una serie de pines para que las
podamos utilizar en nuestros montajes, por ejemplo para
alimentar una protoboard donde tengamos sensores o
actuadores. En concreto los pines de alimentación son los
siguientes:

2.- VIN: en este pin tendremos la tensión de alimentación que le está entrando a la
placa, es decir, la misma tensión que proporciona la fuente externa que conectemos
a la placa.

3.- GND: estos dos pines están conectados a la masa de la placa.

4.- 5V: en este pin tenemos una tensión continua de 5V, que proviene del regulador de
tensión incorporado en la propia placa. Podemos utilizar esta tensión para alimentar un
pequeño circuito en una protoboard conectada a Arduino.

5.- 3.3V: en este pin tenemos una tensión continua de 3.3V, generada por un chip
integrado en la placa, que proporciona una corriente máxima de 50mA.

 Entradas analógicas:

6.- Entradas analógicas: la placa Arduino UNO dispone de 6


entradas analógicas, cuya nomenclatura va de AN0 hasta AN5.
Cada uno de estos canales analógicos proporciona una resolución
de 10 bits (es decir, 1024 valores distintos). Por defecto la
tensión se mide con un fondo de escala de 5V, pero es posible
cambiar este valor usando el pin AREF (elemento 9).
 Entradas/salida digitales:

La placa de Arduino UNO dispone de 14 pines de entrada/salida digitales,


numerados del 0 al 13. Cada uno de estos pines se puede configurar de forma
independiente como entrada o salida, pero nunca ambas cosas al mismo tiempo.
Pueden proporcionar o recibir un máximo de 40mA, por lo que para activar actuadores
que tengan un consumo mayor será necesario intercalar un transistor o un driver de
potencia, como veremos más adelante. Todos estos pines disponen de una resistencia
interna de pull-up (deshabilitada por defecto) que permite conectar pulsadores o
interruptores de forma directa. Dentro de estos 14 pines, distinguimos dos grandes
grupos:

7.- Pines NO PWM. Los pines que no tienen el símbolo ˜ junto al número, son pines
digitales de entrada/salida normales. En concreto, se trata de los pines 0, 1, 2, 4, 7, 8, 12
y 13.

8.- Pines PWM. Los pines que tienen el símbolo ˜ junto al número, además de
comportarse como pines digitales de entrada/salida, también pueden proporcionar a su
salida una señal modulada en PWM, por lo que se pueden usar para controlar la
velocidad de un motor o el brillo de un LED, por ejemplo. En concreto, se trata de los
pines 3, 5, 6, 9, 10 y 11. Por tanto, esta placa dispone de 6 salidas PWM.

Estos son los dos grandes grupos de pines de entrada/salida digitales. No obstante,
alguno de esos pines tiene, además, alguna función especial, como se explica a
continuación:

-Pines 0 (RX) y 1 (TX): pines de comunicación serie. Estos pines pueden utilizarse
para recibir y transmitir datos por el puerto de comunicación serie (USART) del
microcontrolador. A estos pines deberemos conectar cualquier dispositivo que
queramos comunicar con nuestra placa por el protocolo de comunicación serie.

-Pines 2 y 3: pines de interrupciones externas. Se trata de pines que, si se configuran


adecuadamente, pueden generar una interrupción externa cuando se produzca algún
cambio de nivel en dichos pines.
-Pin 13: LED interno. Este pin tiene conectado un diodo LED SMD a través de una
resistencia limitadora. Por tanto, poniendo a nivel alto este pin se encenderá el LED.

-Pines para comunicación SPI: pin 10 (SS), pin 11 (MOSI), pin 12 (MISO) y pin 13
(CLK). Estos pines sirven para establecer una comunicación serie con dispositivos que
siguen el protocolo SPI.

 Tensión de referencia:

9.- AREF (Tensión de referencia). Cuando se realiza la conversión


analógico/digital, por defecto se utiliza como fondo de escala (límite superior)
de la conversión la tensión de 5V. Si se quiere emplear una tensión diferente
como fondo de escala, dicha tensión debe introducirse a través de este pin.

 Reset:

10.- Botón de reset. Al presionarlo, se aplica un nivel bajo al pin de reset del
microcontrolador, lo que provoca un reset del sistema.

 Diodos LED:

11.- LED ON. Se enciende cuando la placa está alimentada.

12.- LEDs TX y RX. Se encienden cuando hay comunicación serie con el


microcontrolador.

16.- LED de usuario conectado al pin 13. Este LED lo puede utilizar el usuario para
su aplicación. Como vimos, está conectado al pin 13 mediante una resistencia
limitadora.
 Microcontrolador:

13.- Microcontrolador ATmega328P. Es el cerebro de la placa Arduino, y por


supuesto se trata del elemento más importante. Las principales características de este
microcontrolador se estudiaron en el tema 1.

 Otros elementos:

14.- Regulador de tensión. Este circuito integrado recibe la tensión de entrada de la


fuente externa (de 7V a 12V) y proporciona a su salida una tensión estabilizada de 5V,
que se utiliza para alimentar los circuitos electrónicos de la placa.

15.- Cristal de cuarzo. Se trata de un cristal de cuarzo de 16MHz que, junto con un par
de condensadores SMD, forman el oscilador que genera la señal de reloj del
microcontrolador.

17.- Conector ICSP. Se trata de un conector para la programación ICSP (In Circuit
Serial Programming). El ICSP es el sistema utilizado para poder programar los
dispositivos sin necesidad de tener que retirar el chip del circuito del que forma parte.
Este conector se utilizaría en caso de que se estropeara el microcontrolador que lleva la
placa y tuviéramos que reemplazarlo por uno virgen, es decir, no programado. Para que
la comunicación de la placa con su entorno de programación fuera posible, sería
necesario programar el bootloader en el microcontrolador. Para ello, conectaríamos un
programador externo a la placa Arduino mediante el conector ICSP.
18.- Microcontrolador Atmega16U2. Este microcontrolador tiene una única función
en esta placa: permitir que el microcontrolador ATmega328P y el ordenador se puedan
comunicar por el puerto USB. Este elemento es indispensable ya que el
microcontrolador ATmega328P no dispone de un puerto de comunicación USB, por lo
que es necesario adaptar las señales procedentes del puerto USB del ordenador a un
protocolo de comunicación serie, que sí es entendible por el microcontrolador de
Arduino. Por este motivo, cuando conectamos nuestro Arduino al ordenador aparece
como un puerto COM virtual, es decir, un puerto serie virtual.

A continuación se muestra una tabla resumen con las principales características de la


placa Arduino UNO, extraídas de la propia web de Arduino:

Microcontrolador Atmega328P

Voltaje de operación 5V

Voltaje de entrada (recomendado) 7 – 12V

Voltaje de entrada (límite) 6 – 20V

Pines para entrada- salida digital. 14 (6 pueden usarse como salida de PWM)

Pines de entrada analógica. 6

Corriente continua por pin IO 40 mA

Corriente continua en el pin 3.3V 50 mA

Memoria Flash 32 KB (0,5 KB ocupados por el bootloader)

SRAM 2 KB

EEPROM 1 KB

Frecuencia de reloj 16 MHz

Puerto de comunicación USART 1

Puerto de comunicación SPI 1

LED de usuario 1

Posibilidad de programación ISP SI

A continuación se muestra el esquema electrónico de la placa Arduino UNO, extraído


de la web arduino.cc
A continuación se presenta un gráfico que muestra la correspondencia entre los pines de
la placa Arduino UNO y el microcontrolador ATmega328
Cuestiones

1.- ¿Cuál es la principal diferencia de la placa Arduino DUE con respecto al resto de
placas de Arduino?

2.- ¿Cuál es la principal diferencia de la placa Arduino YUN con respecto al resto de
placas de Arduino?

3.- ¿Qué es una shield de Arduino?

4.- Pon un ejemplo de utilización de la placa GSM shield.

En cuanto a la placa Arduino UNO, contesta las siguientes preguntas:

5.- ¿En qué se diferencian los pines de entrada/salida digitales que tienen el símbolo ˜
de los que no lo tienen?

6.- Además de funcionar como entrada/salida digital, ¿qué otra función pueden tener
los pines 0 y 1?

7.- ¿Para qué sirve el pin AREF?

8.- ¿Para qué sirve el microcontrolador ATmega16u2 incorporado en la placa?

9.- ¿Todas las placas de Arduino necesitan incorporan un segundo microcontrolador?


¿Por qué?

10.- Observa en esquema electrónico de la placa Arduino y localiza los siguientes


elementos:
- Botón de reset.
- Regulador de tensión.
- Cristal de cuarzo para el reloj del ATmega328P

4.- Entorno de desarrollo (IDE) de Arduino

Para instalar el entorno de desarrollo de Arduino, lo primero que debemos hacer es


descargarlo de forma gratuita desde la página web de Arduino, en el apartado Download
(arduino.cc/en/Main/Software).

Actualmente, la versión más reciente es la 1.6.4., que está disponible para los tres
principales sistemas operativos.
Una vez descargado, lo instalaremos siguiendo los pasos adecuados, dependiendo del
sistema operativo con el que estemos trabajando. Finalmente, conectaremos nuestra
placa Arduino UNO al ordenador mediante un cable USB y ejecutaremos el entorno de
desarrollo. Nos aparecerá una imagen como la siguiente:
Como podemos observar, el IDE de Arduino está dividido en cuatro zonas principales:
zona de menús, zona de iconos, zona de trabajo y zona de mensajes, que se describirán a
continuación.

4.1.- Descripción de la zona de menús

En la zona de menús nos encontramos con los siguientes menús seleccionables:

 Menú Archivo:

Dispone de las mismas opciones que cualquier programa de Windows (Nuevo, Abrir,
Cerrar, Salir, etc), y algunas opciones específicas como por ejemplo:

-Sketchbook: en Arduino, un Sketch es lo que se ha venido llamando siempre un


programa. Por tanto, al situarnos encima se de esta opción despliegan todos los Sketch
o programas que hemos guardado dentro de nuestra carpeta Sketchbook.

-Ejemplos: al situarnos encima se despliegan todos los programas de ejemplo que trae
el IDE de Arduino por defecto. Esto es muy interesante porque nos pueden ayudar
cuando estamos empezando a trabajar con un elemento nuevo, como la pantalla LCD, el
teclado o las comunicaciones serie, por ejemplo.

-Cargar: al seleccionar esta opción, se envía el Sketch que tenemos en pantalla a la


placa Arduino. Para ello, como es lógico, se compila previamente, y si se encuentra
algún error no se enviará a la placa.

-Cargar usando Programador: permite enviar el Sketch a la placa Arduino usando un


programador externo.
 Menú Editar

Este menú dispone de las clásicas opciones que aparecen en el menú Editar de cualquier
programa de Windows (Cortar, Copiar, Pegar), así como otras específicas que no son
demasiado importantes (Copiar para el foro, Copiar como HTML, etc).

 Menú Sketch

Las principales opciones que tenemos en este menú son las siguientes:

-Verificar/compilar: como un propio nombre indica, compila el Sketch que tenemos en


pantalla. Si se produce algún error, se mostrará en la zona de mensajes.

-Agregar archivo: permite añadir un archivo a nuestro Sketch.

-Importar librería: permite importar una librería, por ejemplo cuando tengamos que
trabajar con un determinado sensor y necesitemos una librería para ello. El IDE de
Arduino ya tiene por defecto incorporadas una serie de librerías para poder manejar los
dispositivos más comunes, como pantallas LCD, servomotores, motores paso a paso,
etc. Todas estas librerías aparecen en cuanto situamos el cursor sobre la opción
“Importar librerías”. Las primeras librerías que aparecen son las que vienen por defecto
en el IDE, mientras que las últimas son las que hemos importado nosotros en particular.
Por ejemplo, en la imagen que se muestra a continuación, la librería “Keypad” ha sido
importada por el propio usuario, lo que le permitirá manejar teclados matriciales de
forma sencilla. Más adelante se explicará cómo importar librerías.
 Menú Herramientas:

-Formato automático: establece adecuadamente las tabulaciones para nuestro Sketch,


para que de esta forma sea más inteligible.

-Archivar el Sketch: comprime todos los Sketch abiertos en el IDE, creando un único
archivo *.zip.

-Reparar Codificación y Recargar: compila y carga el Sketch en el que estamos


trabajando, descartando todos los cambios efectuados desde la última vez que se guardó.

-Monitor Serial: abre una ventana de monitorización que permite visualizar los datos
enviados por el microcontrolador al ordenador, o enviar datos desde el ordenador hasta
el micro.

-Tarjeta: sirve para elegir la placa o tarjeta de Arduino con la que estamos trabajando.

- Puerto serie: sirve para escoger el puerto donde tenemos conectado la placa Arduino.

-Programador: permite escoger el tipo de programador externo, en caso de no usar la


propia placa Arduino como programador.

-Grabar Secuencia de Inicio: permite grabar el bootloader de Arduino en un


microcontrolador que no disponga de dicho bootloader. Para ello será necesario emplear
un programador externo.

4.2.- Descripción de la zona de iconos

Al igual que en el resto de programas basados en Windows, estos iconos no son más
que accesos rápidos a las funciones más utilizadas de la zona de menús. En la siguiente
imagen se muestran los diferentes iconos con sus correspondientes funciones:
4.3.- Descripción de la zona de mensajes

En la zona de mensajes el IDE de Arduino nos indica en qué puerto está conectada
nuestra placa, en qué línea del programa está ubicado el cursor y sobre todo nos
proporciona información muy importante sobre el proceso de compilación.

Si la compilación se ha realizado con éxito, aparecerá el mensaje “Compilación


terminada”, junto con la información sobre el espacio que ocupa nuestro programa
en la memoria de programa, como se puede observar en la siguiente imagen.

Si en la compilación se ha detectado algún error, aparecerá el mensaje “Error


compilando”, junto con un mensaje del compilador que tratará de aportar alguna pista
acerca de la causa del error. A veces esta pista es realmente aclaratoria, y otras veces no
tanto. Además, en la parte inferior izquierda aparecerá el número de la línea donde
se encuentra el error.
4.4.- Descripción de la zona de trabajo

El área de trabajo es la zona editable del IDE de Arduino donde escribiremos nuestro
código para posteriormente compilarlo y transferirlo a la placa.

En esta área las palabras clave del compilador cambian automáticamente de color, lo
que facilita en gran medida la compresión de los programas. Además, es importante
tener en cuenta que el compilador distinguirá las letras entre mayúsculas y minúsculas.

4.5.- Configuración del IDE

Antes de empezar a trabajar con Arduino debemos realizar unas sencillas


configuraciones. En primer lugar, iremos al menú “Herramientas” y después
pincharemos en “Tarjeta”. Nos aparecerá un listado con las diferentes placas de Arduino
que existen. Debemos seleccionar aquella con la que vamos a trabajar, que en este caso
es Arduino UNO.

Después volveremos a seleccionar el menú “Herramientas”, y a continuación


elegiremos “Puerto Serial”, donde deberemos seleccionar el puerto donde el sistema ha
reconocido a nuestro Arduino. A pesar de que lo estamos conectando por puerto USB,
nos aparecerá como un puerto COM virtual.
Por último, pincharemos en el menú “Archivo” y después en “Preferencias”,
modificando la ventana según la siguiente figura:

En el apartado “Ubicación del Sketchbook” elegiremos la ruta donde se guardarán todos


los programas o Sketchs que escribamos.

Por otro lado, activaremos las casillas para que el entorno de desarrollo nos muestre los
números de línea de nuestro Sketch, el resultado detallado durante la compilación del
programa, así como para que se verifique la correcta programación de la placa después
de cargar un programa.

Hasta aquí la descripción del IDE de Arduino y su configuración inicial. Ahora tan sólo
queda aprender los fundamentos de programación para comenzar a programar nuestra
placa Arduino, cosa que desarrollaremos en la próxima unidad.
Tema 2
Programación de Arduino I
Primeros Pasos con Arduino
El lenguaje de programación de Arduino se basa en C/C++, aunque se añaden muchas
instrucciones y librerías que son exclusivas de Arduino y por tanto no existen en el
lenguaje C estándar. En las próximas unidades se tratará de explicar las características
más importantes del lenguaje C para Arduino, aunque en la página web que se cita a
continuación se puede consultar la información completa (en inglés):

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

1.- Estructura básica de un programa de Arduino

La estructura básica del lenguaje de programación de Arduino es bastante sencilla y se


compone, como mínimo, de dos funciones. En programación una función es un bloque
de código que contiene un conjunto de instrucciones. Pues bien, en Arduino hay dos
funciones que son necesarias en todos los programas: la función setup() y la función
loop().

 Función setup()

La función setup() se ejecuta una sola vez, cuando el microcontrolador arranca después
de un reset. Por tanto, en esta función se deben escribir las instrucciones de
inicialización de los recursos del microcontrolador que se vayan a emplear. Por
ejemplo, los pines digitales que se vayan utilizar habrá que definirlos como pines de
entrada o salida; si se va a realizar comunicación por puerto serie, habrá que definir su
velocidad, etc.

Es importante tener en cuenta que esta función siempre debe estar incluida en el
programa, aunque no haya que realizar ninguna inicialización. En ese caso, la función
quedaría vacía.

 Función loop()

Después de ejecutar las instrucciones de la función setup() el microcontrolador


comienza a ejecutar las de la función loop(). Esta función, como su propio nombre
indica, es un bucle. Por tanto, una vez que el microcontrolador haya ejecutado todas las
instrucciones que hayamos escrito en esta función, volverá de nuevo al principio y
empezará a ejecutarlas otra vez. Es decir, la ejecución de esta función se realiza de
forma cíclica, lo que posibilita que el programa esté respondiendo continuamente a los
eventos externos que se produzcan en nuestra placa.
Por tanto, el esqueleto fundamental de un programa en Arduino sería el siguiente:

2.- Normas básicas de gramática em la programación en Arduino _

 Uso de las llaves { }

El uso de las llaves es fundamental, ya que se emplean para definir el principio y el


final de un bloque de instrucciones. Todo lo que haya comprendido entre la llave de
apertura y la de cierre pertenece al mismo bloque de instrucciones, ya sea para una
función setup(), loop(), o para una instrucción if(), for(), etc.

 El punto y coma ;

El punto y coma “;” se utiliza para separar instrucciones en el lenguaje de


programación de Arduino. Es la manera que tiene el compilador de saber que una
instrucción ha terminado. Por tanto, todas las instrucciones deben finalizar con un
punto y coma. De lo contrario se producirá un error de compilación. De hecho, el
olvido de un punto y coma es el error de compilación más habitual en los
programadores noveles.

Aunque no es lo habitual, podemos escribir varias instrucciones en una misma línea,


siempre que vayan separadas por punto y coma. En la siguiente imagen se muestran
diferentes formas de escribir varias instrucciones, siempre separadas por ;.

2
 Comentarios

Cuando estamos programando es muy útil añadir comentarios en el programa que


expliquen lo que hace una instrucción o un grupo de instrucciones. De esta manera,
cuando al cabo del tiempo lo volvamos a leer, será mucho más fácil de entender el
programa.

Hay dos maneras de introducir comentarios en Arduino.

 Comentario de una sola línea:

Cuando queremos introducir un comentario que ocupe una sola línea de código, tan solo
hay que añadir antes del comentario los símbolos “//”. Todo lo que escribamos en esa
línea a continuación de estos símbolos será ignorado por el compilador, y por tanto no
ocuparán espacio en la memoria del microcontrolador.

Los comentarios de una sola línea se utilizan a menudo después de una instrucción, para
proporcionar más información acerca de lo que realiza dicha instrucción.

 Comentarios multi-línea:

Cuando queremos introducir un comentario que ocupe más de una línea de texto, hay
que poner los símbolos “/*” al principio del comentario y los símbolos “*/” al final
del comentario. Todo el texto comprendido entre ambos símbolos será ignorado por el
compilador, independientemente del número de líneas que comprenda.

Los comentarios multi-línea se suelen emplear al principio de un programa o de una


función, para explicar lo que hace dicho programa o función.
3.- Configuración de los pines de entrada/salida digitales

Cuando vamos a utilizar un pin digital de Arduino, antes de poder usarlo es necesario
configurarlo como pin de entrada o de salida. Para ello disponemos de la instrucción:

pinMode(pin, modo)

donde:

 pin es el número del pin digital que queremos configurar, que en Arduino UNO
será cualquier número entre el 0 y el 13.
 modo hace referencia al modo en el que va a trabajar dicho pin, que puede ser
OUTPUT, es decir, salida; INPUT, es decir, entrada; o INPUT_PULLUP, es
decir, entrada con resistencia interna de pull up habilitada.

Todos los pines digitales que vayamos a utilizar deben haber sido configurados
previamente con esta instrucción. Lógicamente, esta instrucción debe colocarse en la
función setup(), que es la que se ejecuta al principio para configurar correctamente
todos los recursos del microcontrolador.

4.- Escritura en un pin digital

Cuando hemos configurado un pin digital como pin de salida, podemos escribir en él un
´1´ lógico, lo que equivale a 5V aproximadamente, o un ´0´ lógico, lo que equivale a 0V
aproximadamente. Para ello disponemos de la instrucción:

digitalWrite(pin, valor)
donde:

 pin es el número del pin donde queremos escribir, y que previamente debe haber
sido configurado como pin de salida.
 valor es el valor que queremos escribir en el pin, que puede ser HIGH (1
lógico) o LOW (0 lógico).

5.- Generación de retardos

Cuando programamos tenemos que tener en cuenta que la velocidad de ejecución de las
instrucciones por parte del microcontrolador es realmente rápida, ya que la placa de
Arduino UNO dispone de un reloj de 16MHz de frecuencia. Es decir, las instrucciones
se ejecutan a un ritmo de 16 millones de instrucciones por segundo (en realidad es un
poco menos, ya que muchas de las instrucciones que escribimos en Arduino se dividen
en varias instrucciones al compilarlas, pero igualmente la velocidad es muy alta).

Por tanto, en muchas ocasiones será necesario generar un retardo, es decir, hacer que el
microcontrolador se espere para que no vaya tan veloz, porque de lo contrario irá tan
rápido que no veremos lo que hace.

Imaginemos, por ejemplo, que queremos provocar un parpadeo en un LED conectado al


pin 13. Si después de haber configurado el pin en la función setup() escribimos el
siguiente código:

El LED se apagará y encenderá todo el tiempo, pero lo hará a una velocidad tan elevada
que nosotros lo percibiremos siempre encendido. Lo que podemos hacer para solucionar
este problema es decirle al microcontrolador que, una vez encendido el LED, se espere
un tiempo antes de apagarlo. Esto se realiza con la instrucción:

delay(tiempo)
donde:

 tiempo es la cantidad de tiempo, expresada en milisegundos, que queremos


que el microcontrolador se espere sin hacer nada.

Es importante tener en cuenta que, durante el tiempo indicado en la instrucción delay(),


el microcontrolador detiene la ejecución del programa, por lo que si sucede algún
evento externo, por ejemplo la activación de un pulsador, el microcontrolador no será
capaz de detectarlo. Por tanto, si bien la instrucción delay() es muy útil, hay que
emplearla con precaución.

En Arduino existe otra manera mucho más interesante para generar retardos, pero para
ello se requiere la instrucción millis(), que será explicada más adelante.

6.- Primer programa con Arduino

Con todo lo que hemos visto ya estamos en disposición de realizar nuestro primer
programa en Arduino. Se trata de conseguir que el microcontrolador provoque un
parpardeo cada segundo en el LED interno de la placa Arduino UNO, manteniéndolo
durante 500ms encencido y durante 500ms apagado.

A continuación se muestra el programa ya realizado:


7.- La instrucción #define

En el programa anterior le hemos dicho a Arduino que encendiera y apagara el pin 13,
que es donde tenemos conectado el LED. Esto ha sido fácil de recordar porque
solamente teníamos una salida. Pero si en un mismo programa tenemos muchas entradas
y salidas, se hace muy difícil recordar en qué número de pin tenemos conectada cada
entrada o salida.

Para solucionar esto tenemos la instrucción #define. Esta instrucción permite dar un
nombre, el que nosotros queramos, a un valor constante:

#define nombre valor_constante

Por ejemplo, si escribimos lo siguiente:

#define LED 13

Le estamos diciendo al compilador que, cuando compile el programa, busque la palabra


LED y la reemplace por el número 13.

Utilizando la instrucción #define podemos escribir los programas de una forma mucho
más fácil de leer, ya que podemos asignar un nombre a cada uno de los pines que
estamos utilizando. Por ejemplo, el programa del apartado anterior quedaría:

La instrucción #define únicamente se puede emplear al principio del programa,


antes de escribir la función setup(). Además, esta instrucción no debe finalizar en
punto y coma.
Si lo has entendido todo hasta aquí, ¡enhorabuena! Ya estás comprendiendo los
principios de funcionamiento de Arduino. Pero la única manera de aprender de verdad a
programar es practicando mucho, así que ahora te toca a ti. A continuación tienes 5
ejercicios que se pueden resolver con lo que hemos visto hasta ahora. Realízalos y
pruébalos sobre tu placa Arduino.

Ejercicios_

1.- Realiza un programa para controlar el parpadeo de dos diodos LED que funcionen
de forma complementaria el uno del otro, es decir, que cuando uno de ellos esté
encendido, el otro permanezca apagado, y viceversa.

2.- Realiza un programa para que el microcontrolador genere la secuencia de


encendido y apagado de un semáforo que dispondrá de tres bombillas diferentes,
simuladas con tres LEDs: verde, rojo y ambar. La secuencia será la siguiente:

SEMÁFORO DURACIÓN
Verde 10 segundos
Ambar (parpadeante) 3 segundos
Rojo 10 segundos

3.- Modifica el programa del ejercicio anterior para que el microcontrolador genere la
secuencia de encendido y apagado de dos semáforos complementarios en un cruce.
Cada semáforo dispondrá de tres luces, simuladas con tres LEDs: verde, rojo y ambar.
La secuencia será la siguiente:

PASO SEMÁFORO 1 SEMÁFORO 2 DURACIÓN


1 Verde Rojo 10 segundos
2 Ambar (parpadeante) Rojo 3 segundos
3 Rojo Verde 10 segundos
4 Rojo Ambar (parpadeante) 3 segundos

4.- Realiza un programa para que el microcontrolador genere una secuencia de


encendido de 8 LEDs de derecha a izquierda, con una velocidad de encendido de cada
LED de 100ms. Inicialmente, se encenderá el LED situado en el extremo derecho. Tras
100ms, se encenderá el LED siguiente, manteniendo en anterior encendido, y así
sucesivamente hasta que todos los LEDS queden encendidos. Cuando se termine la
secuencia, volverá a empezar automáticamente desde el principio.

5.- Modifica el programa del ejercicio anterior para que la secuencia de encendido de
los LEDs vaya de derecha a izquierda y, una vez estén todos los LEDs encendidos,
vayan apagándose de izquierda a derecha, hasta que queden todos apagados,
repitiéndose la secuencia de forma indefinida.
Tema 3
Programación de Arduino II
Variables , Tipos de Datos e
Instrucciones de Selección
1.- Variables

Cuando Arduino ejecuta un programa, normalmente debe manejar datos. Por ejemplo,
guardar las lecturas de un sensor de temperatura para después procesarlas. En
programación, los datos se almacenan en variables. Por tanto, una variable es un trozo
de la memoria de datos (SRAM) del microcontrolador donde almacenamos un
dato de un tipo concreto. El contenido de las variables se puede leer o cambiar en
cualquier momento del programa. Es decir, no son datos fijos o constantes. De ahí
viene su nombre.

Las variables pueden ser de distintos tipos dependiendo del tipo de dato que queramos
meter. Por ejemplo, no es lo mismo guardar un carácter que un número, y por supuesto
no se pueden hacer las mismas operaciones sobre un número con decimales que sobre
un carácter.

1.1.- Declaración de variables

Para poder usar una variable primero hay que declararla. Declarar una variable es, por
decirlo así, crear una variable nueva, lo que equivale a reservar un espacio de la
memoria RAM para guardar un dato. Para declarar una variable es preciso indicar
dos cosas: el nombre de la variable y el tipo de dato que almacenará la misma. Esto se
hace de la siguiente manera:
tipo_dato nombre_variable;
donde
:

 tipo_dato es el tipo de dato que vamos a guardar en la variable, que puede ser
int (número entero), char (carácter), float (número con decimales), etc.
 nombre_variable es el nombre que nosotros le vamos a dar a esa variable.

Además, de forma opcional podemos inicializar la variable cuando la declaramos, es


decir, es decir, al mismo tiempo que la creamos podemos darle un valor inicial con el
que comenzará en cuanto empiece la ejecución del programa. Esto se hace así:
tipo_dato nombre_varible = valor;
donde
:
 valor representa el valor inicial que contendrá la variable al crearse.
Además, podemos declarar más de una variable en una sola línea, siempre que las
variables sean del mismo tipo. Esto se hace de la siguiente manera:

tipo_dato nombre_variable1, nombre_variable2;

A continuación se muestran algunos ejemplos:

 Nota sobre los nombres de las variables:

A las variables no se les puede dar cualquier nombre. No se pueden poner más que
letras de la 'a' a la 'z' (la ñ no vale), números y el símbolo '_'. No se pueden poner signos
de admiración, ni de interrogación. Además, el nombre de una variable puede contener
números, pero su primer carácter no puede serlo. Tampoco valen como nombres de
variable las palabras reservadas que usa el compilador, como por ejemplo: for, main, do,
while.

A continuación se muestran algunos ejemplos de nombres no válidos:

2
Es importante tener en cuenta que el lenguaje de programación C distingue entre
mayúsculas y minúsculas. Por lo tanto, los siguientes nombres serán tres variables
diferentes:
nombre
Nombre
NOMBRE

Por último, con el objetivo de escribir un código que sea fácilmente legible, para
nombrar a las variables se deben utilizar nombres descriptivos, es decir, nombres que
definan de alguna manera el dato que van a guardar. A continuación se muestran
algunos ejemplos de nombres descriptivos y no descriptivos:

1.2.- Variables globales y locales

Ya sabemos cómo se declaran las variables, pero la siguiente pregunta sería: ¿en qué
lugar de nuestro programa hemos de declararlas?

Dependiendo de dónde las declaremos, el funcionamiento de las variables será


diferente. En concreto, distinguimos dos tipos de variables, en función del lugar donde
han sido declaradas:

 Variable global: es aquella variable que se declara al principio del programa,


es decir, antes de la función setup(). Esta variable puede ser leída y utilizada
en cualquier parte del programa.

 Variable local: es aquella variable que se declara dentro de una función,


como por ejemplo dentro la función setup(), loop(), o dentro de una función
definida por el usuario. Esta variable sólo será visible y por tanto sólo podrá ser
utilizada dentro de la función en la que se declaró.
A continuación se muestra un ejemplo de variables globales y locales:

2.- Tipos de datos

A continuación se explican los principales tipos de datos usados en la programación de


Arduino, aunque estos no son los únicos que existen. La lista completa se puede
encontrar en la web: http://arduino.cc/es/Reference/HomePage.

 Boolean: es un tipo de dato que sólo puede adquirir dos valores diferentes: true
o false. En principio un dato de tipo boolean debería ocupar un solo bit de
información, pero la realidad es que no se puede acceder a la memoria RAM del
microcontrolador bit a bit, sino que el acceso es por grupos de 8 bits. Por tanto,
una variable de tipo boolean ocupará 1 byte de memoria RAM.

Declaración e inicialización de una variable tipo boolean:


boolean FinalCarrera = true;

 Byte: las variables de tipo byte almacenan un número entero sin signo de 8
bits. Por tanto, el rango de números que pueden almacenarse con este tipo de
dato va de 0 a 255. Para valores mayores será necesario emplear un tipo de dato
de más bits (16 o 32).

 Int: las variables de tipo int almacenan un número entero con signo de 16 bits.
Por tanto, el rango de números que pueden almacenarse con este tipo de dato va
de -32768 a 32767.
 Long: las variables de tipo long almacenan un número entero con signo de 32
bits. Por tanto, el rango de números que pueden almacenarse con este tipo de
dato va de -2147483648 a 2147483647.

 Float: en una variable de tipo float podemos almacenar números reales, es decir,
números con parte entera y parte decimal. Una variable de tipo float ocupa
32 bits, es decir, 4 bytes. El rango de posibles valores es del 3.4 ⋅10 al 3.4 ⋅10 38
−38

Declaración e inicialización de una variable de tipo float:


float numero_decimal=2.75;

 Char: las variables de tipo char sirven para almacenar caracteres. Los
caracteres se almacenan en realidad como números enteros codificados según el
código ASCII estándar. Una variable char ocupa 8 bits, es decir, 1 byte. En
una variable char podemos almacenar un solo carácter, no podemos
almacenar ni frases ni palabras. Para asignar un carácter a una variable char se
pone el carácter entre comillas simples.

Declaración e inicialización de una variable tipo char:


char letra=’A’;

A continuación se muestra una tabla resumen con los principales tipos de datos:

Tipo Datos Nº Valores posibles (rango)


almacenados de
bi
boolean Booleanos 8 true o false
byte Enteros 8 0 a 255
pequeños
int Números enteros 16 -32.767 a 32.767
long Enteros largos 32 -2.147.483.648 a 2.147.483.647
float Nums.coma 32 3,4E-38 a 3,4E38
flotante
char Caracteres 8 -128 a 127

Cuando se programa un microcontrolador es importante tener en cuenta que cada


variable que se declare ocupará un espacio en la memoria RAM interna, y que esa
memoria RAM es muy limitada. Por tanto, en el uso de las variables habría que tener en
cuenta dos normas generales:

 No crear más variables de las que sean necesarias.


 Ajustar el tamaño de la variable al tamaño de los datos que vayan a ser
guardados en ella. Por ejemplo, si en una variable vamos a almacenar los
resultados de una cuenta que irá de 0 a 100, deberíamos declarar esa variable
de tipo byte y no int o long, para no desaprovechar espacio de memoria.
3.- Lectura de una entrada digital

En la unidad anterior vimos cómo se hacía una escritura digital en Arduino. Ahora
vamos a ver cómo se hace una lectura de un pin digital.

En primer lugar, el pin que vamos a leer debe haber sido configurado en la función
setup() como pin de entrada, utilizando para ello la instrucción pinMode. Como vimos
en la unidad anterior, se puede configurar como pin de entrada normal, o como pin de
entrada con resistencia de pull up interna habilitada. Esto se utilizará, por ejemplo, para
conectar pulsadores o interruptores al microcontrolador sin usar resistencias de pull up
externas.

Una vez configurado como entrada, cuando queramos leer el valor de un pin digital
utilizaremos la siguiente instrucción:
digitalRead(pin)
donde
:

 pin es el número del pin que queremos leer (del 0 al 13 en Arduino UNO).

Esta función leerá el valor del pin y devolverá uno de los siguientes valores: HIGH
(valor alto) o LOW (valor bajo).

 Ejercicio resuelto:

Realizar un programa en el que el microcontrolador de la placa Arduino UNO lea


constantemente el valor de un conmutador, y refleje dicho valor en el LED interno del
propio Arduino.
Para resolver este ejercicio se crea una variable de tipo boolean donde se guarda el valor
leído en el pin del conmutador. Finalmente se escribe en el pin del LED el valor
guardado en la variable.

Este mismo ejercicio se podría haber resuelto sin el uso de ninguna variable, tal y como
se muestra a continuación:

En el programa de arriba se le está diciendo al microcontrolador que escriba en el pin


del LED lo que lee del pin del conmutador.

Ejercicios_

1.- Utilizando el mismo programa del ejercicio resuelto, monta en la protoboard un


pulsador con resistencia de pull-up, de forma que el LED de la placa Arduino UNO
refleje el estado del pulsador. Una vez lo hayas probado, cambia la configuración del
pulsador, conectándolo en este caso con una resistencia de pull-down, y ejecuta de
nuevo el programa, para ver la diferencia de funcionamiento.

2.- Modifica el programa anterior para poder conectar a tu placa Arduino el pulsador
sin usar una resistencia de pull up externa, habilitando para ello la resistencia interna
de pull up que incorpora el microcontrolador en cada pin.
4.- Operadores

Ya hemos visto cómo crear variables nuevas y cómo inicializarlas. Sin embargo, sólo
con esto no podemos hacer ningún programa complejo, ya que normalmente cualquier
programa lo que hace es tomar datos de sensores o del teclado, procesarlos y actuar en
consecuencia. Y, para procesar los datos, necesitamos hacer operaciones con ellos, y
para eso es para lo que están los operadores.

Existen diferentes tipos de operadores, según el tipo de operación que realicen: de


asignación, de relación, aritméticos, lógicos y de manipulación de bits. A continuación
estudiaremos cada uno de ellos.

4.1.- Operador de asignación

Se trata del operador ‘=’ y sirve para dar valor a una variable. Esto en C se hace de la
siguiente manera:

num1 = 7; // Asigna a la variable ‘num1’ el número 7


num2 = num1; // Asigna a la variable ‘num2’ el contenido de la variable ‘num1’

También podemos dar valores a diferentes variables a la vez:

num1 = num2 = 7; // Asigna a las variables ‘num1’ y ‘num2’ el número 7

4.2.- Operadores aritméticos

Son aquellos que sirven para realizar operaciones tales como la suma, resta,
multiplicación, etc., es decir, operaciones aritméticas.

A continuación se muestra una tabla con los diferentes operadores aritméticos:

Símbolo Operación Símbolo Operación


+ Suma % Resto
- Resta ++ Incremento
* Multiplicación -- Decremento
/ División

A la hora de trabajar con los operadores aritméticos, hemos de tener en cuenta algunas
consideraciones importantes:

 Si todos los operandos son del mismo tipo, el resultado de la operación será
también del mismo tipo. En cambio, si los operandos son de diferentes tipos,
para el cálculo se utilizará el tipo más grande de los operandos en juego. Por
tanto, cuando programamos puede darse la siguiente paradoja:
 Al realizar una operación aritmética, la variable que guarda el resultado de la
operación puede sufrir desbordamiento, si dicho resultado es mayor que el
valor máximo que puede almacenar la variable. Por tanto:

3.3.- Operadores de comparación

También llamados operadores de condición, sirven para evaluar una determinada


comparación o condición, e indicar si la condición se cumple o no.

Cuando se evalúa una condición, el resultado que se obtiene es 0 si no se cumple dicha


condición, y un número distinto de 0 (normalmente 1) si se cumple.
A continuación se muestra una tabla con los diferentes operadores de comparación:

Símbolo Operación Símbolo Operación


== Igual que < Menor que
!= Distinto que >= Mayor o igual que
> Mayor que <= Menor o igual que

Estos operadores, que en principio parece que no tengan demasiada utilidad, los
emplearemos muchísimo en las instrucciones de control de flujo, que veremos al final
de este tema. A continuación se muestra un ejemplo:

Es muy importante no confundir el operador de asignación ‘=’ con el de


comparación ‘==’, error que suele producirse muy a menudo en los programadores
principiantes. El primer operador se usa para asignar un valor a una variable, mientras
que el segundo se usa para realizar una comparación entre dos operandos.
4.4.- Operadores lógicos

En muchas ocasiones queremos que una acción se realice cuando se cumplen dos o más
condiciones. Los operadores lógicos se utilizan para concatenar varias condiciones en
las instrucciones de control de flujo. Los comparadores lógicos son 3:

Símbolo Operación Comentario


&& AND Devuelve 1 si se cumplen las dos condiciones
|| OR Devuelve 1 si se cumple al menos una de las condiciones
! NOT Devuelve 1 si el resultado de la condición era 0 y viceversa

A continuación se muestran algunos ejemplos:

4.5.- Operadores de manipulación de bits

Como sabes, el contenido de cualquier variable está expresado en bits. Los operadores
de manipulación de bits sirven para hacer operaciones lógicas con las variables por
dentro, es decir, con los bits que componen las variables.

Estos operadores son los siguientes:


Símbolo Operación Comentario
& AND Realiza una AND entre 2 operandos bit a bit
| OR Realiza una OR entre 2 operandos bit a bit
^ XOR Realiza una XOR entre 2 operandos bit a bit
~ NOT Realiza una NOT de una operandos bit a bit
>> Desp der. Desplaza todos los bits de un operando a la derecha
<< Desp. izq. Desplaza todos los bits de un operando a la izquierda

Por ejemplo, dadas tres variables de tipo int llamadas a, b y c:

a = 92; // en binario: 0000000001011100


b = 101; // en binario: 0000000001100101

c = a & b; // resultado: 0000000001000100, es decir, 68 en decimal.

c = a | b; // resultado: 0000000001111101, es decir, 125 en decimal.

c = a ^ b; // resultado : 0000000000111001, es decir, 57 en decimal.

5.- Instrucciones de control de flujo _

Hasta el momento, en todos los programas que hemos visto, el orden de ejecución de las
instrucciones era secuencial, es decir, una instrucción se ejecutaba después de la
inmediatamente anterior.

Sin embargo, la mayoría de aplicaciones más complejas requieren que ese flujo
secuencial se rompa en algún momento, de forma que la siguiente instrucción en
ejecutarse no tenga por qué ser siempre la instrucción que se encuentra en la línea
siguiente.

Por ejemplo, nos puede interesar que dependiendo del valor de una variable se ejecuten
unas instrucciones u otras, o que un conjunto de instrucciones se repita un determinado
número de veces.

Para conseguir romper ese flujo secuencial se emplean un tipo de instrucciones


denominadas instrucciones de control de flujo. Éstas constituyen una herramienta muy
potente de todo leguaje de programación. Por tanto, cuando terminemos de estudiarlas,
estaremos en disposición de elaborar programas mucho más complejos.
Las instrucciones de control de flujo se dividen en dos tipos diferentes:

 Instrucciones de selección: permiten elegir qué bloque de instrucciones se


ejecutará a continuación, en función de una determinada condición. Las
instrucciones de selección son if-else y switch-case.

 Instrucciones de repetición: permiten elegir el número de veces que se


ejecutará un determinado bloque de instrucciones. Es decir, sirven para crear
bucles. Las instrucciones de repetición son for, while y do-while.

A continuación se explicarán las instrucciones de selección, mientras que las de


repetición se abordarán en la siguiente unidad.

5.1.- Instrucciones de selección

5.1.1.- Instrucción if-else

La instrucción de control de flujo más sencilla es la conocida como if – else, cuya


estructura más básica se muestra a continuación:

Esta instrucción evalúa la condición situada entre paréntesis. Si la condición se


cumple, ejecuta la acción, que podría ser una instrucción o un conjunto de
instrucciones. Si la condición no se cumple, no ejecuta la acción.

Si queremos que, en caso de que no se cumpla la condición, se ejecute una acción


diferente a la primera, entonces tendremos que escribir lo siguiente:
En este caso, si la condición se cumple, ejecuta la acción 1, pero si no se cumple, se
ejecutará la acción 2. De esta forma, la instrucción if – else permite seleccionar qué
instrucción o instrucciones se van a ejecutar en función de una determinada
condición.

 Ejemplo:

La siguiente instrucción escribe un 1 o un 0 en un pin al que hemos llamado


LED en función del valor leído en un pin al que hemos llamado SWITCH:

Como hemos visto, la instrucción if – else permite elegir entre dos posibilidades
diferentes en función de una determinada condición. Pero, ¿qué pasa si queremos poder
elegir entre 3 o más posibilidades? En ese caso podemos anidar varias instrucciones
if – else de la siguiente manera:

En el programa de arriba, en primer lugar se evaluará la condición 1. Si se cumple, se


ejecutará la acción 1. Si no se cumple, se evaluará la condición 2. Si se cumple, se
ejecutará la acción 2, y si no, se ejecutará la acción 3. Es importante tener en cuenta que
se pueden anidar tantas instrucciones if-else como se desee.
 Programa resuelto

Realizar un programa para controlar el estado del LED interno de la placa Arduino
UNO mediante dos pulsadores, llamados MARCHA y PARO. Cuando se acccione el
pulsador de MARCHA, el LED se encenderá, manteniéndose en ese estado hasta que se
accione el pulsador de PARO, que apagará el LED. Ten en cuenta que los pulsadores
que se van a utilizar están conectados mediante una resistencia de pull-up, por tanto
son activos a NIVEL BAJO.

Si lo has entendido todo hasta aquí, ahora es tu turno de programar. Resuelve los
siguientes ejercicios utilizando la instrucción if-else y todo lo aprendido hasta este
momento.

 Ejercicios

3.- Realizar un programa que controle la velocidad de parpadeo del LED interno de la
placa Arduino UNO mediante un conmutador. Si el conmutador está a nivel bajo, los
tiempos de encendido y apagado del LED durarán 500ms cada uno. Si el conmutador
está a nivel alto, los tiempos de encendido y apagado serán de 250ms cada uno.
4.- En el ejercicio 3 de la unidad anterior realizaste un programa para controlar la
secuencia de encendido y apagado de dos semáforos complementarios en un cruce.
Ahora debes modificar dicho programa para controlar dos semáforos, también
complementarios, pero en esta ocasión se trata de los semáforos de un paso de
peatones: uno para los coches y otro para los peatones. La diferencia es que ahora el
accionamiento del semáforo de los peatones se realizará con un pulsador. El
funcionamiento debe ser el siguiente: Si ningún peatón acciona el pulsador, el semáforo
de los coches debe estar SIEMPRE EN VERDE, mientras que el de peatones SIEMPRE
EN ROJO. Cuando algún peatón accione el pulsador, el semáforo de coches se
mantendrá 5 segundos más en verde, tras lo cual comenzará su secuencia de puesta en
rojo (primero en ambar parpadeante durante 3 segundos, y luego en rojo), al mismo
tiempo que el semáforo de peatones comenzará su secuencia de puesta en verde. Tras
10 segundos en verde, el semáforo de peatones iniciará su secuencia de puesta en rojo
(primero en ambar parpadeante durante 3 segundos y después en rojo), mientras que el
de coches iniciará su secuencia de puesta en verde. Finalmente, este estado se
mantendrá hasta que un nuevo peatón vuelva a accionar el pulsador. A continuación se
muestra un resumen de la secuencia:

PASO SEMÁF. COCHE SEMÁF. PEATÓN DURACIÓN


1 Verde Rojo Indefinida (hasta pulsador)
2 Verde Rojo 5 seg (después de pulsador)
3 Ambar (parpadeante) Rojo 3 segundos
4 Rojo Verde 10 segundos
5 Rojo Ambar (parpadeante) 3 segundos

5.- Realiza un programa para que el microcontrolador genere una secuencia de


encendido de 8 LEDs, con una velocidad de encendido de cada LED de 100ms, de
forma que se pueda elegir el sentido de la secuencia mediante un conmutador. Si el
conmutador está a nivel bajo, los LEDs se irán encendiendo de derecha a izquierda,
mientras que si está a nivel alto, lo harán de izquierda a derecha. Siempre que se
encienda un LED, el anterior se mantendrá también encendido, hasta que queden los 8
LEDs encendidos. Entonces se apagarán todos los LEDs y la secuencia comenzará de
nuevo, con el sentido de encendido que indique el conmutador.

6.- Modifica el programa anterior para, además de controlar el sentido de encendido


de los LEDs, controlar la velocidad de encendido de los mismos mediante otro
conmutador. Si el conmutador está a 0, el tiempo de encendido de cada LED será de
150ms, mientras que si está a 1, el tiempo será de 50ms.

NOTA: Para realizar este programa de forma eficiente, no se debe escribir dos veces la
misma secuencia, con dos retardos diferentes, sino que se debe emplear una variable
para generar los retardos.
5.1.2.- Instrucción switch-case

Existe otra instrucción de selección parecida a if – else, pero con algunas diferencias,
conocida como switch-case, cuya estructura se muestra a continuación:

La instrucción switch-case evalúa una variable y ejecuta una acción u otra en


función del contenido de dicha variable. Es importante señalar que en este caso, a
diferencia de la instrucción if – else, no se evalúa el cumplimiento de una
condición, sino el valor de una variable. Dependiendo del valor se ejecutará una
acción u otra.

Como puedes observar, después de cada acción se debe escribir la palabra break.
Esto es para que, llegado a ese punto, el programa salte el resto de opciones y comience
a ejecutar la siguiente instrucción después del switch-case. Si no ponemos la palabra
break, una vez que el programa entra en un bloque case, ejecutaría el resto de
instrucciones hasta el final.

Por otro lado, al final de la instrucción se puede añadir de forma opcional la palabra
default. Esto se hace para indicar la acción que se debe realizar por defecto, es decir, la
acción que se realizará si el valor de la variable no coincide con ninguno de los
indicados anteriormente en las sentencias case.

 Ejemplo:

La siguiente instrucción leerá el contenido de la variable num_led y encenderá el LED


indicado por dicha variable (1, 2 o 3). Si el número indicado es cualquiera que no sea
1, 2 o 3, se apagarán los tres LEDs.
 Ejercicios

Realiza los siguientes ejercicios utilizando la instrucción switch-case y todo lo


aprendido hasta ahora.

7.- Utiliza la placa Arduino UNO y una protoboard para implementar un sencillo
contador de segundos. Nada más resetar el microcontrolador, éste comenzará a contar
segundos desde el 0 hasta el 9, que serán visualizados en una pantalla de 7 segmentos.
Cuando llegue al número 9, el contador deberá comenzar de nuevo con el 0.

8.- Realiza un programa que implemente un sencillo contador de pulsos con la placa
Arduino UNO, una pantalla de 7 segmentos y un pulsador. Inicialmente en la pantalla
debe aparecer el número 0. Cada vez que el usuario accione el pulsador, el número que
irá apareciendo se incrementará en 1, hasta llegar al número 9. Después del número 9
la cuenta volverá otra vez a 0, repitiéndose el proceso indefinidamente.

9.- Modifica el ejercicio anterior para que se pueda controlar el sentido de la cuenta
mediante dos pulsadores. Cada vez que se accione el primer pulsador, la cuenta se
incrementará en 1. Cada vez que se accione el segundo pulsador, la cuenta se
decrementará en 1. En ambos casos la cuenta debe ser cíclica, es decir, si se
incrementa el número 9 se debe volver al 0, y si se decrementa el número 0 se debe
volver al 9.
10.- Utiliza la placa Arduino UNO y una protoboard para implementar un dado
electrónico. Nada más resetar el microcontrolador, éste comenzará a contar del 1 al 6
periódicamente a mucha velocidad. De esta forma, el usuario no podrá distinguir el
número que aparece en la pantalla de 7 segmentos. Cuando el usuario apriete un
pulsador, la cuenta se detendrá durante dos segundos, de forma que el usuario podrá
ver el valor de la tirada del dado electrónico.
Tema 4
Programación de Arduino III
Instrucciones de Repetición

1.- Instrucciones de repetición _

En la unidad anterior vimos que hay dos tipos de instrucciones para controlar el flujo de
un programa: las instrucciones de selección y las de repetición. Después de haber
estudiado las de selección, le llega ahora el turno a las instrucciones de repetición.

Estas instrucciones permiten crear bucles en nuestro programa. Un bucle es un bloque


de código que se repite un determinado número de veces. A cada una de esas
repeticiones se le llama iteración. Por tanto, las instrucciones de repetición permiten
hacer que un bloque de código se repita tantas veces como nosotros queramos. Estas
instrucciones son for, while y do-while.

2.- Instrucción for __

Imagina que queremos ejecutar un conjunto de instrucciones un determinado número de


veces. Por ejemplo, queremos que un LED parpadee 100 veces seguidas. Con lo que
sabemos hasta ahora, no tendríamos más remedio que repetir 100 veces las mismas
instrucciones, lo que implicaría un código muy largo y pesado.

Para evitar tener que repetir código innecesario, existe una instrucción que permite
repetir un determinado código las veces que queremos. Tan sólo hay que especificarle
cuántas veces queremos que se repita. Esta instrucción se llama for, y su estructura es la
siguiente:

La instrucción for inicializa una variable al valor elegido por nosotros. Cuando termina
la primera iteración, incrementa la variable según lo especificado, y comprueba si
dicha variable cumple la condición indicada. Si la cumple, se ejecuta una nueva
iteración. Si no la cumple, se abandona el bucle.
Por ejemplo, para hacer que el LED interno parpadee 100 veces escribiríamos:

En este ejemplo, estamos utilizando la variable i para contar el número de iteraciones.


Concretamente, estamos diciendo que inicialmente la variable i valga 0. Después
decimos que las acciones se repitan mientras i sea menor que 100. Finalmente, estamos
diciendo que cada vez que se ejecute una nueva iteración, la variable i se incremente en
1 valor.

 Cuestión:

Indica cuántas veces se ejecutará el código que se encuentra dentro de la siguiente


instrucción for:

 Ejercicios

1.- Realiza un programa para que el microcontrolador de Arduino haga que cuatro
diodos LED parpadeen al mismo tiempo cuatro veces cada vez que se acciona un
pulsador.

2.- Realiza un programa para que el microcontrolador de Arduino controle el parpadeo


de cuatro diodos LED mediante cuatro pulsadores, según las siguientes reglas:
- Si se acciona el pulsador 1, los LEDs papadearán 2 veces.
- Si se acciona el pulsador 2, los LEDs parpadearán 4 veces.
- Si se acciona el pulsador 3, los LEDs parpadearán 6 veces.
- Si se acciona el pulsador 4, los LEDs parpadearán 8 veces.

2
3.- Si el ejercicio 2 lo has resuelto escribiendo 4 bucles for, cada uno de ellos con un
número de iteraciones diferente, vuelve a realizar el ejercicio 2, pero esta vez
escribiendo un único bucle for, en el que el número de iteraciones no sea un número
fijo sino una variable.

4.- Realiza un programa para que el microcontrolador de Arduino provoque el


parpadeo de cuatro diodos LED, de forma que el usuario pueda elegir el número de
veces que los LEDs parpadean, utilizando para ello 2 pulsadores. El funcionamiento
será el siguiente: el usuario irá pulsando uno de los pulsadores, y el microcontrolador
deberá ir contando el número de pulsaciones. Cuando el usuario accione el segundo
pulsador, los LEDs deberán parpadear tantas veces como se haya pulsado el primer
pulsador.

3.- Instrucción while_

Existe otra instrucción que sirve para repetir un mismo código un número determinado
de veces. Esa instrucción se llama while, y su estructura es la siguiente:

While significa en inglés mientras. Por tanto, la acción o acciones que se encuentran
dentro de las llaves se ejecutarán mientras se cumpla la condición establecida entre
paréntesis. Esta condición puede cambiar a expensas de una expresión dentro del
código del bucle o por un evento externo, por ejemplo un cambio en un pin al que esté
conectado un sensor o un pulsador.

Para hacer que el LED interno de Arduino parpadee 100 veces escribiríamos:
En este caso, la variable que utilizamos para contar el número de iteraciones ha de ser
inicializada antes de empezar la instrucción while, y debe ser actualizada durante la
ejecución del bucle para que el programa pueda salir de él en un momento dado.

Como acabamos de ver en el ejemplo anterior, es posible escribir el mismo bucle


utilizando dos instrucciones diferentes: while o for. Si esto es así, ¿por qué existen dos
instrucciones distintas cuando sobraría con una sola?

La respuesta es que en realidad no son dos instrucciones equivalentes, sino que tienen
una diferencia muy importante: cuando escribimos una instrucción for, tenemos que
saber de antemano cuántas veces queremos que se repita el bucle. Sin embargo, cuando
utilizamos la instrucción while, no necesariamente tenemos que saber cuántas veces
debe ejecutarse el bucle, sino que eso puede definirse a lo largo de la ejecución del
programa. Por ejemplo, imagina que quieres hacer un programa para que el LED interno
parpadee indefinidamente hasta que el usuario accione un pulsador. En este caso,
cuando escribimos el código no sabemos cuántas veces tiene que repetirse el bucle, ya
que de hecho el número de repeticiones puede cambiar cada vez. Por tanto, deberíamos
usar la instrucción while de la siguiente manera:

En el programa de arriba, las acciones se repetirán mientras el valor leído en el pin del
pulsador sea 1, es decir, mientras el pulsador no esté pulsado. En el momento en que
alguien accione el pulsador, el valor leído en el pin será 0, por lo que no se cumplirá la
condición y se saldrá del bucle. Es decir, en este programa la condición de salida del
bucle depende de algo que sucede externamente.

 Ejercicios

5.- Vuelve a escribir el programa del ejercicio 1, pero utilizando un bucle while en
lugar de un bucle for.

6.- Vuelve a escribir el programa del ejercicio 4, pero utilizando un bucle while en
lugar de un bucle for.
7.- Realiza un programa para que el microcontrolador de Arduino genere una
secuencia de encendido y apagado de 2 diodos LED. La secuencia en concreto debe ser
la siguiente:
- Inicialmente debe parpadear 4 veces el diodo derecho.
- A continuación deben parpadear los dos LEDs indefinidamente hasta que el
usuario accione un pulsador.
- Finalmente debe parpadear 4 veces el LED izquierdo.
- Una vez terminada la secuencia, ésta debe repetirse desde el principio.

8.- Realiza un programa para que el microcontrolador de Arduino genere una


secuencia de encendido y apagado de 8 diodos LED controlada por un conmutador. La
secuencia en concreto debe ser la siguiente:
- Inicialmente parpadeará únicamente el primer LED, hasta que el usuario
ponga el conmutador en la posición de ‘1’ lógico.
- A continuación parpadeará únicamente el segundo LED, hasta que el usuario
ponga el conmutador en la posición de ‘0’ lógico.
- Seguidamente parpadeará únicamente el tercer LED, hasta que el usuario
vuelva a poner el conmutador en la posición de ‘1’ lógico.
- A continuación parpadeará únicamente el cuarto LED, hasta que el usuario
vuelva a poner el conmutador en la posición de ‘0’ lógico.
- El proceso continuará hasta que todos los LEDs hayan parpadeado, momento
en el que la secuencia volverá a empezar desde el principio.

9.- Realiza un programa para que el microcontrolador de Arduino una serie de efectos
de visualización sobre dos diodos LED controlados por dos conmutadores y un
pulsador. Cuando el usuario accione el pulsador, el microcontrolador leerá los dos
conmutadores y realizará los siguientes efectos:
- Si los dos conmutadores están a 0, parpadeará 4 veces el LED derecho.
- Si el primer conmutador está a 0 y el segundo está a 1, parpadeará 4 veces el
LED izquierdo.
- Si el primer conmutador está a 1 y el segundo está a 0, parpadearán 6 veces
los dos LEDs.
- Si los dos conmutadores están a 1, parpadearán 8 veces los dos LEDs.

Cuando termine la secuencia seleccionada, los LEDs permanecerán apagados hasta


que el usuario vuelva a accionar el pulsador, momento en que volverá a repetirse la
secuencia elegida.
4.- Instrucción do-while

El formato de la instrucción do-while es el siguiente:

La instrucción do-while funciona de la forma parecida a la instrucción while, con la


salvedad de que la condición se evalúa al final del bucle, en lugar de al principio. Esto
implica que el bucle siempre se ejecutará al menos una vez. En cambio, en la
instrucción while, si la condición no se cumple desde el principio, el bucle no llega a
ejecutarse ninguna vez.

Para hacer que un LED parpadee 100 veces con la instrucción do-while escribiríamos:

A modo de resumen, utilizaremos las instrucciones for, while o do-while según lo


siguiente:
 For: cuando sepamos de antemano el número de veces que debe ejecutarse
el bucle.
 While: cuando no sepamos de antemano el número de veces que se ejecutará
el bucle, sino que esto se decidirá durante la ejecución del programa.
 Do-while: cuando no sepamos de antema el número de veces que se
ejecutará el bucle, y además deseamos que pase lo que pase se ejecute al
menos una vez.
 Ejercicios

10.- Vuelve a escribir el programa del ejercicio 5, pero utilizando un bucle do-while en
lugar de un bucle while.

11.- Vuelve a escribir el programa del ejercicio 6, pero utilizando un bucle do-while en
lugar de un bucle while.

12.- Vuelve a escribir el programa del ejercicio 7, pero utilizando un bucle do-while en
lugar de un bucle while.

5.- Instrucción continue

La instrucción continue se utiliza dentro de un bucle, y hace que el programa se salte el


resto de las instrucciones de la iteración actual del bucle, y vaya directamente a
comprobar si se cumple la condición para la siguiente iteración.

Por ejemplo, en el siguiente programa:

Cuando el bucle se encuentre entre las iteraciones 31 y 49, se ejecutará la instrucción


continue, lo que hará que se salte las acciones que vienen a continuación, pasando
directamente a la siguiente iteración. Es decir, las acciones escritas a continuación de la
instrucción continue no se ejecutan en las iteraciones que van de la 31 a la 49.

La instrucción continue no es muy utilizada, pero conviene conocerla porque puede


ayudar a simplificar la programación en algunos casos.
 Ejercicios finales

13.- Se pretende realizar un sistema que controle la activación de una pantalla de 7


segmentos mediante dos pulsadores. El funcionamiento debe ser el siguiente:
-Inicialmente, la pantalla mostrará el número 0.
-Cada vez que se accione el pulsador 1, el número de la pantalla irá
incrementándose en 1 (para simplificar el problema, supondremos que no se
pulsará más de 9 veces).
-Cuando el usuario accione el pulsador 2, el sistema comenzará a generar una
cuenta atrás automática, empezando en el último número mostrado en pantalla,
y terminando en 0. Cada número se mostrará durante 1 segundo.
-Cuando termine la cuenta atrás, el sistema inicializará todos los valores para
poder comenzar de nuevo.

Ejemplo: si, una vez alimentada la placa, el usuario acciona 5 veces el pulsador 1, la
pantalla irá incrementándose con cada pulsación hasta el número 5. Si en ese momento
acciona el pulsador 2, comenzará la siguiente cuenta atrás automática: 5-4-3-2-1-0
(cada número durante 1 segundo).

14.- Se pretende implementar un dado electrónico con una pantalla de 7 segmentos y un


pulsador. El funcionamiento debe ser el siguiente:
-Nada más resetear el microcontrolador, éste comenzará a contar del 1 al 6
periódicamente a mucha velocidad. De esta forma, el usuario no podrá
distinguir el número que aparece en la pantalla de 7 segmentos.
-Cuando el usuario apriete un pulsador, la cuenta se detendrá durante dos
segundos, de forma que el usuario podrá ver el valor de la tirada del dado
electrónico.
-Después, el número que aparece en pantalla parpadeará tantas veces como
indique el propio número. Es decir, si sale un 4, parpadeará 4 veces, con un
tiempo de apagado y encendido de 500ms.
-Después del parpadeo el microcontrolador volverá a la situación inicial,
contando a gran velocidad, preparado para una nueva tirada.

15.- Utiliza la placa Arduino UNO para diseñar un pequeño programador de riego de 4
sectores. El programador dispondrá de un pulsador para iniciar el riego, 2
conmutadores para que el usuario pueda seleccionar el número de veces que se
repetirá el ciclo de riego, 4 salidas para activar 4 electroválvulas (una por sector) y
una pantalla de 7 segmentos donde aparecerá el tiempo que queda de riego del sector
que se está regando en ese momento.

El funcionamiento del programador será el siguiente: inicialmente, el usuario utilizará


los dos conmutadores para seleccionar el número de veces que se repetirá el ciclo de
riego (00 no se riega; 01  el ciclo se hace sólo una vez; 10 el ciclo se repite dos
veces; 11 el ciclo se repite tres veces). Cuando el usuario accione el pulsador,
comienza el ciclo de riego, en el que cada sector se debe regar durante 3 minutos. En
concreto, el ciclo será el siguiente:

- Inicialmente se activa la electroválvula 1, y en la pantalla aparece el número


3. Transcurrido un minuto, en la pantalla aparece el 2. Transcurrido otro
minuto, aparece un 1.
- Cuando transcurre otro minuto, se apaga la electroválvula 1, se enciende la
número 2, y en la pantalla vuelve a aparecer el número 3, que va
decrementándose conforme pasan los minutos.
- El mismo ciclo se repite para las electroválvulas 3 y 4.

Cuando termina el ciclo de riego, éste debe repetirse tantas veces como haya indicado
previamente el usuario con los conmutadores.

Para simular las electroválvulas se emplearán diodos LED. Por otro lado, para no
tener que esperar tantos minutos para comprobar el correcto funcionamiento del
circuito, se puede sustituir cada minuto por 1 segundo, es decir, que cada sector se
riegue 3 segundos en lugar de 3 minutos.
Tema 5
Lectura Digital
y PWM

1.- Control de potencia gradual: modulación PWM

En los ejercicios que hemos resuelto hasta ahora el control de potencia siempre ha sido del tipo
ON/OFF, es decir, la carga se activa o no se activa. Sin embargo, en muchas ocasiones nos puede
interesar controlar de forma gradual la potencia que se cede a la carga, por ejemplo para controlar
la velocidad de giro de un motor o el nivel de luminosidad de una tira de diodos LED. A
continuación veremos cómo se hace esto, centrándonos en el control gradual de potencia
para cargas de continua. El método empleado para regular la potencia en cargas de alterna es
algo más complejo y se estudiará más adelante.

Imaginemos que queremos regular la velocidad de giro de un pequeño motor de continua. En


principio parece fácil: basta con modificar la tensión continua aplicada al motor mediante
un potenciómetro, por ejemplo. Pero si queremos hacer esta regulación con un microcontrolador,
la cosa se complica más, ya que los microcontroladores sólo pueden sacar en su salida dos
valores de tensión diferentes: 0V o 5V (o 3.3V, dependiendo del modelo). ¿Cómo se puede hacer
entonces la regulación? Para eso está el modulador PWM.

El modulador de anchura de pulsos, más conocido como modulador PWM (Pulse Width
Modulation), es un circuito incorporado en el microcontrolador que genera una señal cuadrada
periódica cuyo valor de tiempo a nivel alto (conocido como ciclo de trabajo) es configurable.
Dicho de otra manera, genera una señal periódica cuyos pulsos tienen una anchura variable. Al
aplicar dicha señal a una carga (a través de un transistor de potencia), se consigue controlar con
mucha precisión y de forma sencilla la potencia entregada a la misma.

La siguiente imagen muestra una señal PWM con diferentes anchuras de pulso, o lo que es lo
mismo, diferentes ciclos de trabajo. En el primer caso el ciclo de trabajo es del 0%, por lo que
la señal está siempre a nivel bajo. Al aplicar dicha señal a una tira de LEDs, estarían siempre
apagados. En el segundo caso el ciclo de trabajo es del 25%, es decir, la señal está el 25% del
tiempo de un ciclo a nivel alto, y el 75% a nivel bajo. Al aplicar esta señal a la tira de LEDs,
estos brillarían débilmente. En el siguiente caso el ciclo de trabajo es del
50%, es decir, la señal pasa la mitad del tiempo a nivel alto y la otra mitad a nivel bajo. Al aplicar
esta señal a la tira de LEDs, estos brillarían más que en el caso anterior, pero todavía no lo
harían al nivel máximo, nivel que se alcanzaría cuando el ciclo de trabajo de la señal PWM
fuera del 100%.
En Arduino UNO existen seis pines digitales que incorporan un modulador PWM, por lo
que podemos controlar hasta seis cargas distintas. Se trata de los pines que vienen
marcados con el símbolo ˜: 3, 5, 6, 9, 10 y 11.

Los moduladores PWM incorporados en el microcontrolador de Arduino UNO son todos


de 8 bits, lo que quiere decir que se pueden configurar un total de 256 anchuras de pulso
diferentes. Dicho de otro modo, si lo que vamos a controlar es una tira de LEDs, podemos
configurar un total de 256 niveles de luminosidad diferentes, lo que sin duda es mucha
precisión.

Para activar el modulador PWM en un pin, en primer lugar hay que configurarlo como pin
de salida con la función pinMode(). Después tan solo hay que llamar a la siguiente función:

analogWrite (pin, valor)


donde
:

 pin: es el pin en el cual se quiere generar la señal PWM.


 valor: es el ciclo de trabajo deseado, comprendido entre 0 (siempre apagado) y 255
(siempre encendido).

En cuanto hagamos la llamada a esta función, automáticamente se generará en el pin


indicado una señal cuadrada periódica de aproximadamente 490Hz con el ciclo de
trabajo especificado. Esta señal se mantendrá estable en el pin hasta que hagamos una
nueva llamada a la función analogWrite(), o utilicemos las funciones digitalWrite() o
digitalRead() sobre ese mismo pin.
Es importante aclarar que, aunque la función se llama analogWrite(), el microcontrolador
no hace una escritura analógica en el pin. Los valores de tensión entregados al pin son
siempre 5V y 0V, pero al variar el tiempo que se entrega cada valor, en el fondo se varía la
tensión media entregada al pin. Por ejemplo, si escribimos analogWrite(pin, 127), estamos
generando una señal cuadrada con un ciclo de trabajo del 50%, lo que equivale a una
tensión media de 2.5V. De hecho, podríamos obtener este valor de tensión añadiendo a la
salida PWM un sencillo filtro paso bajo RC.

Ejercicios

1.- Utiliza el microcontrolador de Arduino para controlar el nivel de iluminación de una


tira de LEDs mediante dos pulsadores. Al accionar el primer pulsador, la iluminación se
incrementará en un nivel. Al accionar el segundo pulsador, la iluminación se decrementará
en un nivel. En total habrá 8 niveles: apagado, encendido y 6 niveles intermedios. Cuando
se alcance el nivel máximo y se siga accionando el pulsador de incrementar, la bombilla se
mantendrá en el nivel máximo. Cuando se alcance el nivel mínimo (apagado) y se siga
accionando el pulsador de decrementar, la bombilla se mantendrá apagada. Inicialmente
la bombilla estará apagada.

2.- Lectura de un sensor analógico con Arduino________________________

Para realizar lecturas de cualquiera de los sensores analógicos estudiados en el apartado


anterior, se emplea el convertidor analógico/digital que está incorporado en la mayoría
de los microcontroladores. En concreto, el microcontrolador ATmega328P, que es el de
la placa Arduino UNO, tiene incorporado un convertidor analógico/digital de 10 bits
de resolución. Ese convertidor además está multiplexado, de forma que disponemos
de 6 canales analógicos, aunque no podemos hacer lecturas de todos ellos al mismo
tiempo, ya que en realidad solo existe un único convertidor. Estos canales analógicos
reciben los nombres de AN0 hasta AN5, y se encuentran separados de los pines de
entrada y salida digitales

2.1.- Funcionamiento del convertidor analógico/digital________________________

El convertidor analógico/digital del microcontrolador lleva a cabo el siguiente proceso


cada vez que tiene que realizar una conversión: primero toma una muestra de la
amplitud de la tensión que entrega el sensor, después redondea el valor tomado a un
conjunto finito de niveles preestablecidos de tensión (conocidos como niveles de
cuantificación) y finalmente asigna a ese valor un código en binario. Por tanto, al final
del proceso obtendremos un número entero expresado en binario que será
proporcional a la tensión analógica entregada por el sensor.

A modo de ejemplo, la siguiente tabla muestra los valores entregados por un


convertidor de 10 bits de resolución, como es el caso de Arduino UNO, para diferentes
tensiones de entrada:

Por tanto, una vez que hayamos leído el número entero proporcionado por el
convertidor, si queremos conocer el valor de tensión entregado por el sensor tan solo
tenemos que aplicar la siguiente ecuación:

donde:
 Lectura es el número entero proporcionado por el convertidor A/D.
A/D

 FS es la tensión de entrada a fondo de escala, es decir, la tensión que hay que


introducir en el convertidor para obtener la máxima señal de salida (todos los
bits a ‘1’, 1023). En el caso de Arduino UNO, esta tensión por defecto es de 5V,
aunque podemos cambiarla por una menor, tal y como veremos más adelante.

2.2.- Resolución de un convertidor analógico/digital___________________________

El parámetro más importante de un convertidor AD es su resolución, que indica el


mínimo cambio de la tensión de entrada que puede ser detectado a la salida del
convertidor.

La resolución está relacionada con el número de bits del convertidor mediante la


siguiente fórmula:

donde:

 n es el número de bits del convertidor


 FS es la tensión de entrada a fondo de escala, como vimos anteriormente (5V
por defecto).

Por tanto, la resolución del convertidor A/D de nuestra placa Arduino UNO es:
Es decir, nuestro convertidor A/D puede detectar cambios en la tensión analógica de
entrada de hasta 5mV, lo cual es una precisión bastante aceptable. No obstante, de la
fórmula de arriba se deduce que si quisiéramos más resolución podemos hacer dos
cosas:
 Aumentar el número de bits del convertidor A/D, algo que solo puede hacerse
eligiendo otro microcontrolador con esta característica.
 Disminuir la tensión de fondo de escala, algo que veremos más adelante.

2.3.- Lectura del convertidor A/D__________________________________________

Para realizar una lectura con el convertidor A/D de Arduino, conectaremos el sensor
analógico a cualquiera de los canales analógicos (AN0- AN5) y llamaremos a la
siguiente función:

analogRead(pin)

donde:
 pin es el número del canal analógico que queremos muestrear (del 0 al 5)

Esta función realizará una lectura de la tensión en el pin especificado y devolverá


un número entre 0 y 1013 proporcional a dicha tensión.

 Ejemplo de uso:

NOTA: es importante tener en cuenta que los pines analógicos no hace falta
configurarlos en la función setup() como pines de entrada, ya que estos pines no
pueden comportarse como pines de salida, por lo que únicamente pueden ser entradas.
Por tanto, para utilizarlos no es necesario realizar ninguna configuración previa en la
función setup().

 Ejercicio resuelto

Realizar un programa que mande cada segundo por el monitor serial un número
proporcional a la tensión que aparece en el cursor de un potenciómetro que tiene sus
extremos conectados entre VCC y masa. En concreto el mensaje que debe mandarse es:
Valor leído: XX

donde XX es el valor leído, comprendido entre 0 y 1023

Ejercicios______________________________________________________________

2.- Modifica el programa anterior para que el número que se envíe al monitor serial se
corresponda exactamente con el valor de tensión que aparece en el potenciómetro. El
mensaje mostrado debe ser el siguiente:

Voltaje leido: XX.YY

donde XX.YY es el voltaje con una precisión de 2 decimales, comprendido entre 0 y 5.

3.- Modifica el programa anterior para se envíe por el monitor serial el voltaje que
aparece en dos potenciómetros diferentes. Para ello se utilizarán 2 canales analógicos
diferentes. Los mensajes que se mostrarán son los siguientes:

Voltaje potenciómetro 1: XX.YY


Voltaje potenciómetro 2: ZZ.WW

2.4.- Escalado de las lecturas del convertidor A/D____________________________

En muchas ocasiones nos puede interesar proceder sobre un determinado actuador de


forma proporcional a la lectura proporcionada por un determinado sensor analógico. Por
ejemplo, controlar la iluminación de una tira de LEDs de forma proporcional a la lectura
de una LDR. Esto se podría hacer de la siguiente manera:
Pero esta forma de proceder tiene un problema: el convertidor A/D y el modulador
PWM del microcontrolador trabajan con escalas diferentes, ya que el primero es de
10 bits, y por tanto trabaja con valores entre 0 y 2013, mientras que el segundo es de 8
bits, y trabaja con valores entre 0 y 255. Para solucionar este problema podríamos
efectuar una sencilla regla de tres, pero en Arduino existe una función que nos facilita
todavía más el trabajo, la función map(), que permite hacer un re-escalado de un
determinado valor:

map (n_rescalar, n_min_in, n_max_in, n_min_out, n_max_out)

donde:
 n_rescalar es la variable que contiene el valor que queremos re-escalar o remapear.

 n_min_in y n_max_in determinan el rango de valores que puede tomar la


variable antes de ser re-escalada.
 n_min_out y n_max_out es el rango de valores que puede tomar la variable una
vez haya sido re-escalada.
Por ejemplo, para controlar el modulador PWM (que tiene un rango de 0 a 255) con una
lectura del convertidor A/D (que tiene un rango de 0 a 1023), escribiríamos lo siguiente:

A la hora de trabajar con la función map() es importante tener en cuenta dos


consideraciones:

 En esta función los límites máximos (los de entrada o los de salida) pueden ser
inferiores a los límites mínimos. En ese caso, la función no realizará un mapeo
proporcional, sino inversamente proporcional. Por ejemplo, la siguiente llamada:

Lectura = map(lectura, 0, 1023, 255, 0)

Entregaría a la variable lectura un valor de 255 cuando el valor de entrada sea 0, y una
valor de 0 cuando la entrada sea de 1023.
 El valor entregado por esta función es siempre un número entero. Por tanto, si
necesitamos hacer el re-escalado con números decimales deberemos llevarlo a cabo
efectuando las operaciones matemáticas correspondientes, pero no usando esta función.

Ejercicios______________________________________________________________

4.- Controlar el nivel de iluminación de un LEDs en función del valor


leído por una LDR. La iluminación proporcionada el LEDs deberá ser
proporcional al nivel de oscuridad que capte la LDR. Para ello se montará un divisor
resistivo formado por una LDR conectada a VCC y una resistencia fija de 10k
conectada a masa.

5.- En el ejercicio anterior habrás comprobado que el LEDs permanece todo el


tiempo encendida, aunque la estancia esté iluminada. En este ejercicio deberás
modificar el programa del ejercicio anterior para, además de controlar el nivel de
iluminación del LEDs, poder ajustar mediante un potenciómetro el nivel de
iluminación por debajo del cual se activará la tira de LEDs.

6.- Añade al ejercicio anterior un pulsador para enviar al ordenador por comunicación
serie el nivel actual de iluminación del LEDs, cada vez que se acciona el
pulsador. Este nivel será indicado en porcentaje: 0% equivale a la tira totalmente
apagada, mientras que 100% equivale a la tira totalmente encendida.
Tema 6
Comunicaciones serie
1.- Comunicación de Arduino con el ordenador por puerto serie

En este apartado vamos a ver cómo podemos comunicar nuestra placa Arduino UNO
con el ordenador, utilizando para ello la USART incorporada en el microcontrolador de
Arduino.

 Comunicación de Arduino con el puerto RS232 de un ordenador


Para comunicar nuestro Arduino UNO con el puerto RS232 de un ordenador en
principio no debería de haber ningún problema, ya que ambos utilizan el mismo
protocolo de comunicaciones. No obstante, sí que existe un impedimento importante:
la USART de Arduino y el puerto serie del ordenador trabajan con niveles de
tensión bien diferentes. Mientras que Arduino trabaja con niveles TTL (0V y 5V),
el puerto serie del ordenador trabaja con tensiones de -12V y +12V, por lo que la
conexión directa destruiría rápidamente nuestra placa Arduino. Así pues, es necesario
insertar entre ambos un dispositivo que realice la función de adaptación de niveles de
tensión, tal y como se muestra en la siguiente figura:
El dispositivo encargado de realizar esta adaptación de niveles es el chip MAX232,
cuyo esquema de conexiones se muestra a continuación:

 Comunicación de Arduino con el puerto USB del ordenador


En principio parece más lógico comunicar nuestro Arduino con un puerto USB del
ordenador, ya que hoy en día muchos ordenadores ya no disponen de puerto serie.
Además, de esa manera nos evitaríamos el problema de la adaptación de niveles, ya que
el puerto USB también trabaja con niveles TTL.

Sin embargo, ¿es posible comunicar un puerto USB del ordenador con la USART de
Arduino, siendo protocolos de comunicación diferentes? La respuesta es que sí. En
este caso, en vez de realizar una adaptación de niveles, es necesario realizar una
adaptación de protocolos (de USB a USART), cosa de la que se encarga otro chip:
el FTDI, que ya viene incorporado en la propia placa de Arduino.

Este integrado canaliza la comunicación serie a traes del USB, mientras que los drivers
FTDI (incluidos en el software de Arduino) proporcionan un puerto serie virtual en el
ordenador. Es decir, cuando nos comunicamos por USB con nuestra placa Arduino
UNO, en realidad lo estamos haciendo a través de su USART, aunque a nosotros nos
parezca una comunicación USB.
Cuando comunicamos nuestro Arduino con el ordenador por puerto USB, los LEDS RX
y TX de la placa parpadean cuando se detecta comunicación transmitida través del chip
FTDI. En cambio, no parpadean si se usa la comunicación serie a través de los pines
digitales 0 y 1 (por ejemplo para comunicar con otro dispositivo por USART).

Además, el propio IDE de Arduino incluye una herramienta llamada Monitor Serial
que permite enviar y recibir datos por ese puerto serie virtual que se crea cuando
conectamos nuestro Arduino a un ordenador a través del puerto USB.

Esta herramienta permite enviar datos por el puerto serie, y muestra en pantalla los
datos recibidos. Además, permite configurar la velocidad de transmisión y los datos que
se envían al pulsar la tecla ENTER. A este respecto tenemos 4 opciones:
- No hay fin de línea: al pulsar ENTER se envían únicamente los datos escritos en
la pantalla
- Nueva línea: al pulsar ENTER se envían los datos escritos en pantalla, seguido
del comando de nueva línea (\n).
- Retorno de carro: al pulsar ENTER se envían los datos escritos en pantalla,
seguidos del comando de retorno de carro (\r).
- Ambos: al pulsar ENTER se envían los datos escritos en pantalla, seguidos del
comando de nueva línea (\n) y del retorno de carro (\r).
2.- Funciones de Arduino para la comunicación serie _

A continuación se describirán las principales funciones que incluye el lenguaje de


Arduino para la comunicación por puerto serie. Las funciones se han clasificado en tres
grupos diferentes: gestión del puerto, transmisión y recepción.

2.1.- Funciones para la gestión del puerto

Serial.begin(velocidad)

Esta función abre el puerto serie y fija la velocidad en baudios para la transmisión de
datos. El valor típico de velocidad para comunicarse con el ordenador es 9600, aunque
otras velocidades pueden ser soportadas (4800, 19200, 115200, etc). Si no se especifica
lo contrario, la comunicación se realiza con 8 bits de datos, 1 bit de stop y sin
paridad.

IMPORTANTE: Cuando se utiliza la comunicación serie los pines digitales 0 (RX) y 1


(TX) no pueden utilizarse para otros propósitos.
Serial.begin(velocidad, configuración)

De forma opcional se puede añadir un segundo parámetro que configura el resto de


características de la comunicación: el número de bits que se transmiten cada vez (5,
6, 7 u 8), la paridad (sin paridad, paridad par o impar) y el número de bits de stop (1 o
2). Si no se añade este parámetro, se empleará la configuración por defecto, comentada
anteriormente. Para cambiar esta configuración, escribiríamos por ejemplo uno de los
siguientes parámetros (la lista completa de parámetros se puede encontrar en la web de
Arduino):
• SERIAL_5N1 (5 bits de datos, sin paridad, 1 bit de stop)
• SERIAL_6E1 (6 bits de datos, paridad par, 1 bit de stop)
• SERIAL_7O1 (7 bits de datos, paridad impar, 1 bit de stop)
• SERIAL_8O2 (8 bits de datos, paridad impar, 2 bits de stop)

 Ejemplos:

Serial.end()

Esta función deshabilita la comunicación serie, permitiendo que los pines TX y RX


puedan ser usados de nuevo como pines digitales de propósito general. Para
habilitar de nuevo la comunicación serie es necesario llamar otra vez a la función
Serial.begin()

Serial.flush()

La USART del microcontrolador dispone de un buffer de 128 bytes donde se almacenan


los datos que se van recibiendo. Esto permite que se puedan recibir varios datos
seguidos y no se pierdan aunque todavía no se hayan leído. La instrucción Serial.flush()
vacía el buffer de recepción de la USART. No requiere parámetros ni devuelve nada.
2.2.- Funciones para la transmisión de datos

Serial.print(dato)

Imprime el dato indicado entre paréntesis como texto en código ASCII. Se pueden
imprimir caracteres, cadenas de caracteres, números enteros o números decimales, pero
siempre en formato de texto ASCII. Es decir, el número entero 65 se imprimirá como
el carácter 6 y el carácter 5.

A continuación se muestran algunos ejemplos:

Serial.print(dato, formato)

De forma opcional se puede añadir un segundo parámetro en la instrucción


Serial.print(), que indica el formato que se utilizará en el envío de números. En el caso
de números enteros, se puede elegir la base entre las siguientes: BIN (binario), OCT
(octal), DEC (decimal), HEX (hexadecimal). En el caso de números con decimales, este
parámetro indica el número de decimales que serán enviados.

A continuación se muestran algunos ejemplos:


Serial.println(dato)
Serial.println(dato, formato)

Esta instrucción funciona de forma similar a Serial.print(), pero además de enviar el


dato por el puerto serie, a continuación envía un carácter de retorno de carro (\r) y
un carácter de salto de línea (\n). De esta manera, cada vez que se envía un dato
nuevo, en el monitor serie aparece en una nueva línea.

 Ejercicio resuelto

Realiza un programa que haga que el microcontrolador de Arduino transmita el


carácter 'A' de forma periódica cada segundo a través del puerto USB. La transmisión
se realizará como una comunicación serie estándar a una velocidad de 9600 bps.
Ejercicios

1.- Realiza un programa en el que el microcontrolador de Arduino lea el estado de 4


pulsadores y transmita por el puerto USB el número del pulsador que se ha pulsado en
cada momento, con la siguiente frase: "PULSADOR X", donde X representa el número
del pulsador. Cada frase debe aparecer en una línea nueva. Si no se acciona ningún
pulsador, no se debe enviar nada. La comunicación será a 9600bps, y el resto de
parámetros de configuración del puerto serie serán los parámetros por defecto.

2.- Realiza un programa para que cada vez que se accione un pulsador, el
microcontrolador envíe al ordenador a través del puerto USB una tabla con los 255
primeros números en formato decimal, binario y hexadecimal. Cada fila de la tabla
tendrá la siguiente forma:

Decimal: X Hexadecimal: Y Binario Z

Donde X, Y y Z representan un mismo número en sus respectivas codificaciones.

2.3.- Funciones básicas para la recepción de datos

Serial.available()

Esta función se utiliza para saber si se han recibido datos por el puerto serie. Devuelve
un entero con el número de bytes (caracteres) disponibles para leer desde el buffer de la
USART (128 bytes como máximo) ó 0 en caso de que no haya ninguno. Por tanto,
siempre que haya algún dato disponible para leer, el número devuelto por
SerialAvailable() será mayor que 0.

Así pues, para saber si hemos recibido algún dato por el puerto serie, podemos hacer lo
siguiente:
También podemos hacer que nuestro programa de Arduino se espere a que se reciba un
dato por puerto serie escribiendo lo siguiente:

Serial.read()

Esta función se utiliza para leer un dato recibido por el puerto serie. Al invocarla,
devuelve el primer byte recibido por el puerto serie que todavía no haya sido leído (es
decir, el primer byte almacenado en el buffer). En caso de no haber ningún dato
disponible, devuelve el número -1.

 Ejercicio resuelto

Realiza un programa para que el microcontrolador de Arduino se comporte como un


generador de eco con los datos que reciba a través del puerto USB. Es decir, cada vez
que el micro reciba un carácter, volverá a transmitirlo a través del puerto USB.
Ejercicios

3.- Realiza un programa para controlar el encendido de 8 diodos LEDs desde el teclado
del ordenador. El usuario enviará por el monitor serial un número comprendido entre
el 0 y el 8. Una vez recibido, el micro deberá encender tantos LEDs como indique el
número recibido.

4.- Realiza un programa que genere con el microcontrolador una secuencia de


encendido y apagado de los LEDs, cuya velocidad de encendido/apagado se controle a
través del monitor serial del ordenador de la siguiente forma: mientras no se envíe
ningún dato desde el ordenador, la velocidad de encendido/apagado será la menor de
todas. En cualquier momento se podrá mandar desde el ordenador un número
comprendido entre el 1 y el 5, lo que modificará la velocidad de la secuencia, de forma
proporcional al número enviado.

5.- Realiza un programa que permita controlar mediante el teclado del ordenador el
número de veces que pitará un zumbador conectado a la placa Arduino UNO. Si el
usuario pulsa la tecla 3 del ordenador, el zumbador deberá pitar 3 veces. Si pulsa la
tecla 5, deberá pitar 5 veces, y así con todos los números comprendidos entre 1 y 9.

2.4.- Funciones avanzadas para la recepción de datos

La instrucción Serial.read() lee los datos recibidos por puerto serie byte a byte. Esta
instrucción es muy útil cuando el dato enviado por el usuario es un número de un único
dígito. Pero si lo que envía el usuario es un número de varios dígitos, como el 740, si lo
leemos con la instrucción Serial.read() haremos 3 lecturas separadas: el 7, el 4 y el 0,
que después tendremos que juntar de manera compleja por software. Para estos casos
existen dos instrucciones mucho más interesantes, que analizamos a continuación:

Serial.parseInt()

Esta función lee el buffer de recepción de la USART y devuelve un número entero que
contiene todos los dígitos que se encuentran en el buffer hasta que aparece un carácter
que no es un dígito (como un espacio, una coma, un retorno de carro, etc). En caso de
que no se encuentre ningún número, devuelve el número 0.

Dicho de otra manera, devuelve el primer número entero encontrado a partir de la


posición actual del buffer de recepción. Los caracteres iniciales que no son enteros (o
el signo menos) son ignorados. El número devuelto termina cuando se encuentra el
primer carácter que no es un dígito.
Serial.parseFloat()

Esta función lee el buffer de recepción de la USART y devuelve el primer número en


coma flotante (de tipo float) válido a partir de la posición actual del buffer. Los
caracteres iniciales que no son enteros (o el signo menos) son ignorados. El número
devuelto termina cuando se encuentra el primer carácter que no es un número en
coma flotante (un espacio, una coma, un retorno de carro, etc). En caso de que no se
encuentre ningún número, devuelve el número 0.

 Ejercicio resuelto

Realizar un programa en el que el usuario controle a través del monitor serial del
ordenador el nivel de brillo de un diodo LED. En concreto, el usuario escribirá por el
monitor serial cualquier número entre 0 y 255, indicando el porcentaje de brillo (0 
completamente apagado, 255  completamente encendido). El microcontrolador de
Arduino deberá recibir este dato y actuar sobre el modulador PWM para generar el
nivel de iluminación especificado.
3.- Funciones matemáticas _

A continuación se describen algunas funciones matemáticas incluidas en el lenguaje de


programación de Arduino que nos resultarán muy útiles para resolver los siguientes
ejercicios. Estas funciones matemáticas no son propias de la comunicación serie, y por
tanto se pueden utilizar en cualquier otro ámbito de la programación de Arduino.

constrain (numero, minimo, maximo)

Esta instrucción constriñe un número para obligarlo a estar dentro de un rango


determinado, dado por los valores mínimo y máximo.
Donde
: numero es el número a constreñir, que puede ser de cualquier tipo de dato
minimo es el valor más bajo que puede tomar el número
maximo es el valor más alto que puede tomar el número

Esta función devolverá lo siguiente:


numero, si dicho número está entre el mínimo y el máximo especificado.
minimo, si el número está por debajo del mínimo especificado.
máximo, si el número está por encima del máximo especificado.

Por tanto, el uso de la función constrain() equivale al siguiente código:

A continuación se presentan una serie de ejercicios en los que deberás utilizar, además
de todo lo relacionado con las comunicaciones serie, las funciones matemáticas map()
y/o constrain() para resolverlos.

Ejercicios

6.- Realizar un programa en el que el usuario controlará el color de un LED RGB


desde el teclado del ordenador. Para ello, el usuario escribirá en el terminal serie tres
números, que corresponderán con los tres niveles de intensidad en tanto por cien de los
colores ROJO, VERDE y AZUL. Estos números irán separados por comas o por
espacios. Por ejemplo, si el usuario escribe lo siguiente:

0 50 100
El LED rojo debe permanecer apagado, el LED verde debe brillar al 50% de su
intensidad máxima y el LED azul debe brillar a nivel máximo.

7.- Modifica el programa anterior para que, además de controlar el color de un LED
RGB, el microcontrolador mande al ordenador el siguiente mensaje, para comprobar
que se ha recibido correctamente:

VALOR ACTUALIZADO ROJO: X


% VERDE:Y% AZUL:Z%

Donde X, Y y Z se corresponden con los valores introducidos por el usuario.

8.- Realiza un programa para que el usuario controle el tiempo de duración de cada
color de un LED RGB, de la siguiente manera:
-Inicialmente el LED estará apagado.
-El usuario escribirá en el terminal tres números, separados por comas o espacios.
Estos números podrán contener decimales, e indicarán el tiempo (en segundos) que
permanecerá el LED en color rojo, verde y azul.
-En cuanto el usuario pulse la tecla ENTER, el LED comenzará a brillar en color
rojo el tiempo indicado en el primer número, luego pasará a verde el tiempo
indicado en el segundo número y después pasará a azul el tiempo indicado en el
tercer número.
-Finalmente el LED se apagará, quedando a la espera de un nuevo dato.

9.- Modifica el ejercicio 7 para que, en caso de que el usuario cometa un error al
introducir los niveles de iluminación de cada LED, no suceda nada extraño. Para ello,
si el nivel introducido para algún LED es inferior a 0, debe tomarse dicho nivel como 0.
Si el nivel introducido es superior a 100, debe tomarse como 100.
Tema 7
Comunicaciones serie II

1.- Introducción

En la unidad anterior utilizamos la USART del microcontrolador para comunicar


nuestra placa Arduino con el ordenador. No obstante, esta USART también nos permite
comunicar nuestro Arduino con otros dispositivos, como por ejemplo un módulo
bluetooth, un módulo wifi, un acelerómetro o incluso otro Arduino. En esta unidad
estudiaremos algunos de estos casos: comunicación de Arduino con otro Arduino y con
un módulo bluetooth.

2.- Comunicación de Arduino con otro Arduino _

Para comunicar nuestra placa Arduino con otro Arduino a través del puerto serie, la
configuración hardware es mucho más sencilla que en el caso de comunicarlo con un
ordenador, ya que ambos dispositivos disponen de USART. Por tanto, no es necesario
realizar una conversión de protocolos (como hacía el chip FTDI para pasar de
USART a USB) ni realizar adaptación de niveles (como hacía el chip MAX232 para
pasar de niveles TTL a niveles RS232).

Tan solo hay que interconectar los pines RX y TX de ambos dispositivos (TX1 con
RX2 y RX1 con TX2), además de unir las masas de ambas placas, tal y como muestra el
siguiente esquema:
3.- Comunicación de Arduino con un módulo bluetooth

En este apartado utilizaremos la USART del microcontrolador de Arduino para


comunicarnos con un módulo bluetooth, lo que nos permitirá realizar proyectos que
puedan ser controlados de forma inalámbrica (desde un ordenador, desde un móvil o
desde otro dispositivo con bluetooth).

En primer lugar comenzaremos estudiando las características generales del protocolo de


comunicación bluetooth, que resultan necesarias conocer para entender los siguientes
apartados.

3.1.- El protocolo de comunicaciones bluetooth

El bluetooth es un protocolo de comunicaciones inalámbricas creado conjuntamente por


las empresas Ericsson, Nokia, IBM, Toshiba e Intel. Está especialmente diseñado para
dispositivos de bajo consumo que requieren una comunicación de corto alcance, como
por ejemplo para conectar teléfonos móviles a otros dispositivos como auriculares,
micrófonos u otros teléfonos móviles. Posibilita la transmisión de voz y datos entre
diferentes dispositivos mediante un enlace de radiofrecuencia en la banda de los
2.4GHz.

Los equipos que integran este protocolo pueden comunicarse entre ellos cuando se
encuentran dentro de su alcance, aunque no se encuentren alineados e incluso en
distintas estancias, si la potencia de transmisión es suficiente. En ese sentido, estos
dispositivos se clasifican en tres clases diferentes según su potencia de transmisión:

Tipo Potencia máxima Alcance


Clase 1 20dBm (100mW) ~100 metros
Clase 2 4dBm (2.5mW) 1-5 metros
Clase 3 0dBm (1mW) ~1 metro

Cada uno de los dispositivos bluetooth tienen asignada una dirección única de 12
bytes que sirve para identificarlos, conocida como dirección MAC (algo similar a la
MAC de una tarjeta de red). Además de la dirección MAC, presentan un nombre de
dispositivo, que sirve para identificarlo cómodamente, y que se puede cambiar al gusto
del usuario (no así la dirección MAC, que es fija). Generalmente incluyen además un
código PIN que debe teclearse para permitir la comunicación con el dispositivo.

Cuando dos equipos dotados de bluetooth se encuentran dentro de su alcance y quieren


comunicarse, primero han de realizar un procedimiento conocido como
2
emparejamiento (pairing), que sirve para vincular ambos dispositivos. Durante el
emparejamiento los dos dispositivos se identifican con su nombre y su dirección MAC,
y seguidamente se solicitan el código PIN para autorizar la conexión. Si el proceso se
lleva a cabo con éxito, ambos dispositivos suelen guardan la identificación del otro, para
volver a vincularse de forma automática cada vez que se encuentren dentro del alcance.

3.2.- El módulo bluetooth HC-06

Ahora que ya conocemos un poco mejor el protocolo de comunicación bluetooth, nos


centraremos en estudiar uno de los módulos bluetooth de bajo coste más utilizados para
Arduino: el HC-06.

Vista frontal y trasera del módulo bluetooth HC-06

3
Como se puede observar, este módulo de bajo coste y reducido tamaño dispone
únicamente de 4 pines: RXD, TXD, VCC y GND. Por tanto, la conexión con Arduino
es realmente sencilla, ya que únicamente debemos cruzar los pines de transmisión y
recepción, además de alimentar el módulo, tal y como se muestra en el siguiente
esquema:

NOTA: Aunque el dispositivo en cuestión trabaja con una tensión de 3.3V, dispone en
su placa de un pequeño regulador de tensión que obtiene los 3.3V requeridos a partir de
una tensión continua entre 3.3V y 6V. Por tanto, podemos alimentar sin problema el
módulo bluetooth desde el pin de 5V de nuestra placa Arduino.

NOTA 2: Existe en el mercado otro módulo bluetooth que físicamente resulta muy
parecido al que estamos estudiando: el HC-05. La manera más sencilla de diferenciarlos
es observando el número de pines: el HC-06 dispone de 4 pines, mientras que el HC-
05 dispone de 6 pines. En cuanto a diferencias funcionales, el modelo HC-06 solo
puede actuar como esclavo y además dispone de un juego reducido de instrucciones,
mientras que el modelo HC-05 puede funcionar como maestro o como esclavo, y acepta
un número mayor de órdenes de configuración. No obstante, para las aplicaciones que
se abordarán en este documento el modelo HC-06 es más que suficiente.

Vista frontal y trasera del módulo bluetooth HC-05


Una vez analizada la configuración hardware necesaria para comunicar nuestro Arduino
con el módulo HC-06, es el momento de comenzar con la parte software. En primer
lugar veremos los comandos que se utilizan para configurar los diferentes parámetros
del módulo bluetooth, conocidos como comandos AT. Enviando estos sencillos
comandos a través de la USART del microcontrolador podremos configurar todos los
parámetros del módulo, como su nombre, su código PIN y la velocidad de transmisión.

3.3.- Los comandos AT

Los comandos AT comenzaron a utilizarse hace algunas décadas para configurar los
primeros módems mediante las líneas del puerto serie de los ordenadores. Cada
comando consiste en una cadena de texto que siempre sigue el mismo formato:

AT+ORDEN

Donde AT viene de la palabra en inglés attention (atención), que indicaba que lo que
venía a continuación era un comando de configuración, y no un dato que tuviera que
enviarse a través de la línea telefónica.

En la actualidad los comandos AT se utilizan para configurar sencillos dispositivos a


través de una comunicación serie, como por ejemplo módulos bluetooth, módulos wifi o
módulos GSM.

A continuación se muestran los principales comandos AT que acepta nuestro módulo de


comunicaciones HC-06:

 AT+NAMEnombre

Configura el nombre que mostrará el dispositivo cuando sea localizado mediante


otro equipo con bluetooth, como un móvil o un ordenador.

 AT+PINXXXX

Configura el número de identificación personal o PIN que será solicitado cuando


otro dispositivo bluetooth pretenda vincularse con él.

 AT+BAUDX

Configura la velocidad de transmisión de datos que utilizará el módulo bluetooth


en la comunicación serie (en sus pines TXD y RXD). Puede ser cualquiera de las
siguientes:
1 1200bps 5 19200bps
2 2400bps 6 38400bps
3 4800bps 7 57600bps
4 9600bps 8 115200bps

Para este módulo, la configuración por defecto, es decir, la configuración de viene de


fábrica, es la siguiente:

NOMBRE: LINVOR
PIN: 1234
VELOCIDAD: 9600bps

Según acabamos de ver, para cambiar esta configuración lo único que tenemos que
hacer es enviar con nuestra placa Arduino los comandos AT necesarios a través del
puerto serie. A continuación se muestra un ejemplo que configura el módulo con el
nombre “Mi_HC06” y con el PIN 4444, manteniendo la velocidad de comunicación por
defecto:

Una vez cambiados estos parámetros, el módulo los guarda en su memoria interna,
por lo que sólo es necesario enviar los comandos AT una vez (mientras no queramos
modificar de nuevo los parámetros de configuración).

A partir de este momento, cualquier dispositivo bluetooth podrá localizar nuestro


módulo con el nombre “Mi_HC06”. Después podrá vincularse con él escribiendo el
código PIN 4444. Una vez vinculados, cualquier dato que envíe el dispositivo será
recibido por el módulo HC-06, que inmediatamente lo enviará a nuestra placa Arduino a
través de la USART. Por otro lado, cualquier dato enviado por Arduino a través de la
USART será recibido por el módulo HC-06, que lo reenviará por bluetooth al
dispositivo vinculado con él. De esta manera nuestro Arduino dispone de una
comunicación full-duplex inalámbrica con cualquier dispositivo bluetooth.
BTM-5 Bluetooth
Wireless TTL Master/Slave Transceiver Module
Datasheet
Rev 2.0, Jan 2011
BTM-5 Bluetooth Module Datasheet Rev1.0

Content
1. Key Features ............................................................................................................................1
2. Product Description ................................................................................................................1
3. Applications .............................................................................................................................1
4. Specifications ...........................................................................................................................2
5. Electrical Characteristics .......................................................................................................2
6. Power Consumption ................................................................................................................ 2
7. Typical Application .................................................................................................................3
8. Pin Definition ...........................................................................................................................4
9. Package Description and Dimensions ....................................................................................5
10. Schematic Overview..................................................................................................................8
11. Full AT Commands list............................................................................................................11
BTM-5 Bluetooth Module Datasheet Rev2.0

1. Key Features
¾ Bluetooth Spec v2.0+EDR Compliant
¾ Class 2 type Output Power
¾ Full speed Bluetooth operation with full piconet support
¾ Scatternet support
¾ Support Serial Port Profile (SPP)
¾ Onboard antenna
¾ 3.3V operation
¾ UART interface
¾ Support for 8Mbit external onboard Flash
¾ Minimized size 26.9mm(L) x 13mm(W) x 2.2mm(H)
¾ RoHS Compliant

2. Product Description

BTM-5 m odule is a Cl ass 2 B luetooth module using Bl ueCore4-External chipset fro m


leading Bl uetooth chipset s upplier C ambridge Sil icon Radio. Th is module b oth support Mas ter
and Sla ve m ode operation, i t can be e asily changed by A T command c onfiguration. Ea ch
Master/Slave BTM-5 pair auto link with the defa ult device address after power up. After link is
established, user can tra nsmit and rece ive data via t he UAR T i nterface wit h each other. T he
transmission is almost transparent to user, it acts as tow UART connect with each other wirelessly.
It is highly recommend to use BTM-5 pair to communicate with each other. User can also use
the module with the Laptop, PDA, Mobile Phone and etc.

3. Applications
¾ Bluetooth Carkit
¾ PCs
¾ Personal Digital Assistants (PDAs)
¾ Computer Accessories (Compact Flash Cards, PCMCIA Cards, SD Cards and USB Dongles)
¾ Access Points
¾ Digital Cameras

1
BTM-5 Bluetooth Module Datasheet Rev2.0

4. Specifications
Parameters Specifications
Operating Frequency Baud 2.4GHz-2.48GHz unlicensed ISM Band
Bluetooth Specification V2.0+EDR
Output Power Class -4 ~ 6dBm adjustable , Class 2
Sensitivity -80dBm at 0.1% BER
Data Rate Asynchronous: 2Mbps (Max)
Operating Voltage 3.3V
Host Interface USB / UART
Audio Interface PCM and Analog interface
Flash Memory Size 8Mbit
Operation temperature -20 ~ +55 ℃
Dimension 26.9mm(L) x 13mm(W) x 2.2mm(H)
*Specifications are subject to change without prior notice

5. Electrical Characteristics
Absolute Maximum Ratings
Rating Min Max
Storage temperature -40℃ +150 ℃
Supply voltage : VBAT -0.4V 5.6V
Other terminal voltages VSS-0.4V VDD+0.4V

Recommended Operating Conditions


Operating Condition Min Max
Operating temperature range -40℃ +150 ℃
Guaranteed RF performance range -25℃ +75 ℃
Supply voltage : VBAT 2.2V 4.2V

6. Power Consumption
Operation Mode Connection UART Rate Average Unit
Type (kbps)
Page scan - 115.2 0.42 mA
ACL No traffic Master 115.2 4.60 mA
ACL with file transfer Master 115.2 10.3 mA
ACL 1.28s sniff Master 38.4 0.37 mA
ACL 1.28s sniff Slave 38.4 0.42 mA
SCO HV3 30ms sniff Master 38.4 19.8 mA
SCO HV3 30ms sniff Slave 38.4 19.0 mA
Standby Host connecton - 38.4 40 uA

2
BTM-5 Bluetooth Module Datasheet Rev2.0

7. Typical Application
The f ollowing sc hematic i s the ty pical hardw are a pplication for the BTM- 5 module, it
provide both RS232 and 5V TTL logic level connection to the module.

We prov ide t wo varia tions of BTM-5 breakout board, one is RS23 2 in terface, t he ot her is
TTL interface. Note that t hese two dif ferent br eakout bo ard use different su pply v oltage an d
different interface, please take care before using them.

Pins Signals RS232 breakout board TTL breakout board


1 VCC 5V power suppler 3.3V power suppler
2 Mode 1=AT cmd mode, 0=Normal 1=AT cmd mode, 0=Normal
3 RX RS232 logic level
4 TX RS232 logic level 3.3V logic level
5 GND Power ground Power ground

User can change t he d efault s etting of BTM-5 m odule w ith t he AT c ommand v ia onboard
button or ‘Mode’ pin. If t he bottom pressed or ‘Mode’ pin pulled high, the module enter the AT
command mode. Th e breakout board provide two LE D to i ndicate the st atus of t he module, th e
RED led indicate the link activity status, the GREEN led indicate the pairing status.

3
BTM-5 Bluetooth Module Datasheet Rev2.0

8. Basic AT Command
Users can use AT commands t o s etup the m odule with dif ferent co nfigurations. Every AT
command must be fol lowed with <CR> and<LF> control character which is 0x0D and 0 x0A in
hexadecimal. Every AT command will foll owed with a response "OK". They will be som e basic
AT command you should know.
1. AT
AT command is use to test the module to see if it is OK.
2. AT+RESET
AT+RESET command is reset the module back to power up status.
3. AT+ROLE?
AT+ROLE? command inquiry the module's role, 0 = Slave, 1 = Master, 2 = Slave-loopback.
4. AT+ROLE=<param>
AT+ROLE command is used to set the module with master or slave, 0 = Slave, 1 = Master, 2
= Slave-loopback. You have to configure one module to master and the other to slave to become a
pair.
5. AT+CMODE?
AT+CMODE? command inquiry the link mode. 0 = Specific bluetooth link address, 1 = Any
bluetooth link address, 2 = Slave-loopback
6. AT+CMODE=<param>
AT+CMODE com mand is use d to set up m odule l ink m ode. 0 = Spec ific b luetooth link
address, 1 = Any bluetooth link address, 2 = Slave-loopback. It is better to set the mode to 1 if you
only have one pair device, because it is much easier to make them a pair.
7. AT+PSWD?
AT+PSWD? command inquiry the password of the module.
8. AT+PSWD=<param>
AT+PSWD command is used to set the pairing password.
9. AT+UART?
AT+UART? command inquiry the uart configurations

4
BTM-5 Bluetooth Module Datasheet Rev2.0

9. Pin Definition
Pin Description
1 UAR T_TXD
2 UAR T_RXD
3 UAR T_CTS
4 UAR T_RTS
9~11 N A
12 3.3V Supply input
13 GND
14~20 N A
21,22 G ND
23 PIO0 Programmable IO port
24 PIO1 Programmable IO port
25 PIO2 Programmable IO port
26 PIO3 Programmable IO port
27 PIO4 Programmable IO port
28 PIO5 Programmable IO port
29 PIO6 Programmable IO port
30 PIO7 Programmable IO port
31 PIO8 Programmable IO port
32 PIO9 Programmable IO port
33 PIO10 Programmable IO port
34 PIO11 Programmable IO port

5
FULL
BTM-5 Bluetooth Module Datasheet Rev2.0

6
Schematic overview
The following schematic is the typical hardware application for the BTM-5 module, it provide
both RS232 and 5V TTL logic level connection to the module.

The BTM-5 module pairs is default configured with 115200bps baud rate, the master and slave's
PIO8 (Pin31) indicate the link status which is connected to a LED (D2) shown in the application
schematic. When power up, the both module's LED flashes every 0.5 seconds and look for each
other for pairing. After successfully pairing, the LED flashes 3 seconds. At this time you can
transmit data via the UART port with each other.

The module's PIO11 (Pin32) is a mode selection pin to switch between normal mode and AT
command mode. In the application schematic, it is connected to a button S1. When it is press
down the module enter AT command mode, it come back to normal mode if the button is
released. Note that, when the link is not established, once the module enter AT command mode,
it will not come back to normal mode until link established or send a AT+RESET command or
re-power the module.
FAQ and Known Issues
• The module is delivered with a default baud rate of 115200, although 38400baud is
specified in the document.

• After sending AT+RESET, the module restores some "factory defaults" and the baud rate
changes to 38400

• Changing the PIO11 level from 0 to 1 or vice-versa, when the module is powered,
changes the mode of operation istantly but the LED on PIO8 blinks the same way. Thus
the user does not know whether the module changed the operation mode or not. The only
way to find out is trying to send AT commands and see if it responds in any way.

• When the module is powered up in Data Transfer Mode, the LED blinks quickly (2-3Hz)
indicating that the module is ready to connect. After a connection has been established
the LED on PIO9 lights up and the LED on PIO8 blinks short twice every second.

• When the module is powered up in AT Command Mode, the LED on PIO8 blinks
slowly(1 Hz).

• REGARDLESS of PIO11 level (0 or 1) changing the BT Connection state switches the


module into Data Transfer Mode. If PIO11 is 1 and the user wants to continue with the
AT Command Mode after a BT connection has been establishes it has to toggle PIO11 to
switch the module back in AT Command mode.
Full list of AT Commands
(AT commands can be upper or lower case, and also end with \r\n)

#1 : Test Command

Command Return Argument


AT OK NONE

#2 : Reset

Command Return Argument


AT+RESET OK NONE
Results: It works as power cycle.

#3: Poll the software version

Command Return Argument


AT+VERSION? +VERSION:<Param Param: software version
OK
Example:
at+version?\r\n
+VERSION:1.0-20090818
OK

#4: Restore the default setting

Command Return Argument


AT+ORGL OK NONE
Restore the default setting:
1. Device class: 0
2. Inquiry code: 0x009e8b33
3. Device mode: Slave mode
4. Binding mode: SPP
5. Serial port: 38400 bits/s; 1 stop bit, no parity
6. Pairing code: “1234”
7. Device name: “HHW-SPP-1800-2
#5: Poll the address of the Bluetooth device

Command Return Argument


AT+ADDR? +ADDR: <Param> Param: the address of the
OK Bluetooth device

Representation of the address: NAP:UAP:LAP (HEX)


Examples:
The address of the Bluetooth device is: 12:34:56:ab:cd:ef

At+addr?\r\n
+ADDR:1234:56:abcdef
OK

#6: Set and poll device name

Command Return Argument


AT+NAME=<Para1> OK Param: device name
AT+NAME? 1: +NAME: <Param> Default: “HHW-SPP-1800-
OK --- successful 2”
2: FAIL --- fail

Example:

AT+NAME=HHW-SPP-1800-2\r\n ————— Set Device name as HHW-SPP-1800-2

OK

AT + NAME=“HHW-SPP-1800-2”\r\n ————— Set Device name as HHW-SPP-1800-2

OK

at+name?\r\n

+NAME: Beijin

OK
#7: Poll remote device name

Command Return Argument


AT+RNAME? <Param1> 1: +RNAME: <Param2 > Param1: remote device address
OK --- successful Param2: remote device name
2: FAIL --- fail
Representation of the address: NAP:UAP:LAP (HEX)
Examples:
The address of the remote Bluetooth device is: 00:02:72:od:22:24, the device name is:
Bluetooth

t+rname? 0002,72,0d2224\r\n
+RNAMELBluetooth
OK

#8: Set/Poll device role

Command Return Argument


AT+ROLE= <Param> OK Param:
0 – slave
1 – Master
2 – Slave-loop
Default: 0
AT+ROLE? +ROLE: <Param >
OK
Explanation of device roles:
Slave – be connected by other device
Slave-loop – be connected by other device, receive and send back whatever received
Master – Actively poll the nearby device and initialize binding to other devices.

#9: Set and poll device type

Command Return Argument


AT+CLASS=<Param> OK Param: device type
Device type is a 32-bit
parameter. It is used to indicate
the device class and the service
1. +CLASS: <Param>
it supports
AT+CLASS? OK
Default: 0
2. FAIL
The actual meaning is explained
in appendix 1.

In order the effectively filter the nearby device and quickly locate the users self defined
device, user can set the device to be nonstandard device, such as 0x1f1f (hex)
#10: Set/Poll Inquire Access Code

Command Return Argument


AT+IAC=<Param> 1: OK Param: Inquire Access Code
2: FAIL Default: 938b33
AT+IAC? +IAC: <Param>
OK Detailed explanation can be found
the appendix.

If the inquire access code is set to GIAC(General Inquire Access Code: 0x9e8b33), it can be
used to discover or be discovered by all nearby devices. If user wants the device to be able
to be found quickly, user can set the Inquire Access Code to be code not as GIAC and LIAC,
such as 0x928b3f.

Example:
AT+IAC=928b3f\r\n
OK
AT+IAC?\r\n
+ IAC: 928b3f
OK

#11: Set and poll Inquiry mode

Command Return Argument


AT+INQM=<Param1>, <Param2>, 1. OK Param1: Inquiry Mode
<Param3> 2. FAIL 0— inquirey mode
standard
1— inquiry mode rssi
Param2: max response
+INQM: <Param1>,
number
AT+INQM? <Param2>,<Param3>
Param3: time out, 1-48
OK
(1.28s-61.44s)

Default: 1,1,48

AT+INQM=1,9,48\r\n -- Set inquiry mode: with RSSI, max device response number 9 then
stop inquiry, max time out 48X1.28=61.44s
OK
AT+INQM?\r\n
+INQM:1,9,48
OK
#12: Set and poll paring password

Command Return Argument


AT+PSWD=<Param> OK Param: paring password
+PSWD:<Param
AT+PSWD?
> OK Default: “1234”

#14: Set and poll serial port parameters

Command Return Argument


AT+UART=<Param1>,<Param2>, OK Param1: baud rate (bits/s)
<Param3> 4800
9600
19200
38400
57600
115200
230400
460800
912600
+UART:<Param1>,<Param2>,<
1382400
AT+UART? Param3>
Param2: stop bit
OK
0- 1 bit
1- 2 bits
Param3: parity bit
0- None
1- Odd
2- Even

Default: 9600,0,0

Example: Set serial port parameters to 115200, 2 bits stop bit, and even parity

AT+UART=115200, 1,2 \r\n

OK

AT+UART

+UART:115200,1,2

OK
#14: Set and poll connection mode

Command Return Argument


AT+CMODE=<Param> OK Param:
0 – specific address mode
(the address is specified in
+CMODE::<Param> binding command)
AT+CMODE?
OK 2- No specific address

Default: 0

#15: Set and poll binding device address

Command Return Argument


AT+BIND=<Para1> OK Param – Binding Bluetooth
device address
+BIND:<Param>
AT+BIND?
OK Default address:
00:00:00:00:00:00

The address can be represented as NAP:UAP:LAP (hex)


The binding command is only valid in specific address mode.

Example:
AT+BIND=1234,56,abcdef\r\n
OK
AT+BIND?\r\n
+BIND:1234:56:abcdef
OK

#16: Set/Poll the polarity of LED indicator driver

Command Return Argument


AT+POLAR=<Param1>, <Param2> OK Param1:
AT+DEFAULT 0 – PI08 outputs low level to turn
on LED
1- PI08 outputs high level to turn
on LED

Param2:
0-PI09 outputs low level to turn on
LED
1-PI09 outputs high level to turn on
LED

Default: 1,1
PI08 drives the working status, and PI09 drives the link status.

Example:
PI08 outputs low level to turn on LED, and PI09 outputs high level to turn on LED.
AT+POLAR=0,1 \r\n
OK
AT+POLAR?\r\n
+POLAR:0,1
OK

#17: Set single PIO output

Command Return Argument


AT+PIO=<Param1>,<Param2> OK Param1: PIO port number
(decimal)
Param2L PIO port output
0- Low voltage
1- High voltage

The useable port is PIO2- PIO7 and PIO10.

Example:
1. PIO10 outputs high level
AT+PIO=10,1\r\n
OK
2. PIO10 outputs low level
AT+PIO=10,0\r\n
OK

#18: Set multiple port output

Command Return Argument


AT+MPIO=<Param> OK Param: PIO port number
mask combination (hex)

The useable port is PIO2- PIO7 and PIO10.


PIO port mask = (1 << port number)
PIO port mask combination = ( PIO port mask 1| PIO port mask 2 |PIO port mask 3 |…)

Example:
PIO2 mask= (1<<2)=0x004
PIO10 mask = (1<<10)=0x400
PIO port mask combination= (0x004 | 0x400)=0x404
PIO 2 and PIO 10 output high:
AT+MPIO=404\r\n
OK
#19: Poll PIO port input

Command Return Argument


AT+MPIO? +MPIO: <Param> Param- PIO port value (16
OK bits)
Param[0]=PIO0
Param[1]=PIO1
Paramp2]=PIO2

Param[10]=PIO10
Param[11]=PIO11

#20:Set/Poll Inquiry parameters

Command Return Argument


AT+IPSCAN=<Param1>,<Param2>, OK Param1: inquiry time interval
<Param3>, <Param4> Param2:continous poll time
AT+IPSCAN? +IPSCAN:<Param1>, Param3: call time interval
<Param2>,<Param3>,<P Param4: call continuous time
aram4> All above are decimal numbers

Default: 1024, 512, 1024, 512

#21:Set/Poll SNIFF energy saving parameters

Command Return Argument


AT+SNIFF=<Param1>,<Param2>,< OK Param1: max time
Param3>,<Param4> Param2: min time
AT+SNIFF? +SNIFF:<Param1>,<Param2>,< Param3: try time
Param3>,<Param4> Param4: time out

All above are decimal


numbers

Default: 0,0,0,0
#22: Set/Poll Security and Encryption modes

Command Return Argument


AT+SENM=<Param1>,<Param2> 1: OK Param1: Security mode
2:FAIL 0- Sec_mode0_off
AT+SENM? +SENM:<Param1>,<Par 1- Sec_mode1_non-secure
am2> 2- Sec_mode2_service
OK 3- Sec_mode3_link
4- Sec_mod_unknown
Param2:encryption mode
0- hci_enc_mode_off
1- hci_enc_mode_pt_to_pt
2- hci_enc_mode_pt_to_pt_
and_bcast

Default: 0,0

#23: Delete Authenticated Device from the authenticated device list

Command Return Argument


AT+RMSAD=<Param> OK Param: Bluetooth device
address

Example:
Delete device with address: 12:34:56:ab:cd:ef
at+rmsad=1234:56:abcdef\r\n
OK

Or
at+rmsad=1234:56:abcdef\r\n
FAIL ==== there is no such device in the list

#24: Delete all Authenticated Devices from the authenticated device list

Command Return Argument


AT+RMSAD OK None
#25: Locate Authenticated Device from the authenticated device list

Command Return Argument


AT+FSAD=<Param> 1. OK - exists Param: Bluetooth device
2. FAIL- no-exisit address

Example:
Finddevice with address: 12:34:56:ab:cd:ef
at+FSAD=1234:56:abcdef\r\n
OK

Or
at+fsad=1234:56:abcdef\r\n
FAIL ==== there is no such device in the list

#26: Obtain the total Authenticated Device number in the authenticated device list

Command Return Argument


AT+ADCN?=<Param> +ADCN:<Param> Param: total number of device in
OK the authenticated device list

#27: Obtain the most recently used Authenticated Device

Command Return Argument


AT+MRAD? +MRAD:<Param> Param: most recently used
authenticated device

#28: Obtain the working status of the Bluetooth device

Command Return Argument


AT+STATE? +STATE:<Param> Param: working status
OK “INITIALIZED”
“READY”
“PAIRABLE”
“PAIRD”
“INQUIRING”
“CONNECTING”
“CONNECTED”
“DISCONNECTED”
“NUKNOW”
#29: Initialise the spp profile lib

Command Return Argument


AT+INIT 1. OK NONE
2. FAIL

#30: Inquire nearby devices

Command Return Argument


AT+INQ +INQ: Param1: address
<Param1>,<Param2>,<Param3> Param2: device class
…. Param3: RSSI
OK

Example 1:
at+init\r\n —— Initialize SPP (can’t repeatedly initialize)
OK
at+iac=9e8b33\r\n ——inquire general inquire access code
OK
at+class=0\r\n —— inquire all devices types
OK
at+inqm=1,9,48\r\n —— Inquire mode: RSSI, max number 9, timeout 48
At+inq\r\n —— inquire
+INQ:2:72:D2224,3E0104,FFBC
+INQ:1234:56:0,1F1F,FFC1
+INQ:1234:56:0,1F1F,FFC0
+INQ:1234:56:0,1F1F,FFC1
+INQ:2:72:D2224,3E0104,FFAD
+INQ:1234:56:0,1F1F,FFBE
+INQ:1234:56:0,1F1F,FFC2
+INQ:1234:56:0,1F1F,FFBE
+INQ:2:72:D2224,3E0104,FFBC
OK

#31: Cancel Inquire nearby devices

Command Return Argument


AT+INQC OK None
#32: Device pairing

Command Return Argument


AT+PAIR=<Param1>,<Param2> 1. OK Param1: remote device address
2. FAIL Param2:timeout
Example:
Pair with remote device: 12:34:56:ab:cd:ef, timeout 20 s.
At+pair=1234,56,abcdef, 20\r\n
OK

#33: Device Connection

Command Return Argument


AT+LINK=<Param> 1. OK Param: remote device address
2. FAIL
Example:
Link to remote device: 12:34:56:ab:cd:ef
At+fsad=1234,56,abcdef\r\n -- check if remote device is in the authenticated device list or
not
OK
At+link==1234,56,abcdef\r\n -- it is in the list, doesn’t need to be inquired and can be
directly linked
OK
#34: Device Disconnection

Command Return Argument


AT+DISC 1. +DISC: SUCCESS None
2. +DISC:LINK_LOSS
3. +DISC:NO_SLC
4. +DISC:TIMEOUT
5. +DICS:ERROR
#35: Enter into energy saving mode

Command Return Argument


AT+ENSNIFF=<Param> OK Param: Bluetooth device address

#36: Exit energy saving mode

Command Return Argument


AT+EXSNIFF=<Param> OK Param: Bluetooth device address
Appendix 1: AT command error

ERROR code decoder


Error_code (hex) Explanation
0 AT command error
1 The result is default value
2 PSKEY write error
3 Device name is too long (more than 32
bytes)
4 Device name is 0 byte
5 Bluetooth address: NAP is too long
6 Bluetooth address: UAP is too long
7 Bluetooth address: LAP is too long
8 PIO port mask length is 0
9 Invalid PIO port
A Device class is 0 byte
B Device class is too long
C Inquire Access Code length is 0
D Inquire Access Code is too long
E Invalid Inquire Access Code
F Pairing password is 0
10 Pairing password is too long (more than 16
bytes)
11 Role of module is invalid
12 Baud rate is invalid
13 Stop bit is invalid
14 Parity bit is invalid
15 No device in the pairing list
16 SPP is not initialized
17 SPP is repeatedly initialized
18 Invalid inquiry mode
19 Inquiry timeout
1A Address is 0
1B Invalid security mode
1C Invalid encryption mode
Appendix 2: Device Class

The Class of Device/Service(CoD)is a 32 bits number that is made of 3 fields. One field
specifies the service supported by the device. Another field specifies the major device
class, which broadly corresponds to the type of the device. The third field specifies the
minor device class, which describes the device type in more detail.

The Class of Device/Service (CoD) field has a variable format. The format is indicated
using the 'Format Type field' within the CoD. The length of the Format Type field is
variable and ends with two bits different from '11'. The version field starts at the least
significant bit of the CoD and may extend upwards. In the 'format #1' of the CoD
(Format Type field = 00), 11 bits are assigned as a bit-mask (multiple bits can be set)
each bit corresponding to a high level generic category of service class. Currently 7
categories are defined. These are primarily of a 'public service' nature. The remaining 11
bits are used to indicate device type category and other device-specific
characteristics.Any reserved but otherwise unassigned bits, such as in the Major Service
Class field, should be set to 0.

Figure 1.2: The Class of Device/Service field (first format type). Please note the order in
which the octets are sent on the air and stored in memory. Bit number 0 is sent first on
the air.
1. MAJOR SERVICE CLASSES

Bit no Major Service Class


13 Limited Discoverable Mode [Ref #1]
14 (reserved)
15 (reserved)
16 Positioning (Location identification)
17 Networking (LAN, Ad hoc, ...)
18 Rendering (Printing, Speaker, ...)
19 Capturing (Scanner, Microphone, ...)
20 Object Transfer (v-Inbox, v-Folder, ...)
21 Audio (Speaker, Microphone, Headset
service, ...)
22 Telephony (Cordless telephony, Modem,
Headset service, ...)
23 Information (WEB-server, WAP-
server, ...)
TABLE 1.2: MAJOR SERVICE

CLASSES [Ref #1 As defined in See Generic Access Profile,

Bluetooth SIG]

2. MAJOR DEVICE CLASSES

The Major Class segment is the highest level of granularity for defining a Bluetooth Device.
The main function of a device is used to determine the major class grouping. There are 32
different possible major classes. The assignment of this Major Class field is defined in
Table 1.3.

12 11 10 9 8 Major Device Class


0 0 0 0 0 Miscellaneous [Ref #2]
0 0 0 0 1 Computer (desktop,notebook, PDA, organizers, .... )
0 0 0 1 0 Phone (cellular, cordless, payphone, modem, ...)
0 0 0 1 1 LAN /Network Access point
0 0 1 0 0 Audio/Video (headset,speaker,stereo, video display,
vcr.....
0 0 1 0 1 Peripheral (mouse, joystick, keyboards, ..... )
0 0 1 1 0 Imaging (printing, scanner, camera, display, ...)
1 1 1 1 1 Uncategorized, specific device code not specified
X X X X X All other values reserved
TABLE 1.3: MAJOR DEVICE CLASSES

[Ref #2: Used where a more specific Major Device Class code is not suited (but only as
specified in this document). Devices that do not have a major class code assigned can use
the all-1 code until 'classified']
3. THE MINOR DEVICE CLASS FIELD

The 'Minor Device Class field' (bits 7 to 2 in the CoD), are to be interpreted only in
the context of the Major Device Class (but independent of the Service Class field).
Thus the meaning of the bits may change, depending on the value of the 'Major
Device Class field'. When the Minor Device Class field indicates a device class, then
the primary device class should be reported, e.g. a cellular phone that can also work
as a cordless handset should use 'Cellular' in the minor device class field.

4. MINOR DEVICE CLASS FIELD - COMPUTER MAJOR CLASS

7 6 5 4 3 2 Minor Device Class bit no of CoD


0 0 0 0 0 0 Uncategorized, code for device not assigned
0 0 0 0 0 1 Desktop workstation
0 0 0 0 1 0 Server-class computer
0 0 0 0 1 1 Laptop
0 0 0 1 0 0 Handheld PC/PDA (clam shell)
0 0 0 1 0 1 Palm sized PC/PDA
0 0 0 1 1 0 Wearable computer (Watch sized)
X X X X X X All other values reserved

TABLE 1.4: SUB DEVICE CLASS FIELD FOR THE 'COMPUTER' MAJOR CLASS

5. MINOR DEVICE CLASS FIELD - PHONE MAJOR CLASS

7 6 5 4 3 2 Minor Device Class bit no of CoD


0 0 0 0 0 0 Uncategorized, code for device not assigned
0 0 0 0 0 1 Cellular
0 0 0 0 1 0 Cordless
0 0 0 0 1 1 Smart phone
0 0 0 1 0 0 Wired modem or voice gateway
0 0 0 1 0 1 Common ISDN Access
0 0 0 1 1 0 Sim Card Reader
X X X X X X All other values reserved

6. MINOR DEVICE CLASS FIELD - LAN/NETWORK ACCESS POINT MAJOR CLASS

7 6 5 Minor Device Class bit no of CoD


0 0 0 Fully available
0 0 1 1 - 17% utilized
0 1 0 17 - 33% utilized
0 1 1 33 - 50% utilized
1 0 0 50 - 67% utilized
1 0 1 67 - 83% utilized
1 1 0 83 - 99% utilized
1 1 1 No service available [REF #3]
X X X All other values reserved

TABLE 1.6: THE LAN/NETWORK ACCESS POINT LOAD FACTOR FIELD

[Ref #3: "Device is fully utilized and cannot accept additional connections at this
time, please retry later"]
The exact loading formula is not standardized. It is up to each LAN/Network Access
Point implementation to determine what internal conditions to report as a
utilization percentage. The only requirement is that the number reflects an ever-
increasing utilization of communication resources within the box. As a
recommendation, a client that locates multiple LAN/Network Access Points should
attempt to connect to the one reporting the lowest load.

4 3 2 Minor Device Class bit no of CoD


0 0 0 Uncategorized (use this value if no other apply)
X X X All other values reserved

TABLE 1.7: RESERVED SUB-FIELD FOR THE LAN/NETWORK ACCESS POINT

7. MINOR DEVICE CLASS FIELD - AUDIO/VIDEO MAJOR CLASS

7 6 5 4 3 2 Minor Device Class bit no of CoD


0 0 0 0 0 0 Uncategorized, code for device not assigned
0 0 0 0 0 1 Device conforms to the Headset profile
0 0 0 0 1 0 Hands-free
0 0 0 0 1 1 (Reserved)
0 0 0 1 0 0 Microphone
0 0 0 1 0 1 Loudspeaker
0 0 0 1 1 0 Headphones
0 0 0 1 1 1 Portable Audio
0 0 1 0 0 0 Car audio
0 0 1 0 0 1 Set-top box
0 0 1 0 1 0 HiFi Audio Device
0 0 1 0 1 1 VCR
0 0 1 1 0 0 Video Camera
0 0 1 1 0 1 Camcorder
0 0 1 1 1 0 Video Monitor
0 0 1 1 1 1 Video Display and Loudspeaker
0 1 0 0 0 0 Video Conferencing
0 1 0 0 0 1 (Reserved)
0 1 0 0 1 0 Gaming/Toy [Ref #4]
X X X X X X All other values reserved

[Ref #4: Only to be used with a Gaming/Toy device that makes audio/video
capabilities available via Bluetooth]
TABLE 1.8: SUB DEVICE CLASSES FOR THE 'AUDIO/VIDEO' MAJOR CLASS

8. MINOR DEVICE CLASS FIELD - PERIPHERAL MAJOR CLASS

7 6 Minor Device Class bit no of CoD


0 1 Keyboard
1 0 Pointing device
1 1 Combo keyboard/pointing device
X X All other values reserved

TABLE 1.9: THE PERIPHERAL MAJOR CLASS KEYBOARD/POINTING DEVICE FIELD

Bits 6 and 7 independently specify mouse, keyboard or combo mouse/keyboard


devices. These may be combined with the lower bits in a multifunctional device.

5 4 3 2 Minor Device Class bit no of CoD


0 0 0 0 Uncategorized device
0 0 0 1 Joystick
0 0 1 0 Gamepad
0 0 1 1 Remote control
0 1 0 0 Sensing device
0 1 0 1 Digitizer tablet
X X X X All other values reserved

TABLE 1.10: RESERVED SUB-FIELD FOR THE DEVICE TYPE

9. MINOR DEVICE CLASS FIELD - IMAGING MAJOR CLASS


7 6 5 4 Minor Device Class bit no of CoD
X X X 1 Display
X X 1 X Camera
X 1 X X Scanner
1 X X X Printer
X X X X All other values reserved

TABLE 1.11: THE IMAGING MAJOR CLASS BITS 4 TO 7

Bits 4 to 7 independantly specify display, camera, scanner or printer. These may be


combined in a multifunctional device.

3 2 Minor Device Class bit no of CoD


0 0 Uncategorized, default
X X All other values reserved

TABLE 1.12: THE IMAGING MAJOR CLASS BITS 2 AND 3

Bits 2 and 3 are reserved


Appendix 3 The Inquiry Access Codes

The General- and Device-Specific Inquiry Access Codes (DIACs)

The Inquiry Access Code is the first level of filtering when finding Bluetooth devices and
services. The main purpose of defining multiple IACs is to limit the number of responses
that are received when scanning devices within range.

0. 0x9E8B33 —— General/Unlimited Inquiry Access Code (GIAC)

1. 0x9E8B00 —— Limited Dedicated Inquiry Access Code (LIAC)

2. 0x9E8B01 ~ 0x9E8B32 RESERVED FOR FUTURE USE

3. 0x9E8B34 ~ 0x9E8B3F RESERVED FOR FUTURE USE

The Limited Inquiry Access Code (LIAC) is only intended to be used for limited time periods
in scenarios where both sides have been explicitly caused to enter this state, usually by user
action. For further explanation of the use of the LIAC, please refer to the Generic Access
profile.

In contrast it is allowed to be continuously scanning for the General Inquiry Access Code
(GIAC) and respond whenever inquired.
Tema 9
Pantalla LCD

1.- Introducción___________________________________________________

Una pantalla LCD es un dispositivo diseñado para mostrar información de forma


gráfica. LCD significa Liquid Crystal Display (pantalla de cristal líquido). Funciona
modificando la luz que lo incide: dependiendo de la polarización que se esté
aplicando, la pantalla LCD reflejará o absorberá la luz en determinadas zonas.
Cuando un segmento de la pantalla reciba la tensión de polarización adecuada no
reflejará la luz y por tanto aparecerá en esa zona del dispositivo un segmento oscuro.

El líquido de una pantalla LCD está entre dos placas de vidrio paralelas con una
separación de unos micrones. Estas placas de vidrio tienen unos electrodos especiales
que definen, con su forma, los símbolos, caracteres, etc. que se visualizarán.

La superficie del vidrio que hace contacto con el líquido es tratada de manera que
induzca la alineación de los cristales en dirección paralela a las placas. Esta alineación
permite el paso de la luz incidente sin ninguna alteración.

Cuando se aplica la polarización adecuada entre los electrodos, aparece un campo


eléctrico entre estos electrodos (campo que es perpendicular a las placas) y esto causa
que las moléculas del líquido se agrupen en sentido paralelo a este (el campo eléctrico),
no dejando pasar la luz que viene reflejada, provocando que aparezca una zona
oscura sobre un fondo claro (contraste positivo). De esta manera aparece la
información que se desea mostrar.

Por tanto, los LCD son visualizadores pasivos. Esto significa que no emiten luz como
una pantalla de 7 segmentos hecha con un conjunto de diodos LED. Por esa razón la
pantalla LCD tiene muy bajo consumo de energía.
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

2.- Partes de una pantalla LCD______________________________________

La siguiente gráfica muestra los diferentes elementos que componen una pantalla de
cristal líquido:

1. Film de filtro vertical para polarizar la luz que entra.


2. Substrato de vidrio con electrodos de Óxido de Indio. Las formas de los
electrodos determinan las formas negras que aparecen cuando la pantalla se
enciende y apaga.
3. Cristal líquido.
4. Substrato de vidrio con film electrodo común con los cantos horizontales para
alinearse con el filtro horizontal.
5. Film de filtro horizontal para bloquear/permitir el paso de luz.
6. Superficie reflectante para enviar devolver la luz al espectador. En un LCD
retroiluminado, esta capa es reemplazada por una fuente luminosa.

3.- Tipos de pantallas LCD__________________________________________

A la hora de clasificar las pantallas LCD, podemos hacerlo en base a dos criterios: su
tamaño y su iluminación.

 Tamaño:

El tamaño viene definido por el número de filas y columnas de que dispone la pantalla.
Las pantallas más habituales son de 2x16 (2 filas y 16 columnas), aunque las hay de
muchos tamaños diferentes, incluso de 4x80.

Pantalla de 1x16

2
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Pantalla de 2x16 Pantalla de 4x16

La pantalla de cristal líquido con la que vamos a trabajar es una pantalla estándar que
dispone de 2 filas de 16 caracteres cada una, y cada carácter dispone de una matriz de
5x7 puntos (pixeles). Es importante tener en cuenta que, aunque esta pantalla sólo puede
mostrar 16 caracteres en una fila, realmente cada fila tiene una memoria de 40
caracteres, por lo que se pueden escribir mensajes con más de 16 caracteres,
desplazando después la pantalla por software para mostrar todo el mensaje.

 Iluminación:

A este respecto podemos distinguir dos tipos de pantallas LCD:

 Sin retroiluminación: la propia pantalla no emite ninguna luz. Para visualizar los
caracteres usa la propia luz ambiente, que es reflejada por el fondo de la pantalla
excepto en aquellos lugares en los que el cristal líquido ha sido polarizado, dibujando
así las formas de los caracteres. Por tanto, en ausencia de luz externa, es imposible
ver el mensaje de la pantalla. Como ventaja, su consumo se mínimo, ya que no emite
luz.

 Con retroiluminación: estas pantallas emiten una luz, generada normalmente con
diodos situados en la parte trasera de la pantalla, lo que permite ver el mensaje
mostrado incluso en condiciones de total oscuridad. Como desventaja, como es
normal, presentan un consumo mayor que las pantallas sin retroiluminación.

Pantalla LCD sin retroiluminación Pantalla LCD sin retroiluminación

3
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

4.- El controlador Hitachi HD44780__________________________________

Manejar una pantalla LCD directamente desde un microcontrolador sería prácticamente


imposible, ya que el microcontrolador debería enviar la tensión adecuada a cada uno de
los pixeles que componen la pantalla, que son muchísimos. Por eso todas las pantallas
incorporan en su parte trasera un controlador específico que se encarga de
realizar esta tarea. Por tanto, el microcontrolador tan sólo tendrá que comunicarse con
el controlador de la pantalla e indicarle qué mensaje quiere representar.

La mayoría de pantallas LCD utiliza para comunicarse con el “exterior” el


controlador HD44780 de la empresa Hitachi. Esto hace posible que prácticamente
con las mismas instrucciones podamos manejar desde una sencilla pantalla de una línea
de 16 caracteres hasta una de 4 líneas y 80 caracteres por línea.

Las imágenes superiores muestran el aspecto de la parte trasera de dos pantallas LCD.
En ambos casos se observan dos circuitos integrados. Uno de ellos es el controlador de
la pantalla (El HD44780 de Hitachi u otro compatible), mientras que el otro es una
memoria EEPROM donde vienen almacenados los caracteres que puede representar la
pantalla. Se trata de 240 caracteres ASCII ya predefinidos (letras mayúsculas,
minúsculas, signos de puntuación, números, etc), junto con 8 caracteres definibles por el
usuario vía software.

5.- Distribución de pines de una pantalla LCD__________________________

La gran mayoría de las pantallas existentes en el mercado están basadas en el mismo


controlador de Hitachi y por tanto respetan la misma distribución de pines. De todas
formas, antes de conectar nada, debemos asegurarnos de que así sea, para no dañar de
forma permanente el LCD.

Las pantallas LCD pueden ser de 14 pines (en caso de que no dispongan de
retroiluminación), o de 16 pines (si disponen de retroiluminación).

La siguiente gráfica muestra la distribución habitual de los pines de una pantalla LCD:

4
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Veamos qué función cumple cada uno de los pines de la pantalla:

• Pines 1,2 y 3: Estos pines están dedicados a la alimentación y contraste del


LCD.

Pin 1 – GND Se debe conectar a masa


Pin 2 – VCC Se debe conectar a alimentación
Pin 3 - VEE Permite el ajuste del contraste de la pantalla

El pin 3 permite el ajuste del contraste de la pantalla. Se puede unir al pin 1


mediante una resistencia de 220 ohmios para obtener un contraste adecuado (pero fijo) o
bien utilizar un potenciómetro de 10 KOhm para variar el contraste a gusto, tal y
como se muestra en la siguiente imagen:

Conexión de un potenciómetro para variar el contraste

5
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

• Pines 4, 5, 6: Estos pines son los que controlan el funcionamiento de la pantalla.

Pin 4 – RS Indica al controlador interno del LCD que el valor presente en el bus
de datos es un comando o bien un carácter para representar
RS = 0  Comando
RS = 1  Datos
Pin 5 – RW Permite decidir si queremos enviar datos a la pantalla o bien nos
interesa leer lo que la pantalla tiene en su memoria o conocer su estado.
RW = 0  El módulo LCD es escrito
RW = 1  El módulo LCD es leído
Pin 6 - E Señal de activación del módulo LCD:
E = 0  Módulo desconectado
E = 1  Módulo habilitado

• Pines 7, 8, 9, 10, 11, 12, 13, 14: Estos ocho pines son el “bus de datos” del
controlador de la pantalla. Llamados DB0-DB7, son los encargados de recibir (o
enviar) los comandos o datos desde o hacia la pantalla.

Esto quiere decir que, en principio, para establecer la comunicación entre el


microcontrolador y la pantalla serían necesarias 11 líneas de entrada/salida: 3 para las
líneas de control y 8 para las de datos. Esto sin duda es un número muy elevado,
teniendo en cuenta que, por ejemplo, la placa Arduino UNO dispone únicamente de 14
líneas de entrada/salida digitales.

Afortunadamente estas pantallas soportan dos modos de comunicación para el bus de


datos: uno de 8 bits, en el que se usan todas las líneas de datos (DB0-DB7), y otro de
4 bits, en el que solo se usan las líneas DB4-DB7, enviando los datos en dos pasos
sucesivos. Este último modo supone un ahorro de 4 pines en el bus de datos, algo muy
importante en microcontroladores con pocas líneas de E/S, como es el caso de Arduino
UNO.

• Pines 15 y 16: estos pines solo aparecen en las pantallas que disponen de
retroiluminación, y se utilizan para alimentar los LEDs del fondo de la
pantalla que proporcionan la retroiluminación. El pin 15 debe ser conectado
a 5 voltios y el 16 a masa. En estas condiciones, la luz de fondo estaría
encendida al 100% de su intensidad. Nuevamente, se puede utilizar un
potenciómetro para ajustar el brillo.

6
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

6.- Manejo de la pantalla LCD con Arduino____________________________

6.1.- Conexión hardware_________________________________________________

A continuación analizaremos la forma de conectar una pantalla LCD con nuestro


Arduino UNO. La conexión mostrada aquí es la más sencilla posible, pero válida
para la gran mayoría de aplicaciones. Utiliza el modo de comunicación de 4 bits, y no
permite ni el ajuste del contraste ni el del brillo. La siguiente tabla y su
correspondiente esquema muestran dichas conexiones. Se han utilizado los pines de
Arduino del 4 al 9, pero se podrían haber utilizado cualquieras otros de los digitales.

Nº pin Pin LCD Conexión


1 GND GND
2 VCC VCC
3 VEE VCC
4 RS 8 (Arduino)
5 RW GND
6 ENABLE 9 (Arduino)
7 DB0 No conect
8 DB1 No conect
9 DB2 No conect
10 DB3 No conect
11 DB4 4 (Arduino)
12 DB5 5 (Arduino)
13 DB6 6 (Arduino)
14 DB7 7 (Arduino)
15 Led+ VCC
16 Led- GND

7
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

6.2.- Control software: librería LiquidCrystal_______________________________

Controlar una pantalla LCD con Arduino es realmente fácil gracias a la librería
LiquidCrystal incorporada en el IDE de Arduino. Esta librería contiene una serie de
funciones que permiten escribir texto, borrar la pantalla, situar el cursor en la
posición deseada, etc, para cualquier pantalla LCD basada en el controlador
Hitachi HD44780 o compatible.

Para poder utilizar las funciones de la librería, en primer lugar es necesario incluir la
librería al principio del programa, antes de la función setup() de la siguiente forma:

En segundo lugar es necesario crear un objeto de la clase LiquidCrystal, indicando los


pines en los que hemos conectado la pantalla LCD. Para ello escribiremos el siguiente
código:

LiquidCrystal nombre(rs, enable, db4, db5, db6, db7)

donde:
 nombre es el nombre del objeto de tipo LiquidCrystal que crearemos. Podemos
usar el que queramos, por ejemplo lcd, milcd o cualquier otro.
 rs, enable, db4, db5, db6, db7 son el número de los pines de Arduino donde
conectamos cada uno de los pines de la pantalla LCD.

 Ejemplo:

Los pines de Arduino a los que conectemos la pantalla LCD pueden ser cualquiera de
los digitales.

8
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Una vez creado el objeto de clase LiquidCrystal, ya se pueden utilizar cualquiera de las
funciones de la librería. A continuación se describen las principales funciones de la
librería para el manejo de la pantalla LCD, separadas en dos grupos: funciones básicas y
funciones avanzadas.

6.3.- Funciones básicas de la librería LiquidCrystal___________________________

lcd.begin(columnas, filas)

Establece el tamaño de la pantalla LCD. El tamaño más habitual de este tipo de


pantallas es de 16x2. Es necesario llamar a esta función antes de poder usar el resto
de funciones de la librería. Por eso es lógico hacer la llamada de esta función al
principio de todo, en la función setup().

lcd.print(dato)

Escribe el dato indicado en la pantalla LCD en la posición en la que se encuentra el


cursor en ese momento. El dato puede ser una variable o una cadena de caracteres.
En este último caso, la cadena debe ir entre comillas.

lcd.print(dato, formato)

De forma opcional se puede añadir el formato en la función lcd.print(), en caso de que


se vaya a representar un número en la pantalla LCD.

Si el número es un entero, el formato indica la base en la que se representará: BIN


para binario; DEC para decimal (opción por defecto); OCT para octal y HEX para
hexadecimal.

Si se trata de un número en coma flotante (float), el formato indica el número de


decimales que se mostrarán en la pantalla. Por defecto se muestran 2 decimales.

9
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

lcd.clear()

Borra la pantalla y sitúa el cursor en la posición de inicio, que se corresponde con la


esquina superior izquierda de la pantalla.

lcd.setCursor(columna,fila)

Sitúa el cursor en la posición especificada por los parámetros columna y fila. La primera
columna de la izquierda es la 0 y la última es la 15. En cuanto a las filas, la superior es
la 0, y la inferior es la 1.

 Ejercicio resuelto:

Realiza un programa para que el microcontrolador de Arduino escriba en la pantalla


LCD el mensaje “Hola”.

10
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Ejercicios______________________________________________________________

1.- Modifica el programa anterior para que muestre por la pantalla LCD de forma
alternativa los mensajes “Hola” y “Adios”. Cada mensaje debe tener una duración de
2 segundos. Los mensajes deberán superponerse, es decir, cuando sale la palabra
"Adios", deberá desaparecer la palabra "Hola".

2.- Modifica el programa anterior para que la palabra “Hola” salga en el centro de la
primera línea y la palabra “Adios” en el centro de la segunda.

3.- Realiza un programa que muestre por la pantalla LCD un mensaje parpadeante.
Concretamente, la pantalla debe mostrar la frase “Mensaje parpadeo” durante un
segundo, y después debe estar en blanco durante otro segundo, repitiéndose este
proceso de forma indefinida.

4.- Realiza un programa que muestre por la primera línea de la pantalla LCD un
mensaje parpadeante y por la segunda línea un mensaje fijo. Concretamente, la
pantalla debe mostrar las frases “Esta SI parpadea” y “Esta NO parpadea”, cada una
en una línea diferente. La velocidad de parpadeo debe ser, como en el ejercicio
anterior, de 1 segundo.

5.- Realiza un programa en el que el microcontrolador de Arduino lea la temperatura y


la humedad proporcionada por el sensor DHT11 y muestre los valores leídos una
pantalla LCD con el siguiente formato:

TEMPERATURA: XX C
HUMEDAD: XX %

6.- Modifica el programa anterior para que Arduino genere una alarma sonora con un
zumbador cada vez que la temperatura supera los 25 grados.

7.- Modifica el programa anterior para que la alarma sonora pueda activarse o
desactivarse apretando un pulsador. Cada vez que se accione el pulsador, la alarma
cambiará de estado (activa/desactiva). Para indicar que la alarma está activa, la
pantalla LCD mostrará en su esquina inferior derecha el símbolo ‘*’. Si no se muestra
el símbolo, significará que la alarma está desactivada, y por tanto el zumbador no
pitará aunque la temperatura supere los 25 grados.

11
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

6.4.- Funciones avanzadas de la librería LiquidCrystal________________________

lcd.scrollDisplayRight()
Realiza el desplazamiento de la pantalla de una posición a la derecha.

lcd.scrollDisplayLeft()
Realiza el desplazamiento de la pantalla de una posición a la izquierda.

lcd.home()
Lleva el cursor a la esquina superior izquierda (sin borrar la pantalla).

lcd.cursor()
Provoca la aparición del cursor, que por defecto no aparece. El cursor se representa
como un guión bajo ( _ ).

lcd.noCursor()
Hace desaparecer el cursor. Solamente es necesario llamar a esta función si previamente
se ha llamado a la función lcd_cursor(), ya que por defecto el cursor no aparece.

lcd.blink()
Hace que el cursor aparezca parpadeando. En este caso el cursor no se representa como
un guión bajo, sino como un rectángulo ( █ ).

lcd.noBlink()
Hace que el cursor deje de parpadear y desaparezca. Solamente es necesario llamar a
esta función si previamente se ha llamado a la función lcd_blink(), ya que por defecto el
cursor no aparece.

lcd.leftToRight()
Determina el sentido de escritura de los caracteres de izquierda a derecha, es decir, el
sentido normal de escritura.

lcd.rightToLeft()
Determina el sentido de escritura de los caracteres de derecha a izquierda, es decir, el
sentido contrario al habitualmente utilizado.

lcd.autoscroll()
Activa la función de autoscroll, es decir, que la pantalla se desplace una posición cada
vez que se imprima un nuevo carácter.

lcd.noAutoscroll()
Desactiva la función de autoscroll.

12
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

lcd.display()
Enciende la pantalla LCD

lcd.noDisplay()
Apaga la pantalla LCD

 Ejercicio resuelto:

Realiza un programa para que el microcontrolador de Arduino controle la pantalla


LCD de la siguiente manera: inicialmente, aparecerá en el centro de la primera línea la
palabra "Pillame", que permanecerá hasta que el usuario accione un pulsador. En ese
momento, la frase comenzará a desplazarse hacia la izquierda de la pantalla hasta
desaparecer. Tras dos segundos, la palabra comenzará a aparecer por donde se había
ido, desplazándose hacia la derecha, hasta llegar a la posición inicial (centro de la
pantalla), momento en el que se detendrá a la espera de que el usuario vuelva a
accionar el pulsador. El tiempo de desplazamiento de cada carácter será de 100ms.

13
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Ejercicios______________________________________________________________

8.- Modifica el programa anterior para que el sentido del desplazamiento de la palabra
se pueda elegir mediante dos pulsadores. Si se acciona el primer pulsador, la palabra
se desplazará hacia la izquierda, como en el ejercicio anterior. Si se acciona el
segundo pulsador, la palabra de desplazará hacia la derecha.

9.- Modifica el ejercicio 8.6. de forma que el camino que siga la palabra "Pillame" una
vez accionado el pulsador sea más largo. En concreto, deberá ser el siguiente: la
palabra se irá desplazando hacia la izquierda hasta salirse por el lado izquierdo de la
pantalla. Dos segundos después volverá a aparecer por el lado izquierdo de la pantalla,
pero por la fila de abajo, e irá desplazándose hacia la derecha hasta salirse por
completo por el lado derecho de la pantalla. Dos segundos después comenzará a
aparecer por la fila superior del lado derecho, desplazándose hacia la izquierda, hasta
situarse en el centro de la fila superior, es decir, en el punto de partida.

10.- Realiza un programa que cambie el sentido de desplazamiento de un mensaje


(izquierda a derecha - derecha a izquierda) cada vez que se acciona un pulsador. La
velocidad de desplazamiento de cada carácter será de 250ms. El mensaje que se debe
mostrar es: “Mensaje en ambos sentidos”.

11.- Realiza un programa en el que se escriban dos frases en la pantalla LCD, una en
cada fila. En la primera fila aparecerá la frase "sentido normal", y en la segunda
aparecerá "sentido inverso". Las frases no se escribirán de golpe, sino letra a letra, con
un tiempo entre cada letra de 250ms. En la primera frase se utilizará el sentido normal
de escritura (de izquierda a derecha), mientras que en la segunda se empleará el orden
inverso (de derecha a izquierda). El cursor permanecerá activado todo el tiempo.
Cuando se terminen de escribir las dos frases, se borrará la pantalla y comenzará de
nuevo el proceso.

12.- Realiza un programa que muestre en la pantalla LCD el turno de una cola, de 1 a
99, incrementándose cada vez que se acciona un pulsador. En el centro de la primera
línea se visualizará el mensaje “SU TURNO”, mientras que en el centro de la segunda
línea aparecerá el turno actual. Cuando se pase del turno 99, se volverá a comenzar
por el turno 1. Además, se añadirá al sistema un zumbador, de forma que cada vez que
se cambie de turno, el zumbador sonará durante medio segundo.

13.- Realiza un programa que lleve a cabo la siguiente función: cada vez que se
accione un pulsador, se escribirá en la primera línea una letra del abecedario,
incrementándose desde la 'a' hasta la 'z'. Cuando se alcancen las primeras 16 letras, la
primera línea de la pantalla estará completa, por lo que, para poder ver la siguientes
letras, cada vez que se escriba una nueva letra la pantalla se desplazará una posición a
la izquierda. Cuando se llegue a la letra 'z', se borrará la pantalla y se empezará de
nuevo.

14
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

14.- Realiza un programa que lleve a cabo la siguiente función: cada vez que se
accione un pulsador, se escribirá en la primera línea una letra del abecedario,
incrementándose desde la 'a' hasta la 'z'. Cuando se alcancen las primeras 16 letras, la
primera línea de la pantalla estará completa, por lo que, para poder ver la siguientes
letras, se continuará escribiendo las letras en la segunda línea. Cuando se llegue a la
letra 'z', se borrará la pantalla y se empezará de nuevo.

15.- Realiza un programa para controlar el nivel de iluminación de una tira de LEDs
mediante dos pulsadores y un menú que aparecerá en la pantalla. Inicialmente
aparecerá el siguiente menú:

OFF 20% 40%


60% 80% MAX

Para indicar la elección escogida por el usuario se utilizará el cursor en modo


parpadeante, que se situará junto a la cifra elegida por el usuario. Inicialmente el
cursor se situará junto a la palabra OFF, y la tira de LEDs permanecerá apagada.
Cada vez que el usuario accione el pulsador 1, el cursor se desplazará a la siguiente
cifra, y cuando llegue al final (valor MAX) empezará de nuevo por el principio (OFF).
Cuando el usuario haya situado el cursor sobre el valor deseado, accionará el pulsador
2. En ese momento la tira de LEDs se encenderá con el nivel de iluminación indicado
por el usuario. El proceso se podrá repetir tantas veces como se desee.

16.- Modificar el ejercicio anterior para que en el menú aparezca la información del
nivel actual de iluminación. Para ello, cuando el usuario escoja un nivel de iluminación
determinado, aparecerá junto a la cifra elegida el símbolo '*', que se mantendrá en
dicha posición hasta que el usuario cambie el nivel de iluminación, momento en el que
el símbolo se situará junto al nuevo valor elegido.

17.- En el ejercicio 7 del tema 7 (sensores analógicos) realizaste un programa que


simulaba el sensor de aparcamiento de coche, con un sensor de distancia y un
zumbador. Modifica el programa de dicho ejercicio para añadir una pantalla LCD al
sensor de aparcamiento, de forma que se pueda visualizar de manera intuitiva la
información proporcionada por el sensor. El sistema funcionará de la siguiente forma:
para activar o descativar el sensor de aparcamiento se utilizará un pulsador. Cuando el
sensor de aparcamiento esté desactivado, no funcionará ni la pantalla LCD ni el
zumbador. Cuando el sensor de aparcamiento esté activado, el zumbador funcionará de
la misma manera que en el ejercicio 7.7, y en la pantalla LCD aparecerá la siguiente
información: en la primera línea se mostrará el mensaje "SENSOR ACTIVADO",
mientras que en la segunda aparecerá una especie de barra de nivel que irá
aumentando conforme la distancia al objeto sea menor, tal y como se muestra a
continuación:

15
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

distancia segunda línea


>50cm no se muestra nada
40cm-50cm ####
30cm-40cm ########
20cm-30cm ############
10cm-20cm ################

7.- LCDKeypad Shield____________________________________________

Aunque con Arduino podemos controlar cualquier pantalla LCD, existe una shield
especialmente diseñada para Arduino, conocida como LCDKeypad, donde además de la
pantalla disponemos de 6 pulsadores, un circuito de regulación de contraste con un
potenciómetro multivuelta y, como todas las shields, se integra sobre el Arduino
conectándose sin necesidad de cableado.

Panel frontal de la LCDKeypad shield

Conexión de la LCDKeypad shield con Arduino UNO

16
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Esta shield puede ser usada instalando la librería “LCDKeypad.h” en el directorio


correspondiente, aunque también se puede utilizar con la librería “Liquid Crystal”
integrada en el IDE de Arduino.

En la página siguiente se muestra el esquema electrónico de la shield:

Aunque la shield lleva muchas conexiones con Arduino, sólo utiliza las que se
enumeran en la siguiente tabla, dejando el resto libre para otros usos:

Pin Arduino Pin LCDKeypad shield


AN0 Botones
Digital 4 DB4
Digital 5 DB5
Digital 6 DB6
Digital 7 DB7
Digital 8 RS
Digital 9 ENABLE
Digital 10 Retroiluminación

Como se puede observar, esta shield utiliza 7 líneas de entrada/salida digitales y una
entrada analógica de Arduino. La entrada analógica se emplea para leer el estado de
los pulsadores con una única línea, utilizando para ello un divisor resistivo, tal y como
se muestra en el siguiente esquema:

17
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Cuando se accione uno de los pulsadores, aparecerá una tensión en el pin AN0 cuyo
valor dependerá del pulsador accionado. Por tanto, haciendo una lectura analógica
de dicho pin se puede determinar la identidad del pulsador accionado. Para ello,
teniendo en cuenta que el convertidor A/D de Arduino es de 10 bits y su valor máximo
es de 1023, podemos seguir la siguiente regla:

Valor leído en AN0 Pulsador accionado


>850 Ninguno
>650 y <850 Selección
>450 y <650 Izquierda
>250 y <450 Abajo
>50 y <250 Arriba
<50 Derecho

En la página siguiente se muestra un ejemplo en el que se lee el estado de los pulsadores


de la LCDShield y se muestra por pantalla el nombre del botón pulsado. Como se puede
observar, para averiguar la identidad del pulsador accionado se hace una lectura
analógica del canal AN0 y se compara el valor obtenido con los márgenes mostrados en
la tabla anterior.

18
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Por otra parte, el pin 10 de Arduino se conecta al pin de alimentación de la


retroiluminación de la LCD. Esto permite apagar o encender la retroiluminación por
software. Para encenderla hay que escribir un nivel alto en el pin 10, mientras que para
apagarla hay que escribir un nivel bajo.

En la página siguiente se muestra un ejemplo que cambia el estado de la


retroiluminación (apagada/encendida) cada vez que se acciona el pulsador SELECT.
Además, en la pantalla aparece el mensaje “RETROILUMINACIÓN APAGADA” o
“RETROILUMINACIÓN ENCENDIDA” según cada caso.

19
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

Por último, en la página siguiente se muestra el ejercicio resuelto de la página 13, pero
en esta ocasión adaptado a la LCDKeypad shield. Como se puede observar, la única
diferencia reside en la lectura del pulsador, que en esta ocasión se resuelve efectuando
una lectura analógica del pin AN0.

20
_________________Gonzalo Penalva Torregrosa y Marcos Benavent Pla__________________

21

También podría gustarte