Вы находитесь на странице: 1из 60

2016-17 PRIMEROS PASOS CON ARDUINO

PRIMEROS PASOS
CON ARDUINO

1 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Cuando comenzamos a trabajar con Arduino, parece que la cantidad de cosas que hay que
aprender es tan grande que parece inabordable. Necesitamos aprender conceptos de electricidad,
electrnica, programacin, algo de ingeniera. Y dependiendo de lo que quieras hacer, algo de
matemticas y mucha fsica.

Hemos diseado este itinerario pensando en la gente que como t, que probablemente tenga que
empezar desde el principio.

Por eso, estos primeros captulos esta pensados para irte llevando de la mano, en los conceptos
bsicos que vas a necesitar en la aventura que empiezas, e ir presentando todas las ideas
necesarias para ir siguiendo el curso en orden.

Iremos mezclando componentes electrnicos con la ley de Ohm e irn apareciendo las primeras
instrucciones de Arduino C++, con algunos programas y circuitos en los que haremos prcticas.

Las primeras sesiones de este tutorial estn pensadas para alguien que quiere iniciarse y cuyos
conocimientos en estos temas son nulos, pero que quiera aprender. Y creemos que si nos sigues
conseguirs ese objetivo. En ello hemos puesto todo nuestro empeo.

1 Instalacin del entorno de trabajo Arduino.


Empecemos por el principio. Descargando e instalando el entorno de trabajo IDE.
2 Nuestro primer programa.
Siempre hay una primera vez. Un programa muy sencillo y algunas ideas bsicas.
3 Nuestro primer circuito.
Un circuito para quitar el miedo. Un diodo LED en serie con una resistencia.
4 Circuito con mltiples LEDs.
Si funciona con un LED Porque no con 8 diodos LED?
5 Las entradas digitales de Arduino.
Los sentidos de Arduino. Percibiendo el exterior en formato digital.
6 Condicionales y botones.
Seguimos introduciendo instrucciones de C++ : Los condicionales.
7 Comunicacin con el exterior.
Los puertos USB en Arduino y la comunicacin serie.
8 Funciones y enteros.
Seguimos trabajando vuestro conocimiento de C++ jugando con nmeros primos como
excusa.
9 Un programa con varias funciones.
Sabemos que se est haciendo cuesta arriba. Animo, como en la bici hay tramos as.
10 Los salidas analgicas.
Las salidas analgicas PWM.
11 Los diodos LED RGB.
Un captulo divertido. O como mezclar colores con un LED RGB.
12 Arduino y las puertas analgicas.
Cmo usar las puertas analgicas para leer valores continuos del exterior.

2 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

1 INSTALACIN DEL ENTORNO


DE TRABAJO DE ARDUINO
Descargar y configurar el IDE.
1.1 OBJETIVOS

Descargar del entorno de trabajo IDE de Arduino.


Instalacin del entorno.
Comprobar su correcto funcionamiento .

1.2 DESCARGA E INSTALACIN DEL IDE ARDUINO.

Comenzaremos descargando e instalando el entorno de desarrollo de Arduino (IDE),y


comprobaremos que est correctamente configurado. Para ello vamos a la pgina de descarga:

http://arduino.cc/en/main/software

Y bajamos la versin ms reciente del IDE (Entorno de desarrollo de Arduino) Que a la fecha de
escribir los apuntes es la 1.6.9, suficientemente estable para usarla en condiciones normales.

Elegir la versin correspondiente a nuestro sistema (En Windows recomendamos la versin


Installer).

Una vez finalizado, ejecuta el fichero que acabas de descargar y respondiendo a las opciones de
instalacin. Aceptar las opciones por defecto de instalacin es una opcin razonable en caso de
no estar seguro de las preguntas que nos hace.

Al cabo de unos minutos finalizara la instalacin, y en el rea de trabajo del equipo


aparecer el icono de Arduino.

1.2 COMPROBACIN DE LA INSTALACIN.

Una vez instalado el IDE, vamos a comprobar que reconoce nuestra placa de Arduino
correctamente y que podemos programarlo. Para ello, Conecta tu Arduino a tu ordenador
mediante el cable USB.

Comprueba que las luces de la placa de Arduino se iluminan, esto indica que recibe alimentacin.

Al hacerlo nuestro PC debe detectar el nuevo dispositivo USB y montar el driver adecuado.

Y finalmente:

3 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Atencin, el puerto serie en que se instala en tu equipo puede variar del indicado en la imagen,
dependiendo de las caractersticas del equipo.

Ahora, ya podemos arrancar el programa desde el icono de Arduino que tenemos en el escritotio
de trabajo, configurar el modelo de placa de Arduino y el puerto serie al que est conecta la placa.
En Men\Herramientas\Placa deberemos elegir el modelo exacto de nuestra placa Arduino. En
nuestro caso elegimos un Arduino Uno:

En Men]\Herramientas\Port es necesario comprobar que tenemos asignado un puerto y que


tiene la marca de seleccin.

Es importante asignar el puerto y el modelo de Arduino para garantizar el correcto funcionamiento


del IDE. La marca de seleccin debe estar con el tick.

Volquemos ahora un programa de ejemplo para comprobar que podemos comunicarnos con la
placa que acabamos de seleccionar:

4 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Al pulsar Men\Archivo\Ejemplos\01.Basics\Blink, aparecer una serie de textos en el entorno


de trabajo, que ignoraremos por ahora. Pulsar el botn Marcado en amarillo, Veremos una lnea
de progreso verde avanzando.

Si todo va correctamente veremos un mensaje en la parte inferior del IDE:

5 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Este mensaje en color blanco indica que hemos volcado correctamente el programa y ya
deberamos ver una luz que parpadea en nuestra placa Arduino, tal como se indica en la figura
siguiente.

Si vemos el LED marcado como L parpadeando en nuestro Arduino, enhorabuena, el entorno est
instalado y configurado correctamente. Ya podemos pasar a la siguiente sesin.

6 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

2 NUESTRO PRIMER
PROGRAMA
Blinking LED.
2.1 OBJETIVOS.

Fijar algunas ideas bsicas sobre programacin.


Comprender la estructura de un programa Arduino (Sketch).
Definir las estructuras de bloques.
Las primeras instrucciones.

2.2 MATERIAL REQUERIDO.

Arduino Uno o similar.


CableUSB, un cable USB adecuado al conector de tu Arduino.
PC, un PC con el entorno de Arduino correctamente instalado y configurado.

2.3 ALGUNAS IDEAS BSICAS SOBRE PROGRAMACIN.

Un programa de ordenador es bsicamente el equivalente a una receta de cocina, pero destinado


a un pblico distinto.

Mientras que las personas somos razonablemente buenas interpretando las vagas instrucciones
de una receta de cocina, cuando programamos, quien debe entendernos es un ordenador que
espera instrucciones precisas respecto a lo que debe hacer y que por otro lado carece por
completo de la imaginacin o capacidad de improvisacin que posen los humanos.

Por ello se desarrollan los lenguajes de programacin de ordenador, para dar instrucciones a una
mquina de forma:

Precisa: Sin ambigedades inherentes a la comunicacin humana.


Univoca: Solo se puede interpretar de una manera.
Concisa: Preferiblemente ordenes cortas.

El Arduino se programa en una variante del lenguaje de programacin C++ , que es un lenguaje
muy extendido por sus caractersticas, aunque no es un lenguaje sencillo. C++, fija reglas estrictas
de cmo escribir estas instrucciones.

Un programa es una serie de instrucciones que se ejecutan en secuencia, salvo que indiquemos
expresamente condiciones precisas en las que esta secuencia se ve alterada.

Un programa interno comprueba que la sintaxis de nuestro programa es acorde a la norma de


C++, y si hay cualquier cosa que no le convence dar un error y finalizar la
comprobacin ,obligndonos a revisar lo que hemos escrito.

Cuando el comprobador acepta nuestro programa, invoca a otro programa que traduce lo que
hemos escrito a instrucciones comprensibles para el procesador de nuestro Arduino. A este nuevo
programa se le llama compilador.

7 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

El compilador convierte nuestras instrucciones (cdigo fuente) en instrucciones del procesador


(cdigo ejecutable).

2.4 ESTRUCTURA DE UN PROGRAMA ARDUINO.

Un programa diseado para ejecutarse sobre un Arduino (un sketch) siempre se compone de
tres secciones:

La seccin de declaraciones de variables globales: ubicada directamente al principio del


sketch.
La seccin llamada void setup(): delimitada por llaves de apertura y cierre.
La seccin llamada void loop(): delimitada por llaves de apertura y cierre.

La primera seccin del sketch (que no tiene ningn tipo de smbolo delimitador de inicio o de final)
est reservada para escribir, tal como su nombre indica, las diferentes declaraciones de variables
que necesitemos. En un apartado posterior explicaremos ampliamente qu significa todo esto.

En el interior de las otras dos secciones (es decir, dentro de sus llaves) deberemos escribir las
instrucciones que deseemos ejecutar en nuestra placa, teniendo en cuenta lo siguiente:

Las instrucciones escritas dentro de la seccin void setup() se ejecutan una nica vez,
en el momento de encender (o resetear) la placa Arduino.

Las instrucciones escritas dentro de la seccin void loop() se ejecutan justo despus de
las de la seccin void setup() infinitas veces hasta que la placa se apague (o se resetee). Es
decir, el contenido de void loop() se ejecuta desde la primera instruccin hasta la ltima, para
seguidamente volver a ejecutarse desde la primera instruccin hasta la ltima, para
seguidamente ejecutarse desde la primera instruccin hasta la ltima, y as una y otra vez.

Por tanto, las instrucciones escritas en la seccin void setup() normalmente sirven para realizar
ciertas preconfiguraciones iniciales mientras que las instrucciones del interior de void loop() son,
de hecho, el programa en s que est funcionando continuamente.

8 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Cuando abrimos el IDE de Arduino o hacemos Men]\Archivo\nuevo el programa nos escribe


ya estas dos funciones setup() y loo():

Ntese que el principio de cada funcin se indica mediante la apertura de llave { y el fin de la
misma corresponde al smbolo de cerrar llave } .

De hecho el conjunto de instrucciones contenidas entre una apertura y cierre de llaves se llama
bloque y es de capital importancia a la hora de que nuestro Arduino interprete de una u otra
manera las instrucciones que le damos. Es obligatorio que a cada apertura de una llave
corresponda un cierre de llave. En sucesivos captulos ampliaremos este concepto.

Por ahora resaltar las lneas que aparecen dentro de los bloques principales:

// put your setup code here, to run once


// put your main code here, to run repeatedly

La primera lnea del sketch del ejemplo contiene un comentario (concretamente, son las dos
primeras lneas: desde los smbolos /* hasta los smbolos */). Un comentario es un texto escrito
intercalado con el cdigo del sketch que se utiliza para informar sobre cmo funciona ese cdigo a
la persona que en algn momento lo est leyendo. Es decir, los comentarios son texto de ayuda
para los seres humanos que explica el cdigo asociado y ayudan a entenderlo y recordar su
funcin. Los comentarios son completamente ignorados y desechados por el compilador, por lo
que no forman parte nunca del cdigo binario que ejecuta el microcontrolador (as que no ocupan
espacio en su memoria).

Los comentarios pueden aparecer dentro del cdigo de diferentes formas:

Comentarios compuestos por una lnea entera (o parte de ella): para aadirlos deberemos
escribir dos barras ( // ) al principio de cada lnea que queramos convertir en comentario.
Tambin podemos comentar solamente una parte de la lnea, si escribimos las barras en otro
punto que no sea el principio de esta; de esta manera solamente estaremos comentando lo
que aparece detrs de las barras hasta el final de la lnea, pero lo anterior no.

Comentarios compuestos por un bloque de varias lneas seguidas: para aadirlos


deberemos escribir una barra seguida de un asterisco ( /* ) al principio del bloque de texto que
queramos convertir en comentario, y un asterisco seguido de una barra ( */ ) al final de dicho
bloque. Todos los caracteres y lneas ubicados entre estas dos marcas de inicio y final sern
tratadas automticamente como comentarios. Hay que tener en cuenta, por otro lado, que
comentarios unilineales se pueden escribir dentro un comentario multilineal, pero uno
multilineal dentro de otro no. Este es el tipo de comentario escrito en el sketch del ejemplo.

Una prctica bastante habitual en programacin es comentar en algn momento una (o ms)
partes del cdigo. De esta forma, se borran esas partes (es decir, se ignoran, y por tanto, ni se
compilan ni se ejecutan) sin borrarlas realmente. Normalmente, esto se hace para localizar
posibles errores en el cdigo observando el comportamiento del programa con esas determinadas
lneas comentadas. A lo largo de los ejemplos de este libro se ir viendo su utilidad.

2.5 PRIMERAS INSTRUCCIONES EN ARDUINO C++.

Parece obligado en el mundo Arduino, que el primer programa que hagamos sea el blinking LED,
y est bien porque ilustra algunas ideas interesantes en cuanto a las posibilidades de la
programacin:

9 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

La capacidad de Arduino para interactuar con el mundo externo. Algo bastante inusual para
quienes estn acostumbrados a la informtica tradicional, donde la potencia de clculo ha
crecido de forma espectacular, pero sigue siendo imposible, influir en el mundo exterior.
La sencillez del entorno de trabajo. En contraposicin a un sistema tradicional de editor /
compilador / linker.

Arduino puede relacionarse de diferentes maneras con el mundo que le rodea, Empezaremos por
los pines digitales que pueden usarse de dos modos, como:

Entradas: Para leer informacin digital del mundo exterior.


Salidas: Para activar una seal al mundo exterior.

Las funciones que nos ofrece el lenguaje Arduino para trabajar con entradas y salidas digitales
son:
pinMode(): configura un pin digital (cuyo nmero se ha de especificar como primer parmetro)
como entrada o como salida de corriente, segn si el valor de su segundo parmetro es la
constante predefinida INPUT o bien OUTPUT, respectivamente. Esta funcin es necesaria
porque los pines digitales a priori pueden actuar como entrada o salida, pero en nuestro sketch
hay que definir previamente si queremos que acten de una forma u de otra. Es por ello que
esta funcin se suele escribir dentro de setup(). No tiene valor de retorno.

digitalWrite(): enva un valor ALTO (HIGH) o BAJO (LOW) a un pin digital; es decir, tan solo
es capaz de enviar dos valores posibles. Por eso, de hecho, hablamos de salida digital. El
pin al que se le enva la seal se especifica como primer parmetro (escribiendo su nmero) y
el valor concreto de esta seal se especifica como segundo parmetro (escribiendo la
constante predefinida HIGH o bien la constante predefinida LOW, ambas de tipo int).

digitalRead(): devuelve el valor ledo del pin digital (configurado como entrada mediante
pinMode()) cuyo nmero se haya especificado como parmetro. Este valor de retorno es de
tipo int y puede tener dos nicos valores (por eso, de hecho hablamos de entrada digital): la
constante HIGH (1) o LOW (0).

Arduino dispone de 14 pines que pueden ser usados de este modo, numerados del 0 al 13:

En la sesin anterior cargamos un programa de ejemplo que hacia parpadear un LED en la placa
con una cadencia definida. Veamos como podemos programar Arduino para que realice esto.

Primero configuraremos Arduino para que configure su pin 13 como de salida digital y despus
encenderemos y apagaremos la seal en esa salida, lo que har que el LED que tiene conectado
en serie se encienda o apague al ritmo que marquemos.

Para indicar al sistema que deseamos usar el pin 13 como salida digital utilizamos la instruccin:

10 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

pinMode ( 13, OUTPUT ) ;

El primer parmetro indica el pin a usar y el segundo OUTPUT es para usarlo como salida, y
tambin podramos usar como segundo parmetro INPUT, para indicar que usamos ese pin
como entrada, vamos a leer de este pin.

Estas definiciones se harn solo una vez al principio, en la funcin setup(). La nuestra quedar,
con una nica instruccin que declara que vamos a usar el pin 13 como salida digital:

void setup()
{
// initialize the digital pin as an output
pinMode( 13, OUTPUT) ;
}

Es importante que nos fijemos en que a pesar de ser una nica instruccin, hemos delimitado el
bloque de esta funcin mediante abrir y cerrar llaves.

Obsrvese que la instruccin finaliza con un ; . C++ obliga a terminar las instrucciones con un
punto y coma que delimite la orden. Si se omite generar un error al compilar.

Para encender el LED usaremos la instruccin:

digitalWrite( 13 , HIGH) ;

Y otra instruccin similar que le ordena apagarlo:

digitalWrite( 13 , LOW) ;

El primer parmetro 13 indica el pin a utilizar y segundo parmetro HIGH o LOW indican el valor
que deseamos poner en esa salida. En Arduino corresponden 5V para HIGH y 0V para LOW.

Si en la funcin loop() escribiramos estas dos instrucciones seguidas, Arduino cambiara estos
valores tan deprisa que no percibiramos cambios, as que necesitamos frenarle un poco para que
podamos percibir el cambio.

Para hacer este retraso de, digamos, un segundo, utilizaremos:

delay(1000) ; // delay(n) congela Arduino n milisegundos

Por tanto para programar una luz que se enciende y se apaga, tendramos que generar una
secuencia de rdenes (Como en una receta de cocina) que hicieran:

1. Informar a Arduino de que vamos a utilizar el pin13 para escribir valores( en el Setup).
2. Encender el LED : Poner un valor alto ( 5V) en dicho pin.
3. Esperar un segundo.
4. Apagar el LED: Poner valor bajo (0V) en dicho pin.
5. Volver a esperar un segundo.
A. Si omitiramos este segundo retraso, apagara la luz y volvera a empezar encontrndose
la orden de volver a encender. No apreciaramos que se haba apagado. Comprobadlo.
B. El procesador de Arduino UNO es muy lento desde el punto de vista electrnico, pero es
capaz de conmutar la luz, pasar de encendido a apagado y vuelta a encender, unas 15.000
veces por segundo.

11 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

El primer concepto que tenis que recordar, es que los ordenadores procesan las ordenes en
secuencia, una instruccin despus de otra y en el orden en que se las dais. Nuestro programa
instruye al ordenador para que ejecute esas instrucciones y fija el orden en el que se ejecutan.

La forma de escribir un programa en Arduino C++ que haga lo anteriormente descrito es algo
parecido a esto:

void setup()
{
pinMode( 13 , OUTPUT); // Usaremos el pin 13 como salida
}
void loop()
{
digitalWrite(13 , HIGH); // Enciende el LED
delay(1000); // Esperar un segundo
digitalWrite(13 , LOW); // Apagar el LED
delay(1000); // Esperar otro segundo
}

Conviene aclarar ya pequeos detalles que deberemos tener en cuenta a la hora de escribir
nuestros sketches para evitarnos muchos dolores de cabeza. Por ejemplo, es necesario saber que
el lenguaje Arduino es case-sensitive. Esto quiere decir que es totalmente diferente escribir una
letra en mayscula que en minscula. Dicho de otra forma: para el lenguaje Arduino HolA y
hOLa son dos palabras distintas. Esto tiene una implicacin muy importante: no es lo mismo
escribir por ejemplo digitalWrite(13 , HIGH); que digitalwrite(13 , HIGH);;. En el primer caso la
instruccin estara correctamente escrita, pero en el segundo, en el momento de compilar el
cdigo el IDE se quejara porque para l write (con w minscula) no tiene ningn sentido. As
que hay que vigilar mucho con respetar esta distincin en los cdigos que escribamos.

Otro detalle: las tabulaciones de las instrucciones contenidas dentro de las secciones void
setup() y void loop() del sketch del ejemplo no son en absoluto necesarias para que la
compilacin del sketch se produzca con xito. Simplemente son una manera de escribir el cdigo
de forma ordenada, clara y cmoda para el programador, facilitndole la tarea de leer cdigo ya
escrito y mantener una cierta estructura a la hora de escribirlo. En los prximos ejemplos se ir
viendo mejor su utilidad.

Otro detalle: todas las instrucciones (incluyendo tambin las declaraciones de variables) acaban
con un punto y coma. Es indispensable aadir siempre este signo para no tener errores de
compilacin, ya que el compilador necesita localizarlo para poder detectar el final de cada
instruccin escrita en el sketch. Si se olvida, se mostrar un texto de error que puede ser obvio
(falta un punto y coma) o no. Si el texto del error es muy oscuro o sin lgica, es buena idea
comprobar que la causa no sea la falta de un punto y coma en las lneas justamente anteriores a
la marcada por el compilador como causante del problema.

Cuando os equivoquis ( y creadme, os vais a equivocar) el sangrado ayuda mucho a visualizar el


programa. Solo hay dos tipos de programadores. Los que se equivocan y los que se van a
equivocar.

Solo nos falta ya, comprobar si hay errores y para ello pulsamos el icono en amarillo, verificamos
y compilamos:

12 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Si todo va bien,( si no hay errores en rojo al final de la ventana) podemos compilar y volcar con
la flecha, En caso contrario ( y creedme que os pasar con frecuencia) habr que revisar los
posibles errores y corregirlos. Volveremos sobre esto en el futuro.

La flecha en amarillo volcara nuestro programa a la placa Arduino y comprobaremos que la luz
del pin 13 parpadea con una cadencia de un segundo.

Sugerencia: Si modificamos los valores del delay, modificaremos la cadencia del parpadeo.
Nota: Esto no funcionara con ningn otro Pin del Arduino UNO, porque solo el 13 tiene un LED
conectado.

2. 6 RESUMEN DE LA SESIN

En esta sesin hemos aprendido varias cosas importantes:

El concepto clave de un programa, como secuencia de instrucciones que se ejecuta en el orden


marcado.
Hay dos funciones bsicas en todo programa Arduino: Setup() y Loop().
Para delimitar un bloque de instrucciones usamos apertura y cierre de llaves.
Todas las instrucciones acaban en punto y coma (Aunque hay excepciones).
Podemos usar comentarios usando // .
Hemos aprendido algunas instrucciones iniciales del Arduino C++.

13 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

3 NUESTRO PRIMER CIRCUITO


Arduino, primer circuito
3.1 OBJETIVOS

Fijar algunas ideas bsicas sobre electrnica.


Montar un circuito con LED y Resistencia comprender el esquema elctrico..
Aprender el manejo de la Protoboard..
Instalar del blinking LED en la Protoboard.

3.2 MATERIAL REQUERIDO.

Arduino Uno o similar. Esta sesin acepta cualquier otro modelo de Arduino.
Un PC con el entorno de Arduino correctamente instalado y configurado.
Una Protoboard.
Un diodo LED
Una resistencia de 330 Ohmios.
Algunos cables de Protoboard.

3.3 NUESTRO PRIMER CIRCUITO ELECTRNICO

En la sesin anterior programamos el LED conectado al pin 13 de nuestro Arduino. En esta sesin
vamos a duplicar este circuito en el exterior montndolo desde el principio con componentes
discretos. Su esquema elctrico sera.
Vemos a la izquierda el smbolo del diodo LED en serie una resistencia de 220.

A su vez vemos a la izquierda el smbolo GND para indicar que es el negativo. Por ltimo a la
derecha del smbolo de la resistencia tendremos el terminal que deberemos colocar a positivo
VCC o +5 V para conseguir que el LED se encienda.

Un diodo, es un componente electrnico que solo permite pasar la


corriente en una direccin. En la direccin del nodo al ctodo, la
punta del tringulo indica la direccin en que circula la corriente.
El terminal de mayor longitud de un diodo LED es el nodo y el
terminal ms prximo al chafln es el ctodo. Para que se ilumine
deberemos conectar el nodo a positivo y el ctodo al negativo,
recordar que es preciso utilizar una resistencia imitadora para
impedir que el diodo se funda.
Si se conecta en inversa se cortar el flujo de corriente impidiendo
que se ilumine.
Las resistencias en cambio no diferencian un extremos del otro,
decimos que no tienen polaridad.

14 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Es importante entender los esquemas, esto me permite comprender con rapidez cualquier circuito.
Vale la pena dedicarle un poco de esfuerzo porque son el lenguaje de la electrnica.

Una vez comprendido el esquema elctrico del circuito, veamos la conexin en la Protoboard:

Este esquema sigue una pauta de marcar los cables que van a positivo en rojo y los que van a
GND en azul (mejor negro). Recomendamos encarecidamente se siga esta norma en la prctica
porque ayuda a identificar posibles problemas y evita errores.

Podemos ahora volcar el programa que hicimos en la sesin 2 (o simplemente cargar el ejemplo
Blink), siguiendo el procedimiento que definimos all, y veremos cmo sta vez, adems del LED
propio en la placa de Arduino, nuestro LED exterior parpadea siguiendo el mismo ciclo de
encendido y apagado.

3.4 RESUMEN DE LA SESIN

En esta sesin hemos aprendido varias cosas importantes:

Hemos identificado dos componentes bsicos en electrnica, resistencias y los diodos LED.
Aprendimos a descifrar los primeros esquemas electrnicos.
Hemos montado nuestro primer circuito con estos componentes.

15 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

4 CIRCUITO CON MLTIPLES


LEDS
Arduino con 7 LEDs, iteraciones
4.1 OBJETIVOS

Conocer las Iteraciones en C++, Instruccin for.


Primeras variables en C++.
Circuito con mltiples LEDs.
Aprendiendo a programarprogramando.

4.2 MATERIAL NECESARIO.

Arduino Uno o similar. Esta sesin acepta cualquier otro modelo de Arduino.
Un PC con el entorno de Arduino correctamente instalado y configurado.
Una Protoboard.
7 x diodos LED.
7 x resistencia de 220 Ohmios.
Algunos cables de Protoboard.

4.3 UN CIRCUITO CON VARIOS LED: ITERACIONES FOR

En las sesiones anteriores vimos como gobernar un diodo LED externo. Si quisiramos montar un
circuito que tuviera 7 LEDs y en el que la luz se desplazara de uno a otro, una posibilidad sera
repetir varias veces las mismas secuencias de instrucciones que ya conocemos.

Por ejemplo si conectamos distintos LEDs a distintos pines digitales de Arduino, deberamos
declararlo en nuestra Funcin de setup() que podra ser:

void setup()
{
// initialize the digital pins as an output
pinMode( 10, OUTPUT) ;
pinMode( 9, OUTPUT) ;
pinMode( 8, OUTPUT) ;

pinMode( 4, OUTPUT) ;
}

Y a su vez nuestro loop() debera repetir tantas veces como LEDs tengamos el juego de encender
y apagar cada uno de los LEDs en secuencia desde el pin 10 hasta el 4.

Esta solucin es la que podramos describir como de fuerza bruta, pero no es muy elegante, es
trabajosa y probablemente cometeramos ms de un error al escribirla, porque las personas
tendemos a equivocarnos haciendo tareas repetitivas aburridas, y esta lo es mortalmente,
imaginad un circuito de 16 LEDs.

En cambio los ordenadores no se aburren y adems C++ nos ofrece un medio cmodo de
indicarle que debe repetir algo un nmero definido de veces. Este medio es la instruccin For
que podemos usar en combinacin con una variable.

16 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Una variable es un contenedor que puede tomar varios valores, en nuestro caso aceptar todos
los valores entre 4 y 10.

C++ nos exige declarar el tipo de las variables antes de usarlas. En nuestro caso usaremos el tipo
entero que se escribe int para indicar que esta variables es numrica y entera, sin decimales.
Iremos viendo que existen otros tipos de variables. Volveremos sobre este tema en prximas
sesiones.

As por ejemplo, para inicializar en nuestro setup() los pines desde el 10 hasta el 4 como salidas
(requerido por nuestro Arduino) podramos usar la instruccin for de la siguiente manera:

void setup()
{
int i = 0 ; // Inicializamos la variable i como un entero
for ( i = 4 ; i < 11 ; i++)
pinMode( i , OUTPUT) ;
}

Aunque la sintaxis parece complicada al principio, uno se acostumbra con rapidez. Aqu lo
importante es que for necesita 3 parmetros separados por un carcter de punto y coma.

for (valor_inicial_contador; condicion_final; incremento){


//Instrucciones que se repetirn un nmero determinado de veces
}

Estos parmetros son en ste orden:

valor_inicial_contador: una variable que ira tomando valores segn una cierta regla, y a la que
asignamos un valor inicial. En este caso: i = 4 .
condicion_final: el ciclo contina mientras se cumpla esta condicin. En nuestro caso mientras
la i sea menor que 11, o sea hasta el 10: i <11
incremento: como cambia la variable en cada iteracin. En nuestro caso i++ que es pedirle a
C++ que incremente en uno la variable i, al final de cada iteracin.

Con el mismo criterio podramos escribir la funcin loop() as:

void loop()
{
int i = 0 ; // Inicializamos la variable i como un entero
for ( i = 4 ; i < 11 ; i++)
{
digitalWrite( i , HIGH) ;
delay (500) ;
digitalWrite( i , LOW);
delay (500) ;
}
}

En la sesin 3 el cdigo era muy similar excepto en que escribamos el valor 13 para el nico pin
que tena un LED conectado. Aqu asignamos el pin con una variable i , que va tomando los
valores de 4 hasta el 10 para el pin.

Ntese que la instruccin for no lleva un punto y coma al final. Esto es porque se aplica al bloque
de instrucciones que le siguen entre llaves, como es el caso del loop() La iteracin realiza las
cuatro instrucciones que siguen a la lnea del for, porque estn dentro de un bloque de
instrucciones.

17 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Las instrucciones que se aplican a bloques de cdigo, no llevan punto y coma al final.

En el caso de particular de que el bloque lleve una nica lnea de cdigo, las llaves pueden ser
omitidas, como en el caso de la instruccin for en la funcin setup() de arriba.

4.4 ESQUEMA ELECTRNICO DEL CIRCUITO

El esquema del circuito es muy similar al de la sesin 3, salvo por el hecho de que colocamos en
la Protoboard 7 LEDs.

Cuando nuestro programa coloque el pin correspondiente a valor HIGH, se cerrar el circuito
iluminndose el LED asociado a ese pin.
Con este circuito, y con el programa descrito en las pginas anteriores, tendremos un efecto de
luces similar al del coche fantstico.

A continuacin incluimos un esquema de conexin del circuito en una protoboard.

18 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

En general, se considera buena costumbre, montar los circuitos que veamos a partir del esquema
electrnico del mismo, ms que a partir del diagrama de conexiones de la Protoboard.

La razn es que con el esquema, la comprensin del circuito es completa y se evita la tentacin
de copiar la prctica sin necesidad de entenderla.
Adems, el diagrama electrnico del circuito es su completa descripcin y suele resultar ms
sencillo comprender la funcin del mismo. En cambio a medida que los circuitos se hacen ms
complejos, comprender su funcin desde un esquema de Protoboard puede complicarse mucho, y
peor an llevar a una interpretacin errnea.

4.5 VARIANTES DEL PROGRAMA CON EL MISMO CIRCUITO

Este montaje nos permite jugar con las luces y se presta a varios programas diferentes para
conseguir distintos efectos.

Por ejemplo, con el programa anterior, el efecto no es exactamente el del coche fantstico porque
cuando acabamos de iterar el for, el programa vuelve a empezar desde el principio, lo que hace
que la luz salte desde el pin 4 hasta la del pin 10.

As pues Podramos hacer que la luz rebotara? Pensadlo un poco.

Desde luego que s, bastara con usar dos ciclos for, similar a lo siguiente:

void loop()
{
for ( int i = 4 ; i < 11 ; i++) // Definimos la variable i
sobre la marcha
{
digitalWrite( i , HIGH) ;
delay (500) ;
digitalWrite( i , LOW);
delay (500) ;
}
for ( int i = 9 ; i >4 ; i--) // Definimos la variable i
sobre la marcha
{
digitalWrite( i , HIGH) ;
delay (500) ;
digitalWrite( i , LOW);
delay (500) ;
}
}

El primer ciclo for hace que las luces se encienda en secuencia desde la 4 hasta la 10. El segundo
bucle entra a continuacin empezando con la luz 9 (para no repetir la 10) y finalizando con la
5(para no repetir la 4), y vuelta a empezar.
En el segundo bucle hemos hecho una cuenta atrs dicindole a la variable i que se decrementara
en uno en cada iteracin mediante la instruccin i - - .
Tambin nos hemos aprovechado de que C++ nos permite definir variables sobre la marcha
dentro de la propia instruccin for, sin necesidad de dedicarle una lnea completa a la declaracin
e inicializacin.

Otra variante seria, hacer un efecto de ola en al que las luces subieran dejando encendidos los
LEDs previos hasta alcanzar el mximo y ahora descender apagando los LEDs superiores. Os
recomendamos intentar resolver el problema como desafo.

19 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Programar es en parte aprender las instrucciones de un lenguaje, la parte fcil, y otra ms difcil
que es aprender a resolver los problemas de un modo que nos permita darle instrucciones a un
ordenador para que lo lleve a cabo.
Estos procedimientos secuenciales de cmo resolver un cierto tipo de problemas es lo que se
conoce como un algoritmo.
Segn el problema que abordemos el algoritmo ser ms o menos complicado pero aprender a
programar tiene ms que ver con desarrollar esta capacidad de resolver problemas lgicos en una
secuencia de pasos que podamos codificar en un ordenador.
Por cierto, cualquiera puede aprender a programar. No lo dudis. Solo que como en todo, a unos
les lleva ms tiempo que a otros desarrollar la habilidad necesaria. Al principio muchos dicen que
les duele la cabeza de pensar en este tipo de cosas, pero os animo a continuar, poco a poco si es
preciso, porque encontrareis que vale la pena.

4.7 RESUMEN DE LA SESIN

En esta sesin hemos aprendido varias cosas importantes:

La instruccin For, nos permite iterar un bloque de instrucciones tantas veces le indiquemos.
Hemos visto uno de los tipos de variables que C++ acepta: los enteros.
Hemos introducido el concepto de algoritmo, como un procedimiento secuencial para resolver un
problema concreto y lo hemos aplicado a varios ejemplos de programas sencillos con luces.

20 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

5 LAS ENTRADAS DIGITALES DE


ARDUINO
Leyendo un pulsador con Arduino
5.1 OBJETIVOS

Conocer las entradas digitales.


Leer el estado de un pulsador.
Conocer los valores booleanos.
Conocer el operador negacin.

5.2 MATERIAL REQUERIDO.

Arduino Uno o similar.


Un PC con el entorno de Arduino correctamente instalado y configurado.
Una placa Protoboard.
Un diodo LED.
Un pulsador.
Dos resistencias, una de 220 Ohmios y otra 10 KOhmios.
Algunos cables de conexin para la placa Protoboard.

5.3 ENTRADAS DIGITALES

Con frecuencia en electrnica necesitamos saber el estado (ON/OFF) de un determinado


elemento, si alguien ha pulsado un botn o si una puerta o ventana ha quedado abierta o est
cerrada.

A este tipo de seales todo/nada, SI/NO, TRUE/FALSE, 1/0 u ON/OFF se les llama digitales, y
podemos manejarlas con los pines digitales del 0 al 13 de Arduino.

Muchos de los detectores, (sensores) y actuadores que vemos en el mundo real son digitales:

Como actuadores digitales, tenemos luces, alarmas, sirenas, apertura/bloqueo de puertas, etc.

Como detectores digitales podemos mencionar interruptores y pulsadores, finales de carrera,


detectores de nivel, sensores de llamas, de humo o gases txicos, etc.

Hemos visto que Arduino pueden usar los pines digitales como salidas todo o nada para encender
un LED. De la misma manera podemos leer valores, todo o
nada, del mundo exterior.

En esta sesin veremos que los pines digitales de Arduino


pueden ser usados tanto de entrada como de salida. Vamos a
leer un pulsador externo y dependiendo de la lectura que
realicemos encenderemos o apagaremos un LED en funcin
de que el botn se pulse o no.

5.4 ESQUEMA ELECTRNICO DEL CIRCUITO.

Montaremos un circuito como el de la izquierda, con un diodo


LED en serie con una resistencia limitadora de 220 Ohmios

21 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

conectado al pin digital 2 de Arduino y ademas un segundo circuito con un pulsador S1 conectado
al pin 8 con una resistencia de 10K, tal como se muestra en el diagrama anterior.

Obsrvese que mientras no pulsemos S1 el


pin 8 de Arduino est conectado a GND a
travs de la resistencia DE 10K forzando una
lectura de tensin baja (LOW). En cambio
cuando pulsemos S1 cerraremos el circuito del
pin 8 a +5V con lo que leer tensin alta
(HIGH). En ambos casos tenemos un valor de
tensin definido.

A esta resistencia de 10K que fuerza el valor


bajo en vaco se le conoce como pulldown. Si
la conectramos a +5V para forzar una lectura
a valor alto se le llamara resistencia de
pullup, Tal como se representa en el esquema
de la derecha.

Esta resistencia es clave para que las lecturas


del pulsador sean consistentes. El circuito,
simplemente, no funcionar bien si se omite
(volveremos sobre esto).

Y aqu tenemos el esquema para protoboard del circuito.

En este esquema hemos seguido la prctica habitual de usar cables negros para conectar a masa
y cables rojos para conectar a tensin (+5V).
Obsrvese que el pulsador S1 tiene cuatro terminales. Esto es porque cada entrada del interruptor
tiene dos terminales conectados. En nuestro circuito simplemente ignoramos los terminales
secundarios. Ante cualquier duda del funcionamiento del pulsador utilizar un polmero para
comprobarlo.

22 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

5.5 LEYENDO LOS PULSADORES

Empecemos haciendo un programa que haga que el LED se encienda cuando pulsamos el botn
y se apague cuando lo soltamos. Para ello pediremos a Arduino que configure el pin digital 2 (D2)
como salida para manejar el LED, y el pin digital 8 (D8) como entrada para leer el pulsador.

Normalmente en programas sencillos basta con poner el nmero de pin en las instrucciones. Pero
a medida que el programa se complica esto tiende a provocar errores difciles de detectar.

Por eso es costumbre definir variables con los nmeros de pin que usamos, de forma que
podamos modificarlos en un solo lugar del cdigo, y no teniendo que buscar a lo largo de todo el
programa. Vamos a escribir esto un poco ms elegantemente:

int LED = 2 ;
int boton = 8;

void setup()
{
pinMode( LED, OUTPUT) ; // LED como salida
pinMode( boton , INPUT) ;//botn como entrada
}

Atencin, recordar que, como vimos en la segunda sesin, C++ diferencia entre maysculas y
minsculas y por tanto LED, Led y led no son lo mismo. Del mismo modo, pinMode es correcto y
en cambio pinmode generar un error del compilador.
He usado la variable boton sin acento porque no es recomendable usarlos y tampoco la
cualquier otro smbolo en los nombres de variables, porque pueden pasar cosas extraas.

Vimos que para encender el LED bastaba usar digitalWrite( LED, HIGH). Para leer un botn se
puede hacer algo similar: digitalRead( boton). Veamos cmo podra ser nuestro loop:

void loop()
{
int valor = digitalRead(boton) ; // leemos el valor de boton
digitalWrite( LED, valor) ; //y lo almacenamos en valor

Fcil no? Comprobamos que el LED est apagado hasta que pulsamos el botn y se ilumina al
pulsar.

Cmo podramos hacer lo contrario sin modificar el montaje?, es decir que el LED se apague al
pulsar y se encienda si no pulsamos. Bastara con escribir en el LED lo contrario de lo que
leamos en el botn.

Existe un operador que hace eso exactamente, el operador negacin ! . Si una valor dado x es
HIGH, entonces !x es LOW y viceversa.

Un operador es un smbolo que relaciona varios valores entre s, o que modifica el valor de una
variable de un modo previsible.

Ejemplos de operadores en C++ son los matemticos como +,-,* , / ; y hay otros como la
negacin ! o el cambio de signo de una variable : x. Iremos viendo ms.

C++ incorpora un tipo de dato llamado bool o booleano que solo acepta dos valores TRUE (cierto)
y FALSE (falso) y son completamente equivalentes al 1 / 0, y al HIGH / LOW.

23 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Este nuevo programa sera algo as:

void loop()
{
bool valor = digitalRead(boton) ; // leemos el valor de boton y
//lo almacenamos en valor
digitalWrite( LED, !valor) ; //Escribimos lo contrario de valor en
// LED
}

Hemos definido valor como bool, porque podemos usar el valor de tensin alto como TRUE y el
valor bajo como FALSE.

SI el botn no est pulsado el D8 leer FALSE y por tanto pondr LED a TRUE. En caso contrario
apagar el LED.

De hecho podramos escribir una variante curiosa del blinking LED usando el operador negacin:

void loop()
{
bool valor = digitalRead (LED) ;
digitalWrite( LED, !valor) ;
delay ( 1000) ;
}

En este ltimo ejemplo observamos que, podemos leer la situacin actual de un pin ,nos devuelve
su estado actual, an cuando lo hayamos definido como salida. Por el contrario no podemos
escribir en un pin definido como entrada.

La primera linea lee la situacin del LED y la invierte en la segunda lnea, despus escribe esto
en LED. Y puestos a batir algn record, podemos escribir el blinking led en solo dos lneas:

void loop()
{
digitalWrite( LED , ! digitalRead( LED)) ;
delay ( 1000) ;
}

Las instrucciones dentro de los parntesis se ejecutan antes que las que estn fuera de ellos. Por
eso el digitalRead se ejecuta antes que el digitaWrite.

5.6 RESUMEN DE LA SESIN

Hemos visto una forma de leer seales digitales del mundo exterior adems de poder enviarlas:
digitalRead( pin)
digitalWrite( pin , valor)
Hemos conocido un nuevo componente, el pulsador.
Conocemos un nuevo tipo en C++, el booleano y un nuevo operador el de negacin.

24 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

6 CONDICIONALES Y BOTONES
La instruccin if
6.1 OBJETIVOS

Lgica digital y algebra de Bool.


Los condicionales. Instruccin if.
Botones, pulsadores y pullups.
Debouncing (antirrebotes).

6.2 MATERIAL REQUERIDO.

Arduino Uno o similar.


Un PC con el entorno de Arduino correctamente instalado y configurado.
Una Protoboard.
Un diodo LED.
Un pulsador.
Dos resistencias de 220 Ohmio 10 KOhmios.
Algunos cables de Protoboard.

6.3 LGICA DIGITAL Y ALGEBRA DE BOOL

En la sesin anterior presentamos el tipo de variable booleano (bool) destacando que solo puede
tomar dos valores: TRUE o FALSE. Aunque para quienes no estn acostumbrados al lgebra
Booleana o binaria puede parecer excesivo dedicar un tipo a algo tan simple, en la prctica buena
parte de las instrucciones de programacin se apoyan o dependen de este tipo de variables.

La razn prctica es que con frecuencia hay que tomar decisiones para seguir un camino u otro en
funcin de que se cumpla una condicin dada. Esta condicin se debe evaluar necesariamente, a
TRUE o FALSE para tomar una decisin.

Por ejemplo, en las sesin 4 usamos la instruccin for y comentamos que la iteracin se
mantiene mientras se cumpla una cierta condicin. Esta condicin se evaluaba a TRUE o FALSE,
es decir es un booleano.

Existen otras muchas instrucciones que se apoyan en los valores booleanos, como los
condicionales if que veremos en esta sesin, pero de un modo muy explicito toda la computacin
actual se basa en la lgica digital de solo dos valores que solemos llamar 1 y 0, True y False.

Los ordenadores modernos funcionan mediante la aplicacin del lgebra de bool a variables
booleanas y contamos dentro de C++, con un juego completo de operadores lgicos como la
negacin, que vimos en la sesin anterior, algunos de estos operadores lgicos son AND (&&) y
OR (||).

6.4 LA INSTRUCCIN IF

En este captulo vamos a presentar unas instrucciones nuevas de C++, que nos permitan tomar
decisiones para tomar una decisin entre realizar una determinada cosa u otra.

Los bloques if y if/else


Un bloque if sirve para comprobar si una condicin determinada es cierta (true,1) o falsa
(false,0). Si la condicin es cierta, se ejecutarn las instrucciones escritas en su interior (es decir,
dentro de las llaves de apertura y cierre). Si no se cumple, puede no pasar nada, o bien, si existe
25 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

tras el bloque if un bloque else (opcional), se ejecutarn las instrucciones escritas en el interior
de ese bloque else. Es decir, si solo escribimos el bloque if, el sketch tendr respuesta
solamente para cuando s se cumple la condicin; pero si adems escribimos un bloque else, el
sketch tendr respuesta para cuando s se cumple la condicin y para cuando no se cumple
tambin. En general, la sintaxis del bloque if/else es:

if (condicin) {
//Instrucciones una o ms que se ejecutan si la condicin es cierta
true,1 }else{
//Instrucciones una o ms que se ejecutan si la condicin es falsa false,0 }

Tanto si se ejecutan las sentencias del bloque if como si se ejecutan las sentencias del bloque
else, cuando se llega a la ltima lnea de esa seccin (una u otra), se salta a la lnea
inmediatamente posterior a su llave de cierre para continuar desde all la ejecucin del programa.

Hemos dicho que el bloque else es opcional. Si no lo escribimos, el if quedara as:

if (condicin) {
//Instrucciones una o ms que se ejecutan si la condicin es cierta
true,1
}

En este caso, si la condicin fuera falsa, el interior del if no se ejecutara y directamente se


pasara a ejecutar la lnea inmediatamente posterior a su llave de cierre (por lo que, tal como ya
hemos comentado, el programa no hace nada en particular cuando la condicin es falsa).

Tambin existe la posibilidad de incluir una o varias secciones else if, siendo en este caso
tambin opcional el bloque else final. Esta construccin tendra la siguiente sintaxis (puede haber
todos los else if que se deseen):

if (condicin) {
//Instrucciones una o ms que se ejecutan si la condicin es cierta
true,1 }
if (condicin) {
//Instrucciones una o ms que se ejecutan si la condicin es cierta
} else if (otra_condicin) {
/*Instrucciones una o ms que se ejecutan si la condicin
del anterior if es falsa pero la actual es cierta */ } else if (otra_condicin) {
/*Instrucciones una o ms que se ejecutan si la condicin del anterior if es falsa
pero la actual es cierta */
} else {
//Instruccin(es) que se ejecutan si todas las condiciones anteriores eran falsas
}

Es posible anidar bloques if uno dentro de otro sin ningn lmite (es decir, se pueden poner ms
bloques if dentro de otro bloque if o else, si as lo necesitamos).
Ahora que ya sabemos las diferentes sintaxis del bloque if, veamos qu tipo de condiciones
podemos definir entre los parntesis del if. Lo primero que debemos saber es que para escribir
correctamente en nuestro sketch estas condiciones necesitaremos utilizar alguno de los llamados
operadores de comparacin, que son los siguientes.

Operadores de comparacin
== Comparacin de igualdad
!= Comparacin de diferencia

26 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

> Comparacin de mayor que


>= Comparacin de mayor o igual que
< Comparacin de menor que
<= Comparacin de menor o igual que

Ejemplo 6.1: Recordemos que en el circuito de la sesin anterior disponamos de un pulsador y de


un LED, en esta sesin vamos a continuar con el mismo circuito y para conseguir que el LED se
encienda o apague al pulsar el botn. Para ello podramos mantener la misma funcin setup() y
escribir el loop() diferente:

int LED = 2 ;
int boton = 8;

void setup()
{
pinMode( LED, OUTPUT) ; // LED como salida
pinMode( boton , INPUT) ;//botn como entrada
}
void loop()
{
bool valor=digitalRead(boton);// leemos el estado del botn
if(valor) // s est pulsado
digitalWrite(LED,HIGH);// enciende LED
else // s no est pulsado
digitalWrite(LED,LOW); //apaga LED
}

Leemos primero el botn y almacenamos su valor en una variable de tipo bool y despus
decidimos si encendemos o apagamos el LED dependiendo de que su valor sea True o False.

Recordemos que un bloque es un conjunto de instrucciones encerrados entre llaves y que hay un
caso particular en el que se pueden omitir si y solo si, el bloque consta de una nica instruccin
como es nuestro caso.

6.5 VOLVIENDO CON LOS BOTONES

Ejemplo 6.2: Vamos con un programa diferente. Queremos que el botn acte como un interruptor,
que al pulsarlo una vez se encienda, y la prxima vez lo apague. Podramos plantear algo as y os
recomiendo que lo probis en vuestro Arduino:

int LED=2;
int boton= 8;
bool estado=false;

void setup()
{
pinMode( LED , OUTPUT) ; //configura pin 2 como salida
pinMode(boton, INPUT); // configura pin 8 como entrada
digitalWrite(LED,LOW); // apaga el led
}

void loop()
{
bool valor=digitalRead(boton);//leemos el botn
if(valor == true)// s se ha pulsado el botn
{
estado=!estado; //cambiamos el estado
digitalWrite(LED,estado);//escribimos el nuevo valor

27 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

}
}
La idea es definir una variable llamada estado al principio para guardar la situacin del LED. El
loop comprueba si se ha pulsado el botn, y de ser as invierte su estado, y despus escribe el
valor de estado en el LED. Si estaba encendido lo apaga. Si estaba apagado se enciende.

Aunque parece un plan perfecto, en la prctica no va a funcionar. En el tiempo que nosotros


tardamos entre pulsar y liberar el botn, nuestro humilde Arduino es capaz de leer unos cuantos
miles de veces el pulsador e invertir el valor del LED otras tantas.

Por eso, si lee un nmero par de veces dejara el LED como estaba y si lo lee un nmero impar de
veces lo invertir. En la prctica la situacin del LED se torna aleatoria, y si pulsis repetidamente
el botn veris que el resultado es impredecible.

Otra fuente de problemas es que en el mundo real un interruptor no cambia de un estado a otro de
forma perfecta, sino que suele rebotar y causar varios conexiones y desconexiones muy rpidas
antes de quedar en un valor estable. A esto se le llaman rebotes (bouncing) y al procedimiento
para eliminar estos rebotes se le llama debouncing en la jerga electrnica.

Ejemplo 6.3: El debouncing se puede hacer por hardware con un conjunto de resistencia y
condensador, o por software, mucho ms frecuentemente (por ms barato) y para esto una
solucin es nuevamente frenar a Arduino y hacerle esperar un tiempo entre 50 y 250 milisegundos
una vez que detecta que se ha pulsado el botn, de modo que nos d tiempo a liberar el pulsador:

void loop()
{
bool valor=digitalRead(boton);//leemos el botn
if(valor == true)// s se ha pulsado el botn
{
estado=!estado; //cambiamos el estado
digitalWrite(LED,estado);//escribimos el nuevo valor
delay(250);
}
}
Muy importante: Ntese que la condicin es (valor == false), con doble = . En C++ la comparacin
de dos valores usa ==, la asignacin de valor a una variable solo uno. Esto es fuente de errores
frecuentes al principio (entre programadores inexpertos).

Este lapso de 250 ms es suficiente para pulsar y liberar el botn cmodamente. Si probis esta
variante veris que ahora el LED invierte su valor cada vez que pulsas, siempre y cuando no te
demores demasiado en liberar el botn.

Pero Qu pasa cuando dejas el botn pulsado?

Pues sencillamente que el LED invierte su estado cada 250 ms (milisegundos) y tenemos otra
variante del blinking LED.

Ejemplo 6.4: Si queremos poder mantener pulsado sin que se produzca este efecto hay que
sofisticar un poco ms el programa:

int LED=2;
int boton= 8;
bool estado=false;
bool estadoAnterior = true;

void setup()
{
28 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

pinMode( LED , OUTPUT) ;


pinMode(boton, INPUT);
digitalWrite(LED,LOW);
}

void loop()
{
estado=digitalRead(boton);
if(estado != estadoAnterior)//hay algn cambio, se ha pulsado o
soltado
{
if(estado==HIGH)//Al pulsar botn cambiar el estado del LED, pero
no al soltar
digitalWrite(LED,!digitalRead(LED));
estadoAnterior=estado; //recordamos el ltimo valor
}
}

Ya dijimos que para comprobar si dos valores son iguales usamos ==, Para comprobar si son
diferentes usamos !=.

Vale la pena comentar aqu que, a pesar de su aparente inocencia, los botones tienen una
sorprendente habilidad para complicarnos la vida, y que en la prctica la combinacin de rebotes y
la necesidad de corregirlos, junto al uso de pullups que garanticen la correcta lectura, pueden
hacer que su uso se pueda complicar mucho ms de lo que parece, sino se estudia el problema
con calma.

Por ltimo, una condicin lgica se puede construir mediante los operadores lgicos AND, OR, y
NOT cuyos smbolos son respectivamente: &&, || y !

Si usramos un circuito con dos pulsadores con pullups (True, si no se pulsa) y un LED,
dependiendo del comportamiento que se busque podemos especificar diferentes condiciones:

If ( boton1 && boton2) Que ambos botones estn sin pulsar


If ( !( boton1 && boton2)) Que ambos estn pulsados.
If( boton1 || boton2 ) Que al menos uno este pulsado, o ambos.

6.6 RESUMEN DE LA SESIN

Hemos visto la instruccin if / else.


Vimos varios programas con pulsadores y como hacer el debouncing.
Hemos presentado los operadores lgicos de relacin y comparacin.
Continuamos escribiendo pequeos programas para desarrollar la forma de pensar necesaria
para escribir nuestras propias aplicaciones.

29 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

7 COMUNICACIN CON EL
EXTERIOR
El puerto serie en Arduino y los tipos String
7.1 OBJETIVOS

Comprender la comunicacin va puerto serie.


Utilizar la librera Serial.
Operaciones con enteros.
Los tipos String y char.
Operando con Strings.
La instruccin while.

7.2 MATERIAL REQUERIDO.

Arduino Uno o similar.


Un PC con el entorno de Arduino correctamente instalado y configurado.

7.3 COMUNICACIN SERIE CON EL MUNDO EXTERIOR

Antes o despus, necesitaremos comunicar nuestro Arduino con nuestro PC. Las razones son
varias, enviarle rdenes o recibir informacin de seales, por ejemplo.

Los PCs disponen de teclados, pantallas y adaptadores de red, pero con Arduino tenemos que
usar el puerto USB para establecer una conexin en serie con nuestro PC.

La comunicacin en serie es muy sencilla, bastan dos hilos para enviar una diferencia de tensin
entre ellos y poder marcar niveles alto (5V) y bajo(0V) y con esto podemos transmitir informacin
digital. Ahora solo nos falta pactar dos cosas entre quien enva y quien recibe:

Un cdigo comn para codificar los caracteres que enviamos.


Un acuerdo de velocidad para saber a qu ritmo hay que leer los datos.

El cdigo comn que vamos a usar con Arduino se llama cdigo ASCII y es estndar en todos los
PCs. Es una forma de codificar las letras mediante nmeros que representas estos caracteres.
Recordad que solo podemos transmitir unos y ceros.

As por ejemplo la letra A se representa por el numero 65, la B el 66, C el 67 Prcticamente


todos los PCs actuales utilizan este cdigo y eso incluye a Windows, Mac y Linux (y por eso
podemos leer emails enviados desde distintas plataformas), pero es importante comprender que
est es uno ms entre varios cdigos de caracteres posibles (EBCDIC por ejemplo).

Actualmente, en realidad, se suele usar una extensin del cdigo ASCII (llamada Unicode) que
permita el uso de caracteres no incluidos en la tabla original, y que permita representar
caracteres como las , o acentos para el espaol, pero tambin alfabetos distintos como el Kanji
chino o el alfabeto cirlico. Y este es el motivo por el que podis leer las letras chinas o rusas en
las pginas de internet de estos pases..

El otro factor a pactar para realizar una comunicacin serie es la velocidad. Dado que solo
disponemos de dos hilos para transmitir, necesitamos saber cundo hay que leer la lnea y esto se

30 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

hace estableciendo un acuerdo de velocidad. Si la velocidad de envo es distinta de la velocidad


de lectura, el mensaje final ser irreconocible.

Buena parte de los errores de comunicacin serie programando con Arduino se suelen deber a
una diferencia de velocidad entre el emisor y el receptor.

Esta velocidad se mide en bits por segundo y vamos a ver que Arduino soporta diferentes
velocidades de comunicacin serie.

7.4 ESTABLECIENDO LA COMUNICACIN SERIE

Arduino dispone de una librera serie incluida llamada Serial, que nos permite enva informacin al
PC y para usarla simplemente tenemos que pedirle en nuestro setup() que la incluya. La
instruccin que se encarga es:

Serial.begin( velocidad ) ;

Ntese que Serial tiene la S maysculas y que C++ diferencia entre maysculas y minsculas

La velocidad es una valor entre 300 y 115.200 bits por segundo. Y suele ser costumbre
establecerla en 9600 (el valor por defecto) pero no hay ninguna razn para ello y esta no es una
velocidad especialmente alta.

Para enviar un mensaje desde Arduino a nuestro PC podemos usar las funciones Serial.print() y
Serial.println().Veamos un Ejemplo 7.1:

void setup()
{
Serial.begin(9600) ;// Inicializa el Puerto seria 9600 bits por segundo
}
void loop()
{
int i = 54 ;
Serial.println( i );
}

El println() enviara el valor de i al puerto serie de Arduino. Para leerlo en nuestro PC necesitamos
un monitor de puerto serie. El IDE de Arduino incluye uno muy sencillo, pero suficiente que se
invoca con el botn del monitor:

Necesitamos adems asegurarnos de que la velocidad de conexin es la misma en ambos


extremos. Fjate en la parte inferior derecha del monitor serie:

31 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Normalmente la velocidad por defecto son los 9600 bits por segundo o baudios en los que hemos
programado nuestra puerto serie, y si lo desplegis, veris las diferentes velocidades aceptables
para Arduino.

Estrictamente hablando, bits por segundo y baudios no son exactamente lo mismo salvo bajo
ciertas condiciones particulares que en Arduino se cumplen, por lo que aqu podemos usarlos
como sinnimos.
En el mundo Arduino parece haber un acuerdo de usar velocidades bajas como 9600 en lugar
de ms altas como 115200, para evitar problemas. Esto es algo que hace aos estaba
justificado por problemas de transmisin, pero con la tecnologa actual no hay motivo para ello.
Es ms, en cuanto necesitemos utilizar dispositivos de comunicaciones como adaptadores
Ethernet o BlueTooth para comunicarnos, la velocidad tendr que subir necesariamente.

Ahora que sabemos enviar informacin y resultados al PC, vamos a ver cmo podemos operar
con enteros y mostrar el resultado en el puerto serie. En C++ los operadores numricos son los
normales en clculo y otros menos frecuentes:

Adicin: +
Resta:
Multiplicacin: *
Divisin entera: / Cociente sin decimales (puesto que operamos con enteros
Resto: % Devuelve el resto de una divisin.

En C++ tenemos que expresar las operaciones matemticas en una sola lnea y utilizar parntesis
para garantizar que se opera como necesitamos. Vamos con algunos ejemplos:

OPERACIN RESULTADO COMENTARIO

int i = 4 * 2 resultado = 8
int i = 4 * 2 / 3 resultado = 2 Porque desprecia los decimales al ser i entero

int i = 14 % 3 esultado = 2 El resto de 14 entre 3

Int i = 2 + 8 / 2 resultado = 6 Calcula primero la divisin.

nt i = (2+8) / 2 esultado = 5 El parntesis fuerza a que se realice primero la suma

Dada una expresin, la precedencia de operadores indica que operaciones se realizaran antes y
cuales despus en funcin de su rango. Para los que se inician en C++ no es fcil saber que
operadores tienen preferencia, por lo que es ms seguro que ante la duda usis parntesis.

Los parntesis fuerzan las operaciones de una forma clara y conviene utilizarlos ante la duda
porque de otro modo, detectar los errores de operacin puede volverse muy difcil especialmente
cuando uno empieza a programar.

El operador resto es ms til de lo que parece a primera vista porque nos permite saber si un
numero es mltiplo de otro. Supongamos que queremos saber si un nmero dado es par.

Podramos escribir un programa como este. Ejemplo 7.2:

void setup()
{
Serial.begin(9600) ; // Inicializa el Puerto serie
}
void loop()
32 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

{
int i = 27 ; //El nmero en cuestin
if ( i % 2 == 0)
Serial.println("Es par.") ;
else
Serial.println("Es impar");
}

Dando a i distintos valores podemos comprobar cmo funciona el operador resto %. Volveremos
sobre esto cuando veamos algunos ejemplos de cmo calcular nmeros primos.

En este programa hemos usado de un modo diferente el Serial.println() pasndole una String de
texto entrecomillada. Serial.print() enva el texto entrecomillado que le pongamos pero no realiza
el salto de lnea cuando termina. En cambio Serial.println() hace lo mismo pero incluye al final el
salto de lnea Ejemplo 7.3:

void setup()
{
Serial.begin(9600) ; // Inicializa el Puerto serie
}
void loop()
{
Serial.print("Buenos ") ;
Serial.print("Dias ") ;
Serial.println("a todos.") ;
}

C++ dispone de un tipo de variables llamadas Strings, capaces de contener textos. Podemos
operar con ellas simplemente definindolas como cualquier otro tipo de C++.Ejemplo 7.4:

void setup()
{
Serial.begin(9600); // Inicializa el puerto serie a 9600 bps
}

void loop()
{
int resultado = 25;
String s="El resultado es: "; // la S de String es mayscula
Serial.print(s);
Serial.println(resultado);
}

Un tipo String se define simplemente poniendo entre comillas dobles un texto, y se puede operar
con ellas de una forma similar a como operamos con enteros. Prueba Ejemplo 7.5:

void setup()
{
Serial.begin(9600); // Inicializa el puerto serie a 9600 bps
}
void loop()
{
String a = "hola " ;
String b = "a todos." ;
Serial.println( a + b);
}

Y tambin podemos construir un String sobre la marcha as.Ejemplo 7.6:

33 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

void setup()
{
Serial.begin(9600); // Inicializa el puerto serie a 9600 bps
}
void loop()
{
int resultado = 25 ;
String s = "El resultado es: " ;
Serial.println( s + String( resultado ));
}

Donde imprimimos el resultado de concatenar s y String, y la conversin de un int a String (El


operador + aade un String al final de otro).

7.5 RECIBIENDO MENSAJES A TRAVS DEL PUERTO SERIE

Hasta ahora solo hemos enviado mensajes desde Arduino hacia el PC, Pero como recibimos
mensajes en Arduino?

En primer lugar disponemos de una funcin llamada Serial.parseInt() que nos entrega lo que se
escribe en el monitor serie convertido a entero.Ejemplo 7.7:

void setup()
{
Serial.begin(9600); // Inicializa el puerto serie a 9600 bps
}
void loop()
{
if (Serial.available() > 0)
{
int x = Serial.parseInt();
Serial.println ( x) ;
}
}

Este programa simplemente recibe en x los nmeros que nos tecleen en la consola (cuando
pulsemos intro) y si es un texto, lo interpreta como cero.

Hemos utilizado otra funcin de Serial.available() que es un booleano. Conviene por costumbre
comprobar que antes de leer el puerto serie comprobemos si nos han enviado algo. Si lo hay
Serial.available() es True y en caso contrario es False.

Para leer un String del puerto serie tenemos que complicarnos un poco ms y hablar del tipo char.

Uno de de las mayores quebradero de cabeza al iniciarse en C++ es comprender la diferencia,


anti-intuitiva, entre char y String. char es un tipo que representa un nico carcter y se define con
comillas simples, a diferencia de String que necesita comillas dobles:

char c = a ;
String s =a ;

Aunque parezca lo mismo para C++ son muy distintos.

34 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Para leer una cadena desde el puerto serie necesitamos leer un carcter cada vez y despus
montar un String a partir de ellos, pero antes, asegrate de seleccionar ambos NL & CR en la
parte inferior del monitor serie, para garantizar que se enva el carcter de fin de lnea:
Un programa para leer la consola sera algo as. Ejemplo 7.8:

void setup()
{ Serial.begin(9600); }

void loop ()
{
char c = ' ' ;
String mensaje ="" ;
if (Serial.available()) //Comprobamos si hay algo esperando
{
while( c != '\n') //Si lo hay, lo leemos hasta el intro
{
mensaje = mensaje + c ; // Aadimos lo ledo al mensaje
c = Serial.read(); //Leer 1 carcter
delay(25);
}
Serial.println( mensaje); //Al salir imprimir el mensaje
mensaje = "" ; //Brralo para la prxima vez
}
}

Aqu usamos otra instruccin de C++ llamada while. Es similar a if, Ejecuta repetidamente el
bloque que le sigue mientras se cumpla la condicin que le pasamos entre parntesis:

while ( condicin)
{ }

Cuando lee el intro final de lo que escribimos, La condicin c != \n se torna falso y sale del while.

Por lo dems, comprobamos si hay algo disponible en el puerto serie y de ser as montamos el
mensaje leyendo un char cada vez y sumndoselo a mensaje para construir un String que
podamos imprimir al salir.

El motivo del delay(25) es que a una velocidad tan lenta, enviar un char de 8 bits por el puerto
serie, tarda mucho ms de lo que tarda Arduino en ejecutar las instrucciones del while y volver a
empezar. Por eso si se suprime el delay (y os recomiendo la prueba) leer un carcter bueno
(de la palabra escrita y como 10 caracteres basura para un Arduino UNO o Mega).
Si subimos la velocidad de comunicacin a 115200 bits por segundo, comprobareis que no hay
este problema ya que al multiplicar la velocidad de envo por ms de 10 Arduino ya no tiene
tiempo de volver a por ms caracteres antes de que lleguen.

7.6 RESUMEN DE LA SESIN

Hemos visto como establecer la comunicacin con el PC externo, tanto para enviar como para
recibir mensajes enteros y de texto.
Hemos presentado los tipos String y char.
Hemos visto las reglas bsicas para operar con enteros y con Strings.
Presentamos una nueva instruccin: while.

35 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

8 ARDUINO Y LAS ENTRADAS


ANALGICAS
Convertidores Analgico a digital ADCs
8. 1 OBJETIVOS

Conocer los potencimetros.


Comprender la conversin analgica a digital.
Aprender a usar las entradas analgicas de Arduino.

8. 2 MATERIAL NECESARIO.

Arduino Uno o similar. Esta sesin acepta cualquier otro modelo de Arduino
Una Protoboard.
Un diodo LED.
Un potencimetro de 10K
Una resistencia de 220 Ohmios.
Algunos cables de Protoboard.

8.3 EL POTENCIMETRO

Hasta ahora hemos usado siempre resistencias fijas, de un valor dado. Pero a veces es
conveniente disponer de un valor variable de resistencia o tensin, para controlar el circuito que
nos interesa.

Un potencimetro es, simplemente, un mecanismo para


proporcionar una resistencia variable.

Hay potencimetros de muchos tamaos, formas y colores


como podis imaginar, pero al final se trata una resistencia
fija de un valor dado (1-3),10 k en nuestro caso y un
mecanismo que permita deslizar un dial conductor sobre esa
resistencia, que nos permita tomar una parte de ese valor
(2).

Por eso un potencimetro siempre tiene 3 terminales. Los del extremo 1 y 3 se comportan como
una resistencia del valor de fondo de escala del potencimetro, y el pin central 2 va tomando
valores de resistencia en funcin del movimiento que hagamos con el ajuste.

8. 4 ARDUINO Y LAS ENTRADAS ANALGICAS

Con Arduino hemos visto que podemos influir en el mundo exterior aplicando salidas todo / nada
en los pines digitales.

Tambin hemos visto cmo detectar pulsaciones de botones, definiendo como entradas los pines
digitales. Pero en muchas ocasiones los sensores que usamos para supervisar el mundo exterior,
nos entregan una seal analgica. Es el caso de los sensores de temperatura, intensidad
luminosa, de presin o de PH, de intensidad de corriente en un circuito, etc.

36 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Para leer este tipo de seales continuas necesitamos un convertidor analgico a digital (ADC) y
que nos permite leer el valor de una seal analgica en un instante dado y convertirla a digital.

Estos convertidores toman una muestra del valor actual de la seal y nos entregan su valor
instantneo, medido en Voltios.

Mediante la lectura repetida de muestras a lo largo del tiempo podemos reconstruir la seal
original con mayor o menor precisin, dependiendo de la exactitud de nuestra medida y de la
velocidad a la que pueda tomar esas muestras.

Arduino UNO dispone de seis convertidores analgico a digital, nombrados de A0 hasta A5 y


rotuladas como ANALOG IN, recuadro rojo de la figura inferior:

Veamos cmo usar las entradas analgicas con un circuito como este, en el que damos tensin a
los extremos 1 y 3 de un potencimetro y conectamos el pin central (2) a la entrada de la puerta
A5 de Arduino:

Parece buen momento para destacar que


los convertidores ADC leen valores de
tensin y no resistencia, por lo tanto, lo que
vamos a leer es la cada de tensin en el
potencimetro a medida que giramos el
ajuste.

La primera curiosidad es que no


necesitamos declarar en el setup() que
vamos a usar una puerta analgica. Y la
segunda es que para tomar una muestra
(leer) del pin A5, usaremos la instruccin:
37 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

int Val = analogRead(A5) ;

Los convertidores de Arduino UNO y Mega son de 10 bits de resolucin por lo que nos devolver
valores entre 0 y 210 0 y 1.024 para tensiones entre 0 y 5V. En cambio el Arduino DUE dispone de
convertidores de 12 bits por lo que el valor de sus lecturas estar entre 0 y 1012 o sea 4.096, es
decir tiene mejor resolucin(pero slo puede leer hasta 3,3V).
Asegrate de no usar sensores que puedan dar ms de 5V mximo (con Arduino UNO y Mega),
ya que daaras el chip principal de Arduino.

Vamos a escribir un programa que lea el valor del pin A5 y lo enve a la consola, puerto serie, para
que podamos visualizarlo.

8. 5 USANDO LAS PUERTAS ANALGICAS

Prueba este programa. Ejemplo 8.1:

void setup()
{
Serial.begin(9600); // Iniciamos la puerta serie
}
void loop()
{
int Lectura = analogRead(A5) ;
Serial.println( Lectura);
delay(200) ;
}

Cuando lo vuelques, arranca la consola y veras que a medida que giras el ajuste del
potencimetro, las lecturas varan de forma continua reflejando la posicin del potencimetro, las
lecturas reflejan la caida en voltios en el potencimetro.

No puedo resistirme a proponeros esta prueba: Desconecta el potencimetro de la puerta A5 y


observa los resultados que arduino enva a la consola. Porque salen esos valores?
38 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Al no estar el A5 conectado a ninguna referencia vlida, est flotando y los valores que captura
son muestra de esa incoherencia.

8.6 UN LTIMO COMENTARIO

Decamos en una seccin anterior, que la fidelidad con que podemos muestrear una seal
analgica dependa, bsicamente, de la resolucin de la muestra y de la velocidad a la que
podamos muestrear la seal (Sample Rate en ingls).

Ya dijimos que la familia Arduino, dispone de convertidores de 10 bits por lo que nuestra
resolucin es de 210 = 1.024 y en el caso del DUE de 212 = 4.096. Pero hasta ahora no hemos
visto a qu velocidad podemos tomar muestras con nuestro Arduino. Vamos a comprobarlo, con
este mismo circuito.

Tenemos una funcin llamada millis() que nos indica en milisegundos el tiempo transcurrido
desde que iniciamos Arduino y la podemos usar para ver cuantas muestras podemos tomar por
segundo. Ejemplo 8.2:

void setup()
{
Serial.begin(9600);
}

void loop()
{
unsigned long T ;
int n = 0 ;
T = millis();
while (millis() <= T + 1000)// Mientras no pase un Segundo = 1000 mS
{
analogRead( A5) ;
n++; // Contamos cada vez que leemos
}
Serial.println(n);
}

Hemos usado un unsigned long para guardar millis porque es el tipo que Arduino usa
internamente para su reloj. Sera un error manejar millis con un int porque su valor mximo es
32.767 y midiendo milisegundos el contador desbordara en poca ms de 32 segundos.

SI corris este programa en un Arduino UNO os dar, poco ms o menos, un resultado de 8.940
muestras o lecturas por segundo. No est mal.

Es adecuado para muestrear seales que no varen demasiado rpido con el tiempo, como son
casi todos los sensores habituales en la industria, pero que se quedar corto si queris muestrear
seales de audio.

8.7 RESUMEN DE LA SESIN

Ya conocemos el uso del potencimetro.


Hemos presentado los conceptos bsicos en la conversin analgica to digital.
Aprendimos a leer las entradas analgicas de Arduino.
Sabemos que podemos leer las entradas analgicas unas 8.900 veces por segundo con una
resolucin de 10 bits, o sea entre 0 y 1.024.
Conocimos la funcin millis().
39 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

9 LAS SALIDAS ANALGICAS


Los salidas casi analgicas, PWM.
9.1 OBJETIVOS

Comprender las diferencias entre analgico y digital.


Conocer las salidas que se comportan como analgicas de Arduino.
Modulacin PWM.

9.2 MATERIAL REQUERIDO.

Arduino Uno o similar. Esta sesin acepta cualquier otro modelo de Arduino
Una Protoboard.
Un diodo LED.
una resistencia de 220 Ohmios..
Algunos cables de Protoboard..

9.3 ANALGICO Y DIGITAL

En la sesin anterior ya hemos introducido el concepto de seal analgica y hemos comprobado


como se pueden leer desde determinados pones ese tipo de seales. Veamos que mecanismo
podemos usar para generar seales que varen su valor eficaz.

En la vida muchas variables no se comportan de esta manera, es decir, apruebas o suspendes,


enciendes la luz o la apagas. Muchas otras variables son continuas y pueden tomar cualquier
valor entre un mximo y un mnimo, como la temperatura, la humedad, el ngulo de giro, etcque
aun dentro de valores finitos pueden tomar tantos valores intermedios como podamos imaginar.

A esta clase de variables las llamamos analgicas y una representacin por contraposicin a lo
digital, sera algo como esto:

40 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

No es raro que queramos controlar algo del mundo exterior con una seal analgica de forma que
el comportamiento del sistema siga esa seal. Podemos por ejemplo querer variar la luminosidad
de un diodo lampara LED y no simplemente apagarla o encenderla.

En esta sesin aprenderemos a enviar seales analgicas a alguno de los pines de salida de
Arduino.

9.4 SALIDAS CASI ANALGICAS

Hasta ahora hemos visto como activar las salidas digitales de Arduino, para encender y apagar un
LED por ejemplo. Pero no hemos visto como modificar la intensidad de brillo de ese LED. Para
ello, tenemos que modificar la tensin de salida de nuestro Arduino, o en otras palabras tenemos
que poder presentar un valor analgico de salida.

Para empezar tenemos que dejar claro que los Arduino carecen de salidas analgicas puras que
puedan hacer esto,con la notable excepcin del Arduino DUE.

Pero como los chicos de Arduino son listos, decidieron emplear un truco, para que con una salida
digital podamos conseguir que casi parezca una salida analgica.

A este truco se le llama PWM, siglas de Pulse Width Modulation, o modulacin de ancho de
pulsos. La idea bsica es poner salidas digitales que varan de forma muy rpida de modo que el
valor eficaz de la seal de salida sea equivalente a una seal analgica de menor voltaje.

Lo sorprendente es que el truco funciona.

Fijaros en la anchura del pulso cuadrado de arriba. Cuanto mas ancho es, mas tensin promedio
hay presente entre los pines, y esto en el mundo exterior es equivalente a un valor analgico de
tensin comprendido entre 0 y 5V. Al 50% es equivalente a una seal analogica del 50% de 5V,
es decir 2,5. Si mantenemos los 5V un 75% del tiempo, ser el equivalente a una seal analgica
de 75% de 5V = 3,75 V.

Para poder usar un pin digital de Arduino como salida analgica, lo declaramos en el Setup() igual
que si fuera digital:

41 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

pinMode( 9, OUTPUT) ;

La diferencia viene a la hora de escribir en el pin:

digitalWrite(9, HIGH); //Pone 5V en la salida


digitalWrite(9, LOW); //Pone 0V en la salida
analogWrite( 9, V) ;

analogWrite escribe en el pin de salida un valor entre 0 y 5V, dependiendo de V, que debe estar
comprendido entre 0 y 255.

De este modo si conectamos un LED a una de estas salidas PWM podemos modificar su brillo sin
ms que variar el valor que escribimos en el pin.

Pero hay una restriccin. No todos los pines digitales de Arduino aceptan poner valores PWM en
la salida. Solamente aquellos que tienen un smbolo ~ delante del nmero. Fijaros en la
numeracin de los pines de la imagen:

Solamente los pines 3, 5, 6, 9, 10 y 11 pueden hacer PWM y simular un valor analgico en su


salida.

Si intentas hacer esto con un pin diferente, Arduino acepta la orden tranquilamente, sin error, pero
para valores de 0 a 127 entiende que es LOW y para el resto lo pone HIGH y sigue con su vida
satisfecho con el deber cumplido.

9.5 MODIFICANDO EL BRILLO DE UN LED

Vamos a hacer el tpico montaje de una resistencia y un diodo LED, similar al de la sesin 3, pero
asegurndonos de usar uno de los pines digitales que pueden dar seales PWM. En el ejemplo he
usado el pin 9.
Podemos escribir un programa parecido a esto:

void setup()
{
pinMode( 9, OUTPUT) ;
}
void loop()
{
for ( int i= 0 ; i<255 ; i++)
{
42 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

analogWrite (9, i) ;
delay( 10);
}
}
El LED va aumentando el brillo hasta un mximo y vuelve a empezar bruscamente. Podemos
modificar un poco el programa para que la transicin sea menos violenta:

void setup() //

{
pinMode( 9, OUTPUT) ;
}

void loop()
{
for ( int i= -255 ; i<255 ; i++)
{
analogWrite (9, abs(i)) ;
delay( 10);
}
}

Aqu aprovecho para hacer con un nico bucle for el ciclo de subir y bajar el brillo del LED. La
funcin abs(num), devuelve el valor absoluto o sin signo de un nmero num, y por eso mientras
que i va de -255 a 255, abs(i) va de 255 a 0 y vuelta a subir a 255.

9.6 RESUMEN DE LA SESIN

Describimos a grandes rasgos la diferencia ente valores digitales y valores analgicos.


Hemos visto como simular valores analgicos en una salida digital de Arduino.
Solo con las salidas que lo aceptan: pines 3, 5, 6, 9, 10 y 1.
Podemos asignar valores entre 0 y 255.

43 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

10 DISPLAYS LCD
Usando displays de texto LCD 16x2 con Arduino

10.1 OBJETIVOS

Cmo conectar un display LCD de 162.


Cmo enviar informacin al display desde Arduino
Cmo presentar la informacin en el display LCD.

10.2 MATERIAL NECESARIO.

Arduino Uno o similar. Esta sesin acepta cualquier otro modelo de Arduino.
Una Protoboard.
Cables de conexin.
Una resistencia ajustable de 10K.
Un display LCD, de 162 o 164.

10.3 LOS DISPLAYS LCD

Los displays LCD se utilizan para mostrar mensajes de texto sencillos. Son fciles de encontrar en
diversos formatos : 162 (16 caracteres x 2 lneas) o LCD 164 (16 caracteres x4 lneas). LCD
viene del ingls Liquid Crystal Display, o sea Pantalla de cristal liquido.

Son una opcin muy sencilla de usar, y adems, dan un toque muy profesional a nuestros
proyectos, y por eso, en los ltimos aos los displays LCD han ganado mucha aceptacin en
productos comerciales de todo tipo.

Bsicamente porque:

Son baratos.
Estn disponibles en varios tamaos y configuraciones.
Son de bajo consumo.
Muy prcticos si te basta con mostrar solo texto (y algunos caracteres especiales).

En esta sesin veremos cmo conectarlos a vuestro Arduino y cmo usarlos para sacar mensajes
por ellos, procedentes de Arduino.

44 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

10.4 DIAGRAMA DE CONEXIN

Aqu tienes el esquema de conexin.

Y este es el esquema para protoboard:

La conexin no es complicada, pero requiere ser cuidadoso. As que vamos a ir paso a paso con
los diferentes cables. Empieza conectando tensin y GND a la protoboard.
45 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Paso 1
Aunque no aparece en el esquema, vamos a conectar la retro iluminacin del panel LCD. Conecta
el pin16 del LCD a GND y el 15 a 5V. Si conectas ahora el cable USB a tu ARDUINO, el LCD
debera iluminarse, si no, revisa tus cables antes de seguir.

Paso 2
Desconecta el USB y conecta ahora, el potencimetro de ajuste. Para ello conecta uno de los
extremos del potencimetro a GND y el otro a 5V. El centro al pin 3 del LCD. Aprovechemos
tambin para dar tensin al display LCD, El pin 1 va a GND y el 2 a 5V:

Paso 3
Si todo ha ido bien, ya podemos encender el display y probarlo. Conecta el USB a tu Arduino y
veamos. Si vas girando el potencimetro, en algn momento tienes que ver unos cuadraditos en la
pantalla, en caso contrario revisa las conexiones. No sigas, si no ves esto.

Si ya veis las matrices de puntos en la pantalla, podemos seguir.

Paso 4
Vamos a conectar ya los pines de datos y control. Sin entrar en muchos detallas, no vamos a usar
todos los pines disponibles, porque no los necesitamos. Solo usaremos dos pines de control, RS y
EN y los 4 pines de datos D7, D6, D5, y D4 . No necesitamos mas por ahora.

Vamos con las conexiones de control del display:

RW, LCD pin 5 a GND


RS, LCD pin 4 a Arduino pin 12
EN, LCD pin 6 a Arduino pin 11

Y ya solo nos quedan los 4 cables de datos.

DB7, LCD pin 14 a Arduino pin 2


DB6, LCD pin 13 a Arduino pin 3
DB5, LCD pin 12 a Arduino pin 4
DB4, LCD pin 11 a Arduino pin 5

12.5 EL PROGRAMA DE CONTROL

Vamos a usar una librera para el control del panel LCD, que viene incluida en nuestro Arduino.
Pinchad en: \\Programa\Importar Libreria\LiquidCrystal. Y ahora podemos importar uno de los
ejemplos o escribir el nuestro, comentando el cdigo.

Lo primero es que al importar la librera nos ha escrito esto:

#include <LiquidCrystal.h>

Despus, hay que inicializar la librera. Creamos una instancia llamada lcd, de la clase
LiquidCrystal y le pasamos como parmetros los pines que hemos usado:
46 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // ( RS, EN, d4, d5, d6, d7)

Tened cuidado porque los pines que hemos usado, no corresponden a los ejemplos de Arduino,
as que podis cargarlos, pero aseguraros de cambiar la lnea de definicin de los pines, o no
funcionaran.

El resto es sencillo. Ejemplo 12.1:

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2); // ( RS, EN, d4, d5, d6, d7)
void setup()
{
lcd.begin(16, 2); // Fijar el numero de caracteres y de filas
}
void loop()
{
lcd.setCursor(0, 0); // coloca el cursor en la columna 0 lnea 0
lcd.print("Curso iDOM 16-17"); // Enviar el mensaje
lcd.setCursor(0, 1); // coloca el cursor en la columna 0 lnea 1
lcd.print(millis()/1000);//muestra el n de seg. desde el reset
}

Ojo: Como siempre la primera linea, la superior, es la linea 0 y la segunda la linea 1.

Ejemplo 12.2: Otro ejemplo muy sencillo es el siguiente, que muestra en el LCD aquello que se
escribe en el Serial monitor en tiempo real (suponiendo que nuestra placa Arduino la tenemos
conectada a un computador va USB).

#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int luzFondo = 13; //Defino el pin para la luz de fondo
void setup() {
pinMode(luzFondo, OUTPUT);
digitalWrite(luzFondo, HIGH); //Activo la luz de fondo
lcd.begin(16,2);
Serial.begin(115200);
}
void loop() {
if (Serial.available()>0) {
//Me espero un poco para que llegue el mensaje entero
delay(100);
lcd.clear();
//Leo todos los caracteres disponibles del buffer
while (Serial.available() > 0) {
//Muestro cada carcter en el LCD
lcd.write(Serial.read());
}
}
}

La librera LCD, viene con varios ejemplos muy interesantes, que os conviene probar. Recordad,
simplemente, que tenis que cambiar las definiciones de los pines para que funcionen en vuestro
montaje.

Un ejemplo particularmente interesante, es el de CustomCharacter, en el que define una serie de


smbolos especiales y los mueve por la pantalla en funcin de los valores que lee de un
potencimetro.

47 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Sin llegar a tanta sofisticacin, es muy interesante que veamos cmo definir algunos caracteres
especiales, porque en la tabla base del LCD, no estn incluidas , acentos, grados, o . As que
dependiendo del uso que le deis pude seros de inters saber cmo definir tus propios smbolos.

10.6 LA LIBRERA LiquidCrystal

Lo primero que debemos hacer para poder utilizar pantallas LCD compatibles con la librera oficial
LiquidCrystal es declarar una variable global de tipo LiquidCrystal, la cual representar dentro de
nuestro sketch al objeto LCD que queremos controlar. La declaracin se ha de realizar usando la
siguiente sintaxis (suponiendo que llamamos milcd a dicha variable-objeto): LiquidCrystal
milcd(rs, rw, enable, d0, d1, d2, d3, d4, d5, d6, d7); donde todos los parmetros especificados
entre parntesis en realidad son valores numricos que representan:

rs : no del pin de la placa Arduino conectado al pin RS de la LCD.


rw: no del pin de la placa Arduino conectado al pin RW de la LCD. Opcional.
enable: no del pin de la placa Arduino conectado al pin ENABLE de la LCD.
d0... hasta d7: los nmeros de los pines de la placa Arduino conectados a los
pines de datos correspondientes de la LCD. Los parmetros d0, d1, d2 y d3 son opcionales: si se
omiten, la LCD ser controlada usando solo cuatro lneas (d4, d5, d6, d7) en vez de 8.

Por ejemplo, una posible declaracin para una LCD de 4 bits sin uso del pin rw podra ser:

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

Una vez creado el objeto lcd con la lnea anterior, lo primero que debemos hacer es establecer el
tamao de la pantalla para poder trabajar con ella. Esto se hace mediante la siguiente funcin:

lcd.begin(): especifica las dimensiones (columnas y filas) de la pantalla. Tiene dos


parmetros: el primero es el nmero de columnas que tiene la pantalla y el segundo es el
nmero de filas. No tiene valor de retorno. Esta funcin ha de ser ejecutada antes de poder
empezar a imprimir ningn carcter en ella.

A partir de aqu, ya podremos escribir caracteres en la pantalla con alguna de las tres funciones
siguientes:

lcd.write(): escribe un carcter en la pantalla. Como nico parmetro tiene ese carcter, el
cual se puede especificar explcitamente entre comillas simples o bien a travs de una variable
de tipo byte (cuyo valor puede haber sido obtenido de un sensor, o ledo del canal serie,
etc.). Su dato de retorno es de tipo byte y vale el nmero de bytes escritos (por tanto, si todo
es correcto, valdr 1, aunque no es obligatorio utilizarlo.

lcd.print(): escribe un dato (de cualquier tipo) en la pantalla. Como primer parmetro tiene ese
dato, que puede ser tanto un carcter de tipo char como una cadena de caracteres, pero
tambin puede ser numrico entero (int, long, etc.). Opcionalmente, se puede especificar un
segundo parmetro que indica, en el caso de que el dato a escribir sea entero, el formato con
el que se ver: puede valer la constante predefinida BIN (que indicar que el nmero se
visualizar en formato binario), HEX (en hexadecimal) y DEC (en decimal, que es su valor por
defecto). Su dato de retorno es de tipo byte y vale el nmero de bytes escritos, aunque no es
obligatorio utilizarlo.

lcd.createChar(): crea un carcter totalmente personalizado. Se pueden crear hasta ocho


caracteres diferentes de 5x8 pxeles cada uno. La apariencia de cada carcter es especificada
por un array de 8 bytes. Cada uno de estos bytes representa una fila de pxeles. Cada fila de
pxeles se dibuja dependiendo de los valores de los ltimos cinco bits (los de ms a la
48 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

derecha) de su byte correspondiente: si el bit vale 1, se pintar el pxel pertinente y si vale 0,


no. No obstante, esta funcin no escribe el carcter en la pantalla, tan solo lo crea; para
poderlo escribir, deberemos utilizar lcd.write(). Esta funcin tiene dos parmetros: el primero
es la identificacin del carcter a crear (puede ser un nmero entre 0 y 7) y el segundo es el
array con el dibujo de los pxeles. Para transformar el dibujo que queremos en los valores
adecuados del array, podemos usar la ayuda interactiva que ofrece la pgina http://
www.quinapalus.com/hd44780udg.html.

10.7 RESUMEN DE LA SESIN

Hemos visto los displays LCD de 16 caracteres y 2 lneas.


Cmo usar la librera LiquidCrysta que incorpora una serie de funciones que nos permiten manejar
el LCD de forma cmoda y sencilla.

49 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

10 FUNCIONES Y ENTEROS
Definiendo funciones y diferentes tipos de enteros
10.1 OBJETIVOS

Operar con enteros.


Aprender a definir funciones en Arduino.
Trabajar el pensamiento lgico y algortmico.
Diferentes tipos de enteros en C++.

10.2 MATERIAL NECESARIO.

Arduino Uno o similar.


Un PC con el entorno de Arduino correctamente instalado y configurado.

10.3 LA PRIMERA FUNCIN: CALCULANDO SI UN NMERO ES PRIMO

Ya hemos comentado antes, que programar es un poco como andar en bici, se aprende
pedaleando y a programar se aprende programando. Hay que ir aprendiendo la sintaxis del
lenguaje, C++ en nuestro caso, pero tambin aprendiendo a resolver problemas lgicos y partirlos
en instrucciones.

Hacer cursos de programacin, o de andar en bici, est bien, pero al final hay que ponerse a
programar y tener problemas, porque tenindolos y resolviendo los problemas, solo o con ayuda
de alguien, se aprende. No se puede aprender a montar en bici slo estudiando.

Con un cierto temblor de manos, vamos a centrarnos en esta sesin en algunos ejemplos clsicos
de programacin, como son el clculo de nmeros primos para entrenar esta capacidad de
bsqueda de algoritmos prcticos para resolver problemas ms o menos abstractos y para
presentar algunos conceptos adicionales.

Es importante destacar que no existe una forma nica de resolver un problema concreto y que una
solucin no tiene porque ser mejor que otra, aunque con frecuencia se aplican criterios de
eficiencia o elegancia para seleccionar una solucin.

Esta sesin va a requerir un esfuerzo un poco mayor que las anteriores porque vamos a empezar
a entrenar un msculo poco usado, el cerebro, en una tarea poco frecuente, pensar. Y esto es
algo que exige un poco de esfuerzo, pero es necesario para avanzar.

Supongamos que queremos crear un programa que nos devuelva true o false segn que el
nmero que le pasamos sea primo o no y que podamos llamar varias veces sin copiar el cdigo
una y otra vez. La llamaremos Primo () y queremos utilizarla de la siguiente manera: Si el numero
n que le pasamos es primo nos tiene que devolver true y en caso contrario que devuelva false, o
sea queremos que nos devuelva un valor bool.

Esto es lo que llamamos una funcin.

En realidad, ya hemos utilizado varias funciones que Arduino trae predefinidas como Serial.print()
o abs() , o Serial.available() y se las reconoce por esa apertura y cierre de parntesis.

C++ nos ofrece todas las herramientas para crear nuestras propias funciones y es algo muy til
porque nos ayuda a organizar un problema general en trozos o funciones ms pequeas y ms
fciles de manejar.
50 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Para definir una funcin as, tenemos que declararla primero y describirle a C++ que hacer:

bool Primo( int x) // int x representa el parmetro que pasaremos a esta


//funcin
{
Aqu va lo que tiene que hacer

return( bool);
}

Declaramos la funcin como bool Primo (int x), o sea va a devolver un valor bool y por eso en
algn punto de la funcin tendremos que usar la instruccin return( true) o return( false) para
devolver un resultado a quien la llame. Si devolviera un entero habra que definirla como int
Primo( int x).

Si una funcin no va a devolver ningn valor, sino que simplemente realiza su trabajo y finaliza sin
mas entonces hay que declararla como void (vaca). Ya conocemos dos funciones as : setup() y
loop().

Veamos cmo podra ser el cdigo de la funcin Primo():

bool Primo( int n)


{
for ( int i = 2 ; i <n ; i++)
{
if ( n % i == 0) // Si el resto es 0 entonces es divisible.
{
Serial.println(String(n)+"es divisible por: " + String(i));
return(false) ;
}
}
return (true) ;
}

Para saber si un nmero es o no primo basta con dividirlo por todos los nmeros positivos
menores que l y mayores que 1. En el ejemplo dividimos el nmero n empezando en 2 y
finalizando en n-1.

Si encontramos un valor de i que devuelve resto 0, entonces es divisible (no es primo),


devolvemos false con return y volvemos a la instruccion que llamo a la funcin. Si no hallamos
ningn divisor, al finalizar el for devolvemos true y listo. Este es el mtodo de fuerza bruta y sin
duda es mejorable pero de momento nos sirve.

Para usar Primo hay que pasarle un entero. Recordad que al definir la funcin dijimos bool Primo
(int n) donde n representa el valor que queremos probar. As pues:

void loop()
{
int x =48; //el nmero a probar
bool p = Primo(x);
if (p)
Serial.println(String(x) + " Es primo.");
else
Serial.print(String(x) + " No es primo, el ");
}

51 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Veamos un ejemplo distinto, cuantos nmeros primos hay desde el 1 hasta el 1024:

bool control = true;


int maximo = 1024;

void setup()
{
Serial.begin(9600); // Inicializa el pueto serie a 9600 bps
}

void loop()
{
if (control)// para que realice el lazo una sola vez
//y no lo repita indefindamente
{
Serial.println("Los nmero primos hasta el " +String(maximo));
for(int x=2;x<maximo;x++)
{
bool p = Primo(x);
if(p) Serial.println(x);
}
}
control=false;
}

bool Primo(int n)
{
for(int i=2;i<n;i++)
{
if(n%i ==0) // S el resto es cero es divisible.
return(false);
}
return(true);
}

Aunque el programa funciona correctamente la salida no es muy presentable( Recordad que nos
gusta ser elegantes). Vamos a formatearla. Para ello usaremos el carcter tabulador que se
representa como \t y una coma despus.

bool control = true;


int maximo = 1024;
int contador=1;
bool Primo (int); // declaramos la funcin Primo()

void setup()
{
Serial.begin(9600); // Inicializa el pueto serie a 9600 bps
}

void loop()
{
if (control)// para que realice el lazo una sola vez
//y no lo repita indefindamente
{
Serial.println("Los numeros primos hasta el " +String(maximo));
for(int x=2;x<maximo;x++)
{
if(Primo(x)) // mandamos ha imprimir el numero
{
52 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

if( contador++ %8 ==0)


Serial.println(String(x)+",");// hasta completar a 8 por
lnea
// y salta de linea
else
Serial.print(String(x)+","+'\t');// mete un tabulador entre
cada nmero
}
}
}
control=false;
}

bool Primo(int n)// Definimos la funcin Primo()


{
for(int i=2;i<n;i++)
{
if(n%i ==0) // S el resto es cero es divisible.
return(false);
}
return(true);
}

Ahora el programa formatea la salida de una forma un poco ms presentable y cmoda de leer.

Para conseguirlo, hemos aadido una coma y un tabulador a cada nmero excepto a uno de cada
8 que aadimos intro. Tambin tenemos una lnea que conviene comentar:

if ( contador++ % 8 == 0)

53 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Cuando a una variable se le aaden dos signos mas al nombre (++), significa que primero se use
su valor actual en la instruccin en curso, en este caso es en el if, y despus se incremente en 1
su valor.

Si hubiramos escrito:

if ( ++contador % 8 == 0)

Querra decir que queremos incrementar su valor antes de utilizarlo. Esta notacin es muy habitual
en C++ y conviene reconocerla. Tambin podemos usar contador- - y - - contador para
decrementar.

10.4 EL TIPO ENTERO

Este sera un buen momento para preguntarnos hasta donde podra crecer la variable mximo en
el programa anterior. Le asignamos un valor de 1024, pero Tiene un entero lmite de tamao?

La respuesta es afirmativa. Los enteros int en Arduino C++ utilizan 16 bits por lo que el mximo
seria en principio 216 = 65.536, Pero como el tipo int usa signo, su valor est comprendido entre
-32.768 y +32.767.

De hecho en Arduino C++ hay varios tipos distintos de tamaos para manejar enteros:

Todos estos tipos representan enteros con y sin signo y se pueden utilizar para trabajar con
nmeros realmente grandes pero no sin lmite.

De hecho C++ tiene la fea costumbre de esperar que nosotros llevemos el cuidado de no
pasarnos metiendo un valor que no cabe en una variable. Cuando esto ocurre se le llama
desbordamiento (overflow) y C++ ignora olmpicamente el asunto, dando lugar a problemas
difciles de detectar si uno no anda con tiento.

Prueba a calcular esto en un programa:

int i = 32767 ;
Serial.println ( i+1);

Enseguida veras que si i=32767 y le incrementamos en 1, para C++ el resultado es negativo. Eso
es porque sencillamente no controla el desbordamiento. Tambin es ilustrativo probar el resultado
de:

int i = 32767 ;
Serial.println (2* i + 1);

Que segn Arduino es -1.

Esto no es un error, sino que se decidi as en su da y C++ no controla los desbordamientos, as


que mucho cuidado, porque este tipo de errores pueden ser muy complicados de detectar

10.5 MS SOBRE LAS FUNCIONES EN C++

Hemos visto ya de pasada las dos funciones o rutinas principales de un sketch: setup() y loop().
Ambas se declaran de tipo void, lo cual significa que no retornan ningn valor. Arduino simplifica
muchas tareas proporcionando funciones que permiten controlar entradas y salidas tanto
analgicas como digitales, funciones matemticas y trigonomtricas, temporales, etc.

54 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Tu puedes tambin escribir tus propias funciones cuando necesites programar tareas o clculos
repetitivos que vas a usar varias veces en tu programa(o en futuros programas). La primera cosa
que tienes que hacer es declarar el tipo de funcin ,int si retorna un entero, float si es un nmero
en coma flotante, etc).

Te recomendamos dar a la funcin un nombre que tenga que ver con lo que hace para que te
resulte fcil recordarla, o identificarla cuando la veas escrita en uno de tus programas. A
continuacin del nombre de la funcin y sin dejar espacios, van los parmetros de la funcin
entre parntesis. Y ya slo queda lo ms difcil: escribir el cdigo de la funcin entre llaves:

type functionName(parameters)
{
// el cdigo de la funcin va aqu.
}

Recuerda que si la funcin no retorna un valor hay que definirla como de tipo void (vacio). Para
devolver el control al programa la funcin usa la instruccin return seguida por el nombre de la
variable que se quiere devolver y luego un punto y coma (;).

La siguiente rutina muestra una funcin que convierte una temperatura expresada en grados
Fahrenheit a Celsius o grados centgrados:

float calcTemp(float fahrenheit){


float celsius;
celsius = (fahrenheit 32)/ 1.8;
return celsius;
}

La funcin se declara de tipo float y se le pasa un parmetro, tambin de tipo float, que representa
los grados Fahrenheit medidos por un sensor. Dentro de la funcin se declara la variable Celsius
de tipo float que va a contener la medida de la temperatura pasada en Fahrenheit tras su
conversin a Celsius. La instruccin return devuelve el valor en Celsius de la temperatura pasada
en Farenheit. Esta funcin puede ser usada como parte de un sistema para registrar las
temperaturas captadas por un sensor a lo largo del tiempo.

Como puedes ver, el uso de funciones es la manera ideal de simplificar tu cdigo y abordar tareas
repetitivas.

10.6 RESUMEN DE LA SESIN

Hemos definido una funcin propia para saber si un nmero es primo.


Vimos que el tipo entero tiene un lmite de tamao.
Conocimos tipos con mayor y menor capacidad para manejar nmeros enteros mas o menos
grandes, pero que todos siguen teniendo un lmite de tamao.
El efecto de desbordamiento de tipos es clave y debe ser tenido muy en cuanta cuando
operamos con enteros.
Hemos ido jugando con problemas lgicos y hemos visto algunas soluciones que os pueden
ayudar a plantear las vuestras propias.

55 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

11 UN PROGRAMA CON VARIAS


FUNCIONES
Un programa un poco mas complicado
11.1 OBJETIVOS

Aprender a operar con Arrays .


Como partir un problema en funciones especialistas.
Operar con enteros y Strings.
Entrenar y desarrollar algunas habilidades claves para programar.

11.2 MATERIAL NECESARIO.


Arduino Uno o similar.
Un PC con el entorno de Arduino correctamente instalado y configurado.

11.3 PLANTEANDO UN PROGRAMA UN POCO MS COMPLICADO.

Hemos visto en la sesin anterior, como definir funciones. En esta sesin vamos a ampliar el
programa que comprobaba si un nmero era primo, en ste nuevo programa introduciremos por
consola un nmero y el programa deber comprobar si es o no primo imprimiendo por consola el
resultado de la comprobacin.

Normalmente para resolver un problema complejo es buena poltica partirlo en otros problemas
ms pequeos que podamos resolver ms fcilmente. En este caso vamos a plantear al menos 2
funciones:

Primo() Calcula si un nmero dado es primo, devuelve true y en caso contrario false.
getLine() Vamos a definir una funcin genrica que recoja una cadena de texto de la puerta
serie, para procesarla a posteriori. En este caso recoger el nmero a probar.

La idea es, que nuestro programa empiece comprobando si un numero es primo. Y por ultimo
necesitamos una funcin que nos lea un numero de entrada desde la consola.

Fijaros que casi sin haber escrito una linea de programa, ya he decidido como partirlo en bloques
mas sencillos de manejar y programar. En otras palabras, he buscado una estrategia, de
resolucin

11.4 OPERANDO CON ARRAYS.

Un array es simplemente una coleccin de elementos organizados como una tabla, y pueden
definirse con varias dimensiones. Empecemos con un array de una sola dimensin. Para definirlo
podemos optar por dos maneras:

int serie1[5] ; //Creamos una coleccin de 5 enteros


int serie2[] = { 3,5,6,12,23} ;

En el primer caso definimos un array de enteros, de una sola dimensin con 5 elementos, sin
asignarle valores.

56 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

En el segundo caso asignamos un array de enteros a los valores que le pasamos entre llaves, sin
especificar cuantos, porque le dejamos a C++ la tarea de contarlos. Decimos que definimos el
array por enumeracin.

Para asignar o leer los valores de un array se utiliza un ndice entre corchetes. Veamos este
programa:

int serie2[] = { 3,5,6,12, 23} ;


void setup()
{
Serial.begin(9600) ;
}
void loop()
{
for (int i=0 ; i<5 ; i++)
Serial.println("Posicion "+String(i)+": +String(serie2[i]));
delay(2000);
}

El programa imprime el contenido del array recorriendo sus 5 posiciones, indicando posicin y
contenido.Esto lo hace de forma repetida cada 2 segundos.

Atencin: la primera posicin del un array es la 0 y la ltima el nmero de elementos del array 1.
As serie2 [0] devuelve el primer elemento 3, y serie2[4] el ltimo 23.

Un error muy peligroso, y difcil de detectar sera algo as:

int serie2[] = { 3,5,6,12, 23} ;


for (int i=0 ; i<99 ; i++)
Serial.println("Posicion " + String(i)+ ": "+ String(serie2[i])) ;

Uno esperara que C++ generase un error, ya que definimos un array de 5 elementos y hacemos
referencia a 100, pero no. Nuevamente C++ nos sorprende devolviendo correctamente los 5
primeros valores y luego sigue leyendo posiciones de memoria consecutivas tan tranquilo, como si
tuvieran sentido.C++ espera que seamos nosotros quienes controlemos esto, as que mucho
cuidado.

Por ltimo, mencionar que podemos manejar arrays de varias dimensiones:

Int Tablero[8,8];

Imaginad que Tablero representa las posiciones de una partida de ajedrez y cada valor que
contiene esa posicin corresponde a una pieza que se encuentra en esa casilla.

11.5 LA FUNCIN GETLINE()

Aunque ya comentamos que podemos usar una funcin parseInt () incluida en Arduino para
recoger un valor del puerto serie, tiene el inconveniente de que si no recibe una entrada salta al
cabo de un tiempo ( muy escasito) y devuelve 0, por lo que tendramos que controlar el valor
devuelto para que no se repitiese continuamente.

Por eso vamos a escribir una funcin de uso general que nos permita recoger una cadena de texto
de la puerta serie sin que salga hasta que reciba un String que vamos a hacer finalice en intro. De
hecho ya vimos este programa, aunque no como funcin en la sesin Comunicacin con el
exterior

57 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

String GetLine()
{
String S = "" ;
if (Serial.available())
{
char c = Serial.read(); ;
while ( c != '\n')//Hasta que el character sea intro
{
S = S + c ;
delay(25) ;
c = Serial.read();
}
return(S) ;
}
}
Definimos Getline() de tipo String, porque queremos que nos devuelva un texto. Comprobamos
que hay algo disponible en la puerta serie, y en caso afirmativo construimos un String S
aadindole cada uno de los caracteres que leemos del puerto serie, hasta que encontremos un
intro.

Al encontrar el intro, se cumple la condicin de salida del while y termina la funcin devolviendo la
cadena construida (sin el intro).

Normalmente convendr comprobar si hay algo disponible en la puerta serie antes de llamar a
GetLine(), y si es as, la comprobacin que hace GetLine() de tener algo disponible en el Serial
seria redundante.

Pero si llamramos a GetLine() sin comprobarlo y esta no lo controlase, quedaramos atrapados


en esta funcin hasta que alguien escribiera algo finalizado con intro para poder salir y podra no
ser sencillo comprender el problema.

Nuevamente hemos incluido un delay de 25 ms en el while para asegurarnos de que Arduino no


puede volver a leer mas caracteres antes de que a la velocidad de 9600 bps haya llegado el
prximo carcter. Si la velocidad de comunicacin es de 115200 bits por segundo o ms, se puede
suprimir este retraso.

11.6 EL PROGRAMA PRINCIPAL

Podemos ya escribir nuestra funcin principal loop(), que llame a las funciones que hemos
definido a lo largo de esta sesin, para determinar si un numero que le pasamos por la puerta
serie es primo o no y en caso negativo que nos muestre los divisores primos encontrados.

Podra ser algo as:Calcula si un nmero es primo en arduino:

void setup()
{
Serial.begin(9600) ;
}
void loop()
{
if (Serial.available())
{
String s = GetLine();
int i = s.toInt() ;//Como esperamos un numero,
convertimos el texto a numero
if ( Primo(i))
Serial.println(String(i) + " Es primo.");
else
58 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

Serial.println(String(i) + " No es primo.");


}
}

String GetLine()
{
String S = "" ;
if (Serial.available())
{
char c = Serial.read(); ;
while ( c != '\n')//Hasta que el character sea intro
{
S = S + c ;
delay(25) ;
c = Serial.read();
}
return(S) ;
}
}

bool Primo(int n)
{
for(int i=2;i<n;i++)
{
if(n%i ==0) // S el resto es cero es divisible.
return(false);
}
return(true);
}

Empezamos comprobando si hay algo sin leer en la puerta serie y si es asi llamamos a GetLine()
para que nos consiga lo que hay.

Como GetLine() nos devuelve un tipo String() usamos la funcin estndar de Arduino C++, s.toInt()
que convierte el contenido String a tipo numrico int.

Despus llamamos a Primo() para que compruebe este nmero. Y, simplemente imprime un
mensaje para confirmarlo.

11.7 RESUMEN DE LA SESIN

Hemos operado con arrays de una nica dimensin.


Hemos utilizado el programa de primos como excusa para mostrar cmo se pueden resolver
problemas complejos, dividindolos en otros ms sencillos que podamos resolver con funciones
simples.
Esta es, sin duda, una de las habilidades clave para ser un programador competente, y como
todo en la vida requiere practica e ir trabajando.
Tambin hemos definido una funcin de propsito general GetLine() que utilizaremos ms veces
en el futuro.

59 de 60
2016-17 PRIMEROS PASOS CON ARDUINO

60 de 60

Вам также может понравиться