Subido por jdoblevg

Arduino 7

Anuncio
Arduino
Arduino es una plataforma de desarrollo en base a un microcontrolador ATMEL de código
abierto y hardware libre.
Por hardware libre se entiende a todos los dispositivos cuyas especificaciones y
diagramas son de acceso público, de manera que cualquiera puede replicarlos. Esto
quiere decir que Arduino ofrece las bases de información para que cualquier otra persona
o empresa pueda crear sus propias placas, pudiendo ser diferentes entre ellas pero
igualmente funcionales al partir de la misma base.
El software libre son los programas informáticos cuyo código está disponible para que
cualquiera pueda utilizarlo y modificarlo.
Una plataforma de desarrollo es una plaqueta con un uC a la que puedo cargarle un
programa para que ejecute y desarrolle ciertas tareas. (básicamente un prototipo)
Actualmente hay varias placas de desarrollo; Arduino y Raspberry Pi son las más
conocidas.
A diferencia de Raspberry, que es sistema similar a una microcomputadora del tamaño de
una tarjeta de crédito, Arduino es una plataforma que cuenta con varias opciones de
placas y microcontroladores, aunque todos de la línea ATMEL.
Los tres tipos de Arduino más populares son: NANO, UNO y MEGA. Las dos primeras
versiones cuentan con un microcontrolador (uC) ATMEGA328 mientras que el Arduino
MEGA cuenta con un ATMEGA2560 (mucho más potente que el anterior).
Veamos la placa de un Arduino UNO, que es prácticamente un estándar en la industria.
1
A primera vista se destaca el microcontrolador. Hay otras versiones de Arduino UNO en
los que el uC es de montaje superficial, sin zócalo. Obviamente funciona igual, el
inconveniente es que si se daña ese circuito integrado, al no poder reemplazarlo hay que
tirar la placa.
Hay un conector para la alimentación y otro conector para la conexión a una PC de forma
de cargarle el programa. Este es un conector USB (microUSB en otros tipos de Arduino).
Hay un segundo microcontrolador en la placa, está indicado como ATmega16U2, este es
siempre de montaje superficial y permite la comunicación entre la placa y la computadora
que le carga el programa. (algunas placas de Arduino UNO pueden tener otros circuitos
integrados para cumplir con esta función)
Ambos microcontroladores tienen los cristales que les dan la señal de sincronismo (reloj/
clock). En el caso del ATmega16U2 se lo ve a simple vista, está a su izquierda en la foto.
El cristal del microcontrolador principal es mucho más chico, difícil de distinguir a simple
vista.
A la derecha del conector de alimentación hay un regulador serie del tipo 7805 que baja la
tensión de alimentación a los 5 volts que requieren los microcontroladores para operar sin
correctamente.
A la derecha del conector USB hay un pulsador que es el Reset. Al oprimirlo el sistema se
reinicia y comienza a ejecutar el programa cargado en el ATmega328 desde cero.
Finalmente a los costados de la placa están dispuestas las entradas y salidas del sistema.
Son pines numerados que permitirán enviar señales a perisféricos (leds, motores,
válvulas, reles, display, etc.) si se los configura como salida o bien leer datos (sensores,
pulsadores, interruptores, teclados, etc.) si se los configura como entradas. Algunos de
estos pines también llevan tensiones para alimentar componentes externos, tanto de 5
como de 3,3 v. Hay otros pines especiales que veremos al momento de necesitarlos.
Arduino además de la placa ofrece la plataforma Arduino IDE (Entorno de Desarrollo
Integrado), que es un software de programación con el que cualquiera puede crear
aplicaciones para las placas Arduino.
Este entorno de programación es una aplicación que se instala en la PC y permite
escribir los programas en un lenguaje similar al C++, compilarlo (transformar las
instrucciones entendibles para el ser humano en un archivo binario ejecutable) y luego
conectarse con la placa para “subirle el programa”. Esta interfase de programación
también cuenta con una cantidad de librerías y ejemplos básicos. Las librerías son
pequeños programas que permiten realizar operaciones tales como conectar la placa
Arduino con un módulo LCD sin ninguna programación adicional por parte del
programador más que aclarar que quiere que se vea en el display.
La carga del programa desde la PC al Arduino es posible porque el uC ya cuenta con un
programa cargado que permite la comunicación. A ese programa se lo llama Bootloader.
Para aprovechar la enorme potencialidad de estas plataformas de desarrollo lo primero es
comprender el lenguaje que permite programarlas, y eso es lo que haremos a
continuación.
Por empezar diremos que un programa es una secuencia ordenada de instrucciones, que
el microcontrolador ejecutará una por una y en órden. Dada la velocidad a la que el uC
ejecuta instrucciones (puede ejecutar cada instrucción en algunos microsegundos), al ser
humano le da la sensación de que muchas ocurren al mismo tiempo pero, realmente el
controlador ejecuta una luego de haber ejecutado la anterior.
2
A los programas de Arduino se los llama scketch, y son los que luego de compilados se
cargarán en la plaqueta Arduino para que esta los ejecute.
Todo scketch constará al menos de dos funciones:
void setup ()
{
}
Entre las llaves se colocan todas las instrucciones de configuración del programa, que se
ejecutarán una sola vez ni bien se alimente al Arduino.
Un ejemplo de instrucciones que se colocan en la función setup (configuración) son las
que configuran los pines para que trabajen como entrada o como salida. Una vez
definidas dentro del setup, el programa las podrá utilizar convenientemente.
Otro ejemplo podría ser configurar la velocidad a la que se comunica el Arduino con un
módulo Bluetooth. Una vez configurada en el setup, esa velocidad se mantendrá siempre
constante.
La segunda función será el programa propiamente dicho
void loop ()
{
}
En este caso, las instrucciones constituyen el programa que queremos desarrollar y se
ejecutarán siempre desde la primera a la última para luego volver a la primera y
ejecutarse nuevamente.
Este ciclo se repite indefinidamente mientras el Arduino se encuentre alimentado. Esta es
la razón por la que esta función se llama “loop”.
Primeras Instrucciones:
El lenguaje de programación es “case sensitive”, es decir que diferencia entre minúsculas
y mayúsculas. Esto quiere decir que hay que respetar exactamente la escritura de las
instrucciones o los programas no se compilaran e indicarán errores.
pinMode:
Instrucción que se escribe dentro de la función setup (eso quiere decir entre
sus llaves), con el objetivo de configurar los pines del Arduino para que trabajen como
entrada o como salida
3
Por ejemplo, si voy a conectar un LED en el pin 10 del Arduino con la intención de
encenderlo y/o apagarlo , ese pin se debe configurar como salida (ya que el programa
tendrá que escribir un 1 o un 0 en cada caso).
La instrucción será:
pinMode (10, OUTPUT);
La instrucción genérica sería
pinMode (número de Pin, estado)
Nótese que detrás de cada instrucción hay que escribir punto y coma (;).
Si por el contrario, el Arduino tiene que “leer” el estado de un sensor que por ejemplo le
indique si una ventana está abierta o cerrada (algo que se haría con un pulsador o con un
sensor magnético), el pin que recibe esa información se debe configurar como entrada.
Supongamos que conectemos el sensor en el pin 4, la instrucción correcta será:
pinMode (4,INPUT);
digitalWrite:
Esta instrucción se utiliza para “escribir” un pin del Arduino que
previamente haya sido configurado en el setup como salida.
Se puede escribir un “cero” o un “uno”. Escribir un uno significa que luego de ejecutar la
instrucción, en ese pin habrá 5 volts mientras que luego de escribir un “cero”, el pin tendrá
0 volts.
Por ejemplo, si tengo conectado un LED en el pin 8 y quiero encenderlo, tengo que
escribir un “uno” en ese pin. La instrucción será:
digitalWrite (8, HIGH);
Como vemos se utiliza el término “HIGH”, en lugar de “uno”, significa que escribo un
“estado alto”.
Si luego quiero apagar el LED conectado en ese pin, la instrucción será:
digitalWrite(8, LOW);
En este caso se utiliza el término “LOW”, en lugar de “cero”. En este caso escribo un
“estado bajo”.
digitalRead:
Esta instrucción se utiliza para “leer” el estado de un Pin del Arduino que
antes fue configurado como entrada.
Como resultado de la lectura se puede obtener un “uno” o un “cero”. Se obtendrá un “uno”
si la tensión en ese Pin es de 5 volts, o sea un estado alto (HIGH).
Se obtendrá un “cero” si la tensión en el Pin al momento de leerlo es de 0 volts, es decir
un estado bajo (LOW).
El estado de la señal colocada en el Pin por medio de algún tipo de sensor (podría ser un
pulsador, un sensor de temperatura, de iluminación, etc.) puede ir cambiando con el
4
tiempo por lo que cuando se utiliza esta instrucción, el valor del estado que se lee debe
ser almacenado para utilizarlo más adelante.
Supongamos que se deben leer varios pulsadores y tomar una decisión al final de
acuerdo a su estado. Cómo el Arduino lee uno por vez, cada vez que lo hace debe
almacenar el estado y al final analizar a todos juntos.
La forma de almacenar el estado de una entrada al momento de leerla lo que se debe
hacer es guardar el dato en una variable, que no es más que una posición en la memoria
interna del microcontrolador.
La instrucción general sería
Variable = digitalRead (Pin);
El ejemplo típico sería
estado = digitalRead (7);
En este caso, el Arduino leerá el Pin 7 y guardará el valor leído (ya sea un “uno” o un
“cero” en la variable que llamamos estado. La variable lógicamente puede tener el nombre
que querramos.
Es conveniente dar a las variables nombres asociados a las informaciones que manejan
para luego identificarlas facilemente. Cuando un programa tiene pocas variables pero, a
medida que aumente su complejidad y con ello la cantidad de variables que utilicemos,
identificarlas fácilmente será de gran ayuda.
Por ejemplo si quisiéramos saber si en un habitación hay oscuridad o claridad podríamos
escribir la siguiente instrucción
luminosidad = digitalRead (5);
O en el caso de estar desarrollando una alarma, si tenemos el sensor de presión del
asiento del conductor en la entreda 9 podríamos escribir
peso = digitalRead(9);
Las variables que vayamos usando en un programa se deben definir al comienzo del
mismo.
Estas variables toman valores binarios (1 o 0) así que al comienzo del programa (antes de
la función “setup”) debemos escribir:
boolean luminosidad;
boolean peso;
Aunque 1 y 0 también son enteros por lo que es frecuente definirlas como:
int estado;
int luminosidad;
Donde int identifica a las variables que toman valores enteros. Existen otros tipos de
variables como char, byte, long, word, float, y otras que veremos en breve.
5
Alias: Los Alias nos permiten identificar fácilmente, por medio de “etiquetas” o “alias” los
distintos elementos del hardware del Arduino. Es decir, les podemos dar un nombre.
Supongamos por ejemplo que en el Pin 3 tenemos instalado un led azul.
Si a lo largo de un programa tengo muchas instrucciones que encienden o apagan ese led
nos encontraremos con instrucciones del tipo:
digitalWrite (3, HIGH);
.............. ....
. . . . . . . . . . .. . . . . . .
. .. . . . . . .. . . . . . .. . .
digitalWrite (3, LOW);
. .. . . . . . . . .. . . . . .. .
. . .. . . . . .. . . . .. . . . ..
. . . .. . . . . .. . . . .. . . .
digitalWrite (3, HIGH);
………………………..
………………………..
Podría haber muchas instrucciones de este tipo a lo largo del programa.
Si por alguna razón (y ocurre con frecuencia) quisiera cambiar el led de Pin, digamos
pasarlo del Pin 3 al 5, tendría que ubicar todas las instrucciones donde aparezca y
cambiar el 3 por 5.
Esto quiere decir que tendría hacer una gran cantidad de operaciones.
Si en lugar de hacer eso declaro un Alias al principio del programa escribiendo:
azul= 3;
(lo que digo es que cada vez que
aparezca la palabra azul, el progra
ma lo considerará como un 3)
ahora el programa quedaría:
digitalWrite (azul, HIGH);
. . . . . . . . . . . . . . . .. .
. . . . . .. . . . . . . . . . . . .
. .. . . . . . .. . . . . . .. . .
digitalWrite (azul, LOW);
. .. . . . . . . . .. . . . . .. .
. . .. . . . . .. . . . .. . . . ..
…………………………..
. . . .. . . . . .. . . . .. . . . …
digitalWrite (azul, HIGH);
…………………………..
…………………………..
6
y si por alguna razón tengo que cambiar de Pin, lo único que tendría que hacer es ir al
Alias y cambiar por:
azul= 5
Es decir, resuelvo el problema cambiando una sola instrucción que se donde se encuentra
delay( ):
Esta instrucción detiene al procesador un tiempo expresado en milisegundos
que se escribe entre los paréntesis.
Supongamos que quiero que el microcontrolador no haga nada por el término de 2
segundos, escribiría:
delay(2000);
Hola Mundo
Se suele definir de esta forma, “hola mundo”, al primer programa que se desarrolla en un
lenguaje de programación.
La IDE de Arduino ya viene con un ejemplo que obra de Hola Mundo. Es un programa que
sirve para verificar que la placa está funcionando correctamente, sin necesidad de instalar
ningún componente adicional, ya que tiene un led instalado en el Pin 13 visible al usuario.
El programa se llama blink, y es el siguiente:
int led=13;
void setup()
{
pinMode(led, OUTPUT);
}
void loop()
{
digitalWrite(led, HIGH);
delay(1000);
digitalWrite(led, LOW);
delay(1000);
}
7
Como vimos en la página 4, hay una instrucción que permite leer el estado de una entrada
del Arduino, esa instrucción es digitalRead
Esta instrucción le permite al Arduino conocer datos del mundo exterior, es decir, recibir
información de hechos que ocurren fuera de él.
Por ejemplo, podemos colocar un pulsador en una entrada del arduino y esta instrucción
nos permitiría saber si alguien lo está oprimiendo o no.
De igual forma podríamos conectar algún tipo de sensor a una entrada del arduino.
Por ejemplo supongamos querer saber si se abre una ventana para activar una alarma.
Una forma de hacerlo es colocar un sensor magnético (un pulsador que se activa por
medio de un imán) en una puerta o ventana y, cuando se abren cambiarían su estado, de
cerrado a abierto, y esto sería registrado por el arduino.
El sensor sería del tipo
Una de las dos partes tiene un iman en su interior y la otra parte un interruptor magnético
del tipo
Que tiene dos tiras metálicas que se pegan cuando se acerca el imán y se despegan
cuando se aleja.
8
Este es sólo un ejemplo, hay muchos tipos de sensores como para determinar si es de día
o de noche, si llueve o no, si alguien aplaude, si hay gas en un ambiente, etc., que se
pueden conectar a una entrada del arduino para que éste los lea y de acuerdo a que
estén abiertos o cerrados realice algún tipo de acción.
Veamos como se conectaría el pulsador a un arduino
En este circuito vemos un pulsador conectado a la entrada 10 del arduino.
Como funciona?
Si el pulsador está abierto (no están conectados sus terminales por lo que es lo mismo
que si no existiera) los 5 volts de la fuente llegan a la entrada 10 a través de la resistencia
R2. Las entradas del arduino no toman corriente por lo que no hay caída de tensión en la
resistencia, o sea que la tensión en el pin de entrada van a ser los 5 volts.
Si alguien oprime el pulsador, sus terminales se tocan y la entrada 10 queda conectada a
masa, es decir que la tensión en la entrada se va a 0 volts. Circulará corriente desde la
fuente de 5volts a masa a través de R2 pero, como la resistencia se elije de un valor alto
(10 KΩ es un valor típico), su valor es mínimo.
Resumiendo, cuando el pulsador está abierto hay un “1” en la entrada y cuando el
pulsador está oprimido hay un “0”.
9
Para poder aprovechar esa información, tenemos que ver una nueva instrucción que es
posiblemente la instrucción más poderosa de los sistemas digitales. Esto es porque les
permite a los microcontroladores tomar decisiones, es decir actuar como los seres
humanos.
If – Else:
(traducido significaría
si – sino )
Esta instrucción permite tomar decisiones a partir del estado de una variable. Si la
variable tiene el valor de la lectura de un Pin del Arduino, la decisión que se termina
tomando depende del estado del Pin leído.
El formato de la instrucción es:
If (condición)
{
Entre estas llaves se escriben las instrucciones (puede ser una sola o
muchas) que el Arduino ejecutará SI se cumple la condición
}
else
{
Entre estas llaves se escriben las instrucciones (puede ser una sola o
muchas) que el Arduino ejecutará si NO se cumple la condición
}
Siguiente instrucción a ejecutar luego de ejecutar el if-else (A)
Es decir, Si se cumple la condición escrita entre paréntesis luego del If, el Arduino
ejecutará las instrucciones que están entre las llaves que le siguen.
Si no se cumple la condición que se encuentra entre paréntesis, el Arduino ejecutará
las instrucciones que se encuentran debajo de la palabra else.
Luego de ejecutar las instrucciones (ya haya sido que se encuentran entre las primeras
llaves o entre las segundas llaves), el arduino continuará ejecutando las instrucciones que
aparezcan luego de las llaves del else, es decir donde se encuentra la letra A.
10
Veamos un ejemplo con el circuito que acabamos de ver, donde hay un pulsador en el Pin
10 del Arduino y un LED en el Pin 7.
Supongamos que queremos que al oprimir el pulsador se encienda el Led y cuando no
está oprimido que el Led esté apagado…
Un posible programa puede ser (siempre hay más de una forma de escribir un programa
que realice una tarea)…
int led=7;
int pulsador=10;
int estado;
void setup()
{
pinMode (led, OUTPUT);
pinMode (pulsador, INPUT);
}
void loop()
{
pulsador = digitalRead(pulsador)
If ( pulsador == LOW)
{
digitalWrite (led, HIGH);
}
else
{
digitalWrite (led, LOW);
}
}
En este programa, al comienzo se escribieron los Alias, del led y del pulsador.
Se definió luego la variable donde se va a guardar la información de la lectura. A esta
variable se la llamó “estado” (porque guarda el estado de la lectura, pero podría tener
cualquier nombre. Se la definió como variable entera (int) ya que va a tener valores
enteros (0 y 1) pero también se podría haber definido como variable boolean.
Luego se definieron los pines que se van a utilizar como entrada y como salida en la
función setup. El pulsador envía información al Arduino así que el Pin que recibe la
información debe definirse como una entrada.
11
Finalmente, en el programa principal ( loop, que se repetirá indefinidamente) primero se
lee el estado del pulsador con la función digitalRead y se guarda el estado leído (0 si el
pulsador está abierto y 1 si está cerrado) y se guarda ese valor en la variable estado.
En la instrucción siguiente (if) se compara la lectura para saber si es 0. Nótese que la
comparación se hace con LOW, no se escribe 0. Es decir se pregunta si el valor leído es
LOW, que significa preguntar si el valor es “bajo”.
Si se quisiera preguntar si el estado de la variable es 1 se preguntaría if(pulsador==HIGH)
Otra cosa que se debe notar es que, para comparar se repite el signo =, es decir se
escribe dos veces. Si se escribe una vez, la comparación no funcionará, es decir que está
mal.
Si se cumple la condición, es decir si el estado de la variable es 0, es decir si al leer el
Pin del arduino el pulsador estaba oprimido, el Arduino ejecutará las instrucciones que se
encuentran entre las llaves que están debajo.
En este caso eso significa escribir un estado alto (un 1) en el Pin 7, es decir encender el
Led.
Si no se cumple la condición, es decir si el estado de la variable es 1, es decir si al leer
el Pin del arduino el pulsador estaba abierto, el Arduino ejecutará las instrucciones que se
encuentran entre las llaves que están debajo del else.
Ya sea que el arduino haya ejecutado las instrucciones de las primeras llaves luego del IF
o de las segundas, luego continuá el programa. En este caso no hay más instrucciones
así que se vuelve al comienzo del loop, es decir a leer de nuevo el Pin de entrada y
nuevamente a tomar la decisión de encender o apagar el led. Este ciclo se realizará
eternamente a menos que se interrumpa la energía.
for :
Hemos visto que la función “loop” en un bucle infinito o ciclo infinito. Esto quiere decir que
todas las instrucciones que se encuentren dentro de esta función se ejecutarán desde la
primera a la última para luego retornar a la primera y volver a ejecutarse y este proceso
continuará mientras el Arduino esté alimentado.
Esta no es la única forma de generar bucles o ciclos.
Existen instrucciones que nos permiten realizar tareas en forma repetitiva, ya sea una
cantidad determinada como una cantidad indeterminada de ocasiones. A estas
instrucciones también se las llama bucles o ciclos.
Ciclos determinandos. Son aquellos que nos permiten realizar un grupo de operaciones
repetitivas una determinada cantidad de veces. El ejemplo más simple de este tipo de
bucles es la función for.
12
Esta instrucción tiene el siguiente formato
for ( variable = valor inicial; valor final; incremento)
{
Instrucción 1
Instrucción 2
…………….
…………….
…………….
Instrucción N
}
El encontrar una instrucción de este tipo, el Arduino ejecutará en forma ordenada, de la
primera a la última, las instrucciones que se encuentren entre las llaves inmediatamente
posteriores a la sentencia for.
La cantidad de veces que las ejecute estas instrucciones dependerá de los valores que
tome la variable.
Veamos un ejemplo
for ( int x=1 ; x <10 ; i++)
{
}
Supongamos como ejemplo que en un proyecto necesito definir los pines que van del 0 al
13 como salida dentro de la función setup.
Una opción sería escribir la siguiente secuencia de instrucciones:
void setup ()
{
digitalWrite (0, OUTPUT);
digitalWrite (1, OUTPUT);
digitalWrite (2, OUTPUT);
digitalWrite (3, OUTPUT);
digitalWrite (4, OUTPUT);
digitalWrite (5, OUTPUT);
digitalWrite (6, OUTPUT);
digitalWrite (7, OUTPUT);
digitalWrite (8, OUTPUT);
digitalWrite (9, OUTPUT);
digitalWrite (10, OUTPUT);
digitalWrite (11, OUTPUT);
digitalWrite (12, OUTPUT);
digitalWrite (13, OUTPUT);
}
13
Una forma mucho más eficiente de resolver este problema sería:
void setup ()
{
for ( int i = 0; i<14 ; i++)
{
digitalWrite (i, OUTPUT);
}
}
Cuando llegue a la sentencia for, el Arduino asignará el valor inicial, 0 en este caso, a la
variable i, por lo que la primera instrucción que ejecutará luego será:
digitalWrite (0, OUTPUT);
Luego de ejecutarla volverá al for (ya que es la única instrucción incluida en el ciclo y se
fijará si llegó al límite superior, 14 en este caso.
Como no llegó, le sumará 1 por lo que i ahora valdrá 1 (0 + 1).
Luego ejecutará la instrucción entre llaves.
digitalWrite (1, OUTPUT)
Esta secuencia se repetirá hasta que i llegue a 14 entonces, en lugar de ejecutar la
instrucción entre llaves debajo del for, continuará el programa por la siguiente instrucción.
Resolver
Para el siguiente circuito, escribir el programa que, al presionar el pulsador haga que los
10 leds titilen a la vez (enciendan y apaguen todos juntos) 5 veces. Una vez que dejaron
de titilar, si se vuelve a oprimir el pulsador nuevamente deben titilar los 10 leds.
Mientras no están titilando los leds debe encontrarse el led del Pin13 (incluido en el
Arduino) encendido.
14
While ()
Vimos que la función for nos permite hacer ciclos o bucles determinados y de esa forma
ejecutar secuencias repetitivas de instrucciones sin tener que escribirlas más que una
vez. Esa sentencia no es la única para realizar este tipo de operación.
Un bucle del tipo while es un bucle de ejecución continua que se repite mientras se
cumpla la expresión colocada entre paréntesis en la cabecera del bucle.
En esa expresión existirá una variable que irá cambiando su valor hasta que la condición
deje de cumplirse y entonces el Arduino abandonará el ciclo y seguirá por la instrucción
siguiente.
Las instrucciones que se repiten serán las que se encuentren entre las llaves que se
escribirán inmediatamente debajo del While.
En un diagrama de flujo se vería así:
Mientras se cumpla la condición A se realiza la tarea B, cuando no se cumpla termina el
bucle.
Veamos un ejemplo
int cuenta=0;
while ( cuenta < 200)
// el ciclo se a repetir mientras cuenta sea menor a 200
{
digitalWrite (13,HIGH);
// enciende el led del Arduino
delay (500);
digitalWrite (13,LOW);
delay (500);
cuenta ++;
// incrementa la variable en 1
}
digitalWrite (4,HIGH);
……………………….
……………………….
……………………….
15
Este pequeño programa se repite mientras (while en inglés) la variable cuenta valga
menos de 200.
Al entrar al bucle la variable cuenta vale 1 ya que ese valor se le cargó previamente.
Luego de encender y apagar el Led, el Arduino le suma 1 al valor de la variable cuenta de
forma tal que luego de la primera pasada cuenta valdrá 2.
Como todavía es menor que 200 volverá a ejecutar las instrucciones que se encuentran
entre las llaves. Al final de esta segunda pasada cuenta valdrá 2 por lo que se volverá a
repetir.
Luego de haber encendido y apagado el led 200 veces , el Arduino abandonará el lazo y
seguirá por la instrucción que continúe debajo de la llave de cierre, en este caso es
colocar un 1 en el Pin 4.
Si al momento en el que el Arduino ejecuta la sentencia While, la condición no se cumple,
las instrucciones que se encuentran en el bucle no se ejecutarán ninguna vez.
Esto podría ocurrir si dentro del paréntesis, la variable que se compara tuviese el valor de
una entrada del Arduino. Esto quiere decir que la variable se comprar con una lectura
digital (digitalRead).
De esta forma podemos hacer que una o varias instrucciones se ejecuten según sea el
estado de un elemento externo al Arduino como podría ser una llave, un pulsador, un
sensor de cualquier tipo, que una fuente de tensión esté encendida o apagada, etc.
Veamos un caso con un pulsador
Según como instale el pulsador se podrían dar cualquiera de las dos condiciones:
Caso 1: Cuando presiono el pulsador leo un 1, mientras no lo presiono leo un 0
A la resistencia que se encuentra entre la entrada y masa (generalmente de 10K) se la
denomina Pull-Down, ya que tira hacia abajo (a 0 volts) el valor de la tensión de entrada.
16
Caso 2. Cuando presiono el pulsador leo un 0, mientras no lo presiono leo un 1
A la resistencia que se encuentra entre la entrada y el positivo (generalmente de 10K) se
la denomina Pull-Up, ya que tira hacia arriba (a 5 volts) el valor de la tensión de entrada.
Usando el primer esquema (leyendo un 1 al oprimir el pulsador), vamos a escribir un
programa que parpadee un led mientras el pulsador está oprimido y deje de hacerlo
cuando no lo está.
Supongamos que el pulsador está conectado al Pin 5 del Arduino y el Led al Pin 3.
El sketch sería:
Vemos que luego de configurar los pines en el setup, el Arduino entra a la función loop.
Lo primero que hace es leer el pulsador y salvar el dato que lee en la variable pulsador.
17
Luego, ejecuta el bucle (ciclo o lazo) si al leer la entrada el pulsador estaba oprimido, es
decir si pulsador es igual a HIGH (valor alto, 1)
Dentro del lazo enciende y apaga el led y luego chequea el pulsador para ver si todavía
sigue oprimido, para continuar en el bucle. En caso de que no, abandona el bucle.
Si el pulsador no estaba oprimido, la variable pulsador tendrá un 0 (LOW), por lo que no
ejecutará las instrucciones, solo continuará pero como ya no hay programa volverá al
inicio, por lo que volverá a leer el pulsador y decidirá nuevamente si ejecuta las
instrucciones del bucle o no.
Dentro del While, al momento de la comparación, no es necesario usar una variable para
guardar la lectura, ya que el dato se utiliza en ese preciso momento y tomando la
decisión. Por este motivo este programa también podría ser escrito de la siguiente
manera.
Si quiero crear un bucle ininterrumpido, es decir que se repita una indeterminada cantidad
de veces, podría escribir
while (1)
{
Instrucción 1
Instrucción 2
Instrucción 3
…………….
…………….
Instrucción N
}
Ya que 1 siempre es igual a 1, este ciclo se repetirá por siempre.
18
do – While
El bucle do while funciona de la misma manera que el bucle while, con la salvedad de
que la condición se prueba al final del bucle, por lo que el bucle siempre se ejecutará al
menos una vez.
do
{
digitalWrite (13,HIGH);
delay (500);
digitalWrite (13,LOW);
delay (500);
cuenta ++;
// enciende el led del Arduino
// incrementa la variable en 1
} while (cuenta <200);
Resolver
1 - Realizar el programa escrito para resolver el último ejercicio (el de los 10 leds que
titilan) utilizando la función While.
2 – Para el siguiente circuito, escribir el sketch que: cuando se oprima el pulsador P1 el
dígito muestre la letra H y al oprimir el pulsador P2 muestre la letra L. Utilice la instrucción
While en lugar de IF
19
Switch – case (break, default)
Al igual que if, la sentencia “ switch – case” controla el flujo del programa especificando
en el programa que código se debe ejecutar en función del valor que toma una variables.
En este caso en la instrucción switch se compara el valor de una variable sobre los
valores especificados en la instrucción case.
Esta instrucción es como realizar una secuencia de preguntas (una secuencia de
instrucciones If, pero mucho más eficiente)
En el siguiente diagrama de flujo, de acuerdo a que la variable tome como valores la
“opción 1“, “la opción 2”, etc., el arduino realizará una determinada operación (instrucción
1, o instrucción 2 o …….., instrucción N). Si la variable no toma como valor ninguna de las
opciones, el arduino realizará la acción por default.
Luego continuará por la siguiente instrucción.
Este esquema puede ser reemplazado por una instrucción switch, cuyo diagrama de flujo
se vería como en el siguiente dibujo
:
20
La sintaxis de esta instrucción sería:
switch (var)
{
case Opc 1:
instrucción/es 1;
break;
case Opc 2:
instrucción/es 2;
break;
case Opc 3:
instrucción/es 3;
break;
default:
instrucción/es por default;
break;
}
Siguiente instrucción;
Default indica las instrucciones que se deben realizar cuando la variable no tome como
valor ninguna de las opciones.
El comando break indica el fin de cada opción para el que el arduino continue ejecutando
la siguiente instrucción
21
Resolver
Tenemos tres leds de distinto color conectados a un Arduino.
El led rojo está conectado al Pin 8 del Arduino, el led verde al Pin 9 y el led azul al
terminal 10.
El pulsador se encuentra conectado al Pin 7 del Arduino de forma que al oprimirlo genera
un estado LOW (0 volt), mientras se encuentra inactivo el estado en ese pin es HIGH
(5volts).
Utilizando la función Switch, desarrollar el sketch que permita que cada vez que oprima el
pulsador cambie el led que está encendido, los otros dos deben permanecer apagados.
AnalogRead
Hemos visto que para leer el estado de un pin que ha sido configurado como entrada en
un Arduino existe la función DigitalRead.
La placa Arduino Uno contiene 6 canales (8 canales en el Mini y Nano, 16 en el Mega),
analógicos con convertidor analógico a digital de 10-bit.
Eso significa que, mediante la instrucción AnalogRead, el Arduino puede leer la señal que
se encuentra en una de esas 6 entradas (A0, A1, A2, A3, A4 y A5) y devolver un número
proporcional a esa tensión en una palabra digital de 10 bits.
En su expresión más simple podemos decir que, a tensiones de entrada entre 0 y 5 volts
le corresponderán lecturas entre 0 y 1023
0 volt

0000000000 
0
´´´´´´´´´´´´´´´´
5 volts 
1111111111  1023
22
Si tengo 0 volt en la entrada al momento de leerla, el resultado de la lectura me dará 0.
Si tengo 5 volts en la entrada al momento de leerla, el resultado de la lectura me dará
1023.
Aplicando una simple regla de 3 puedo ver que entre cada bit y el siguiente habrá una
diferencia de 0,0049 volts (4,9 mV). A este valor se lo define como la resolución, que
corresponde a entradas entre 0 volts y 5 volts. Veremos más adelante que, esos valores
se pueden cambiar con analogReference().
Todo esto quiere decir que:
Tensión de entrada =
0v
lectura = 0000000000
0
4,9mV
0000000001
1
9,8mV
0000000010
2
14,6mV
0000000011
3
19,5mV
0000000100
4
……….
……………. .
..
……….
……………..
..
2500mV (2,5v)
1000000000
512
………..
…………….
…..
………..
…………….
…..
………..
…………….
…..
………..
…………….
…..
5000mV (5v)
1111111111
1023
Al igual que ocurría cuando usábamos la instrucción DigitalRead, luego de la lectura
analógica lo habitual es guardar el valor en una variable que por los valores que tomará
será del tipo int (entero).
El proceso de conversión de la señal analógica a la información digital, que se produce al
leer una entrada analógica, tarda unos 100 microsegundos (0.0001 s), por lo que la
velocidad de lectura máxima es de alrededor de 10.000 veces por segundo.
Entonces:
La instrucción será:
AnalogRead (Pin)
Donde el argumento será el número de Pin que estoy leyendo (A0 a A5 en un Arduino
Uno)
El valor que se obtendrá de la lectura será un número entero entre 0 y 1023, proporcional
a la tensión de entrada.
23
Veamos un ejemplo que además incluye otra nueva instrucción:
int entrada = 3;
int lectura = 0;
// Genero un Alias para el pin al que se le conecta las señal a leer
// variable para almacenar el valor leído
void setup()
{
Serial.begin(57600);
// configuración serie
}
void loop()
{
lectura = analogRead(entrada); // lee el pin de entrada
Serial.println(lectura);
// imprime el valor
}
En este programa se lee la entrada analógica 3 y el valor leído se guarda en una variable
a la que llamamos “lectura”.
Para poder ver el valor leído se podría recurrir a varios métodos. Se podría por ejemplo
poner un grupo de dígitos de 7 segmentos, o bien un grupo de leds, o tal vez un módulo
LCD.
La IDE de Arduino nos da una excelente herramienta para verificar el valor que van
tomando las variables. Esta herramienta se llama Monitor y se activa clickeando en la
parte superior derecha de la IDE de Arduino.
24
Al clickear sobre el ícono del Monitor aparecerá una pantalla de monitor que mostrará
todo aquello que le enviemos.
En el área Recibir del monitor irán apareciendo los datos que envíe desde el programa.
En el programa (función loop) encontramos la función:
Serial.println(lectura);
Veremos más en detalle esta instrucción pero, en este momento lo que debemos saber es
que lo que hace es imprimir (print) los datos que se encuentran entre paréntesis en el
monitor.
Si lo que tengo entre paréntesis se encuentra entre comillas lo imprimirá textalmente.
Serial.println(“señal de entrada”);
Esta instrucción haría que aparezca en el monitor la oración: señal de entrada
Si lo que se coloca entre paréntesis es una variable, lo que ocurrirá es que en el monitor
aparecerá el contenido de esa variable.
En nuestro ejemplo, el valor leído en la entrada 3 (como dijimos un valor entre 0 y 1023)
aparecerá en el monitor.
Como esta instrucción se encuentra dentro de la función loop, la lectura se irá repitiendo
indefinidamente.
Para usar el monitor hay que definir en la función setup la velocidad de envío de datos.
En este caso la instrucción es Serial.begin (57600); donde 56700 es dicha velocidad.
25
Ejercicio:
Lo que queremos es escribir un programa que lea la entrada A0 donde vamos a colocar
una batería de control remoto de 3,2v y nos indique que valor tiene.
Para expresar la tensión de la batería será necesario efectuar una operación matemática
Una regla de 3
1…………………4,9 mV
valor leido……… X
y luego pasar el resultado a volts, ya que va a dar en mV.
Como la operación incluye un número no entero, el tipo de variable que va a almacenar el
resultado de la operación no debe ser int (entero) sino float (con coma, flotante).
Al momento de definirla, la expresión será:
float tension;
En este momento la información leída la vamos a presentar en el monitor. [ En breve
vamos a realizar el mismo programa pero presentando la información en un módulo LCD
y encendiendo un led si está debajo de un valor de 2,8v.]
26
Volver a realizar un programa que determine el estado de la batería pero en este caso, el
arduino deberá:

Encender el led verde si la batería tiene más de 3 volts

Encender el led amarillo si la batería tiene entre 2,5 y 3 volts.

Encender el led rojo si la batería tiene menos de 2,5 volts
En este programa podremos utilizar la sentencia if para averiguar si la tensión de entrada
se encuentra por encima, por debajo o entre dos valores determinados.
Por ejemplo, si la lectura de la tensión de entrada se guarda en una variable que se llame
tension, las instrucciones podrían ser:
If (tension > =3)
{
}
o, por ejemplo
if (tension <3 && tension >= 2.5)
{
}
En este lenguaje de programación && significa “and” (y) y || significa “or” (o).
La expresión anterior se leería como: Si la tensión es menor que 3v y mayor que 2,5v.
27
Veamos un ejemplo más:
Desarrollar el sketch que:
Al cerrar el interruptor S el Arduino mida la tensión de la batería.
Si la batería tiene menos de 3 volts encienda el led rojo
Si la tensión se encuentra entre 3 volts y 3,5 volts enciende el led amarillo
Si la tensión supera los 3,5 volts enciende el led verde.
En los tres casos presenta en el monitor el valor de la tensión de la batería
Luego, si la tensión fue inferior o igual a 3,5 volts (quiere decir que encendió el amarillo o
el rojo) el Arduino cierra el relé para que la batería se cargue.
Por último va leyendo la tensión sobre la batería y cuando llega a 4,2 volts desactiva el
relé y deja titilando el led verde indicando carga plena.
Cada vez que lee la presenta el valor de la tensión en el monitor.
28
analogWrite()
Esta función escribe un valor analógico ( realmente una señal PWM ) en un pin. Entre
otras aplicaciones se puede utilizar para encender un LED con distintos brillos o para
impulsar un motor a distintas velocidades.
Después de una instrucción analogWrite(), el pin generará una onda rectangular
constante del ciclo de trabajo especificado hasta que se vuelva a ejecutar otra función
analogWrite(), (o bien instrucción digitalRead() o digitalWrite()), en el mismo pin.
La instrucción tiene el formato:
analogWrite(pin,valor)
Donde pin indica el número de pin del Arduino donde se encontrá la señal de PWM y valor
es un número entre 0 y 255 que indica el ciclo de trabajo (relación entre el tiempo en el
que la señal va a estar en estado alto y el tiempo en el que va a estar en estado bajo)
No todos los pines de un Arduino pueden generar una señal PWM, y dependen del
modelo. Los pines PWM están indicados en la plaqueta Arduino con un tilde similar a la
de la letra ñ .
Debajo una tabla que muestra los datos para los modelos de Arduino más comunes.
JUNTA
PINES PWM
FRECUENCIA PWM
Uno, Nano, Mini
3, 5, 6, 9, 10, 11
490 Hz (pines 5 y 6: 980 Hz)
Mega
2 al 13, 44 al 46
490 Hz (pines 4 y 13: 980 Hz)
Leonardo, Micro, Yún
3, 5, 6, 9, 10, 11, 13
490 Hz (pines 3 y 11: 980 Hz)
Señal de PWM
Lo primero que tenemos que entender es que la mayoría de automatismos (y Arduino no
es una excepción) no son capaces de proporcionar una auténtica salida analógica.
Ni siquiera pueden suministrar una salida analógica discretizada (es decir, a saltos) de
tensión. Lo único que pueden proporcionar es una salida digital, es decir una señal que
varía entre 0V y 5V, sin pasar por valores intermedios.
Para salvar esta limitación y simular una salida analógica la mayoría de los automatismos
emplean un "truco", que consiste en activar una salida digital durante un tiempo y
mantenerla apagada durante el resto. El promedio de la tensión de salida, a lo largo del
29
tiempo, será igual al valor analógico deseado. A la relación entre ambos tiempos (de
encendido y apagado) se lo denomina ciclo de trabajo (duty cycle)
Veamos algunos ejemplos.
PWM NO ES UNA SEÑAL ANALÓGICA
Es importante recordar en todo momento que en una salida PWM el valor máximo
de tensión realmente es Vcc. Por ejemplo, si estamos alimentando un dispositivo que
necesita 3V, y usamos una pulsada, en realidad estaremos suministrando 5V durante un
60% del tiempo y 0V durante el 40%. Pero si el dispositivo, por ejemplo, soporta como
máximo 3V, podemos dañarlo si lo alimentamos mediante un PWM.
Una señal pulsada es suficiente para emular una señal analógica en muchas
aplicaciones. Por ejemplo, podemos variar la intensidad luminosa en un LED mediante un
PWM. El LED realmente se enciende y apaga varias veces por segundo, pero este
parpadeo es tan rápido que el ojo no lo aprecia. El efecto global percibido es que el LED
brilla con menor intensidad.
30
Otro ejemplo, al variar la velocidad de un motor DC con un PWM, en la mayoría de
los casos la inercia del motor se encargará de que el efecto del PWM sea despreciable.
No obstante, en función de la frecuencia podemos notar vibraciones o ruidos, en cuyo
caso deberemos variar la frecuencia del PWM.
Por otro lado, debemos tener en cuenta los efectos que provoca la rápida conexión y
desconexión de la señal pulsada en el dispositivo/componente electrónico al que se
aplica. Por ejemplo, en el caso de cargas inductivas (motores, relés, o electroimanes) la
desconexión supondrá la generación de voltaje inducido que puede dañar la salida digital
o el propio dispositivo, por lo que será necesario disponer de las protecciones oportunas.
En cuanto a transistores, en general, los de tipo BJT resultan apropiados para
funcionar como amplificación de señales PWM. Esto no suele ser así en los transistores
MOS, donde los efectos capacitivos del mismo, unidos a la limitación de corriente de las
salidas digitales, frecuentemente harán que necesitemos un driver de amplificación previo
para evitar que el transistor trabaje en zona activa.
LOS TIMER EN PWM POR HARDWARE
Las funciones PWM emplean los Timer para generar la onda de salida. Cada Timer da
servicio a 2 o 3 salidas PWM. Para ello dispone de un registro de comparación por cada
salida. Cuando el tiempo alcanza el valor del registro de comparación, la salida invierte su
valor.
Cada salida conectada a un mismo temporizador comparte la misma frecuencia, aunque
pueden tener distintos Duty cycles, dependiendo del valor de su registro de comparación.
ASOCIACIÓN DE TIMERS Y PWM

En el caso de Arduino Uno, Mini y Nano

El Timer0 controla las salidas PWM 5 y 6.

El Timer1 controla las salidas PWM 9 y 10.

El Timer2 controla las salidas PWM 3 y 11.

Mientras que en Arduino Mega

El Timer0 controla las salidas PWM 4 y 13.

El Timer1 controla las salidas PWM 11 y 12.

El Timer2 controla las salidas PWM 9 y 10.

El Timer3 controla las salidas PWM 2, 3 y 5.

El Timer4 controla las salidas PWM 6, 7 y 8.

El Timer5 controla las salidas PWM 44, 45 y 46.
31
INCOMPATIBILIDADES
El uso de los Timer no es exclusivo de las salidas PWM, si no que es compartido con
otras funciones. Emplear funciones que requieren el uso de estos Timer supondrá que no
podremos emplear de forma simultánea alguno de los pines PWM.
SERVO
La librería servo hace un uso intensivo de temporizadores por lo que, mientras la
estemos usando, no podremos usar algunas de las salidas PWM.

En el caso de Arduino Uno, Mini y Nano, la librería servo usa el Timer 1, por lo que no
podremos usar los pines 9 y 10 mientras usemos un servo.

En el caso de Arduino Mega, dependerá de la cantidad de servos que empleemos.

Si usamos menos de 12 servos, usa el Timer 5, por lo que perderemos los pin 44, 45 y 46.

Para 24 servos, usa los Timer 1 y 5, por lo que perderemos los pin 11, 12, 44, 45 y 45.

Para 36 servos, usa los Timer 1,3 y 5, perdiendo los pin 2, 3, 5, 11, 12, 44, 45, 46.

Para 48 servos, usa los Timer 1, 3, 4 y 5, perdiendo todos los pin PWM.
COMUNICACIÓN SPI
En Arduino Uno, Mini y Nano, el pin 11 se emplea también para la función MOSI de
la comunicación SPI. Por lo tanto, no podremos usar ambas funciones de forma
simultánea en este pin. Arduino Mega no tiene este problema, ya que figuran en pines
distintos.
FUNCIÓN TONE
La función Tone emplea el Timer 2, por lo que no podremos usar los pines 3 y 11, y
en Arduino mega los pines 9 y 10.
Ejemplo de aplicación : Programa “fade” de la lista de ejemplos de la IDE.
El programa hace que un led instalado en una salida “analógica” encienda y apague
gradualmente, es decir subiendo y bajando su brillo.
32
int led = 9;
// Pin PWM donden se conecta el LED
int brightness = 0; // Brillo del LED
int fadeAmount = 5; // Incremento del brillo del LED
void setup()
{
pinMode(led, OUTPUT);
}
void loop()
{
analogWrite(led, brightness);
brightness = brightness + fadeAmount;
if (brightness <= 0 || brightness >= 255)
{
fadeAmount = -fadeAmount;
}
delay(30);
}
Desarrollar un proyecto con un arduino que controle la velocidad de un motor de corriente
continua.
33
El objetivo es que el arduino sense la temperatura del ambiente por medio de un termistor
y cuando:
La temperatura sea superior a 30 °C el arduino encienda el ventilador (motor) a un 10%
de su máxima velocidad.
Si la temperatura sigue subiendo, por cada grado que aumente el arduino subirá la
velocidad en 10%, es decir que cuando la temperatura supere los 31°C la velocidad será
20% de la máxima, cuando supere los 32°C será 30% del máximo y así hasta llegar al
100% de la velocidad del ventilador.
(más adelante usaremos un sensor digital para determinar la temperatura con mayor
precisión y tomaremos decisiones adicionales si al llegar al 100% de la velocidad la
temperatura sigue subiendo).
El termistor que compramos tiene la siguiente curva de respuesta:
El circuito electrónico podría ser:
34
Librerías de Arduino
Módulo LCD .
Veamos un módulo estándar de 16 columnas y dos filas
El módulo se comunica con el microcontrolador por medio de 8 líneas de datos (D0-D7) y
3 líneas de control (RS – R/W – E).
El pin E realmente habilita todo el módulo (enable) aunque suele considerarse una señal
de control.
35
Según la operación que se desee realizar en el módulo LCD, los pines de control E, RS#,
RW# deben tener un estado determinado. Además debe tener en el bus de datos un
código que indique un carácter para mostrar en la pantalla o una instrucción de control
para el display.
Los módulos LCD responden a un conjunto especial de instrucciones, estas deben ser
enviadas por el microcontrolador o sistema de control al display, según la operación que
se requiera.
Se muestran a continuación el conjunto de instrucciones del modulo LCD.
36
Generar todos los cambios de estado en las señales de control y de datos para que el
Arduino se comunique con el módulo LCD es una tarea compleja que lleva bastante
tiempo e implica un gran conocimiento del hardware de ambos sistemas.
Para hacer más fácil la tarea se pueden emplear librerías. Las librerías son programas
que han sido escrito por otros usuarios y a veces por las mismas empresas que
desarrollan los módulos (este como cualquier otro: Sensor de temperatura, sensor de
humedad, sensor de color, etc.). Estos programas están publicados en distintas páginas
web y hay que buscarlos en la red.
Luego de cargar una librería en un sketch se la puede utilizar pero hay que revisar los
requerimientos de la misma.
En el caso de la librería que nos permite comunicarnos con un módulo LCD y viene por
Default en la IDE de Arduino, deberemos incluir un comando que identifica los pines de
comunican entre el módulo y el arduino y luego indicar en la función “set-up” el modelo de
módulo que estamos usando. Recién luego se podrán utilizar los comandos que permite
la librería tales como, borrar la información del display, posicionar el cursor, escribir un
grupo de caracteres, escribir el contenido de una variable, etc.
El ejemplo de utilización básica que viene incluida en los ejemplos en la IDE de Arduino
es:
#include <LiquidCrystal.h>
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
void setup()
{
lcd.begin(16, 2);
lcd.print("hello, world!");
}
void loop()
{
lcd.setCursor(0, 1);
lcd.print(millis() / 1000);
}
Explicar que función cumple cada línea de programación y que hace el programa.
37
Descargar