You are on page 1of 130

Los siguientes comandos te ayudarn a realizar determinadas funciones en tus

programas Arduino.
IF
Comprueba si cierta condicin se cumple y puede ser usado en conjunto con uno o ms
operadores de comparacin (==igual, != distinto, < menor, > mayor):
if (a == b)
{
cdigo
}
IF y ELSE
Permite agrupar mltiples comprobaciones.
if (a < b)
{
cdigo 1
}
else
{
cdigo 2
}
WHILE
Se ejecuta un bloque hasta que la condicin deje de cumplirse.
while(a > b)
{
cdigo
}
DO y WHILE
Trabaja de la misma manera que el bucle while, con la excepcion de que la condicin se
comprueba al final del bucle, por lo que este bucle se ejecuta "siempre" al menos una vez.
do
{
cdigo
} while (a > b)

BREAK
Es usado para salir de los bucles do, for, o while, pasando por alto la condicin normal del
bucle. Es usado tambin para salir de una estructura de control switch.
while (a > b)
{
cdigo

if(a == 5) {
break
}
}
FOR
Repite un bloque de cdigo hasta que se cumpla una condicin. Se inicializa una variable, se
comprueba una condicin y ejecuta un bloque, luego se comprueba nuevamente la condicin y
asi sucesivamente hasta que la condicin ya no sea vlida.
for (int a = 0; a < 10; a++)
{
cdigo
}
Este cdigo es equivalente al siguiente
int a = 0;
while (a < 10)
{
cdigo
a++
}
SWITCH
Compara el valor de una variable con el valor especificado en las sentencias "case". Cuando se
encuentra una sentencia cuyo valor coincide con dicha variable, el cdigo de esa sentencia se
ejecuta.
switch (variable) {
case 1:
cdigo cuando "variable" es igual a 1
break;
case 2:
cdigo cuando "variable" es igual a 2
break;
default:
cdigo ejecutado cuando ninguna de las sentencias se cumple (es opcional)
}
pinMode:
Configura el pin especificado para comportarse como una entrada o una salida.
pinMode(pin, OUTPUT/INPUT)
digitalWrite:
Pone en 1 o 0 un pin de salida (output)
digitalWrite(pin, HIGH/LOW)
digitalRead:

Lee el valor de un pin configurado como entrada (input).


digitalRead(pin)
analogRead:
Lee el valor de tensin en el pin analgico especificado. Se representa con un numero entero
entre 0 y 1023.
analogRead(pin)
analogReference:
Configura el voltaje de referencia usado por la entrada analgica. La
funcin analogRead() devolver un valor de 1023 para aquella tensin de entrada que sea igual
a la tensin de referencia. Las opciones son:
DEFAULT: Es el valor de referencia analgico que viene por defecto, generalmente 5v o 3,3v.
INTERNAL: Es una referencia de tensin interna que puede ser de 1.1v o 2,56v, dependiendo
las versiones.
EXTERNAL: Se usar una tensin de referencia externa que tendr que ser conectada al
pin AREF.
analogReference(DEFAULT/INTERNAL/EXTERNAL)

Circuito LEDs Multiples


En un ejemplo anterior veiamos que podemos encender y apagar un led en determinado
tiempo, ahora vamos a incorporar varios leds y jugar con ellos. Suerte!
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( 13, OUTPUT) ;
pinMode( 12, OUTPUT) ;
pinMode( 11, OUTPUT) ;

pinMode( 6, 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 13 hasta el 6.
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 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.

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

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 13 hasta el 6 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 = 6 ; i < 14 ; 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.

Estos parmetros son y en ste orden:

Una variable que ira tomando valores segn una cierta regla, y a la que asignamos un
valor inicial. En este caso: i = 6 .
El ciclo contina mientras se cumpla esta condicin. En nuestro caso mientras la i sea
menor que 14, o sea hasta el 13: i <14
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 Descargar:
void loop()
{
int i = 0 ; // Inicializamos la variable i como un entero
for ( i = 6 ; i < 14 ; 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 6 hasta el 13 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.
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.

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 8 LEDs.
La nica novedad es que dado que la funcin de la resistencia es limitar la intensidad de la
corriente que circula por el circuito, y puesto que todos los diodos tienen masa comn, basta
una nica resistencia entre este punto y Ground.
Cuando nuestro programa levante el pin correspondiente a valor a HIGH, se cerrar el circuito
iluminndose el LED asociado.

Con este circuito, y con el programa 4.1 descrito en las pginas anteriores, tendremos un
efecto de luces similar al del coche fantstico (O de los Zylon para los aficionados a la ciencia
ficcin).

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

En general, se considera buena costumbre (la recomendamos), 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.

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 4.1, 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 6 hasta la del pin 13.
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 Descargar:
void loop() // Prog_4_2
{
for ( int i = 6 ; i < 14 ; i++) // Definimos la variable i sobre la marcha
{
digitalWrite( i , HIGH) ;
delay (500) ;
digitalWrite( i , LOW);
delay (500) ;
}
for ( int i = 12 ; i >6 ; 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 6 hasta la 13.
El segundo bucle entra a continuacin empezando con la luz 12 (para no repetir la 13) y
finalizando con la 7(para no repetir la 6), y vuelta a empezar.

En el segundo bucle hemos hecho una cuenta atrs dicindole a la variable i que
se decrcmentara 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, antes de buscar una solucin.

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 me 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 os encontrareis que vale la pena.

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.
Entradas digitales con Arduino
ENTRADAS DIGITALES

Con frecuencia en electrnica necesitamos saber si una luz est encendida o apagada, si
alguien ha pulsado un botn o si una puerta ha quedado abierta o est cerrada.
A este tipo de seales todo / nada, SI / NO, TRUE /FALSE, 0/1 se les llama digitales, y
podemos manejarlas con los pines de 0 al 13 de Arduino y por eso hablamos de pines digitales.
Muchos de los sensores y actuadores que vemos en el mundo real son digitales:

Como actuadores digitales, tenemos luces, alarmas, sirenas, desbloqueo de puertas,


etc.
Como sensores digitales podemos mencionar botones y pulsadores, Finales de
carrera, desbordamiento de nivel, sensores de llamas, humo o gases txicos.
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 botn o pulsador externo y vamos a encender o
apagar un LED en funcin de que el botn se pulse o no.

ESQUEMA ELECTRNICO DEL CIRCUITO.


.

Montaremos un circuito con un diodo LED y resistencia conectado al pin digital 10 de Arduino,
tal y como vimos en las sesiones previas y ademas un segundo circuuito con un pulsador S1
conectado al pin 6 con una resitencia como se muestra en el diagrama siguiente.

Obsrvese que mientras no pulsemos S1 el pin 6 de Arduino est conectado a 5V a travs de


la resistencia R3 forzando una lectura de tensin alta (HIGH). En cambio cuando pulsemos S1
cerraremos el circuito del pin 6 a Ground con lo que leer tensin baja, LOW. En ambos casos
tenemos un valor de tensin definido.
Si no pusiramos la resistencia R3, al pulsar S1 leeramos correctamente LOW en el pin 6.
Pero al dejar de pulsar S1 el pin 6 estara en un estado flotante, que es ni HIGH ni LOW sino
indeterminado. Como esto es inaceptable en circuitos digitales forzamos una lectura alta con
R3.

A esta resistencia que fuerza el valor alto en vacio se le conoce como pullup Si la
conectramos a masa para forzar una lectura a Ground se le llamara pulldown resistor.
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 pines (el que est sobre la resistencia
horizontal). Esto es porque cada entrada del interruptor tiene dos pines conectados. En nuestro
circuito simplemente ignoramos los pines secundarios.

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 10 (D10) como salida para manejar el LED, y el pin digital 6 (D6) como entrada para leer
el botn.
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 tocando en un solo lugar (y no teniendo que buscar a lo largo del
programa). Vamos a escribir esto un poco ms elegantemente:
int LED = 10 ;
int boton = 6;

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

//botn como entrada

Atencin: C++ diferencia entre maysculas y minsculas y por tanto LED, Led y led no
son lo mismo en absoluto. Del mismo modo, pinMode es correcto y en cambio pinmode
generar un error de compilador fulminante.
He usado la variable boton sin acento porque no es recomendable usarlos ni la 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( botn). Veamos cmo podra ser nuestro loop:
void loop()
{
int valor = digitalRead(boton) ;

// leemos el valor de boton en valor

digitalWrite( LED, valor) ;


}
Fcil no? Aunque el LED est encendido hasta que pulsamos el botn y se apaga al pulsar.

Cmo podramos hacer lo contrario, que el LED se encienda al pulsar y se apague si no?
Bastara con escribir en 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.
De hecho este tipo de operaciones son tan frecuentes que C++ incorpora un tipo
llamado bool o booleano que solo acepta dos valores TRUE (cierto) y FALSE y son
completamente equivalentes al 1 / 0, y al HIGH / LOW
Este nuevo programa sera algo as:
void loop()
{
int valor = digitalRead(boton) ;
digitalWrite( LED, !valor) ;

// leemos el valor de boton en valor


//Escribimos 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 D6 leer TRUE y por tanto pondr LED a FALSE. En caso
contrario encender 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) ;
}

Podemos leer la situacin actual de un pin (nos devuelve su estado actual), an


cuando lo hayamos definido como salida, En cambio 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..

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 de negacin.

Tipos de Variables y funciones

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 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 solo tenindolos y resolvindolos, solo o con
ayuda, se aprende. No se puede aprender a nadar 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 no tiene porque ser mejor que otra, aunque con frecuencia se aplican
criterios de eficiencia o elegancia para seleccionar una solucin.

Esta sesion va a requerir un esfuerzo un poco mayor que las anteriores porque vamos a
empezar a entrenar un musculo poco usado,el cerebro, en una tarea poco frecuente,
pensar. Y esto es algo que exige un poco e 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 a la 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 el
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.
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 Primo () como bool, o sea va a devolver un valor bool y por eso en
algn punto 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 cononocemos
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 intruccion 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 Descargar:
void loop() // Prog_8_1
{
int x = 427 ; // El nmero a probar
bool p = Primo(x);
if (p )
Serial.print( String(x) + " Es primo.") ;
else
Serial.print( String(x) + " No es primo." ) ;
}

Veamos cuantos primos hay hasta el, digamos 1024, Descargar:


bool control = true ; // Prog_8_2
int maximo = 1024 ;

void loop()
{
if ( control) // Solo es para que no repita una y otra vez lo mismo
{
Serial.println( "Los numeros primos hasta el " +
String( maximo)) ;
for ( int x = 2 ; x < maximo ; x++)
{
bool p = Primo(x);

if (p ) Serial.println( x) ; // No hay
inconveniente en escribirlo seguido
}
}
control = false ;
}

bool Primo( int n)


{
for ( int i = 2 ; i <n ; i++)
{
if ( n % i == 0) // Si el resto es 0 entonces es divisible.
return(false) ;
}
return (true) ; // Si llega aqui es que no ha encontrado ningun
divisor
}

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. Descargar:
bool control = true ; //Prog_8.3
int maximo = 1024 ;
int contador = 1 ;

void loop()

{
if ( control)

// Solo es para que no repita una y otra

vez lo mismo
{
Serial.println( "Los numeros primos hasta el " +
String( maximo)) ;
for ( int x = 2 ; x < maximo ; x++)
{
if (Primo(x) )
if ( contador++ % 8 == 0)
Serial.println( String(x)+"," ) ;
else
Serial.print( String(x) +","+ '\t') ;
}
}
control = false ;
}

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 tenemosuna lnea que conviene comentar:
if ( contador++ % 8 == 0)

Cuando a una variable se le aaden dos smbolos mas al nombre, significa que primero se
use su valor actual en la instruccin en curso, ene este caso 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.

EL TIPO ENTERO
.

Este sera un buen momento para preguntarnos hasta donde podra crecer 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 de distintos tamaos para manejar enteros:

TIPO

DESCRIPCIN

VALO

int

Entero con signo, 16 bits

entre -32,768

unsigned int

Entero sin signo, 16 bits

216 1 ; de 0 h

long

Entero con signo, 32 bits

232 1 ,Desde -2.147.483,

unsigned long

Entero sin signo, 32 bits

byte

Entero sin signo, 8 bits

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

Desde 232 1 ; 0

28 de 0 ha

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 este 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

MS SOBRE LAS FUNCIONES EN C++


.

Cuando se declara una funcin se debe especificar que parmetro va a devolver. As:

Instruccin

Significa

int Funcion1()

Indica que va a devol

String Funcion2()

Indica que va a devol

unsigned long Funcion3()

void Funcion4()

Indica que va a devolver

No va a devolver valore

Una funcin puede devolver cualquier tipo posible en C++, pero slo puede devolver un
nico valor mediante la instruccin return(). Expresamente se impide devolver ms de un
parmetro. Si se requiere esto, existen otras soluciones que iremos viendo.

Este problema se puede resolver usando variables globales o pasando valores por
referencia, y lo trataremos en futuras sesiones.

Lo que s est permitido es pasar varios argumentos a una funcin:


int Funcion5 ( int x , String s , long y)

Aqu declaramos que vamos a pasar a Funcion5, tres argumentos en el orden definido, un
entero un String y por ultimo un long.

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.

Entradas Analgicas con Arduino

LOS POTENCIMETROS

Hasta ahora hemos usado siempre resistencias fijas, de un valor dado. Pero a veces es
conveniente disponer de una seal variable para controlar el circuito que nos interesa.
Imaginad el volumen de un equipo de msica, o el dial que sintoniza una emisora en una
radio FM.
Un potencimetro es, simplemente, un mecanismo para proporcionar una resistencia
variable.
Hay potencimetros de tantos tamaos, formas y colore,s como podis imaginar, pero al
final son una resistencia fija de un valor dado (10 k en nuestro caso actual) y un
mecanismo que permita deslizar un dial conductor sobre esa resistencia, que nos permita
tomar una parte de ese valor.
Por eso un potencimetro siempre tiene 3 pines en fila. Los del extremo se comportan
como una resistencia del valor de fondo de escala del potencimetro, y un pin central que
va tomando valores de resistencia en funcin del movimiento que hagamos con el ajuste.
Vamos a montar un circuito como este (en el que el potencimetro esta rotulado Pot1):

La idea es conectar 5V y GND a los extremos del Potencimetro (no importa cual es uno y
otro) y luego conectar el pin central al positivo de un LED y el negativo a GND directo,
pasando por una resistencia de limitacin.
De este modo cuando giremos el potencimetro estaremos modificando la tensin que
aplicamos a la entrada del LED, que variara entre 0 y 5V (Aunque ahora parezca extrao
es muy sencillo) y habremos conseguido un regulador de intensidad del LED.

Con una resistencia de 10k la intensidad en el circuito ser de: 5V / 10.000 = 0,5
mA Muy poco para conseguir iluminar el LED que requiere unos 20 mA. As que durante la
mayor parte del giro del potencimetro el LED estar apagado.
Importante: No olvides la resistencia R1.Aunque el potencimetro limite la
intensidad, hay un momento en que llegara a cero y ah y tu LED fallecer en acto de
servicio.

CIRCUITO PARA PROTOBOARD

El montaje en la protoboard sera similar a esto ya que vamos a utilizar el Arduino


simplemente para dar tensin al circuito y nada ms, Veris que la intensidad de la luz
varia de forma continua al girar el potencimetro.

Recuerda que debido al exceso de resistencia del potencimetro de prueba,


durante la mayor parte del giro del ajuste el LED estar apagado.
Ntese que en este caso utilizamos nuestro Arduino simplemente como fuente de
alimentacin para dar tensin al circuito.

ARDUINO Y LAS ENTRADAS ANALGICAS

Con Arduino hemos visto que podemos influir en el mundo exterior aplicando salidas todo /
nada en los pines digitales y tambin que usando PWM podemos simular bastante
satisfactoriamente seales analgicas en algunos de esos pines.

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 o distancia, de presin o PH, de intensidad de corriente en un circuito o de
caudal de agua en una tubera.
Para leer este tipo de seales continuas necesitamos un convertidor analgico a digital (o
ADC por sus siglas en ingles) y que nos permite leer el valor de una seal analgica en un
momento dado.
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, nominados de A0 hasta A5,
rotuladas como ANALOG IN:

Veamos cmo usar las entradas analgicas con un circuito como este, en el que damos
tensin a los extremos de un potencimetro y conectamos el pin central (el variable) 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:
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 = 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 para que
podamos visualizarlo.

USANDO LAS PUERTAS ANALGICAS

Prueba este programa:


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 las
lecturas varan de forma continua reflejando la posicin del potencimetro, las lecturas
reflejan la caida en voltios en el.

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?

Al no estar el A5 conectado a ninguna referencia vlida, est flotando y los valores


que captura son muestra de esa incoherencia. En realidad lo que est haciendo tu Duino
es captar ruido aleatorio de radiofrecuencia e intentar darle sentido, pero lo tiene mal,
como podeis ver.
No obstante en condiciones normales los valores que leer seran relativamente
bajos.Quieres que las oscilaciones crezcan en valor?. Fcil. Ponle una antena. Vale un
simple cable de protoboard conectado desde el A5 a nada (O si coges el otro extremo
entre los dedos, tu mismo haras de antena). Acabas de construir el receptor de Radio
frecuencia mas inutil del mundo

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.
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.

Para jugar con audio es mejor usar un Arduino DUE. Tiene una velocidad de reloj 4
veces ms rpida(os har falta), capacidad de muestreo a velocidad de audio (40Khz) y
autnticos convertidores DAC (digital to analog converters).
De hecho no es complicado aumentar la velocidad de muestreo hasta unas
20.000 muestras por segundo con un Arduino UNO, pero para eso tenemos que puentear
Arduino y saltar a programar el chip interior Atmega 328. No es momento para ello, pero
hay formas.

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 puertas analgicas de Arduino.

Sabemos que podemos leer las puertas analgicas unas 8.900 veces por segundo
con una resolucin de 10 bits, o sea entre 0 y 1.024.
Conocimos la funcin millis().

Uso de Rels con Arduino

QUE ES UN REL Y PARA QU SIRVE

Un rel es un interruptor que podemos activar mediante una seal elctrica. En su versin ms simple es
un pequeo electro-imn que cuando lo excitamos mueve la posicin de un contacto elctrico de
conectado a desconectado o viceversa.
El smbolo del rel muestra la bobina y en este caso, un accionador que conmuta entre dos contactos,
pero tambin existen rels de mltiples contactos. Mediante una seal de control de poca intensidad que
excite la bobina podemos conmutar grandes tensiones o intensidades.
Hemos visto cmo usar un transistor para hacer lo mismo, Porque entonces usar rels?

En primer lugar, los rels llevan entre nosotros desde finales del siglo 19 (y nadie
ha sido todava capaz de convertirlos en obsoletos), es una tecnologa muy probada y bien
establecida en la industria y adems sirve para cosas que son problemticas para los
transistores.

Hay lmites en la corriente que un transistor puede aceptar, pero un rel se puede
disear para que aguante cualquier carga, porque basta con los extremos metlicos de los
contactos lo soporten.

Asla completamente el circuito de control del de potencia, lo que tiene su


importancia especialmente en lneas de media y alta tensin.

Normalmente usaremos un rel cuando se requiera conmutar grandes picos de tensin o


intensidad como por ejemplo arrancando motores de corriente alterna de una cierta
potencia. En cambio el transistor es preferible como conmutador, para pequeas cargas y
cuando la velocidad de conmutacin sea una cuestin importante

Un transistor conmuta varios millones de veces ms rpido que un rel.

En la prctica, con Arduino es ms sencillo utilizar un rel para encender una luz
fluorescente o la calefaccin, que buscar un transistor de caractersticas adecuadas.
Aunque hay rels que necesitan muy poca potencia para excitar la bobina, por regla
general Arduino se quedar corto y vamos a tener que usar un transistor que nos resuelva
la papeleta.
El ejemplo que veremos a continuacin incluye un circuito de transistor / rel completo que
nos permitir atacar cualquier proyecto casero que nos propongamos.

CIRCUITO TPICO REL / TRANSISTOR

Cuando ponemos un valor HIGH en el pin de control, El transistor pasa a saturacin y la corriente entre
emisor y colector excita la bobina del rel, haciendo que el contacto cambie de posicin (y haciendo
adems un clic muy agradable).
Si ponemos LOW en el pin de control el transistor entra en corte e impide el flujo de corriente por lo que la
bobina cae y el contacto de salida vuelve a su posicin de reposo.
La salida del rel consta de 3 pines y no de dos como se podra esperar. El motivo es que la conexin
entre los pines de salida 2 y 3 es de tiponormalmente abierto (circuito abierto sin excitar) y entre los pines
2 y 4es normalmente cerrado (circuito cerrado sin excitar la bobina).
Con un rel funcionando como normalmente abierto podemos hacer unas luces de emergencia. Mientras
hay corriente el rel esta excitado y el circuito abierto, pero si se va la luz, el contacto normalmente
abierto se cierra y si hay una batera se encendern las luces de emergencia automticamente.

Para nuestro ejemplo podemos utilizar un LED rojo y otro verde para marcar la situacin.
Veremos que se enciende uno u otro, pero nunca ambos (como corresponde a una seal
de alarma).

CIRCUITO PARA PROTOBOARD

Por una vez, y sin que sirva de precedente, no vamos a incluir un esquema de Protoboard
para el circuito porque el pinout (patillaje) de un rel depende del fabricante y del modelo y
sera poco prctico establecer mltiples diagramas de protoboard.
Adems, el circuito bsico del transistor de la sesin anterior es exactamente el mismo que
este y bastara reemplazar el motor por los contactos de control del rel por una parte, y
por la otra buscar en el rel cual son los pines de normalmente abierto y normalmente
cerrado, y conectar un LED a cada uno con una resistencia comn.

Lo ms recomendable seria buscar en internet la hoja de caractersticas del rel de


que dispongamos y ver en la descripcin del fabricante que es cada pin.
Si por cualquier motivo no pudisemos conseguir las especificaciones, suele ser
bastante fcil determinar los pines de control (porque suelen estar prximos) y para saber
cul es contacto NA o NC hay que hacer pruebas con los LEDs (suelen ser 3 pines
prximos entre s, y el que esta solo es el comn).
Cuando un rel conmuta se oye un clic muy simptico, as que es fcil saber si lo
has excitado. Incluso algunos rels son transparentes para que puedas ver el mecanismo
interior y el movimiento del contacto.

El diagrama de la protoboard no hara sino complicar las cosas y ya va siendo hora de que
tratemos de montar el circuito a partir del esquema electrnico directamente. Animo

PROGRAMA DE CONTROL DEL MOTOR

Para probar que todo est correctamente conectado, bastara con correr el mismo
programa que para el motor:
const int control = 9 ;

void setup()
{
pinMode(control,

OUTPUT) ;

}
void loop()
{
digitalWrite(control, HIGH);

delay(1000);
digitalWrite(control, LOW);
delay(1000);
}

Este programa causar que el rel conmute cada segundo y los LEDs se encendern
alternativamente.
Para convertir este circuito en unas luces de emergencia bastara con poner una batera o
pilas en el comn del rel en lugar de los 5V de Arduino. De ese modo al desconectar
Arduino la luz de emergencia se activara sola.

RESUMEN DE LA SESIN

Ya conocemos los rels y porque tienen inters para nuestros proyectos

Hemos visto lo que son los contactos normalmente abiertos NA y normalmente


cerrados NC.

Normalmente los rels son muy interesantes para encender y apagar algo que
tiene un consumo relativamente alto de corriente

Uso de Buzzers o Zumbadores con Arduino

PIEZOELECTRICIDAD

Segn la Wikipedia, la piezoelectricidad es un fenmeno que ocurre en determinados


cristales que, al ser sometidos a tensiones mecnicas, adquieren una polarizacin elctrica
y aparece una diferencia de potencial y cargas elctricas en su superficie que generan una
tensin elctrica.
Este fenmeno tambin ocurre a la inversa: se deforman bajo la accin de fuerzas internas
al ser sometidos a un campo elctrico. El efecto piezoelctrico es normalmente reversible:

al dejar de someter los cristales a un voltaje exterior o campo elctrico, recuperan su


forma.
Es decir, que son materiales (el cuarzo es el ms conocido) que si los sometemos a una
tensin elctrica variable (como una seal PWM, que ya nos son familiares) vibran.

Es un fenmeno bastante conocido y muchos encendedores domsticos de gas


funcionan bajo este principio. Un resorte golpea un cuarzo y como resultado tenemos la
chispa que enciende el gas o el calentador de agua con un caracterstico click).

En otro orden de cosas, los circuitos electrnicos digitales, suelen disponer de un


reloj interno que vibra a una velocidad patrn, basados en cristales de cuarzo
piezoelctrico. El cristal de Arduino late a 16Mhz por segundo y la flecha indica su

posicin.

En una sesin prxima utilizaremos uno de estos cristales para sincronizar un


circuito discreto con el corazn de un Arduino, el ATmega 328.

Si conectamos un piezo con una seal digital, vibran a una frecuencia sigue bastante
fielmente la variacin elctrica con que los excita, y si vibran a la frecuencia audible,
oiremos el sonido que producen. A un componente que hace esto, le llamamos Buzzer o
zumbador.
Naturalmente, la calidad del sonido que producen dista bastante de lo que podramos
denominar alta fidelidad. Pero es suficiente para generar tonos audibles (como la tpica
alarma de los despertadores digitales) e incluso tonos musicales reconocibles que
podemos secuenciar, hasta en piezas musicales (por ms que uno quisiera estar en otro
lugar cuando las oyes).

Como antes o despus, disponer de una seal acstica en vuestros proyectos, acaba
siendo til, vamos a ver cmo podemos montar estos elementos, y que tipo de opciones
tenemos disponibles.
En esta sesin, montaremos un circuito muy sencillo con un zumbador.

ESQUEMA ELECTRNICO

xx

La conexin es tan simple como conectar negativo a GND y positivo al pin 9. De todas
maneras hay que tener cuidado. Los piezos tienen polaridad y hay que asegurarse de
conectarlos correctamente.

Si los conectis al revs, simplemente no sonar, y tendris que dar la vuelta.

Adems para este primer montaje, necesitamos usar un pin PWM (como el 9)
porque es la alternancia entre HIGH y LOW lo que produce el efecto piezoelctrico

(recordad que una seal PWM enva un tren de ondas cuadradas de amplitud variable),
por lo que lo ms cmodo es usar un pin PWM en lugar de programar un efecto
equivalente en un pin normal.

EL PROGRAMA
Vamos a empezar creando una funcin, Beep(), que haga ruido simplemente:
void beep(unsigned char pausa)
{
analogWrite(9, 20);
delay(pausa);

// Espera

analogWrite(9, 0);

// Apaga

delay(pausa);

// Espera

Y ahora prueba
void setup()
{
pinMode(9, OUTPUT);
beep(50);
beep(50);
beep(50);
delay(1000);
}
void loop()

beep(200);

Lo nico que beep () hace es poner una seal PWM en el pin 9 de 20 sobre 255. Podis
varias el valor, pero el tono de audio no cambiar gran cosa porque est controlado por la
seal de base. Esto es suficiente para generar una de las molestas seales acsticas de
un despertador barato.
Qu pasa si quiero generar seales de tono variable para hacer una meloda? Bueno
pues Arduino dispone de la funcin tone() que genera una seal de la frecuencia indicada,
y notone() que la corta:
void setup()
{
int pinOut = 8;
int freq = 440;
int duration = 1000;
tone(pinOut, freq, duration);
}

La funcin tone() genera un audio de la frecuencia y duracin definidas.


Podemos definir una matriz con las frecuencias de las notas a utilizar y lee las
correspondencias con las notas musicales. Veamos cmo generar una escala con un
zumbador:
int speakerPin = 9;

int numTones = 10;


int tones[ ] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440,466, 494};
// mid C C# D D# E F F# G G# A

void setup()
{ }

void loop()
{
for (int i = 0; i < numTones; i++)
{
tone(speakerPin, tones[i]);
delay(500);
}
noTone(speakerPin);
}

Dada la aficin reinante a la fsica recreativa, me aterra la idea de ponerme a


perorar sobre la relacin entre las notas musicales y la frecuencia correspondiente, as
como los distintos mtodos de calcularlas y no digamos ya pretender hablar de las escalas
temperadas.
As que vamos a mencionar simplemente que existe una relacin directa entre la
frecuencia de una nota y su posicin, en digamos el teclado de un piano.
Para aquellos con formacin musical e inters en como calcular la frecuencia de
una nota dada podes hacer una bsqueda en Google, que enseguida encontrareis de
todo.

Por ltimo, y para cerrar esta sesin, os dir que internet est lleno de gente a quien le
sobra tiempo y lo dedica a las extravagancias ms inverosmiles. Basta con indicaros aqu
la pgina de alguien que ha dedicado un nmero indecente de horas en transcribir la
msica de la guerra de las galaxias a orquesta de cmara, compuesta por Arduino y
zumbador.Descargar ejemplo:

RESUMEN DE LA SESIN

Hemos usado nuestro zumbador piezoelctrico.

Son muy sencillos de usar aunque su calidad es pobre.

Son un sistema barato y rpido de aadir sonido a tus proyectos.

Hemos planteado unos primeros pasos en generacin electrnica de sonido.Si


tenemos ocasin dedicaremos algn otra sesin a la generacin de snidos electrnico y
MIDI.

Fotoresistencias o LDR

LOS FOTOSENSORES

Una fotorresistencia o LDR (Light Depending Resistor, o resistencia dependiente de la


luz) es un componente fotoelectrnico cuya resistencia vara en funcin de la luz que
incide en l. Esta resistencia es muy baja, de unos pocos s con una luz intensa incide en
l y va creciendo fuertemente a medida que esa luz decrece.
Se les suele utilizar como sensores de luz, para arrancar luces automticamente cuando la
oscuridad sobrepasa un cierto umbral, o como detectores de movimiento prximo
( Cuando algo se interpone).
Vamos a utilizar en esta sesin un tpico LDR, que es bastante fcil de conseguir y es
sensible a los cambios de luz ambiente. Montaremos un circuito con un LDR y el
zumbador que vimos en la ltima sesin, para construir un theremin rudimentario, que
espero que os haga pasar un rato entretenido.

Un theremin es un sintetizador rudimentario que genera audio variable de espectro


continuo, analgico, en funcin de una seal de control (No os asustis, que es una
tontera).
El circuito utiliza un LDR como seal de control y calcularemos una frecuencia en funcin
de la cada de tensin que leamos en nuestra fotorresistencia.

Recordad que los convertidores ADC como los de Arduino no pueden leer
resistencia sino tensin.

Los LDR no son precisamente rpidos en reaccionar a la luz, y puedan tardar


hasta algunas dcimas de segundo en reaccionar. Esto no es importante para una alarma
de luz, pero hace imposible que se puedan utilizar para enviar informacin mediante la luz.

Pero antes de entrar en materia necesitamos hacer un inciso para conocer lo que es
un divisor de tensin.

DIVISORES DE TENSIN

Hablamos en su momento de la ley e Ohm:


V=R*I
Pero no hablamos de cmo se combinan las resistencias y ha llegado el momento de
hacerlo, para desesperacin de los que odian las mates.
Podemos combinar un par de resistencias R1 y R2 de dos maneras. En serie y en
paralelo:

EN SERIE

Cuando ponemos las dos resistencias en serie, la resistencia resultante es la suma de


ambas:

Y cuando las ponemos en paralelo, podemos calcular la resitencia equivalente as:

Imaginemos ahora un circuito como este:

Como las resistencias estn en serie el valor total es R1 + R2. Si Vin es de 5V la intensidad que circular

por el circuito ser:


La pregunta del milln ahora es Si medimos entre las dos resistencias cuanto es Vout? Pues igual de
fcil :

EN

Si todava queda alguien despierto, se habr dado cuenta que si R1 y R2 son iguales
Vout ser exactamente la mitad de Vin pero si R1 o R2, fuese un potencimetro (o un
LDR) cualquier variacin en el ajuste, causara una modificacin en el valor de salida de
tensin Vout.
Esto es lo que se conoce como un divisor de tensin y es un circuito de lo ms prctico
para rebajar una seal de entrada, y podis apostar a que lo usareis mas de una vez.
Por ejemplo, los convertidores analgicos de Arduino aceptan un mximo de 5V, pero
muchas seales industriales son de entre 0 y 12V.Si lo conectas sin ms al A0, por
ejemplo, freirs el chip de largo.
Pero con el truco del divisor de tensin y calculando adecuadamente las resistencias (Que
s, que t puedes con lo que hay en la pgina anterior) puedes adaptarlo tranquilamente
para que tu Arduino viva feliz con una seal que originalmente le hubiera chamuscado.
Los divisores de tensin son un circuito muy sencillo y que conviene que sea parte de
vuestro arsenal electrnico. Resuelven cantidad de problemas con una resistencia y un
potencimetro y son ideales para tratar seales, que por exceso de tensin, quedaran
fuera del alcance de tu Arduino.
De hecho en esta prctica vamos a montar un divisor de tensin con una resistencia y
un LDR y leeremos la cada de tensin en l. Nos va a servir como ejemplo de los
divisores de tensin y adems nos servir como seal de control para calcular la
frecuencia a la que haremos vibrar el buzzer.

EL CIRCUITO PARA UN THEREMIN PTICO

Aunque el titulo impresiona, lo reconozco, el circuito no es para tanto:

Fjate que
el LDR R1, junto con R2 forma un divisor de tensin. La lectura de A0 depender de la
luz que incida en el LDR. El esquema de protoboard es igual de fcil:

VAMOS CON EL PROGRAMA.

El programa es muy sencillo. Leemos la cada de tensin en A0 y lo usamos para mapear


una frecuencia entre 20 y 5.000 Hz para llamar a la funcin tone() y eso es todo.
const int pinBuzzer = 13 ;
void setup()
{
pinMode (pinBuzzer , OUTPUT) ;
}
void loop()
{
int p = analogRead(A0) ;
int n = map (p, 0,1024, 20, 5000) ;
tone ( pinBuzzer, n) ;
}

Para probar el circuito os recomiendo que pongis un foco potente a 50 cm por


encima del LDR y probis a mover la mano por delante y especialmente de arriba abajo y
viceversa.

Escuchareis un tono continuo ms o menos agudo, que ira variando su frecuencia


en funcin de la luz que incida en el LDR.

Se acepta que el odo humano se mueve ente 20 Hz y 20Khz (aunque esto es para
algn adolescente de odo muy fino) para los que peinan canas entre 40Hz y 10Khz ya es
un rango optimista. Por eso, mapeamos los valores del potencimetro, que van de 0 a
1024, entre 20 y 5Khz, pero os recomiendo que cambiis estos valores y veis lo que
pasa.

Aqui teneis un pequeo video con el resultado


Creo que convendris conmigo, en que ha sido tan fcil, que no puedo dejaros marchar,
sin poneros antes algn otro problema. Veamos.
El sonido que obtenemos es de espectro continuo, es decir, que reproduce frecuencias continuas
en el margen que es capaz. Pero nuestro odo est acostumbrado a escuchar las notas en tonos y
semitonos de frecuencia dada, como veamos en el programa de las sesin 20. Cmo harais
para conseguir que el resultado de este theremin, produjera, las notas que definimos all?

Podr ser algo asi:


const int pinLDR = 0 ;
const int pinBuzzer = 13 ;

int tono[ ] = {261, 277, 294, 311, 330, 349, 370, 392, 415, 440,466, 494};
// mid C C# D D# E F F# G G# A
void setup()
{ pinMode (pinBuzzer , OUTPUT) ;
}

void loop()
{
int p = analogRead(A0) ;
int n = map (p, 500,1024, 0, 12) ; // Ell array solo tiene 12 notas
tone(pinBuzzer, tono[n]);

delay(300);
}

He usado un array con las frecuencias temperadas de una octava. Despus, mapeamos las
lectura de la puerta A0 a un entero entre 0 y 12, porque el array e arriba solo tiene 12 notas, y
usamos su valor para leer la frecuencia correspondiente.
En mi caso, adems, A0 solo daba valores entre 500 y 1024, as que por eso he corregido la
escala. Por ltimo el delay impide que el cambio de notas sea instantneo, porque de lo
contrario no notaramos mucho cambio el programa anterior.

RESUMEN DE LA SESIN

Hemos presentado las fotorresistencias o LDRs.

Presentamos los divisores de tensin.


Que utilizaris ms de una vez en vuestros circuitos.

Los usamos para rebajar niveles de tensin en seales de entrada y como


adaptadores para leer cadas de tensin resistencias variables .
Vimos como montar un theremin ptico

Uso del sensor de temperatura DHT11

SENSORES DE TEMPERATURA Y HUMEDAD

Bsicamente hay dos variantes DHT11 y DHT22


Las caractersticas del DHT11 son:

Muy barato, sobre 2

Funciona con 3,3 y 5V de alimentacin

Rango de temperatura: de 0 a 50 con 5% de precisin (pero solo mide por


grados, no fracciones)

Rango de humedad: de 20% al 80% con 5% de precisin

1 Muestra por segundo (No es el ms rpido del oeste)

Bajo consumo

Devuelva la medida en C

En cuanto al DHT22:

Barato, entre 4 y 5

Funciona con 3,3 y %V de alimentacin

Rango de temperatura: de -40 a 125 0.5C

Rango de humedad: de 0% al 100% con 5% de precisin.

Lee 2 veces por segundo.

Bajo consumo.

Devuelva la medida en C

En cuanto a la forma de conectarlos y programarlos es la misma para ambos modelos y


veremos que hay desarrolladas libreras para Arduino que soportan los dos de una forma
sencilla.
Destacar que el chip incorpora electrnica para hacer internamente la conversin de
temperatura y humedad y nos da un valor de medida de forma digital, es decir, que no
necesitamos un pin analgico como en el caso del TMP36, sino que lo leeremos con un
pin digital.

DIAGRAMAS DEL CIRCUITO

La conexin es trivial, pero cabe destacar que se vende en dos encapsulados, uno de tres
pines que son GND, Data y Vcc, y otro 4 pines y uno de ellos, sencillamente sobra y no se
conecta. Normalmente viene rotulado en el sensor el nombre de cada pin, y si no ya
sabeis, a buscar el manual en Google

Vamos con el esquema por cortesa de Fritzing:

Y aqu tenemos el esquema de protoboard.

EL PROGRAMA DE LECTURA DEL DHT11

En primer lugar, tenemos que descargar una librera para manejarlos cmodamente,
DX11.zip e importarla. Aqu tenes la librera DHT11.zip
Hacemos el importar la librera DHT11 que nos pondr:
#include <DHT11.h>

Y definimos una instancia del sensor donde declaramos el pin al que esta conectado.
int pin=2;
DHT11 dht11(pin);

Leerlo ahora es muy sencillo:


int error ;

float temp, humi;


error

dht11.read(humi, temp)

Basta con hacer dht11.read pasandole las variables donde queremos el resultado, y
comprobamos que no haya errors (Siempre es buena idea comprobar que no hay error
cuando hacemos una llamda). El programa completo seria ms o menos algo
as: Prog_24_1
#include <DHT11.h>

int pin=2;
DHT11 dht11(pin);

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

void loop()
{
int err;
float temp, hum;
if((err = dht11.read(hum, temp)) == 0)
bien
{
Serial.print("Temperatura: ");
Serial.print(temp);

// Si devuelve 0 es que ha leido

Serial.print(" Humedad: ");


Serial.print(hum);
Serial.println();
}
else
{
Serial.println();
Serial.print("Error Num :");
Serial.print(err);
Serial.println();
}
delay(1000);

//Recordad que solo lee una vez por segundo

El resultado se enva a la consola y aqu podis ver una muestra.

Para hacer variar os valores, de humedad y temperatura y comprobar que todo funciona
correctamente, podeis, sencillamente, enviar vuestro aliento al sensor, y salvo que estis
en el trpico haris subir tanto la temperatura como la humedad relativa.
Como vereris, son de lo mas sencillos de utilizar y un componente habitual de vuestro
arsenal de sensores

RESUMEN DE LA SESIN

Hemos visto los sensores DHT11, y montado un circuito de prueba con el

Los DHT22, usan el mismo circuito y pines, pero su resolucin y velocidad es


bastante mejor, aunque para muchas aplicaciones el DHT11 es mas que suficiente.

Uso de Servomotores

QUE ES UN SERVO
.
Servos
Normalmente los motores habituales lo que hacen es transformar la energa elctrica
(O qumica) en un giro continuo que podemos usar para desarrollar trabajo mecnico.
En la sesin 13 utilizamos un pequeo motor de corriente continua y regulamos la
velocidad de giro mediante una seal PWM de Arduino.
Los servos son tambin motores de corriente continua, pero en lugar de disearse para
obtener un giro continuo que podamos aprovechar (para mover una rueda por ejemplo), se
disean para que se muevan un angulo fijo en respuesta a una seal de control, y se
mantengan fijos en esa posicin.
Imaginad por ejemplo un timn de un avin o barco. No queremos un giro continuo, sino
un motor al que le pueda indicar el ngulo que deseamos en grados y que mantenga esa
orientacin hasta que le demos una orden en contrario.
Estos servos o servomotores son muy frecuentes en Aero modelismo y en robtica, por la
capacidad que presentan para moverse a un ngulo concreto y mantenerse all. De hecho

se suelen disear para que giren un ngulo proporcional a una seal PWM, de forma que
su control es muy preciso. Un servo suele estar formado por:

Un servo suele estar formado por:

Una reductora.Un circuito de control..

Un motor de CC.

Un circuito de control
En la prctica se comporta como un bloque funcional que posiciona su eje en un ngulo preciso en
funcin de la seal de control

Habitualmente los servos tiene un margen de operacin, es decir, pueden moverse entre
0 y ngulo dado, que suele ser de 180, pero existen modelos comerciales de todas la
caractersticas imaginables (incluyendo servos de 360).
Normalmente estos pequeos servos funcionan sobre 5V y el control se realiza mediante
una seal de control PWM, en la que el ancho el pulso indica el ngulo que deseamos
adopte el eje.
Un servo tiene un conector de 3 hilos, 5V (rojo), GND (negro o marrn) y el otro Control
(amarillo o blanco).
Podramos escribir un pequeo programa en Arduino que controle estos pulsos y los
relacione con el ngulo buscado, pero antes de que nadie se asuste, los servos (y otras
cosas) son tan habituales, que ya ha habido gente que han escrito estos programas y los
han puesto a nuestra disposicin.
De este modo podemos manejar un servo sin preocuparnos para nada de cmo realizar el
control de las seales, o de la operacin interna, basta con instalar estos programas en
una forma especial llamada librera.

Una librera es un conjunto de definiciones y funciones escritas en C++ de Arduino,


que podemos utilizar en nuestros programas. Podemos ver el cdigo de estos programas,
aunque normalmente se requiere un nivel medio alto en C++ para comprender su
funcionamiento.
La ventaja de trabajar con una plataforma tan bien establecida como Arduino, es que hay
cantidad de gente en el mundo desarrollando libreras, casi para cualquier cosa que podis
imaginar.
Y an hay algo mejor: Son gratis.
Veris que en las prximas sesiones vamos a utilizar libreras para cantidad de cosas, pero
hoy vamos a comenzar con la primera, la librera servo.

USANDO NUESTRA PRIMERA LIBRERA: SERVO


.

Servo es una librera estndar en Arduino. Eso quiere decir que viene incluida cuando
instalis el IDE, a diferencia de otras libreras que debemos buscar, descargar de Internet
e instalar para poder usarlas.
Para usar una librera estndar, basta con pedirle al IDE que la incluya en nuestro
programa. Id al men Programa \ Importar Librera y os saldr un desplegable con todas
las libreras que tenis instaladas en el IDE.
Por ahora solo nos interesa la librera Servo. Pinchad en ella. Arduino incluir una lnea al
principio de vuestro programa como esta:
#include <Servo.h>

A partir de ahora ya podemos utilizar las funciones disponibles en la librera.

Normalmente para usar una librera hay que leer la documentacin, en la que se
detalla la forma de usarla, que funciones tenemos disponibles, que parmetros pasarlas
etc.

Como es vuestra primera librera, y nosotros ya nos hemos ledo el manual, vamos
a llevaros de la mano. Veris que es de lo ms fcil.
Vamos a montar un circuito en el que hagamos moverse al servo de forma controlada, e
iremos viendo las instrucciones necesarias.

ESQUEMA ELECTRNICO DEL CIRCUITO


.

Vamos a conectar el servo primero a GND y 5V y luego el pin de control, a un pin de


Arduino que permita PWM (Recordad esto o de lo contrario os costara ver el problema).
Recordad que es el ancho el pulso lo que controla el ngulo.
Vamos tambin a conectar un potencimetro a la puerta A0 para jugar con el servo.

El diagrama de conexin para la protoboard es igual de sencillo:

EL PROGRAMA DE CONTROL

Vamos a empezar con una lnea que ya conocamos el include y otra nueva:
#include <Servo.h>
Servo servo1;

Para poder utilizar la librera debemos crear, lo que se conoce como un objeto tipo
Servo que llamamos servo1.
C++ es un lenguaje orientado a objetos, esto significa que podemos definir objetos tipo
(como servos) sin ms que declarar un nuevo objeto del tipo que deseamos. En la jerga de
la programacin se llama crear una instancia, o instanciar un nuevo objeto.
As, esa segunda lnea significa que vamos a crear una nueva instancia de tipo Servo que
llamamos servo1.

Aunque ahora os pueda parecer una forma extraa de hacer las cosas, la
programacin orientada a objetos (OOP por sus siglas en ingls), es una de las
metodologas ms potentes de las ciencias de computacin actuales y todos los lenguajes
de programacin que se precien, han incorporado las ideas de la OOP.
Entrar en la teora del OOP, desborda con mucho las pretensiones de este humilde
tutorial de Arduino, por ahora nos limitaremos a mostraros como usar los objetos.
Una vez creada la instancia del objeto (y podemos crear tantas como necesitemos, para
manejar varios servos a la vez) tenemos que incluir una lnea en la funcin setup() para
informar a C++ que vamos a conectar ese objeto abstracto que todava es servo1 a un pin
fsico del Arduino para controlarlo. En nuestro caso el pin 9:
servo1.attach(9);

Una vez cumplido el trmite para gobernar la posicin del servo recurrimos a
servo1.write( angulo);

Donde Angulo es el valor en grados de la posicin que deseamos. Fcil No?


Vamos a escribir un programa que vaya barriendo un Angulo en grados y moviendo el
servo a esa posicin.
#include <Servo.h>

// Incluir la librera Servo

Servo servo1;

// Crear un objeto tipo Servo llamado servo1

int angulo = 0 ;

void setup()
{
servo1.attach(9) ;
}

void loop()

// Conectar servo1 al pin 9

{
for(angulo

= 0; angulo

<= 180; angulo

+= 1)

//incrementa angulo 1

grado
{
servo1.write(angulo);
delay(25);
}
for(angulo

= 180; angulo

>=0; angulo

-=1 )

//decrementa angulo 1

grado
{
servo1.write( angulo );
delay(25);
}
}

Veris como el servo se va moviendo primero hacia adelante y luego retrocede para volver
a empezar.
Vamos ahora a hacer que el valor del potencimetro represente la posicin del servo de
manera que el servo se mueva siguiendo al potencimetro. Para ello hay que entender que
el valor que leamos en la puerta A0 est comprendido entre 0 y 1024, y que estos valores
tienen que distribuirse entre 0 y 180. As que para calcular el Angulo correspondiente
basta con hacer:

Como la experiencia me ha
demostrado, que los errores haciendo este tipo proporciones tienden a infinito, voy a
aprovechar para presentaros la funcin map(), que hace exactamente eso de un modo
cmodo, librndonos de los float ( aunque para aprender no os vendra mal hacer as el
programa y luego usar el map()).
angulo

= map( analogRead(A0), 0, 1024, 0, 180);

Traducido quiere decir: Haz la proporcin de los valores que leas en A0, entre 0 y 1024, en
un valor comprendido entre 0 y 180 y asignale ese valor al ngulo. //Prog_16_2
#include <Servo.h>

// Incluir la librera Servo

Servo servo1;

// Crear un objeto tipo Servo llamado servo1

int angulo = 0 ;

void setup()
{
servo1.attach(9) ;

// Conectar servo1 al pin 9

void loop()
{
angulo

= map( analogRead(A0), 0, 1024, 0, 180);

servo1.write(angulo);
delay(250);
}

Aqui teneis un peqeo video, mostrando el movimiento del servo

RESUMEN DE LA SESIN

Hemos presentado los servos y hemos vista una par de programas sencillos para
usarlos.

Hemos introducido algn concepto bsico de programacin orientada a objetos


para que podis utilizar las libreras.

Hemos definido las libreras como conjuntos de funciones y objetos que podemos
utilizar sin preocuparnos de cmo funcionan internamente.

Las libreras son un sistema excepcional de utilizar elementos electrnicos sin


tener que entrar en los detalles tcnicos ms o menos complicados. Esto nos abre un
potencial enorme de componentes a nuestra disposicin.

Introdujimos otra funcin ms para nuestro arsenal: map()

Uso del sensor de distancia Ultrasnico

COMO FUNCIONA UN SENSOR ULTRASNICODE


DISTANCIA

Hemos visto, en los documentales, que los murcilagos son capaces de volar en completa
oscuridad y sin embargo, sortear obstculos o atrapar insectos en vuelo. Sabemos que lo
hacen, pero rara vez pensamos como.
Tenemos una vaga idea de que se llama ecolocalizacin y que ms o menos tiene que ver
con unos sonidos agudos que emiten y que despus recogen con esas enormes orejas
que Dios les ha dado, pero rara vez nos planteamos cmo es esto posible.
Delfines y ballenas utilizan un sistema similar para atrapar a sus presas, y hasta hemos
visto que, en cualquier pelcula de submarinos, en el momento lgido el capitn ordena
emitir un pulso nico de sonar para localizar al enemigo.
El concepto bsico, es siempre el mismo, sabiendo a qu velocidad viaja el sonido, si
emitimos un pulso snico corto y escuchamos cuanto tiempo tarda en regresar el eco
podemos calcular la distancia a la que se encuentra el objeto en el que ha rebotado la
seal.

El radar funciona de modo similar aunque usando ondas de radio frecuencia muy
cortasy con una problemtica propia descomunal. Un pulso de radiofrecuencia se emite
desde la antena y se recoge el eco que vuelve a la velocidad de la luz.

Lo que haremos en esta sesin es utilizar un sensor de distancia sencillo HC-SR04 (y muy
parecido a los sensores de aparcamiento de los coches modernos), que nos permite enviar
estos pulsos ultrasnicos y escuchar el eco de retorno. Midiendo este tiempo, podemos
calcular la distancia hasta el obstculo.

El odo humano no percibe sonidos por encima de 20kHz. Por eso, a las ondas de
mayor frecuencia las llamamos ultrasonidos ( mas all del sonido). Los sensores de
ultrasonidos funcionan sobre los 40 kHz.
No son perfectos, les influye la temperatura ambiente, la humedad y los materiales
en los que reflejan, lo que genera una cierta incertidumbre. Pero a cambio son baratos y
efectivos hasta un poco ms de 3 metros en condiciones normales si la precisin no es un
problema determinante

DIAGRAMA DE CONEXIN

Veamos como conectar uno de esto detectores a nuestros Duinos. Aqu est el esquema
elctrico y de protoboard por cortesa de Fritzing:

Y de nuevo, el diagrama de conexin de la protoboard

EL PROGRAMA DE CONTROL

Vamos con el programa, empezamos definiendo algunos valores:


#define trigPin 13
#define echoPin 12
#define led 2

Hasta ahora habamos visto que podamos definir una variable como int, por ejemplo, y
tambin como una constante (const int pin). Aqu utilizamos otro mtodo, el #define que es
una directiva para el compilador.
Esto solo significa que el compilador (en rigor el pre procesador) cambiar todas las
ocurrencias de estos #define en nuestro programa por su valorantes de compilar. Esta es
la forma clsica de C de hacer esto y tiene la virtud de que no ocupa memoria definiendo
una variable (y con un Arduino UNO, que va muy corto de memoria, esto puede ser crtico
en ocasiones).
void setup()
{
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT);
}

Ya estamos ms que habituados a la funcin delay(milis), pero el reloj interno de Arduino


mide en microsegundos y tenemos otra funcin parecida delayMicroseconds(s) que
simplemente congela Arduino el nmero especificado de microsegundos.
Para dar un pulso ultrasnico lo que hacemos es activar el pin Trigger durante unos
microsegundos y para ello lo ponemos en HIGH, antes de escuchar el eco:

digitalWrite(trigPin, LOW);

// Nos aseguramos de que el trigger est

desactivado
delayMicroseconds(2);

// Para estar seguros de que el trigger ya est LOW

digitalWrite(trigPin, HIGH);

// Activamos el pulso de salida

delayMicroseconds(10);

// Esperamos 10s. El pulso sigue active este

tiempo
digitalWrite(trigPin, LOW);

// Cortamos el pulso y a esperar el echo

Para escuchar el pulso vamos a usar otra funcin, pulseIn() ( Oh s, hay muchas,
muchsimas). Para leer el manual de pulseIn() buscad en google Arduino pulseIn y vereis
que pronto lo encontrais.
Bsicamente lo que hace es escuchar el pin que le pasamos, buscando una seal que
pase de LOW a HIGH ( si le pasamos HIGH como parmetro) y cuenta el tiempo que tarda
en volver a bajar desde que sube.
long duracion, distancia ;
duracion = pulseIn(echoPin, HIGH) ;

Ahora ya sabemos el tiempo que tarda en volver el eco en s. Como la velocidad del
sonido es de 343 metros / segundo, Necesitamos 1/343 = 0,00291 segundos para recorrer
un metro.
Para usar una medida ms cmoda podemos pasar esto a microsegundos por centmetro:

Como nuestro eco mide el tiempo que tarda el pulso en ir y venir la distancia recorrida ser
la mitad:

As que el programa queda parecido a esto ( Prog_18_1) : Descargar ejemplo 18_1:


#define trigPin 13

#define echoPin 12
#define led 2

void setup()
{

Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
pinMode(led, OUTPUT);

void loop()
{

long duracion, distancia ;


digitalWrite(trigPin, LOW);

// Nos aseguramos de que el trigger

est desactivado
delayMicroseconds(2);

// Para asegurarnos de que el

trigger esta LOW


digitalWrite(trigPin, HIGH);

// Activamos el pulso de salida

delayMicroseconds(10);

// Esperamos 10s. El pulso sigue

active este tiempo


digitalWrite(trigPin, LOW);

// Cortamos el pulso y a esperar el

echo
duracion = pulseIn(echoPin, HIGH) ;
distancia = duracion / 2 / 29.1

Serial.println(String(distancia) + " cm.") ;


int Limite = 200 ;

// Medida en vaco del sensor

if ( distancia < Limite)


digitalWrite ( led , HIGH) ;
else
digitalWrite( led , LOW) ;
delay (500) ;

// Para limitar el nmero de mediciones

Para convertir esto en un detector de movimiento hemos creado una variable un poco
menor de la medida que el sensor recibe en vacio (en mi caso unos 200 cm). Si la
distancia medida cae por debajo este valor es que algo se ha interpuesto y por tanto
encendemos una alarma, en nuestro caso un humilde LED.
Despus de este ejercicio de fsica y matemticas, que sin duda causar furor entre los
estudiantes aplicados, vamos a hacer el mismo programa pero usando una librera
externa, que alguien se ha molestado en escribir, paras esas pocas personas que no
disfrutan de los problemas de ciencias y que as, podamos ver la diferencia.
Podes descargar la librera de aqu, Descargar, o bien de la web del autor en
code.google.com/p/arduino-new-ping.
Para instalar una librera externa no incluida en el IDE de Arduino tenemos que importarla
con el men Programa \ Importar librera\Aadir librera:

En la ventana que sale, buscad el fichero NewPing_v1.5.zip que habis descargado y


seleccionadlo.
Ya est. Arduino ha importado la librera y los ejemplos que incluye. Si ahora volvis a
Programa\ImportarLibrera, veris que al final de la lista ya est disponible como NewPing,
y adems el zip incluye varios ejemplos de uso. Vamos a cargar el equivalente del
programa anterior. Haced :

Archivo \ Ejemplos \ NewPing \ NewPingExample


Arduino cargara un programa de ejemplo. Las instrucciones claves son primero inicializar
la librera con:
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE) ;

Y despus medir la distancia:


unsigned int uS = sonar.ping() ;

Aqui os copio el ejemplo para vuestra referencia:


#include <NewPing.h>

#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic


sensor.
#define ECHO_PIN 11

// Arduino pin tied to echo pin on the ultrasonic

sensor.
#define MAX_DISTANCE 200

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins


and maximum distance

void setup()
{
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping
results.
}

void loop()
{

delay(50);
unsigned int uS = sonar.ping(); // Send ping, get ping time in
microseconds (uS)
Serial.print("Ping: ");
Serial.print(uS / US_ROUNDTRIP_CM);
Serial.println("cm");
}

Como veis la librera se encarga de inicializar los pines necesarios, enviar los pulsos,
escuchar el eco de retorno y de hacer los clculos. No est mal.

Fijaros, que el ejemplo, utiliza diferentes pines a los que nosotros hemos usado,as
que tendres que modificarlos. Igualmente, el ejemplo inicializa la puerta serie a 115.200.
Es imprescindible igualar esta velocidad con la que recibe la consola o veris muchas
cosas raras en pantalla.

Los alumnos avispados se habrn dado cuenta de que Arduino viene forrado de
ejemplos que pueden cargar y usar. Os invito a que investiguis y juguis con estos
ejemplos cuanto queris.

RESUMEN DE LA SESIN

Hemos conocido los sensores ultrasnicos de distancia.


Sabemos que sirven para medir algo menos de 3 0 4 metros

Sabemos que no son perfectos pero son tiles y baratos.


Ms sobre medir el tiempo: delayMicroseconds ().

Ms funciones disponibles: PulseIn ().

Importando una librera externa, de nuevo,algo que en las prximas sesiones


iremos haciendo cada vez ms, a medida que los elementos a usar se vayan sofisticando.

Teclados Matriciales

COMO FUNCIONA UN TECLADO MATRICIAL

Un teclado no es ms que una coleccin de botones, a cada uno de los cuales le


asignamos un smbolo o una funcin determinada. Pero botones al fin y al cabo.
Leer botones es algo que ya no tiene secretos para nosotros, pero si conectramos cada
tecla a un pin digital de nuestro Arduino, pronto estaramos en apuros.
El teclado de nuestro ordenador suele ser de alrededor de 106 teclas, as que el mtodo
de fuerza bruta va a entrar en apuros rpidamente. Necesitamos otra solucin.
Y como el mundo est lleno de gente ingeniosa se les ocurri una solucin de lo ms
elegante, una matriz de teclas.
Vamos a ver un ejemplo con un pequeo teclado numrico de 16 teclas tipo los de los
telfonos mviles o los de los cajeros automticos.

Para que nuestro Arduino pueda saber que tecla se pulsa, basta con poner tensin en las
filas de forma secuencial y luego leer las columnas para ver cul de ellas tiene
HIGH.Los teclados matriciales usan una combinacin de filas y columnas para conocer el
estado de los botones. Cada tecla es un pulsador conectado a una fila y a una columna.
Cuando se pulsa una de las teclas, se cierra una conexin nica entre una fila y una
columna.
Por ejemplo, ponemos HIGH en la primera fila (hilo 8 en el diagrama de la derecha) y
despus leemos sucesivamente los hilos correspondientes a las columnas (hilos 4, 3, 2,1).
Si ninguno est en HIGH es que no se ha pulsado ninguna tecla de la primera fila.
Pasamos a la segunda fila (hilo 7) y ponemos HIGH, si al leer los hilos 4, 3, 2,1
encontramos que el hilo 1 est en HIGH, es que se ha pulsado la tecla correspondiente a
la B.
De este modo, para leer un teclado matricial de 44 necesitamos 8 hilos en lugar de 16,
aunque nos dar un poco ms de guerra a la hora de programar. Para un teclado de PC
106 teclas bastara una matriz de 1011 o sea 21 hilos en vez de 106.

DIAGRAMA DE CONEXIN

Lo ms prctico es conectar el teclado a Arduino directamente, podemos usar cables de


protoboard, o bien con un peine de pines para que no se suelte nada.

Esta es otra de esas raras ocasiones en que un esquema electrnico tendra poco sentido,
as que pasaremos rpidamente a ver el tema del programa.

Un apunte rpido: Por comodidad en el diagrama, y porque en los ejemplos que


vienen con Arduino utilizan estos mismos nmeros de pines del 0 al 7, los hemos
mantenido. Pero conviene saber que Arduino usa los pines 0 y 1 para comunicarse a
travs del USB, por lo que no es buena usarlos para otra cosa cuando vayamos a usar el
puerto serie.

EL PROGRAMA DE LECTURA

Como ya dijimos, el programa ha de consistir en ir dando tensin consecutivamente a los


pines de las filas 8, 7, 6, 5 y despus ir leyendo los valores de las columnas para detectar
que teclas se han pulsado.
No es un programa complicado, pero antes de que el pnico se apodere de los que siguen
la sesin con creciente temor (y recuerden que tienen algo urgente e ineludible que hacer)

comentaremos que alguien ha tenido este problema antes que nosotros y amablemente ha
puesto a nuestra disposicin una librera llamada KeyPad ideal para leer este tipo de
matrices sin complicaciones,.

Lo que no quita para que podis escribir un programa que lea directamente la
matriz y reconozcis las pulsaciones. Animo, no es difcil y el ejercicio siempre es bueno.

Lo primero es descargar la librera e instalarla. La tenis aqu Descargar, o bien en la


pgina de Arduino
http://playground.arduino.cc/Code/Keypad#Download
Id a la seccin de Download, install and import donde encontrareis keypad.zip.
Descargadlo y para instalarla recordad que basta con hacer:

En la ventana que sale, buscad el fichero Keypad.zip que habis descargado,


seleccionadlo y listo.
Una vez instalada para usarla basta con que le indiquis que deseis usarla. SI hacis
Programa\Importar Librera \ Keypad veris que incluye la siguiente lnea en vuestro
programa:
#include <Keypad.h>

Vamos a ver como usamos esta librera. Lo primero es definir un par de contantes
const byte Filas = 4;

//KeyPad de 4 filas

const byte Cols = 4;

//y 4 columnas

Y ahora una par de arrays para indicarle a la librera que pines de Arduino corresponden a
las filas y cuales a las columnas del keypad:
byte Pins_Filas[] = {7, 6, 5, 4};

//Pines Arduino para las filas.

byte Pins_Cols[] = { 3, 2, 1, 0};

// Pines Arduino para las columnas.

Recordad que un array es una coleccin de elementos que pasamos entre llaves y
separados por comas. Es ms cmodo que andar definiendo 8 variables.
Recordad lo que vimos en la sesin 9, que cuando definimos una array por enumeracin
de sus elementos, como en este caso, no necesitamos pasar entre corchetes el nmero de
elementos (Los cuenta el mismo C++ solito).
Tendremos que definirle, adems, que smbolos corresponden a cada posicin de las
teclas. Una nueva oportunidad para disfrutar de los arrays, pero esta vez de 2
dimensiones en vez de una.
char Teclas [ Filas ][ Cols ] =
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};

Definimos el array de 44 pasndole las dimensiones entre corchetes. Sus


miembros van a ser 4 filas, cada una de las cuales es un array de 4 elementos, y despus
enumeramos los cuatro arrays de 4 miembros.

Fijaros en que cada array va entre llaves. Los elementos de un array se separan
por comas, pero al final de las llaves exteriores va un punto y coma porque toda el
conjunto es una asignacin.

Los arrays siempre parecen complicados hasta que te acostumbras pero no es


para tanto y este es un buen ejemplo para que comprendis la idea de un array de 2
dimensiones.

Una de las curiosidades de leer una matriz de teclas y despus asignar un carcter
contenido en un array es que podemos redefinir el valor de las teclas sin ms que cambiar
el contenido del array.

Si por lo que sea hubiramos conectado mal los pines del keypad al Arduino,
podramos redefinir los valores del array para que coincidan con lo que pone en las teclas.
Puede ser ms fcil que mover de sitio los cables.

De hecho es esa capacidad de mapear la representacin de un carcter a una


posicin en una tabla, es lo que permite que podamos reconfigurar el mismo teclado a
diferentes lenguas, sin ms que cambiar los valores del array (aunque tambin ayudar
mucho luego cambiar los smbolos rotulados en el teclado).

Por ultimo tendremos que crear una instancia de Keypad que llamaremos Teclado1
Keypad Teclado1 = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Fils,
Cols);

Que ledo as asusta, pero que en realidad es una tontera. Traduciendo sera: Crea una
instancia del tipo Keypad que llamaras Teclado1 y al que asignars las teclas que tenemos
en el array Teclas, y le decimos que hemos conectado las filas del keypad a los nmeros
de pines que te indico en el array Pins_Filas y las columnas al array Pins_Cols.

MakeKeymap (Teclas) es una funcin disponible en la librera y que nos permite


asignar un array de valores a una matriz. Se hace solo una vez al principio salvo que por lo
que sea nos interese cambiarlo sobre la marcha.

Por ultimo para leer el keypad hacemos una llamada a otra funcin de la librera:
char pulsacion = Teclado1.getKey() ;

Por ultimo enviamos a la consola el carcter pulsado. Aqu tenis el programa en versin
completa:Descargar
#include <Keypad.h>

// Prog_19_1

const byte Filas = 4;

//Cuatro filas

const byte Cols = 4;

//Cuatro columnas

byte Pins_Filas[] = {7, 6, 5, 4};

//Pines Arduino para las filas

byte Pins_Cols[] = { 3, 2, 1, 0};

// Pines Arduinopara las columnas

char Teclas [ Filas ][ Cols ] =


{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Keypad Teclado1 = Keypad(makeKeymap(Teclas), Pins_Filas, Pins_Cols, Filas,
Cols);

void setup()
{

Serial.begin(9600) ; }

void loop()
{

char pulsacion = Teclado1.getKey() ;


if (pulsacion != 0)
Serial.println(pulsacion);

// Si el valor es 0 es que no se
// se ha pulsado ninguna tecla

Por cierto, en C++ y en otros lenguajes es muy frecuente escribir la instruccin:


if (pulsacin != 0)

De esta otra manera (ms elegante) completamente equivalente:


if (pulsacin )

Porque la condicin del if debe evaluarse a TRUE o FALSE y para los ordenadores un 0 es
FALSE sin remisin, pero cualquier otro valor que no sea 0 es TRUE, incluyendo un
carcter.

RESUMEN DE LA SESIN

Hemos usado nuestro primer keypad hexadecimal


Son prcticos y muy sencillos de usar en cuanto le pillis el tranquillo.

Estn disponibles en mltiples formatos y tipos, Aqu hemos usado uno


tpico de 44, pero tambin los hay 43 y en diferentes materiales y acabados

Un antiguo telfono mvil roto se puede desmontar y usar su teclado


adems de otras cosas, y se puede utilizar de la forma que hemos descrito.
Hemos usado la excusa del teclado para volver sobre los arrays. Vale la pena de
que les dediquis un poco de tiempo pues os ayudaran a resolver cmodamente ms de
un problemas de programacin, y no se merecen la fama de malotes que tienen.

Hemos conocido otra librera externa, KeyPad. Os vendr muy bien en vuestros
proyectos. Ms adelante confo en que podamos hacer algn ejemplo ms sofisticado con
un keypad como hacer que una cierta combinacin abra una cerradura de servo por
ejemplo.

Circuito con Joystick y Servomotor

QUE ES UN JOYSTICK
Joystick
Un joystick suele estar formado por dos potencimetros a 90 que transforman el
movimiento en X e Y del mando en una seal elctrica proporcional a su posicin y que
adems suele incluir un botn.
As pues, suelen tener 5 pines: X, Y, botn y 6V ms GND.
En realidad ya usamos todos estos componentes previamente y la nica curiosidad del
joystick es que resulta un elemento muy cmodo para posicionar algo, aunque no sea
demasiado preciso.
Vamos a montar un circuito con un servo como en la sesin previa y usaremos uno de los
ejes del joystick para posicionar un servo, y si pulsamos el botn encendemos un LED.
(Ignoraremos el otro eje Y, aunque podramos usarlo para posicionar un segundo servo).
El pin correspondiente al botn suele venir marcado como SW de Switch.
Aqu tenemos el diagrama elctrico:

Y para
la protoboard:

EL PROGRAMA DE CONTROL

Vamos con el programa (Prog_17_1):


#include <Servo.h>

// Incluir la librera Servo

Servo servo1;

// Crear un objeto tipo Servo llamado servo1

int angulo = 0 ;
int Eje_X = A1 ;
int Eje_Y = A2 ;
int boton = 4

, LED = 12 ;

void setup()
{
servo1.attach(6) ;

// Conectar servo1 al pin 6

pinMode( boton, INPUT_PULLUP) ;


}

void loop()
{
angulo

= map( analogRead(A1), 0, 1024, 0, 180);

servo1.write(angulo);
if ( ! digitalRead(boton))
digitalWrite(LED, HIGH);

else
digitalWrite(LED, LOW);
delay(250) ;
}

La parte que corresponde al servo es exactamente lo mismo que en la sesin 16.


Por lo dems hemos incluido unas definiciones al principio indicando que hemos
conectado el eje X a la entrada analgica A1 y el eje Y a la entrada A2.

El pulsador est conectado al pin digital 4 y el LED al 12, de forma que si


queremos cambiar de pines, por la razn que sea, bastara con actualizar esta lista al
principio del programa.

Insistir en que hemos definido la entrada correspondiente al boto del joystick como
INPUT_PULLUP y no como INPUT, porque de este modo no necesitamos incluir una
resistencia, sino que Arduino conecta un pullup internamente
Por eso leeremos LOW al pulsarlo y entre tanto ser HIGH, por ese motivo invertimos la
condicin en el if. Encenderemos el botn solo cuando pulsemos.
El servo sigue la posicion del joystick y cuando soltamos vuelve al centro.
Pero hay algo de epilptico en el movimiento del servo (y ms con uno barato como ste
que estoy usando). Recibe muchas interferencias y el movimiento es muy convulso,
porque, an si el servo tuviera una cierta precisin (lo que es una suposicin entre
optimista y muy optimista) los potencimetros y los convertidores analgicos a digital
siempre tienen un margen de ruido.
Seguro que se nos puede ocurrir una forma de mejorar ese movimiento. Pensadlo, Que
podemos hacer para filtrar ese ruido?
No, en serio. Pinsalo primero antes de seguir.

Vale. En el mundo real, las cosas no son nunca blancas o negras, sino ms bien en tonos
grises (o muy frecuentemente chocolates), por eso no es buena idea enviar las lecturas
directamente al control el servo, o de lo que sea que estamos moviendo.
Hay que filtrar un poco la seal. Sin entrar mucho en este tema (sobre el que hay
enciclopedias),vamos a usar una tcnica muy bsica, pero muy eficaz en muchas
ocasiones y que os conviene conocer.
Vamos a leer el potencimetro para decidir si subimos o bajamos el valor del Angulo. No
para calcular Angulo directamente.
Como el potencimetro nos da valores entre 0 y 10000, cuando est centrado o suelto,
leer sobre 500, poco ms o menos (aunque bailar). As que le vamos a dar un margen
de tolerancia. Solo aumentaremos el Angulo, un valor dado, si la lectura del potencimetro
sobrepasa el valor de 600 y lo disminuiremos cuando baje de 400.
De este modo pequeas oscilaciones alrededor del punto medio, no nos afectarn. Es
decir las hemos filtrado. Esto reflejado en el programa, podra ser algo as: Prog_17_2
#include <Servo.h>

// Incluir la librera Servo

Servo servo1;

// Crear un objeto tipo Servo llamado servo1

int angulo = 90 ;

// Empezamos en el centro

int salto = 3 ;

// Controla el salto por movimiento

int Eje_X = A1 ;
int Eje_Y = A2 ;

void setup()
{
servo1.attach(6) ;

// Conectar servo1 al pin 6

pinMode( boton, INPUT_PULLUP) ;


}

void loop()
{
int p = analogRead(A1);
if ( p < 400 )
angulo = angulo - salto ;
else if (p>600)
angulo = angulo + salto ;

// Si la lectura es menor de 400


// disminuimos el angulo
// Si mayor de 600
// Aumentamos el angulo

servo1.write(angulo);

// Y este es el que mueve el servo

delay (50);

// Este delay regula la velocidad del

movimiento
}

Creo que comprobareis que el movimiento es ms fluido y uniforme, y que prcticamente


elimina las convulsiones del servo. Adems usamos este mtodo para dejar clavado al
servo en la posicin que nos interesa (Aunque soltemos el mando), algo que del otro modo
sera imposible.

RESUMEN DE LA SESIN

Hemos visto que un joystick son dos potencimetros a 90 mas un pulsador, ambos
normales y corrientes.

Aprovechamos el montaje anterior para mover el servo con el joystick y mapear su


valor entre 0 y 180

Hemos introducido el concepto de filtrado de seales, que de por si es una rama


especfica de la electrnica y la computacin, y una, que cada da es mas importante en
todos los mbitos de la tecnologa.

Sensor de Movimiento PIR

SENSORES DE MOVIMIENTO PIR


Sensor de Movimiento PIR
Con bastante frecuencia necesitamos algn sistema de detectar la presencia de personas
o animales en movimiento en un rea dada. Es la base de cualquier sistema de
deteccin de intrusos pero tambin se usan mucho en las escaleras comunitarias o aseos
pblicos para encender la luz en cuanto detecta el movimiento.
Todos los seres vivos desprenden calor y lo mismo ocurre con los automviles y cualquier
otra maquinaria, y ese calor se emite en forma deradiacin infrarroja que podemos
detectar con los dispositivos adecuados, como los sensores PIR.
Ya hablamos algo de la radiacin infrarroja en una sesin previa en relacin con
los mandos a distancia IR y podis darle un vistazo si queris volver sobre el tema.
En esta sesin nos vamos a centrar en los sensores PIR, que son elementos que
detectan cambios en la radiacin infrarroja que reciben y que disparan una alarma al
percibirlo.
Los PIR ms frecuentes son sensores de movimiento, y para ello estn divididos en dos
mitades de forma que detecten el cambio de radiacin IR que reciben uno y otro lado,
disparando la alarma cuando perciben ese cambio.

Parece un poco ms complicado que los sensores que hemos usado hasta ahora, pero la
verdad es que se trata de una tecnologa muy fiable y que cuenta con la ventaja adicional
de ser baratos y mltiples fuentes de suministro disponibles.
El propio sensor PIR se puede comprar independientemente:

Pero naturalmente siempre es ms cmodo de manejar con un pequeo circuito de


estabilizacin y control, que nos permita usarlo como un sensor digital directo.
Lo normal adems es que estos sensores se recubran con pequeas lentes de plstico
que mejoren su angulo de deteccin
La imagen que os pongo anexa, os muestra el sensor HC-SR501 con la lente puesta y
quitada para que veis el sensor montado (Podis sacarla vosotros mismos, va a presin)

ESQUEMA DE CONEXIN

Antes de que vayis a buscar vuestros Arduinos, debis saber que estos sensores
PIR pueden disparar directamente una alarma con una seal de 3.3V y son capaces de
excitar pequeos rels, de modo que no necesitis micro controladores, si lo nico que
queris es encender una luz o dispara una alarma.
Por eso vamos a hacer, en primer lugar, un pequeo circuito de prueba como este, de
modo que nos sirva para probar el sensor, y veais que se puede usar directamente.
Vamos a montar un circuito sencillo de deteccin de movimiento que encienda una
LED cuando perciba algo:

Fijaros que hay 3 pines en el lateral, que usaremos para pinchar el sensor PIR HCSR501 a nuestra protoboard, y aqu debajo os pongo el esquema de conexiones:

Como podis ver enseguida, hay un par de potencimetros que podemos usar para
ajustarlo adems de un jumper para elegir modo. Vamos con ello.

AJUSTANDO EL SENSOR

Empezad por colocar el sensor en la misma posicin que la imagen de arriba porque mi
modelo no trae rotulado ningn nombre (Lo que me hizo poner nervioso al principio pero
despus vi que era completamente estndar).
He visto en Internet que recomiendan poner el jumper en la posicin H para las primeras
pruebas que arriba est rotulado como Auto Reset, pero en mi caso me ha resultado ms
fiable sacar el jumper y dejarlo al aire.

Fijaros que el modelo de la imagen este jumper no existe, pero la mayor parte de
los modelos que encontris por ah podris seleccionar H o L, conectando el jumper entre
el pin central y la seleccin deseada o bien dejarlo sin conectar.
Cuando colocamos el sensor en la posicin L, al detectar algo el LED se encender, y al
poco se apagar y har una cadencia tipo blinking LED dependiendo de lo que detecte. A
este modo se le llama no retriggering y no suele demasiado interesante.
Si lo ponemos en H, cuando detecte movimiento se encender y mantendr as durante un
tiempo (Llamado retrigger mode) y suele ser ms conveniente en buena parte de los
circuitos practicos .
Para ajustar la sensibilidad podemos usar uno de los potencimetros que incluye el sensor,
fijaras en la imagen de arriba. (Girando a favor del reloj aumentamos la sensibilidad)
El segundo potencimetro ajusta el tiempo que estar activa la seal de deteccin
despus de que esta haya desaparecido. Pero parece que tambin afecta al retraso con
que inicia la alarma, as que es cuestin de que vayis jugando para encontrar un punto
adecuado para vuestra alarma.
Aqu os dejo un mini video con una demostracin prctica

PROGRAMA DE CONTROL

Si queris usar estos sensores en conjuncin con vuestro Arduino, por ejemplo para
montar un detector con varios puntos controlados, como una habitacin con
mltiples puertas, basta con tomar la seal del sensor y la leis directamente en los pines
digitales de Arduino.
La seal que os entrega el sensor HC-SR501 es digital todo o nada en cuanto detecta
movimiento de una fuente de calor. Podeis leer el sensor directamente sin mucha
complicacin, con un programa similar a este:
const int led = 6 ;
const int sensor = 7 ;

void setup()
{

pinMode( led , OUTPUT) ;


pinMode (sensor , INPUT);

void loop()
{

if (digitalRead( sensor))
digitalWrite( led , HIGH);
else
digitalWrite( led , LOW);

RESUMEN DE LA SESIN

Presentamos lo sensores de movimiento PIR.


Vimos que se pueden usar diectamente o conectados a nuestros Duinos.
Mostramos el detalle de conexin y la utilidad de los pines y potencimetros
disponibles.

Ms sobre el PUENTE H

A VUELTAS CON LOS MOTORES DE CORRIENTE


CONTINUA, O MOTOR CC

Hemos visto por encima las caractersticas bsicas de los motores de corriente continua
con escobillas (Porque hay varios tipos adems de este), pero vamos a entrar un poco
ms en detalle de que cosas debes considerar cuando vayas a elegir uno de estos
motores.
Cuando compres un motor de corriente continua debes fijarte en tres cosas bsicamente:

Voltaje de funcionamiento: Que especifica los rangos de tensin entre los que el
motor funcionar correctamente. Por ejemplo el que yo estoy usando se mueve entre 3 y
6V, pero no es raro encontrarlos de 9, 12 y 24V
Revoluciones por minuto: Que indica la velocidad que puede alcanzar a las
distintas tensiones y que se suele consignar como Rpm. Tpicamente en motores de
Hobby andaremos entre 200 y 2.000 rpm
Par motor: O potencia que el motor puede desarrollar y que indica la carga til
que puede mover. En ingls se llama Torque.
En la sesin anterior vimos como como conectar uno de estos motores a
nuestro Arduino y como variar la velocidad de giro modificando la tensin que le

entregamos en bornes. La velocidad de giro del motor depende directamente de esta


tensin

Mucho cuidado de no superar la tensin mxima que el fabricante nos indica como
seguras o encontrareis que el olor de un motor quemado es muy caracterstico y
particularmente desagradable.
Pero una cosa que no hicimos en la sesin previa fue invertir el sentido de rotacin del
motor, porque este es un tema espinoso, ya que para ello necesitamos invertir la
polaridad de la tensin en bornes, y esto, queridos amigos, no podemos hacerlo usando
solamente nuestros Arduinos(Porque Arduino puede proporcionar +5V pero no -5V).
Para resolver este problema tenemos que usar un poco ms de ingenio y disear un
circuito que se llama puente en H ( H-bridge). Para comprenderlo, imaginaros el siguiente
montaje a base de interruptores:

Cuando usamos los interruptores en la posicin de la imagen izquierda el motor gira en un


sentido que llamaremos directo. Pero si los colocamos en la posicin de la derecha girar
en sentido contrario, porque hemos invertido la polaridad de la tensin en las entradas del
motor, y por tanto el sentido de giro, sin necesidad de invertir la polaridad de la tensin,
cosa complicada.
A estos circuitos se les llama H-bridge, porque recuerdan vagamente a una H alrededor
del motor.
Claro que invertir el giro mediante interruptores es poco prctico, y como aqu somos
expertos electrnicos (Sin carcajadas, por favor), vamos a ver cmo podemos hacer la
misma funcin usando electrnica y que no tengamos que conmutar manualmente, sino
mediante seales elctricas. Un tpico H-Bridge seria parecido a este circuito:

Olvdate por ahora de los diodos, que son para proteccin de la descarga inductiva del
motor y proteger los transistores. Jugando con la tensin en los pines A; B; C; D podemos
conseguir que los transistores entren en corte o saturacin y disponemos de un medio
electrnico para abrir o cerrar el equivalente a los interruptores mediante transistores.

Observa que dos transistores son unos PNP y otros dos NPN para jugar con la
polaridad de la tensin.
El campo magntico del rotor almacena energa, que puede ser importante, y que
cuando cortamos la alimentacin debe ser liberada en forma de corriente elctrica, y
adecuadamente dirigida por los diodos para impedir daos en los transistores o en la
fuente de alimentacin
Que no se asuste nadie. No voy a pediros que montis ese circuito (aunque no sera
demasiado complicado). Recordad que cuando hay una necesidad en el mercado, siempre
hay alguien dispuesto a fabricar un integrado que hace eso y ms.

Y como esta no iba a ser la excepcin, nos encontramos que disponemos de varias
versiones de circuitos H-bridge dependiendo de la tensin y la intensidad que se debe
conmutar.
Nosotros hoy vamos a utiliza un integrado barato, probado y fcil de encontrar que incluye
dos H-bridge y que nos sirve para pequeos motores de corriente continua. Se
llama L293D.

EL H BRIDGE L293D

El L293D, es un pequeo integrado que incluye dos puentes H-Bridge que podemos usar
para gobernar simultneamente dos motores CC.

Si buscis el manual del L293D, veris que aunque el funciona a 5V internamente, puede
conmutar tensiones de hasta 36V para tus motores.

Asegurarte de que no sobrepasas la tensin mxima nominal de tus motores, es


problema tuyo, as que ojo que el chip lo aguanta, pero lo de tu motor es otra historia.
El patillaje del chip es as:

Veamos que son los diferentes pines del L293D:

El pin 16, Vss, son los 5V con los que alimentamos el chip y el pin 8, Vs, es la
tensin con la que alimentamos el motor.
Los pines del 1 al 7 controlan el primer motor y los pines 9 a 15 controlan el
segundo motor.
El pin 1, Enable1, Activa el uso del motor 1. Con un valor HIGH, el motor puede
girar dependiendo del valor de I1 e I2. Si es LOW se para independientemente de los
valores del resto de pines
Los pines 2 y 7 son los pines de control para el motor 1, e irn conectados a
nuestros Arduino para controlar el sentido de giro.
Los pines 3 y 6 son la salida a la que se conecta el motor 1, cuya polaridad se
invierte en funcin los valores de 2 y 7.
En el diagrama de arriba veis que hay pines equivalentes para el motor 2 y cuales
son.
Los pines 4, 5,12 y 13 van a GND.
Podemos hacer una tabla para mostrar la lgica que sigue el giro del motor en funcin de
los tres pines:
ENABLE

CONTROL PIN 2

CONTROL PIN 7

LOW

HIGH

HIGH

LOW

ENABLE

CONTROL PIN 2

CONTROL PIN 7

HIGH

LOW

HIGH

HIGH

HIGH

HIGH

HIGH

LOW

LOW

Por tanto tenemos que activar el pin enable para que el motor gire y despus usamos los
pines Input1 e Input2 con valore opuestos para hacer girar el motor en una direccin o en
la contraria. Fcil no? Veamos cmo hacer el montaje con nuestros Arduinos.
Hagamos un resumen de conexiones
PIN L293D

PIN ARDUINO

10

Ena

Inp

Moto

4,5, 12,13

GND

Moto

Inp

Vin

Alimentaci

16

5V

Alimentaci

Vamos con el esquema de protoboard.

ESQUEMA DE PROTOBOARD

Una vez que tenemos claras las conexiones, el diagrama de protoboard del chip L293D a
nuestro Duino ser algo as:

DESCR

GN

Veamos el programa que vamos a usar para controlar este motor. Vamos a usar los 3
pines de la tabla anterior. Arduino Pin 10 es el enable del Motor 1 y usamos los pines 8 y 9
para controlar el sentido de giro. Por tanto
#define E1 10

// Enable Pin for motor 1

#define I1 8

// Control pin 1 for motor 1

#define I2 9

// Control pin 2 for motor 1

void setup()
{
for (int i = 8 ; i<11 ; i++)
pinMode( i, OUTPUT);
}

// Inicializamos los pines

void loop()
{

digitalWrite(E1, HIGH);

// Activamos Motor1

digitalWrite(I1, HIGH);

// Arrancamos

digitalWrite(I2, LOW);
delay(3000);

digitalWrite(E1, LOW);

// Paramos Motor 1

delay(1000);
digitalWrite(E1, HIGH);

// Activamos Motor1

digitalWrite(I1, LOW);

// Arrancamos con cambio de direccion

digitalWrite(I2, HIGH);
delay(3000);

digitalWrite(E1, LOW);

// Paramos Motor 1

delay(1000);
}

El programa no puede ser ms sencillo. Activamos el Enable1 para arrancar Motor1, y


luego usamos I1 e I2 con valores invertidos. El motor arranca y lo paramos a los 3
segundos. A la de 1 segundo levantamos de nuevo el Enable1y al intercambiar los valores
de I1 e I2 el giro del motor se inicia y en la direccin contraria.
Aqu va un mini video con el resultado:
Los lectores ms astutos, se habrn dado cuenta de que no hemos variado la velocidad de
giro y dado que en el programa anterior todos los valores son digitales lo vamos a tener
mal para variar la velocidad de forma analgica.

Pero el truco est en que hemos conectado el pin Enable1 al pin Arduino 10 que es PWM
(As, como sin querer) y los L293D vienen diseados para variar la velocidad de giro de los
motores correspondientes con la tensin aplicada a este pin, por lo que resulta trivial variar
la velocidad del motor, sin ms darle valores analgicos.
Si por ejemplo aadimos un potencimetro de nuevo conectado al A1, podemos escribir
este valor directamente (dividido por 4, claro) al pin 10 como analgico, sustituyendo la
lnea
digitalWrite(E1, HIGH);

// Activamos Motor1

Por esta otra que escribe un valor analgico:


analogWrite(E1, analogRead(A1) /4 ) ;

Fijaremos la velocidad de giro del motor en funcin del valor del potencimetro. El
programa corregido, quedara poco ms o menos as:
#define E1 10

// Enable Pin for motor 1

#define I1 8

// Control pin 1 for motor 1

#define I2 9

// Control pin 2 for motor 1

void setup()
{
for (int i = 8 ; i<11 ; i++)

// Inicializamos los pines

pinMode( i, OUTPUT);
}

void loop()
{

analogWrite(E1, analogRead(A1) / 4);


digitalWrite(I1, HIGH);
digitalWrite(I2, LOW);

// Arrancamos

// Activamos Motor1

delay(3000);

digitalWrite(E1, LOW);

// Paramos Motor 1

delay(1000);
analogWrite(E1, analogRead(A1) / 4);

digitalWrite(I1, LOW);

// Activamos Motor1

// Arrancamos con cambio de direccion

digitalWrite(I2, HIGH);
delay(3000);

digitalWrite(E1, LOW);

// Paramos Motor 1

delay(1000);
}

Y eso es todo.

Si montis el circuito de prueba, tened en cuenta que la lectura de A1 solo se hace


al salir del delay, por lo que variacin se efecta al principio de cada ciclo de giro y no en
medio de este.
Sera un buen ejemplo plantear un programita en el que la velocidad se varia
inmediatamente, aunque para ello tendris que eliminar los delays.
Aqu tenemos un vdeo de muestra del resultado.

RESUMEN DE LA SESIN

Hemos presentado los H bridge y porqu son necesarios.


Vimos un integrado, el L293D, que incluye dos H bridge con la capacidad para
regular dos motores tanto en velocidad como en sentido de giro.
Montamos un circuito de pruebas para utilizar el H bridge con nuestros Arduinos.

Display LCD 16x2

LOS DISPLAYS LCD

Los displays LEDs de 7 segmentos, que vimos en las sesiones anteriores, estn muy bien,
son baratos y prcticos, pero tienen el inconveniente de que no pueden mostrar mensajes
de texto, sino solo nmeros.
Se echa de menos algn sistema para mostrar mensajes de texto sencillos, y por eso se
comercializan los displays LCD. Son faciles de encontrar en diversos formatos : 162 (16
caracteres x 2 lneas) o LCD 164 (16 caracteres x4 lunes).

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 pro a vuestros
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 vuestros Duinos y cmo usarlos para sacar
mensajes al exterior.

ANTES DE EMPEZAR

Aunque, ltimamente, estos displays suelen venir con los pines soldados, todava hay
muchos sitios que cuando compras uno de estos, te lo envan en kit, con los pines aparte
para que los sueldes

En algn momento tendremos que hablar de cmo soldar componentes, pero ese
da, an no ha llegado.

Lo primero que tienes que saber, es que tienes que soldarlos, y que no vale sujetar los
pines de algn modo ms o menos extravagante. Los sueldas y punto. Hazte a la idea.
Cualquier otra solucin acabara funcionando mal, o directoramente con el display
quemado.
Cuando lo tengas listo, pincha el display en la protoboard, dejando sitio para el resto de
componentes y cables, recuerda que habr muchos, as que se generoso con el espacio
que dejas.

DIAGRAMA DE CONEXIN

Aqu teneis el esquema de conexin:

Y este es el esquema para potoboard:

La conexin no es complicada, pero requiere ser cuidadoso. Asi que vamos a ir paso a
paso con los diferentes cables. Empieza conectando tensin y GND a la protoboard.

Vamos ahora a a conectar la alimentacin el panel LCD. Conecta el pin16 del LCD a
Ground y el 15 a 5V

Si conectas ahora el cable USB a tu Duino, el LCD debera iluminarse, si no, revisa tus
cables antes de seguir.
Vamos a conectar ahora, el potencimetro de ajuste. Para ello conecta uno de los
extremos del pot a GND y el otro a 5V. El centro al pin 3 del LCD.
Aprovechemos tambin para dar tensin al panel LCD, El pin 1 va a GND y el 2 a tensin:

Si todo ha ido bien, ya podemos encender el dispay 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.


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

GND

RS, LCD pin 4

Arduino pin 7

EN, LCD pin 6

Arduino pin 8

Y ya solo nos quedan los 4 cables de datos.


DB7, LCD pin 14

Arduino pin 12

DB6, LCD pin 13

Arduino pin 11

DB5, LCD pin 12

Arduino pin 10

DB4, LCD pin 11

Arduino pin

EL PROGRAMA DE CONTROL

Vamos a usar una librera de 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>

Despues, hay que inicializar la librera. Creamos una instancia llamada lcd, de la clase
LiquidCrystal y le pasamos como parmetros los pines que hemos usado:
LiquidCrystal lcd(7, 8, 9, 10, 11, 12); //

( 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, peroaseguraros de cambiar la lnea de
definicin de los pines, o no corrern.

El resto es sencillo
void setup()
{
lcd.begin(16, 2); // Fijar el numero de caracteres y de filas
lcd.print("Prometec.net"); // Enviar el mensaje
}

void loop()
{
lcd.setCursor(0, 8);

// set the cursor to column 0, line 1

lcd.print(millis() / 1000);

// print the number of seconds since reset:

Cuidado: Como siempre la primera linea, la superior, es la linea 0 y la segunda la


linea 1.
Estos display son muy pesados de cablear, pero muy sencillos de utilizar.
Vamos a probar sacando un reloj (muy sencillo de momento). Si recordis las funciones
que usamos en las ultimas sesiones, podemos recuperar alguna para presentar el valor de
millis() como un reloj
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

void setup()

{
lcd.begin(16, 2);

// Fijamos el numero de caracteres y filas

lcd.print("Prometec.net");

// Aqi va el mensaje

void loop()
{
lcd.setCursor(6, 1);

// Ponte en la line 1, posicion 6

String s = reloj() ;
lcd.print(s) ;
}
String reloj()
{
int n = millis() / 1000 ;
int segundos = n % 60

int minutos =

n / 60

// Lo pasamos a segundos

String S = String(minutos) + ":" + String(segundos);


return (S);
}

Merece la pena, comentar algunas cosas de este cdigo. En primer lugar en la funcin
reloj, calculamos los minutos y segundos a partir del reloj interno de Arduino en
milisegundos, no hay nada nuevo en esto. Pero fijaros que hemos definido reloj como
String:
String reloj()

Eso significa que vamos a devolver un parmetro tipo String a quien nos haya llamado. En
algn punto de la funcin habr que hacer un return( String).
Fijaros que definimos dentro de la funcin un string llamado s:
String S = String(minutos) + ":" + String(segundos);

En esta lnea no hay que confundir (aunque se escriben exactamente igual), el tipo String
para definir S, con la funcin String(n) que convierte un numero n en un string de texto
para que pueda mezclar el nmero de los minutos y los segundos separados por un
smbolo de :.
Al final le aadimos un par de espacios en blanco, para evitar arrastrar fantasmas en la
pantalla

Quita los espacios y miro lo que pasa en el cambio de minuto. Cmo lo


arreglaras, sin el truco de poner esos espacios al final? Piensalo.
En la funcin loop, hemos usado
lcd.print(s) ;

Para sacar el mensaje de texto. Todo lo que ya sabis de Serial.print() se usa exactamente
igual con esta instruccin. Y por ltimo, tenemos una lnea como esta:
lcd.setCursor(6, 1);

// Ponte en la line 1, posicion 6

Que lo que hace es posicionar el cursor del panel, en la posicin 6 de la segunda lnea,
para escribir la hora centrada. Aqu os dejo un mini video con el resultado.
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
corran.
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.

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.

DEFINIENDO TUS PROPIOS CARACTERES

Vamos a definir un carcter propio, para digamos, el smbolo de grados centgrados, por
ejemplo.
Lo primero que tenis que saber, es que los caracteres se definen con un array ( si, de
nuevo) de 88, como si los dibujarais en una cuadricula de ese tamao, y rellenando el
cuadradito completo.
As por ejemplo para el smbolo del grado seria:

byte grado[8] =
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,

// Los definimos como binarios 0bxxxxxxx

0b00000000,
0b00000000,
0b00000000
};

Para montar los caracteres definidos usamos:


lcd.createChar(0, euro);
lcd.createChar(1, grado);

Y ahora ya estan disponibles. Tened en cuenta que solo podemos definir 8 caracteres
especiales en un momento dado ( Aunque podemos definir 30 arrays, de caracteres y
crearlos y matarlos sobre la marcha).
Aqui tenemos un ejemplo del programa:
#include <LiquidCrystal.h>
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);

byte grado[8] =
{
0b00001100,
0b00010010,
0b00010010,
0b00001100,
0b00000000,
0b00000000,
0b00000000,
0b00000000

};

void setup()
{
lcd.begin(16, 2); // Hay que inicializar el LCD
lcd.createChar(1, grado);
lcd.setCursor(0, 0);
lcd.print("Estamos a 25");
lcd.write(1);
}
void loop()
{
}

Y aqui teneis una foto del resultado

Por ltimo, y para cerrar ya la sesin (Todo llega en la vida), Deciros que de nuevo, hemos
montado este display a la brava, conectando un buen nmero de cables.
Esto solo se puede justificar, porque en su da piqu y me compre un display de estos ( en
realidad, dos. Tengo otro de 164), pero si vais a compraros un LCD, por Dios, compraros uno
que sea I2C o algo as, vuestra salud mental mejorar mucho y solo usa 4 cables.
En la prxima sesin montaremos uno para que veis la diferencia.

RESUMEN DE LA SESIN

Hemos visto los displays LCD de 16 caracteresy 2 lneas.


Lo suficiente como para comprender, que como ejercicio est bien, pero
veremos otras maneras de incluir estos displays, menos trabajosas.
Existen tambin, displays de 16 caracteres y 4 lneas, si necesitis mas espacio en
pantalla.
Son muy comodos de manejar porque podemos imprimir directamente, como si
fuera una puerta serie.

Podemos ( y tendremos que hacerlo, seguro) definir caracteres y smbolos no


incluidos en el display.

Mini Proyecto: Ventilador en funcin de un sensor de


temperatura

UN CIRCUITO CON SENSOR Y ACTUADOR

Hemos ido viendo hasta ahora como utilizar un sensor de temperatura y tambin como
usar un pequeo transistor para mover un motor de CC, pero no los habamos mezclado.
En esta sesin haremos un pequeo ejemplo de control, usando un sensor LM35DZ para
determinar la temperatura y un ventilador de 5V, para que cuando la primera alcance un
valor crtico, usemos el segundo a fin refrigerar el circuito.
Como no disponemos de ningn sistema a refrigerar, nos conformaremos con enfriar el
propio sensor, lo que no resulta especialmente provechoso, pero sin duda, nos servir para
mostraros un ejemplo de control y reaccin, en el mejor espritu de un sistema automtico,
tal como un regulador de temperatura con nuestros Duinos.
Veremos que la regulacin de un sistema tan sencillo no tiene grandes problemas y por
eso esta sesin esta mas pensada como un ejercicio de control sencillo y que como una
regulacin en toda regla.
Adems el parmetro que buscamos controlar, la temperatura, tiene la virtud de variar con
lentitud, lo que nos deja mucho tiempo para reaccionar y no tener que preocuparnos por
cuestin de reaccionar con precisin en tiempo real.

Hace mucho tiempo, cuando empec a trabajar en cosas de estas, y alguien


preguntaba qu era eso de trabajar en tiempo real, definamos el tiempo real como el
margen que tenas para reaccionar y controlar el parmetro dscolo antes de que algo caro
se fuera al guano.
Cuando ests en un marrn as, las tcnicas que vamos a aplicar aqu no valdran
y tendramos que empezar a hablar de cosas como el control PID, pero por ahora es
pronto, as que mejor lo dejamos aqu.

Vamos por tanto a montar un circuito sencillo con el sensor de temperatura y otro
independiente con un transistor para controlar el motor del ventilador en la misma
protoboard.

ESQUEMA ELECTRNICO DEL CIRCUITO.

Vamos a montar un pequeo circuito que lea la temperatura de un sensor, imprima el valor
en la consola y encienda un diodo cuando esta sobrepase un cierto umbral.
Para conectar el sensor de temperatura LM35DZ y el transistor 2N2222, os incluyo el
detalle de sus pines aqu

Aqu tenemos el esquema electrnico del circuito:

Y el circuito para protoboard sera muy sencillo tambin:

PROBANDO EL SENSOR DE TEMPERATURA.

Ya hemos visto en sesiones previas como usar un sensor LM35DZ, pero si alguno queris
revisarlo podis hacerlo aqu: Sensor de temperatura.
Vamos a empezar probando el sensor para comprobar que funciona correctamente, y para
ello vamos a usar este programa:
const int Sensor = 0 ;

// Pin que lee la temperatura

void setup()
{

Serial.begin(115200);

void loop()
{

int lectura = analogRead(Sensor);


float voltaje = 5.0 /1024 * lectura ;
float temp = voltaje * 100

Serial.println(temp) ;
delay(200);
}

Usamos la puerta Analog0 que definimos como una constante sensor, y en el loop leemos
la puerta y convertimos el valor de la lectura a grados centgrados (Recordad que la razn
de hacerlo as la vimos en la sesin de los sensores de temperatura) e imprimimos sin ms
el valor de la temperatura. Deberas ver algo parecido a esto:

El sensor LM35DZ tiene un margen de error de alrededor de 0,5 grados y por eso las
lecturas tienen oscilacin, dando diferencias de hasta un grado.

PARA LOS QUE VAN A POR NOTA

El baile de las lecturas se debe a que el mundo real nunca es perfecto y hay cosas que
van desde la incertidumbre de la medida causada por el propio sensor hasta los errores en
los convertidores de nuestro Arduino (Que no son los mejores del mundo) e incluso
interferencias electromagnticas espurias.
Todo ello se confabula para que tengamos ese molesto baile de cifras en la medida y
aunque en este caso no tiene importancia puede convenirnos filtrar este tipo de errores y
para ello podemos promediar las n ultimas lecturas y presentar esto como el valor de la
temperatura.
Para ello podemos guardarlas digamos 8 ltimas lecturas y promediarlas, con lo que
aplanaremos fuertemente los errores, y la manera ms sencilla es usar un buffer
circular (O Ring Buffer)

La forma de apuntar a la posicin a escribir es una variable llamada ndex que empieza en
0 y cada vez que escribe en la posicin correspondiente se incrementa en 1 Y cmo
evitamos que pase del valor mximo aceptable? Pues tomando el resto del valor de ndex
con respecto al nmero de posiciones del array.
Buffer[ index] = temp ;
index = ++index % 8

Una vez que apuntamos correctamente a la posicin a escribir y despus de los N valores
iniciales en los que la temperatura promedio ser falsa (Porque an no hemos ledo N
valores) tendremos en Buffer las ultimas N lecturas y el resto es aritmtica:
int index = 0 ;

// Posicion a escribir

const int N = 16 ;

// Numero de muestras a considerar

float Buffer[N] ;

// Array donde guardamos las lecturas

Buffer[ index] = temp ;


index = ++index

% N

float Tmedia = 0 ;
for (int i=0 ; I < N ; i++)
Tmedia = Tmedia + Buffer[i] ;
Serial.println( Tmedia / N) ;

Aqu os dejo el programa complete, por si quieres jugar con el: Prog_130_2. Para N = 32
podis ver algo as:

Podis ver que la temperatura baila mucho menos y el baile desciende a medida que
aumentis el nmero de muestras que promediis, pero cuidado, cuanto ms crece N
tambin crece el tiempo que tardis en responder a los cambios ( Para N = 32 a 5
muestras por segundo hay ms de 6 segundos de tiempo de reaccin).

Aunque con una temperatura ambiente eso no es grave, puede haber ocasiones
en que lo sea, por ejemplo porque un quemador arranca, y en 6 segundos le sobra tiempo
para chamuscar lo que sea que estemos controlando, as que ojo.

INCLUYENDO EL VENTILADOR.

Ya tenemos montado el sensor de temperatura y ahora vamos a programar el control de


arranque y apagado del motor / Ventilador, definiendo un valor umbral a partir del cual
queremos ventilar el sensor. Veamos un posible programa: Prog_130_1
int Sensor = 0 ;

// Pin que lee la temperatura

int umbral = 30 ;

// Temparatura que arranca el ventilador

const int control = 9 ;

// Gobierna el ventilador

void setup()
{

Serial.begin(115200);
pinMode(control,

OUTPUT) ;

void loop()
{

int lectura = analogRead(Sensor);


float voltaje = 5.0 /1024 * lectura ;
float temp = voltaje * 100 -5 ;
Serial.println(temp) ;

if (temp >= umbral)


digitalWrite(control, HIGH);
else
digitalWrite(control, LOW);

delay(200);

La nica novedad es que comprobamos que la temperatura medida es inferior al umbral


prefijado y si no es as, arrancamos el ventilador para refrescar el sensor.

Fijaros que al alcanzar el umbral, disparamos el ventilador a tope de modo digital.


Es decir todo o nada. En una situacin real probablemente convendra hacer un control
proporcional de la velocidad del ventilador en funcin de lo lejos que esta del punto que
buscamos ( Aqu es donde entran las cuestiones de control PID)
Os propongo que hagis un ejemplo en el que la velocidad del ventilador sea
proporcional a la diferencia entre la temperatura umbral y la temperatura medida.
Aqu tenis un pequeo vdeo mostrando el montaje:

RESUMEN DE LA SESIN

Mezclamos en un nico proyecto un sensor y un actuador para conseguir control.

Presentamos la idea de buffer circular para promediar las lecturas instantneas.

Vimos un principio de regulacin de temperatura.