PCF8591 Module Thoughts – Revised & Refined

The PCF8591 module is still being widely used by students and hobbyists on various projects all over the world. Sometimes you need to know more about the uses of that compacted module. In this post, I’m going to explain some things about it.

Random Ramblings

The PCF8591 module is a popular and ridiculously cheap module available on Chinese websites. The module itself is not really breadboard friendly. The pin spacing is 0.1” but the connection headers are at aberrant spacing. Ignore this for a while as we must go into a few other interesting things.

The PCF8591 module is a digital to analog (D/A) and analog to digital (A/D) converter module based on the PCF8591 from NXP. The PCF8591 module with I2C interface has four analog inputs and one analog output. It also has a photoresistor, a thermistor and a trimpot wired onboard. The module is basically a reference design to show off some of the possible applications of the PCF8591 chip.

According to the NXP datasheet (https://www.nxp.com/docs/en/data-sheet/PCF8591.pdf), the PCF8591 is a single-chip, single-supply low-power 8-bit CMOS data acquisition device with four analog inputs, one analog output and a serial I2C bus interface. Three address pins A0, A1 and A2 are used for programming the hardware address, allowing the use of up to eight devices connected to the I2C-bus without additional hardware. Address, control, and data to and from the device are transferred serially via the two-line bidirectional I2C-bus. The functions of the device include analog input multiplexing, on-chip track and hold function, 8-bit analog-to-digital conversion and an 8-bit digital-to-analog conversion. The maximum conversion rate is given by the maximum speed of the I2C bus.

This is the block diagram of the PCF8591 chip, copied from its official datasheet (Rev.7).

This is my PCF8591 module bought from a website (sorry for the bad image quality). Note that several other, similar modules exist, but in different shapes and with different options. All are centered around the PCF8591 chip.

The module is composed of:

  • A PCF8591 IC (U1)
  • A thermistor (R6)
  • A photoresistor (R7)
  • A single turn trimpot (VR1/R3)
  • Two LEDs (D1-D2) & Three jumper switches (P4-P5-P6)

This is a general schematic (taken from web) for your quick reference:

Note that the jumper switches (male headers with jumper caps) can be used to configure the analog input channels ie, by removing the cap of a jumper switch allows us to feed an external signal through the external header pin labelled accordingly.

For example:

  • P4: Thermistor or AIN1 Pin
  • P5: Photoresistor or AIN0 Pin
  • P6: Trimpot or AIN3 Pin

Something very quirky:

As pointed out previously, the module has two LEDs onboard, and the first one (D2) is a mere power on indicator (DC3.3V/5V Input). However, the second LED (D1) is wired to the analog output (Pin 15) of PCF8591 IC. The LED makes it easy to see the changes in the analog output during a rough experiment, but in an actual application it limits (due to excess current drain) the output swing from reaching the utmost degree!

See, when there is a load on the analogue output, the maximum output voltage will drop – the datasheet indicates a 10% drop for a 10KΩ load. Then what about an LED load across it?

Also, the ADC and DAC on the PCF8591 are 8-bit which is relatively low and may be a limitation for some critical applications (https://www.eetimes.com/analog-to-digital-converters/).

This means the DAC can only generate a theoretical signal in between zero volts (Gnd) and the reference voltage (Vref) in 255 steps. The voltage given to the VCC pin will serve as the ADC’s reference voltage (Vref).

Likewise, the module includes two 10K pull-up resistors on the I2C (SCL and SDA) lines. But note that the module has a fixed I2C address of 0x48. The chip itself has 3 address pins but they are all hard-wired to ground rail on the module, so it is not adjustable!

See, the lower three bits of the address consist of the three digital inputs A2, A1, A0 while the upper bits are fixed at 1001xxx. The last bit ( LSB ‘ ‘L) is ignored as it is the read write bit (R/Wn). Therefore, the addresses available are 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F (https://www.best-microcontroller-projects.com/pcf8591.html).

To make it clearer, now you know that the I2C address of the PCF8591 is determined by the pins A0-A2. The address of the module is 1001A2A1A0. With A2-A0 being LOW/GND, that is 1001000=0x48.

level, in some Arduino projects you will see the I2C address as “0x90>>1” Which is 48 as well. The “0x90” counts the LSB of the 8 bit address, which is the R/W bit. With the Write Bit Low (=active) the full address is 10010000=0x90, but the right shift 1 removes the LSB again, making it 0x48. Thanks to https://arduinodiy.wordpress.com/.

To sum up, the PCF8591 module may be a good pick if you need a few more analogue channels for your microcontroller projects, if you don’t need high resolution. There are also some other notable limitations. The four ADC channels, however, can be configured as single ended or differential inputs. The latter configuration will help you wipe out noise voltages when taking a reading. For single ended input, they simply measure the input signal with reference to ground (0V).

As mentioned earlier, the D1 LED introduces a heavy loading effect to the Aout pin. So, it would be better to pluck the LED out when you want to have proper analogue out operation. Try to employ a good op-amp buffer circuit at the Aout to buffer the DAC output.

On paper, in a buffer (also known as a unity gain amplifier, or voltage follower, or isolation amplifier) ​​circuit, the output is equal to the input, hence it has a unity gain (x1) and does not amplify the incoming signal. An op-amp buffer allows us to preserve the source signal, as the op-amp has such a high input impedance and a low output impedance. It is also called a buffer or isolation amplifier.

A quick evaluation with Arduino

It is not my intention to reveal the design secrets of the PCF8591, but to verify it is useable for a microcontroller-based hobby project. I have picked the cheap PCF8591 module that already has some “analog” sensors on it. Though I have some bare PCF8591 ICs in stock, the generic Chinese module is enough for a quick evaluation as it is always easy to hook up with an Arduino microcontroller board.

In order to test it, I hooked up the PCF8591 module with an Arduino Uno R3 (SMD), and powered the whole setup through a USB 9V/500mA rechargeable Li-ion battery. Below table shows the wiring between Arduino and PCF8591 Module.

ARDUINO UNO PCF8591 MODULE
5V VCC
GND GND
A4/SDA SDA
A5/SCL SCL
……… AOUT = SIGNAL OUTPUT

Below is the Arduino Sketch used for my quick test. This adapted example code (thanks https://twitter.com/ElectroAmateur) can generate a low-frequency sinewave (or a sawtooth wave) which is available through the AOUT pin of the PCF8591 module. An Arduino Library is used to simplify the code, and you can download it through this GitHub link https://github.com/xreef/PCF8591_library.

[code]

#include “PCF8591.h” //Xreef’s PCF8591 Library

#define PCF8591_I2C_ADDRESS 0x48 //Module’s Default I2C Address

PCF8591 pcf8591(PCF8591_I2C_ADDRESS);

int counter;

void setup()

{

pcf8591.begin();

}

void loop(){

pcf8591.analogWrite(100
+ 100 * sin(2 * 3.1416 * counter/200) ); //Sinewave

//
pcf8591.analogWrite(counter ); //Sawtooth Wave

counter++;

if (counter > 200){

counter = 0;

}

delay(1);

}

[/code]

How well does it work? See the oscillograms provided below and decide for yourself!

The code controls the voltage at the AOUT pin of the PCF8591 module, using the analogWrite() function (https://www.arduino.cc/reference/en/language/functions/analog-io/analogwrite/).

In principle, when the module is powered by 5V, the voltage at AOUT should be 0V with “analogWrite (0)”, near to 5V with “analogWrite (255)”, and a value between 0V and near 5V for an argument between 0 and 255. However, the given code is limited (by the original coder) to a maximum value of 200 as an argument to the analogWrite() function.

In Conclusion

The Chinese PCF8591 module seems to be a budget pick for low-profile hobby and/or educational projects as it is a compact breakout board that also has three onboard analog sensors. However, for real-world applications, serious changes need to be made, most of which are not easy for beginners with poor soldering skills. So, if you think you are going to get a cool analog I/O expander, think twice. There are other ways for expanding the “analog” capabilities of your favorite microcontroller development boards!

My experiment to find out a bit more about the performance of this generic module is still progressing, and I’ve a plan to use it with a Wi-Fi enabled microcontroller later. I won’t go into those details now as it is not the purpose of this post. But I’ll be following up with a future post about another project that builds on this one. Meanwhile, if you have any questions or comments or concerns, put them in the comments below.

Leave a Comment