entrada-analogica-adc-de-16-bits-con-arduino-y-ads1115

Entrada analógica de 16 bits con Arduino y ADC ADS1115

¿Qué es un ADS1115?

El ADS1115 es un conversor analógico digital (ADC) externo que podemos conectar a un procesador como Arduino para medir señales analógicas.

Arduino dispone de ADC internos que empleamos cuando usamos las entradas analógicas de Arduino. En los modelos Arduino Uno, Mini y Nano, disponemos de 6 ADC de 10 bits.

El ADS1115 proporciona 4 ADC de 16 bits, 15 para la medición y un último para el signo. El ADS1115 se conecta por I2C, por lo que es sencillo realizar su lectura. Dispone de 4 direcciones, que se elige mediante la conexión del pin ADDRESS.

El interés de emplear un ADC como el ADS1115 es obtener una mayor precisión, además de liberar de esta carga al procesador. Además, en ciertas configuraciones, es posible medir tensiones negativas.

El ADS1115 tiene dos modos de medición, single ended y diferencial. En el modo single ended disponemos de cuatro canales de 15 bits. En el modo diferencial usamos dos ADC para cada medición, por lo que el número de canales se reduce a 2, pero tendremos la ventaja de poder medir tensiones negativas y mayor inmunidad al ruido.

También dispone de un modo comparador en el que el ADS1115 genera una alerta por el pin ALERT cuando cualquiera de los canales supera un valor de umbral que fijamos por código.

Por último, el ADS1115 incorpora un PGA que permite ajustar la ganancia desde 6.144V a 0.256V. Esto permite obtener precisiones superiores cuando midamos tensiones inferiores a 5V.

Independientemente del PGA elegido la máxima tensión que podemos medir será siempre la tensión de alimentación. Es decir, aunque el PGA sea 6.144V, no podremos medir tensiones superiores a 5V.

Como vemos, las características técnicas del ADS1115 son muy superiores a los ADC internos de Arduino. Por tanto, resultan adecuados cuando necesitemos mediciones de precisión, como en la lectura de sensores, o cuando la señal pueda tomar valores negativos, como en los sensores de intensidad o tensión.

Precio

Podemos encontrar módulos con el ADS1115 preparados para conectar a Arduino por 1.80€ buscando en vendedores internacionales en eBay o AliExpress.

arduino-adc-ads1115-componente

Esquema de montaje

La conexión es sencilla. Por un lado, alimentamos el módulo desde Arduino mediante GND y 5V y conectamos el pin SDA y SCL de Arduino con los pines correspondientes del sensor.

El pin ADDR determina la dirección I2C del dispositivo, según la tabla siguiente. El modo por defecto es conectar el pin ADDR a GND, lo que da lugar a la dirección 0x48.

DirecciónPin ADDR
0x48GND
0x49VDD
0x4ASDA
0x4BSCL

Para la conexión single end, simplemente conectamos la carga a medir entre GND y uno de los 4 pines disponibles.

arduino-adc-ads1115-single-end

Si en su lugar queremos el modo diferencial conectamos la carga entre A0 y A1 o entre A2 y A3.

arduino-adc-ads1115-conexion-comparador

Mientras que, en ambos casos, la conexión vista desde el lado de Arduino quedaría así.

arduino-adc-ads1115-esquema

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de Arduino consultar el esquema patillaje correspondiente.

La tensión a medir no deberá exceder la ganancia que pongamos en el ADC, ni la Vcc +0.3V, o podemos destruir el ADS1115.

Ejemplos de código

Para realizar la lectura del ADS1115 usaremos la librería desarrollada por Adafruit, disponible en este enlace.

La librería proporciona ejemplos de código, que resulta aconsejable revisar. Los siguientes ejemplos son modificaciones a partir de los disponibles en la librería

Modo single end

El siguiente código muestra el uso del modo single end. Realizamos la lectura de los cuatro canales y mostramos el valor por puerto serie. Para convertir el valor a voltaje es necesario emplear un multiplicador, que a la vez depende de la ganancia del PGA que hayamos fijado.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;
const float multiplier = 0.1875F;

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

  // Descomentar el que interese
  // ads.setGain(GAIN_TWOTHIRDS);  +/- 6.144V  1 bit = 0.1875mV (default)
  // ads.setGain(GAIN_ONE);        +/- 4.096V  1 bit = 0.125mV
  // ads.setGain(GAIN_TWO);        +/- 2.048V  1 bit = 0.0625mV
  // ads.setGain(GAIN_FOUR);       +/- 1.024V  1 bit = 0.03125mV
  // ads.setGain(GAIN_EIGHT);      +/- 0.512V  1 bit = 0.015625mV
  // ads.setGain(GAIN_SIXTEEN);    +/- 0.256V  1 bit = 0.0078125mV 
  ads.begin();
}

void loop(void) 
{
  int16_t adc0, adc1, adc2, adc3;

  
  adc0 = ads.readADC_SingleEnded(0);
  adc1 = ads.readADC_SingleEnded(1);
  adc2 = ads.readADC_SingleEnded(2);
  adc3 = ads.readADC_SingleEnded(3);
  Serial.print("AIN0: "); Serial.println(adc0 * multiplier);
  Serial.print("AIN1: "); Serial.println(adc1 * multiplier);
  Serial.print("AIN2: "); Serial.println(adc2 * multiplier);
  Serial.print("AIN3: "); Serial.println(adc3 * multiplier);
  Serial.println(" ");
  
  delay(1000);
}

Modo diferencial

El siguiente código muestra el uso del modo diferencial. Al igual que en el anterior, podemos cambiar la ganancia del PGA, que a su vez influye en el multiplicador empleado para convertir la medición a voltaje.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;
const float multiplier = 0.1875F;

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

void loop(void)
{
  int16_t results = ads.readADC_Differential_0_1();  
 
  Serial.print("Diferencial: "); 
  Serial.print(results); 
  Serial.print(" "); 
  Serial.print(results * multiplier); 
  Serial.println("mV");

  delay(1000);
}

Modo comparador

El siguiente código define una alerta en el canal 0, que se activará cuando el valor registrado supere los 2.5 voltios. Para obtener el valor necesario para fijar la alerta nuevamente tendremos que tener en cuenta la ganancia del sensor.

#include <Wire.h>
#include <Adafruit_ADS1015.h>

Adafruit_ADS1115 ads;

void setup(void) 
{
  Serial.begin(9600);
  
  ads.begin();
  
  // Activar comparador para 2.5V en canal 0 
  // (Donde 13333 = 2500 / 0.1875F)
  ads.startComparator_SingleEnded(0, 13333); 
}

void loop(void) 
{
  int16_t adc0;

  // Actualizar comparadores
  adc0 = ads.getLastConversionResults();
  Serial.print("AIN0: "); Serial.println(adc0);
  
  delay(100);
}

Descarga el código

Todo el código de esta entrada está disponible para su descarga en Github. github-full