馃挕 ARDUINO: Entradas Anal贸gicas



驴Qu茅 es una entrada anal贸gica?

Una se帽al anal贸gica es una magnitud que puede tomar cualquier valor dentro de un intervalo entre 鈥揤cc y + Vcc. Por ejemplo, una se帽al anal贸gica de tensi贸n entre 0V y 5V podr铆a ser 2,72V, o cualquier otro valor con cualquier n煤mero de decimales. Por contrario, recordemos que una se帽al digital de tensi贸n te贸rica 煤nicamente pod铆a registrar dos valores (en el ejemplo, 0V o 5V).

Por norma general en los dispositivos electr贸nicos las entradas anal贸gicas son m谩s escasas, m谩s lentas y m谩s caras que las entradas digitales. En el caso de Arduino uno disponemos de un n煤mero variable de entradas anal贸gicas, que en el caso de Arduino Uno y Mini Pro son 6, y en el Arduino Mega son 16. Este es un n煤mero m谩s que respetable de entradas anal贸gicas, que rivaliza o supera a aut贸matas tradicionales de coste muy superior.

Como vimos al explicar las entradas digitales, una entrada digital supone un proceso de transformaci贸n de una se帽al en un valor digital, atribuyendo un valor HIGH a las medidas que superen un valor umbral, y LOW a la medici贸n que queda por debajo. Por el contrario, una entrada anal贸gica proporciona una medici贸n codificada en forma de un valor digital con un n煤mero N de bits.

Es importante entender que en el mundo real cualquier se帽al de tensi贸n es siempre anal贸gica. Un valor digital es un concepto, una abstracci贸n. Sin embargo conviene se帽alar que la medici贸n que proporciona una entrada anal贸gica tambi茅n es un valor digital, por lo que igualmente es una abstracci贸n. Esto nos lleva al concepto de precisi贸n de la medici贸n.

PRECISI脫N DE LA MEDICI脫N

Para entender la precisi贸n de una entrada anal贸gica es necesario entender c贸mo funciona un conversor anal贸gico digital (ADC), que es su componente fundamental. Un ADC es un dispositivo que convierte una medici贸n anal贸gica en una medici贸n digital codificada con un n煤mero N de bits.

Existen muchas formas de construir un ADC, pero lo importante es entender que en realidad no medimos el valor anal贸gico con todos sus decimales, sino que lo 鈥渃lasificamos鈥 dentro de 2^N niveles, que definen 2^N-1 intervalos. El ancho de este intervalo medido en mV es la precisi贸n de la se帽al. Cuanto mayor sea el n煤mero de bits, mayor ser谩 el n煤mero de intervalos, menor ser谩 el ancho del intervalo, y por tanto mejor la precisi贸n de la medici贸n.

En el caso de Arduino Uno, Mini Pro, y Mega, las entradas anal贸gicas disponen de 10 bits de resoluci贸n, lo que proporciona 1024 niveles digitales, lo que a 5V supone una precisi贸n de la medici贸n de +-2,44mV. Arduino Due tiene una resoluci贸n de 12bits, 4096 niveles digitales, lo que supone una precisi贸n de 0,61 mV.

Precisi贸n Relativa

Hasta ahora hemos supuesto un aut贸mata alimentado entre 0V y 5V, que mide una se帽al anal贸gica de tensi贸n entre 0V a 5V. En este caso, con un ADC de 10 bit tenemos una precisi贸n de 4,88mV, lo que supone una precisi贸n relativa respecto a la se帽al de entrada de 0,1% (1/1024).

Sin embargo, supongamos que medimos una se帽al que var铆a entre 0V y 1V. En este caso, con el mismo ADC de 10 bit tendr铆amos la misma precisi贸n absoluta de 4,88mV, pero una menor precisi贸n relativa respecto a la se帽al, que caer铆a hasta 0,5%.

Es decir, si realizamos una medici贸n a una se帽al que var铆a en un l铆mite inferior a Vcc estamos perdiendo precisi贸n relativa. Esto es la consecuencia de no aprovechar todo el rango de la medici贸n, por lo que en realidad el ADC se comporta como si tuviera un n煤mero inferior de bits.

Referencia de tensi贸n anal贸gica (AREF)

Para resolver esta situaci贸n Arduino permite cambiar la tensi贸n tomada como referencia por el conversor anal贸gico digital. El valor de la referencia se cambia con la funci贸n AnalogRef, y los valores posibles son:

  • DEFAULT: Valor por defecto, correspondiente con Vcc (5V o 3.3V, seg煤n modelos)

  • INTERNAL: Corresponde a 1.1V (en Atmega 168 y 328)

  • EXTERNAL: Voltaje aplicado de forma externa en el pin Vref (siempre entre 0 y Vcc

  • INTERNAL1V1 y INTERNAL2V56, correspondientes a 1.1V y 2.56V (s贸lo en Mega)

En el caso de usar la referencia de tensi贸n externa (EXTERNAL), si sabemos con total seguridad que una se帽al no va a superar de un cierto valor de tensi贸n, por ejemplo 0.7V, podemos proporcionar este valor como referencia a trav茅s del Pin Aref . La medici贸n se realizar谩 tomando esta tensi贸n como referencia en lugar de Vcc, por lo que recuperamos toda la precisi贸n relativa.

Conexi贸n de entradas anal贸gicas en Arduino

Supongamos que disponemos de un sensor anal贸gico que proporciona una se帽al anal贸gica entre 0V a 5V. El esquema de conexi贸n es similar al que empleamos para realizar la lectura digital.

 

 
 

C贸digo en Arduino

El c贸digo para realizar la lectura es realmente sencillo, y similar al que vimos para las entradas digitales. Simplemente realizamos la lectura mediante AnalogRead() y almacenamos el valor devuelto.


const int sensorPin = A0;    // seleccionar la entrada para el sensor
int sensorValue;       // variable que almacena el valor raw (0 a 1023)
 
void setup()
{
   Serial.begin(9600);
}
 
void loop() 
{
   sensorValue = analogRead(sensorPin);   // realizar la lectura
 
   //mandar mensaje a puerto serie en funci贸n del valor leido
   if (sensorValue > 512) 
   {
      Serial.println("Mayor que 2,5V");
   }
   else 
   {
      Serial.println("Menor que 2,5V");
   }
   delay(1000);
}

El valor devuelto por la funci贸n AnalogRead() se codifica como un n煤mero entero entre 0 a 1023. En caso de querer convertir este valor en un valor de tensi贸n podemos usar la siguiente variaci贸n:


const int sensorPin = A0;   // seleccionar la entrada para el sensor
int sensorValue;         // variable que almacena el valor raw (0 a 1023)
float value;            // variable que almacena el voltaje (0.0 a 5.0)
 
void setup() 
{
   Serial.begin(9600);
}
 
void loop() 
{
   sensorValue = analogRead(sensorPin);          // realizar la lectura
   value = fmap(sensorValue, 0, 1023, 0.0, 5.0);   // cambiar escala a 0.0 - 5.0
 
   Serial.println(value);                     // mostrar el valor por serial
   delay(1000);
}
 
// cambio de escala entre floats
float fmap(float x, float in_min, float in_max, float out_min, float out_max)
{
   return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Sin embargo, debemos tener en cuenta que las operaciones en coma flotante (con decimales) son mucho m谩s lentas que con enteros por lo que tenemos que intentar evitar realizar esta conversi贸n y trabajar siempre que sea posible con n煤meros enteros.

Frecuencia de muestreo

Con el c贸digo empleado la frecuencia de muestreo es aproximadamente 9600 Hz, es decir, unos 100 micro segundos para la medici贸n. En comparaci贸n, la funci贸n digitalRead tiene una frecuencia de 15000Hz, unos 66 micro segundos por medici贸n, levemente m谩s r谩pido.

Sin embargo, mediante otros c贸digos la lectura anal贸gica puede aumentarse hasta aproximadamente 1,5 Mhz, o 660 nano segundos por entrada. Por contrario, las entradas digitales pueden acelerarse hasta aproximadamente 15 Mhz, 66 nano segundos, leyendo todas las entradas de forma simult谩nea. Por lo tanto, vemos que realmente las entradas digitales pueden ser mucho m谩s r谩pidas que las anal贸gicas

Lectura de valores mayores de 5V

En caso de requerir leer una entrada de nivel de tensi贸n superior, por ejemplo de 12V, debemos realizar una adaptaci贸n de tensi贸n. La mejor forma de realizar la adaptaci贸n es empleando un simple divisor de tensi贸n

 
 

Con esta configuraci贸n el pin digital de Arduino recibir谩 una tensi贸n que var铆a entre 0 a 3,84V por lo que, como hemos explicado, estar铆amos perdiendo precisi贸n relativa. Una opci贸n podr铆a ser el ajustar las resistencias para que los l铆mites est茅n lo m谩s cercanos posible a 0 y 5V, o usar otro divisor de tensi贸n para alimentar el pin Aref.

Los valores de las resistencias a emplear dependen del voltaje que queremos leer, y de la impedancia del sensor. En general, deben cumplir las siguientes condiciones:

  • Deben convertir la se帽al en un rango inferior pero similar a la tensi贸n de alimentaci贸n.

  • Deben ser muy superiores a la impedancia equivalente del dispositivo a medir.

  • Deben ser despreciables respecto a la impedancia de la entrada Arduino.

  • Deben limitar la corriente que circula por ellas para minimizar p茅rdidas.

  • Deben de ser capaces de disipar la potencia que van a soportar.

Ver m谩s sobre: Lectura de se帽ales superiores a 5V