Documentos de Académico
Documentos de Profesional
Documentos de Cultura
La Conversión de Analógico A Digital
La Conversión de Analógico A Digital
En una sesión previa ya dijimos que Arduino dispone de 6 convertidores analógico a digital
(ADC) que son los pines A0 a A5, y dijimos que son capaces de convertir valores de
tensión hasta un máximo de 5V, que es la tensión de referencia en Arduino.
Ya dijimos también, que una de las características claves del convertidor, es su número de
bits, que define la finura con los que podemos cuantificar esa conversión a digital. En el
caso de Arduino, son 10 los bits que maneja en la puertas analógicas, lo que significa que
su resolución es 210 =1.024 posibles valores.
Cuanto mayor sea esta resolución mejor es la capacidad de aproximación al valor real
cuya conversión buscamos.
Es importante entender que una conversión a digital de una señal analógica es siempre
una aproximación, y ni siquiera en el improbable caso de que el valor analógico fuese
exactamente el que nos dice el convertidor, siempre tendremos una incertidumbre.
En un convertidor como los de Arduino con 10 bits de resolución, cada escalón de medida
es de 5V/1024 = 0,0048828125 V, algo menos de 5mV, lo que significa que no puede
discriminar entre valores de tensión cuya diferencia sea menor que esto.
Sin entrar en muchos detalles, conviene decir que lo que un convertidor ADC hace es
comparar sucesivamente la señal que queremos cuantificar en la entrada, con una tensión
de referencia contra la que hace las comparaciones.
Dicho de otro modo, un ADC no proporciona valores absolutos, sino que proporciona una
comparación cuantificada con relación a un valor de referencia. Por eso, en la
sesión Sensor de temperatura TMP36 hemos calculado la tensión de entrada en uno de
los pines Analógicos como la lectura multiplicada por una relación entre el valor de la
máxima de la entrada 5V con la máxima medida del conversor 1024.
Como las señales que normalmente manejamos en Arduino están alrededor de los 5V,
comparar contra 5V es lo razonable, porque además la industria tiene una gama completa
de sensores cuyo valor máximo devuelve 5V.
Pero cada vez más, la industria produce electrónica de 3,3V, el propio Arduino DUE es un
ejemplo de ello, y si usamos nuestros ADC para digitalizar señales de pico 3,3V, estamos
perdiendo precisión y resolución, porque estamos desperdiciando una parte de las
posibles comparaciones, de hecho un tercio.
En la práctica, al ser 3,3V el máximo de la tensión de entrada compararlo contra 5V
supone que nunca tendremos lecturas mayores de 1.024 * 3,3 /5 = 675 y seguiremos
teniendo escalones de entrada de 5mV.
Pero si el convertidor es un comparador de tensiones, si pudiéramos cambiar el valor de
tensión contra el que comparamos por una de 3,3V, los escalones serian de 3,3V/1024 =
0,00322265625 o sea 3,2 mV. Es decir hemos mejorado la resolución de nuestro
convertidor y sin gastar un chavo.
Por eso en una situación ideal, la tensión de comparación contra la que realizamos
la conversión de analógico a digital, debería ser el valor máximo posible de la señal de
entrada. Porque es cuándo tendremos la mejor resolución posible con ese convertidor.
Los chicos de Arduino, eran conscientes de este asunto y por eso incluyeron un pin
externo, que no habíamos usado hasta ahora, que permite conectar una tensión externa
de referencia, contra la que se comparará la señal que leamos en nuestras puertas A0 a
A5.
Este pin esta rotulado como AREF (Analog Reference o Referencia Analógica en cristiano)
y está dos pines más arriba del digital pin 13:
USANDO LA REFERENCIA ANALÓGICA EXTERNA
La cuestión de la referencia analógica contra la que comparamos las muestras en las
puertas A0-A6, es tan importante, que Arduino provee varias tensiones internas contra las
que comparar y que podemos activar para cambiar dicha referencia.
Para activar una referencia interna de 1,1V en un Arduino UNO usa la instrucción
analogReference(INTERNAL);
analogReference(INTERNAL1V1);
analogReference(INTERNAL2V56);
analogReference(DEFAULT);
Cuidado con la referencia DEFAULT, porque en el DUE significa 3,3V porque es su tensión de
referencia. Asegúrate de esto antes de usarlo alegremente.
Cuando conectemos una tensión de referencia al pin AREF, tenemos que avisar a Arduino
de que queremos usarla. Y eso lo hacemos con la instrucción
analogReference(EXTERNAL);
Asegúrate de que si usas una referencia externa los GND de Arduino y de la referencia
sean el mismo uniéndolos. No hacer esto tiene muy mal pronóstico a la primera de cambio.
No uses bajo ninguna circunstancia menos de 0v en el pin AREF ( O una señal que varíe y
pueda tener transitorios negativos) porque el resultado es impredecible.
Si conectas una tensión externa de referencia, no llames a analogRead() antes de ejecutar
la instrucción analogReference(EXTERNAL), porque harías un cortocircuito entre la señal
de comparación interna y la tensión externa en AREF, y posiblemente podrás aprovechar
la ocasión para comprarte ese Arduino nuevo al que le tienes tantas ganas.
No conectes a AREF menos de 1V ni más de 5V, no puedes poner 12 y esperar que te dé
un valor tranquilamente.
CIRCUITO DE PRUEBA
Vamos a montar un circuito de prueba con un display I2C como vimos en la sesión.. y un
potenciómetro. Pero en esta ocasión, conectaremos en los extremos del potenciómetro
GND y 3,3V de modo que en el pin central que leeremos con A1, no puede nunca superar
los 3,3V simulando un sensor con ese valor máximo.
Al ir girando el potenciómetro, leeremos una caída de tensión entre 0V y 3,3V. y la lectura
del pin A1, dará valores entre 0 y 670, ya que estamos en el caso que definíamos un poco
más arriba.
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#define I2C_ADDR 0x27
LiquidCrystal_I2C lcd(I2C_ADDR,2, 1, 0, 4, 5, 6, 7);
void setup()
{
lcd.begin (16,2); // Inicializar el display con 16 caraceres 2 line
as
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // vamos al principio
lcd.print("Prometec.net");
}
void loop()
{
lcd.setCursor ( 0, 1 ); // Vamos a la segunda linea
lcd.print(analogRead(A1));
}
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
void setup()
{ lcd.begin (16,2); // Inicializar el display con 16 caraceres 2 lineas
lcd.setBacklightPin(3,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // vamos al principioe
lcd.print("Prometec.net");
void loop()
{ lcd.setCursor ( 0, 1 ); // Vamos a la segunda linea
lcd.print(analogRead(A1));
lcd.print(" "); // Para borrar rastros en pantalla
}
Es necesario llamar esta función antes que se lean los valores de voltaje utilizando
analogReference() ya que de lo contrario podrías dañar tu Arduino.
1.5 = 2.5*32/(32+R)
Es decir, R = 74.67 kohms = 75 kohms para valores comerciales. Otra idea sería
utilizar un diodo zener que brinde un voltaje de referencia de 1.5 V. Con esto
entonces tendríamos escalones equivalentes a 1.46 mV, es decir hemos reducido
casi 3 veces el valor de los escalones teniendo una mejor precisión en nuestras
medidas ya que los cambios de temperatura son bastantes lentos.
Para obtener el valor de 1.46 mV utilizamos la fórmula del escalón o de resolución:
Resolución = Vi/2^n
1.46 mV = 1.5/1024
Espero que este artículos les haya servido para entender un poco más sobre el
AREF y para qué sirve.
Este conversor ADC va conectado a un multiplexor, para que así, con uno
solo de estos podamos tener varías entradas, como es en el caso de las
placas Arduino que normalmente cuenta con 6 de estas. La Arduino
MEGA en cambio cuenta con 16 entradas analógicas.
void setup(){
Serial.begin(9600);
muestreo();
void loop(){
}
void muestreo(){
Otro factor a tener en cuenta del ADC es su resolución, para ello hablamos
de los bits de resoluciónque tiene, los bits no permiten hacer
combinaciones, cuantos mas tengamos mayor numero de combinaciones
podremos hacer, cada una de estas combinaciones muestra una medida del
sistema analógico, la cantidad de medidas que tenemos serán 2 elevado al
numero de bits de resolución. Puesto que Arduino UNO, en mi caso, tiene
un ADC de 10 bits de resolución tendrá 1024 combinaciones. La
placa Arduino DUE por ejemplo cuenta con un ADC de 12 bits
(4096 combinaciones).
Pero hay un segundo factor que interviene en la resolución, es el rango de
medida, El rango de Voltae de las placas Arduino por defecto es de 5v o
3.3v. Con esto sabemos que en voltios tenemos una resolución igual a;
int contador;
void setup(){
contador=1;
Serial.begin(9600);
Serial.println("*****************");
Serial.println("ENSAYO RESOLUCION");
Serial.println("*****************");
}
void loop(){
muestreo();
contador++;
}
void muestreo(){
int A=analogRead(A0);
float B= float(A)*5/1023;
Serial.print(" Muestra: ");
Serial.print(contador);
Serial.print(" Medida Digital: ");
Serial.print(A);
Serial.print(" Medida Analogica: ");
Serial.println(B, 5);
delay(1000);
}
//
void setup(){
analogReference(INTERNAL);
contador=1;
Serial.begin(9600);
Serial.println("******************");
Serial.println("ENSAYO RESOLUCION");
Serial.println("REFERENCIA INTERNA");
Serial.println("******************");
}
void loop(){
muestreo();
contador++;
}
void muestreo(){
int A=analogRead(A0);
float B= float(A)*1.1/1023;
Serial.print(" Muestra: ");
Serial.print(contador);
Serial.print(" Medida Digital: ");
Serial.print(A);
Serial.print(" Medida Analogica: ");
Serial.println(B, 5);
delay(1000);
}
Como hicimos antes podemos tomar dos muestras, la 19 y 20, por ejemplo
y calcular la nueva resolución que tenemos:
int contador;
void setup(){
analogReference(EXTERNAL);
contador=1;
Serial.begin(9600);
Serial.println("******************");
Serial.println("ENSAYO RESOLUCION");
Serial.println("REFERENCIA EXTERNA");
Serial.println("******************");
}
void loop(){
muestreo();
contador++;
}
void muestreo(){
int A=analogRead(A0);
float B= float(A)*2.5/1023;
Serial.print(" Muestra: ");
Serial.print(contador);
Serial.print(" Medida Digital: ");
Serial.print(A);
Serial.print(" Medida Analogica: ");
Serial.println(B, 5);
delay(1000);
}