PCF8591 A/D and D/A Converter Module

Module with I2C interface has 4 analog inputs, 1 analog output and built-in LDR, thermistor and potentiometer.

Code: PCF8591 MODULE

The PCF8591 module with I2C interface has 4 analog inputs, 1 analog output and built-in LDR, thermistor and potentiometer.

TECHNICAL SPECIFICATIONS

Operational Ratings
          Vcc 2.7 – 6V (3.3V or 5V typical)
          VOut Output Voltage Range (no load) 0V to Vcc
Output Voltage Range (10K load) 0V to 0.9 x Vcc
         Resolution Analog input 8-bits
analog output 8-bits
Dimensions L x W (PCB) 35 x 23mm (1.38 x 0.9″)

KEY FEATURES OF PCF8591 A/D AND D/A CONVERTER MODULE:

  • 4-channel 8-bit analog-to-digital conversion inputs
  • 1-channel 8-bit digital-to-analog conversion output
  • Built-in LDR (Light Detecting Resistor)
  • Built-in thermistor
  • Built-in potentiometer
  • I2C bus
  • 3.3V and 5V logic compatible.

This module is basically a reference design to show off some possible applications of the PCF8591 chip. It is a good learning module which incorporates both ADC inputs and a DAC output and includes basic sensors in a nice small inexpensive package. It also has some practical use in projects that can make use of the built-in features.

DAC Analog Output

The DAC output is connected to pin AOUT.

The 8-bit single output provides 256 steps of resolution.  For a VCC of 5V, the step size will be 5V/256 = 20mV.

The DAC output has a modest current capability to begin with and also has a 1K resistor and LED hooked up to it. The LED makes it easy to see the affect of changing the analog output for experimenting, but for use in actual applications it limits the output swing from reaching full Vcc.  If Vcc is 5V, it will max out at about 4.2V.  For applications that need the full GND to Vcc swing of the DAC output it is recommended to remove the LED to avoid the extra load on the output.

The DAC is also used internally by the ADC inputs. If using the DAC output, a track-and-hold circuit keeps the value that was set on the output pin while the DAC circuit is being used by the ADC circuit.

ADC Analog Inputs

The 4 analog inputs connect to the header pins AIN0-AIN3 and can be used as 4 general purpose analog inputs.  By default these are 4 single-ended inputs referenced to ground.  The PCF8591 chip also supports using them as 2 differential inputs.  Refer to the datasheet for specifics on using that mode.

There are 3 jumpers installed on the module that alternatively connects an on-board LDR, thermistor and potentiometer to 3 of these 4 inputs as follows.  If you want to use those inputs as general purpose inputs, the jumper should be removed from that location.PCF8591 AD and DA Converter Module - Jumpers

J5 – Connects LDR to channel 0 (AIN0)
J4 – Connects thermistor to channel 1 (AIN1)
J6 – Connects the potentiometer to channel 3 (AIN3)

Note that channel 2 (AIN2) does not have an alternate purpose, so no jumper is necessary.

PCF8591 AD and DA Converter Module - LDRLDR – The Light Detecting Resistor (LDR) can detect basic changes in the intensity of the light striking it.

A decrease in the amount of light hitting the sensor will cause an increase in the voltage on channel 0.

The LDR is useful for detecting larger changes in light or differentiating between night and day.  The value read is a relative number rather than an absolute light intensity value.

PCF8591 AD and DA Converter Module - ThermistorThermistor – The thermistor is a resistor that changes resistance based on temperature.

A decrease in temperature will cause the voltage to increase on channel 1.

The thermistor is useful for detecting changes in temperature.  Since the specification of the thermistor is not known so it is difficult to use it to measure the actual temperature.  It is better suited for measuring relative changes in temperature and in some cases the readings can be correlated to a temperature by empirical testing.

PCF8591 AD and DA Converter Module - PotentiometerPotentiometer – The 10K potentiometer is connected between Vcc and Gnd with the wiper connected to channel 3.

Rotating the potentiometer will cause the voltage to vary between 0V and Vcc.  Rotating the potentiometer CW decreases the voltage on channel 3.

The potentiometer can be used as a general purpose analog control input.  For instance, the potentiometer can be read and the DAC output driving the LED can be set to match the read value.

I2C Interface

I2C Address

The module has a fixed I2C address of 0x48.  The chip itself has 3 address pins but they are all tied to ground on the module, so it is not adjustable.

I2C Pull-Up Resistors

The module includes two 10K pull-up resistors on the I2C SCL and SDA lines.

Module Connections

The connections to the module are fairly simple.

  1. Supply 3.3 or 5V power to match the MCU power and ground.
  2. Connect I2C SCL and SDA lines to same on the MCU.

1 x 4 Header

  • SCL =   I2C SCL connects to MCU SCL
  • SDA =  I2C SDA connects to MCU SDA
  • GND =  Ground connects to MCU ground
  • VCC =  Power (2.5 to 6V).  Typically connects to same power as MCU.

1 x 5 Header

  • AOUT = DAC analog output
  • AIN0 = ADC channel 0 input
  • AIN1 = ADC channel 1 input
  • AIN2 = ADC channel 2 input
  • AIN3 = ADC channel 3 input

PCF8591 A/D and D/A Converter Module Test Program

/*  PCF8591 Module Test Program
 *   CH0 = Photoresistor Input
 *   CH1 = Thermistor temperature input
 *   CH2 = Unassigned analog input
 *   CH3 = Potentiometer Input
 *   
 *   Connect I2C SCL/SDA and power/ground
 *   Uses Rob Tillaart library.  URL: https://github.com/RobTillaart/PCF8591
*/     

#include "PCF8591.h"

PCF8591 dev(0x48);
//===============================================================================
//  Initialization
//===============================================================================
void setup()
{
  Serial.begin(9600);
  Wire.begin();
  dev.begin();
}
//===============================================================================
//  Main
//===============================================================================
void loop()
{
//  Test D/A output
  Serial.println("D/A Output Test - Ramp LED up/down");
  dev.enableDAC();                // Enable DAC output
  for (int i = 0; i < 256; i++)   // Ramp voltage / LED brightness UP
  {
    Serial.println(i);
    dev.analogWrite(i);
    delay(15);                    // just to slow the effect
  }

  for (int i = 255; i >= 0; i--)  // Ramp voltage / LED brightness DOWN
  {
    Serial.println(i);
    dev.analogWrite(i);     
    delay(15);             
  }
  dev.disableDAC(); // Disable DAC output

// Test Ch0 LDR
  Serial.println("Ch 0 LDR Light Test");
  for (int i= 0; i<30; i++)     // Take 30 readings 
  {
    byte ch0 = dev.analogRead(0); // Read LDR sensor input
    ch0 = map(ch0, 0,255, 255, 0); // Map reading so brighter = higher value
    Serial.println(ch0);  // Shield sensor to see change
    delay(350);
  }

// Test Ch1 Thermistor
  Serial.println("Ch 1 Thermistor Temperature Test");
  for (int i= 0; i<30; i++)
  {
    byte ch1 = dev.analogRead(1); // Read Thermistor sensor input
    ch1 = map(ch1, 0,255, 255, 0); //Map reading so warmer = higher value
    Serial.println(ch1);  // Warm sensor to see change
    delay(350);
  }

// Test Ch2 Analog Input
  Serial.println("Ch 2 Analog Input Test");  // Read analog 2 input
  for (int i= 0; i<30; i++)              // Connect to 3.3V to see difference
  {
    byte ch2 = dev.analogRead(2);
    float voltage = ch2 * (5.0 / 256.0);  // Convert reading to voltage
    Serial.println(voltage);
    delay(350);
  }

// Test Ch3 Potentiometer
  Serial.println("Ch 3 Potentiomter Test"); // Read potentiometer input
  for (int i= 0; i<30; i++)               
  {
    Serial.println(dev.analogRead(3));      // Read and print value from pot
    delay(350);
  }
}