domingo, 19 de junio de 2011

Entrada Analógica (Analog Input)

Hoy nos dedicaremos a interactuar con una entrada analógica, la cual a diferencia de una entrada digital (entrega anterior) permite leer un rango de valores. Estos valores representan voltaje, pero dentro del microcontrolador pueden ser representados por un rango de valores enteros, los cuales pueden ir de 0 a 255 o de 0 a 1024, etc., esto depende del tipo de procesador que estemos utilizando... por eso es muy útil obtener las especificaciones del micro y las funciones asociadas (en el lenguaje que escogiéramos) a la lectura de un puerto analógico.

La idea de un puerto analógico es leer de un puerto diferentes valores, lo cual permite tomar decisiones más amplias o interactuar con rangos que permiten realizar tareas diferentes.

En lo personal, cuando pienso en una entrada digital pienso en un switch on/off, y cuando pienso en una entrada analógica pienso en un potenciómetro, o cualquier dispositivo cuya salida oscile entre 0V y 5V.

Estos dispositivos (ejemplo un lm35 - termómetro digital) alimentándolos con 5V, pueden entregar al puerto en donde se conecten un rango de valores de acuerdo a las características con las cuales el dispositivo está diseñado.

Por ejemplo, un potenciómetro permite entregar al micro un rango de voltaje que depende del voltaje con el cual esté alimentado. Un termómetro digital, entregará un voltaje de acuerdo a la alimentación del mismo y a las condiciones de temperatura a la cual esté expuesto. En cualquier caso, siempre se obtiene un voltaje asociado a la lectura del dispositivo, y a través de este voltaje podemos tomar decisiones y ejecutar tareas.


El siguiente circuito conecta 8 leds a la plataforma de prototipado pinguino en los pines 0-7, que son puertos digitales. Un potenciómetro es conectado a los puertos GND,VCC del micro y su salida la enviamos al puerto 13, el cual es analógico.


El código que utilizaremos permite utilizar los 8 leds como una barra de indicación. Cuando el potenciómetro está en el tope izquierdo, este entrega al puerto 13 cero voltios. Cuando el potenciómetro está en el tope derecho le entrega al puerto 5V.

El micro traduce este voltaje en un número entero que oscilará entre 0 y 1024, dependiendo del voltaje, el cual estará en un rango de oV a 5V.

Nuestra intención es que a medida que vamos rotando el potenciómetro a la derecha (0->5)V la barra de 8 leds debe ir iluminándose a la derecha hasta llegar a encender los 8 leds, justamente cuando el potenciómetro esté en el tope derecho. En la rotación contraria (5->0)V, los leds deben irse apagando uno a uno de derecha a izquierda hasta quedar todos apagados.

A continuación el codigo

// Ejemplo de utilización de lectura de potenciometro y encendido de leds
#include "ADlib/__map.c"

const int potPin=13;

void setup()
{
byte i;
for (i=0; i < 8; i++)
pinMode(i,OUTPUT);
pinMode(potPin,INPUT);
}

void apagarLeds()
{
byte i;
for (i=0; i<8; i++)
digitalWrite(i,LOW);
}

void encenderLeds(int count)
{
byte i;
for (i=0; i<count; i++)
digitalWrite(i,HIGH);
}

void loop()
{
apagarLeds();
encenderLeds(map(analogRead(potPin),0,1024,0,8));
delay(50);
}

Veamos como funciona esto. En primer lugar tenemos la declaración de una constante (potPin) que nos indica cual es el puerto que utilizaremos para leer el voltaje que nos entrega el potenciómetro.

Luego tenemos la función setup() para definir la modalidad de los puertos. Los puertos de entrada(0,7) los definimos como salidas en el ciclo for. Asimismo, el puerto 13 lo definimos como entrada con la función pinMode.

Hemos creado 2 funciones. apagarLeds() nos permite apagar todos los leds al tiempo utilizando un ciclo for con el siguiente rango (0<=i<8). Luego definimos una función que nos permite encender hasta el led definido por el parámetro count.

En el ciclo Loop(), vemos como apagamos los leds para luego encender hasta el led que nos devuelve la función map.

La función map es una función que nos permite convertir un rangoA en un rangoB. Esta función es estándar en arduino, pero no en pinguino, por lo que está programada y agregada al directorio de librerías de pinguino, y es por esta razón que la segunda línea existe.

#include "ADlib/__map.c"

En nuestro caso, la función mapea el rango (0,1024) al rango (0,8) utilizando como entrada lo que devuelve analogRead(potPin). Esta conversión es muy conveniente ya que directamente le pasamos un valor entre 0 y 8 a la función encenderLeds(). Este ciclo se repite infinitamente cada 50 milisegundos debido la función delay(50) que hemos colocado al final del loop.

// map function
// Alejandro-Dirgan 2011

#ifndef __MAP__
#define __MAP__

#define MAP 1

float map(int value, int fLow, int fHigh, int tLow, int tHigh)
{
return ((float )tHigh*(float )(value-fLow)+(float )tLow*(fHigh-value))/(float )(fHigh-fLow);
}

#endif

Veamos como funciona en la práctica.


Con las entradas analógicas se pueden hacer infinidad de cosas, solo la imaginación y los requerimientos lo dirán.

En la próxima entrega veremos las salidas analógicas.


1 comentario: