PCF8591 module

Raspberry Pi with PCF8591 Analog To Digital Control in C

by Lewis Loflin

In this demo we'll be using Wiring Pi using C to interface to control-read a PCF8591T sensor module. The PCF8591T features four 8-bit analog to digital converters and a single 8-bit digital to analog converter.

This will operate through the I2C interface on the Raspberry Pi.

In this case I connected the AOUT channel to AIN2 so the output value can be read back. The fact that the AD and DA process uses only 8-bits introduced an error of one or two LSB. The power supply connection for VCC was only 4.75 volts and the most of the apparent error was on the high end. These ADCs are only good to about 4.2 volts.

In addition I used a level converter between the Raspberry Pi's I2C operating at 3-volts with the PCF8255 operating at 5-volts. The converter should not have contributed to the conversion-read back errors.

One oddity is when reading one of the AD channels one must perform what I call a dummy read that begins the conversion. The first read begins the conversion - the next get the first value. As long as one keeps reading the same channel, this only needs to be done once; change channels the process must be repeated.

The device has a sequential read mode for the four AD channels. See the spec sheet for more on that.

PCF8591 spec sheet. (PDF file)

PCF8591 module. (picture)

* by Lewis Loflin www.bristolwatch.com lewis@bvu.net
* PCF8591Test2.c
* Using wiringPi by Gordon Henderson
* https://projects.drogon.net/raspberry-pi/wiringpi/
* This must be installed first.
* Here connect the DAC output to AN0 and a potentiometer to AN1
* Read pot on AN1, write value to DAC, Read DAC with AN0
* DAC output value only good to ~200
* There is no warrenty of any kind use at your own risk.

#include <wiringPiI2C.h>
#include <wiringPi.h>
#include <stdlib.h>
#include <stdio.h>

const char PCF8591 = 0x48; // base address

int fd, adcVal;

int main()   {

  if (wiringPiSetup () == -1) exit (1);

  fd = wiringPiI2CSetup(PCF8591);

  while (1)   {
    // read ADC1
    wiringPiI2CReadReg8(fd, PCF8591 + 1) ; // dummy read
    adcVal = wiringPiI2CReadReg8(fd, PCF8591 + 1) ;
    printf("Pot value = %d ", adcVal);

    // write to DAC reg, 0x04
    wiringPiI2CWriteReg8 (fd, PCF8591 + 4, adcVal) ;

    // read back DAC value with AN0
    wiringPiI2CReadReg8(fd, PCF8591) ; // dummy read
    adcVal = wiringPiI2CReadReg8(fd, PCF8591);
    printf("DAC value = %d \n\n" , adcVal);



  return 0;