PCF8591 Conversor AD-DA de 8 bits I2C

publicado en: Portada | 3

El PCF8591 es un conversor analógico a digital y digital a analógico de 8 bits de resolución que se comunica con el microcontrolador por medio del bus I2C.

Este componente puede ser útil básicamente en tres líneas de aplicación:

  • Añadir una salida analógica, funcionalidad que no está presente en un microcontrolador convencional. El PCF8591 ofrece una salida analógica de 8 bits.
  • Aumentar el número de entradas analógicas disponibles. El PCF8591 dispone de cuatro entradas analógicas de 8 bits.
  • Incrementar la distancia entre los sensores analógicos y el microcontrolador sin perder o distorsionar la señal. Como el PCF8591 convierte en digital la señal medida y la transmite por I2C, el riesgo de interferencias o pérdida de señal disminuye lo máximo posible a la vez que es posible usar tanta distancia (longitud de cable) como permita el bus I2C

Aunque su resolución de 8 bits es modesta, puede servir para muchas aplicaciones y su precio y su sencillez de uso tanto a nivel de programación como a nivel electrónico lo han hecho muy popular. Como además está disponible en formato DIP es perfecto para pruebas y prototipos.

Para hacer más cómodas las pruebas existen en el mercado módulos que integran el PCF8591 y algunos sensores sencillos (luz y temperatura, normalmente) además de resistencias variables con las que establecer valores analógicos arbitrarios.

PCF8591 Conversor AD (analógico a digital) y DA (digital a analógico) de 8 bits y bus I2C

La parte fija de la dirección del PCF8591 en el bus I2C es 0B1001000 (siete bits). Estableciendo a nivel alto o bajo las patillas A0, A1 y A2 se pueden configurar los tres últimos bits para conectar hasta ocho de estos dispositivos en el mismo bus.

PCF8591 pinout patillaje conversor analógico digital AD DA I2C 8 bits

El PCF8591 dispone de un oscilador interno con el que gestionar el ciclo de conversión analógica a digital. En lugar de utilizar este oscilador puede trabajar con uno externo que se conecta a la entrada OSC; para activarlo, la entrada EXT debe conectarse a nivel bajo. Para utilizar el oscilador interno, la configuración más habitual, basta con dejar al aire la patilla OSC y conectar a nivel alto EXT.

Para establecer la referencia de medida de tensión del PCF8591 utiliza las entradas VREF y AGND. En la configuración más básica se puede conectar VREF a VDD y AGND a VSS, es decir, referirlo a la propia tensión de alimentación del circuito.

En el diagrama de ejemplo de la siguiente imagen se utiliza la conexión más habitual (y más sencilla). La dirección del dispositivo en el bus I2C es 0B1001000 por establecer a cero A0, A1 y A2. La tensión de referencia es la de alimentación del sistema y se utiliza el oscilador interno al conectar EXT a VDD.

PCF8591 Conversor AD y DA (analógico a digital y digital a analógico) de 8 bits y bus I2C

Utilizar el PCF8591 desde una placa Arduino es muy sencillo con la librería Wire. En primer lugar hay que inicializar (solamente una vez en el programa) las comunicaciones I2C con Wire.begin().

Para activar la salida analógica del PCF8591 a cierto nivel, primero se inicia la transmisión al bus I2C con Wire.beginTransmission(), luego se activa la escritura analógica en AOUT con Wire.write() y el código de la operación correspondiente (la escritura es 0B01000000), también con Wire.write() se envía el valor del nivel y se libera el bus I2C con Wire.endTransmission(). En el ejemplo de abajo puede verse el proceso completo.

Los 1500 ms (un segundo y medio) de intervalo de medida del ejemplo anterior permiten usar un multímetro convencional para medir la precisión de la salida AOUT del PCF8591. Como experimento, también podemos usar las entradas analógicas de Arduino para medir la tensión generada. El siguiente ejemplo genera un nivel de salida en el PCF8591, calcula el voltaje teórico y mide con Arduino la tensión que llega a su entrada analógica A0.

La lectura de las cuatro entradas analógicas del PCF8591 con la librería Wire también es muy sencilla. En primer lugar se activan las comunicaciones I2C, como siempre, solamente una vez en la aplicación, con Wire.begin() y para cada lectura se realizan los siguientes pasos:

  • Iniciar la conexión con el PCF8591 usando Wire.beginTransmission() y la dirección del dispositivo.
  • Activar una de las entradas enviando su dirección al PCF8591 con Wire.write(). El código corresponde con el número de entrada, 0 para AIN0, 1 para AIN1, 2 para AIN2 y 3 para AIN3.
  • Liberar el bus I2C usando Wire.endTransmission()
  • Solicitar con Wire.requestFrom() dos bytes a la dirección del PCF8591, que devolverá la lectura analógica anterior y la actual.
  • Leer la respuesta del PCF8591 con Wire.read().

El proceso completo de lectura analógica del PCF8591 puede verse en el programa de ejemplo de abajo.

En las condiciones habituales el código anterior funcionará correctamente pero, como ya he explicado otras veces hablando de la librería Wire, lo más ortodoxo sería esperar a leer con Wire.read() después de asegurarse de que los datos están disponibles usando Wire.available().

En el siguiente programa de ejemplo de lectura analógica del PCF8591 con Arduino se ha implementado la espera antes de la lectura de los datos. Para evitar el bloqueo del programa, en el caso de que no llegaran los dos bytes que se esperan, se ha incluido un tiempo de espera, superado el cual se desiste de la lectura.

Víctor Ventura

Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

Más entradas - Página web

Sígueme:
TwitterLinkedIn

Seguir Víctor Ventura:

Programador multimedia y web + IoT. Mejor con software libre.

Desarrollando aplicaciones para la web conocí el potencial de internet de las cosas, encontré la excusa perfecta para satisfacer la inquietud de aprender electrónica que había tenido desde siempre. Ahora puedo darme el gusto de programar las cosas que yo mismo diseño y fabrico.

3 Respuestas

  1. binacs

    Ando buscando cosas por internet para un proyecto y da gusto como te expresas, es muy agradable encontrar gente como tu que no solo saben mucho sino que ademas son maestros.
    Gracias

  2. rafa

    hola que tal, yo estoy trabajando con pic y ccs,
    he visto este sensor y me gustaria acoplarlo a un 16f877A,
    el problema que tengo es que cuando realiza una medida la hace bien, pero cuando vuelvo a medir me pone en pantalla el doble justo de la anterior.
    te paso lo que he realizado a ver donde tengo el error.
    gracias

    void luces()
    {

    i2c_start(); // Inicio la comunicación I2C
    i2c_write(0x90); // Envío Dirección I2C del PCF8591
    delay_ms(0.1);
    i2c_write(0x04); // Envío Configuración del PCF8591 para ADC por AIN0
    delay_ms(0.1);
    i2c_start(); // Inicio la comunicación I2C
    i2c_write(0x91); // Envío Dirección I2C del PCF8591
    lectura=i2c_read(); //leo la conversion de A0
    i2c_stop();

    lectura2=(lectura*5.0)/255.0;

    for ( i=0;i<10;i++){
    //trato la conversion
    lcd_gotoxy(1,1);
    printf(lcd_putc,"Tension:%f V ",lectura2); //y muestro el dato

    }
    }

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *