PCF8591 YL-40 AD DA Module Review


This article describes the design and programming of the PCF8591 A/D-D/A module whose printed circuit board is labelled YL-40 . The module is shown in Figure 1, and its schematic diagram is shown in Figure 2. Note that several other, similar modules exist, but in different shapes and with different capabilities. All, however, are centered on the Philips PCF8591 Analog-to-Digital Converter (ADC) and Digital to Analog Converter (DAC). I noted that the 16-pin DIP form is now available; making it easier to prototype. Soldering SMD ICs to a PCB is not for the faint of heart, in my opinion.


Figure 1: PCF8591 Module YL-40

This particular module is suitable for tutorial use and perhaps for some hobbyists. Its drawback is that its I2C address is hard-wired to all zeros. (Note that I2C is a very effective 2-wire communications standard that is used by many small semiconductor devices such as microcontrollers and sensor peripherals.) If the address lines could be jumpered high or low, then several identical modules could be placed on the same I2C lines. I would therefore recommend the alternative module named the Mini PCF8591 AD DA Shell Module because it has that capability. It is also at least three times the price.

The IC permits only 8 bit data allowing only 256 steps in the analog output value or the digital output value. This is likely borderline for hobbyists who may want to build instrumentation or test equipment.

My tests show another frustration: A lower than expected analog output voltage. For a 4.88 volt supply the output is only 4.17 volts (85%) at maximum value setting. Since the maximum supply voltage is 8 volts, increasing the supply to 6 volts may get a 5 volt result. I did not remove the green LED and related resistor to see if the problem was simply an excess current drain from the IC’s AOUT.

Reference: PCF8591 8-bit A/D and D/A converter Product Specification, 2003-01-27, Philips Semiconductor.

PCF8591 Module YL-40

The module is composed of:

  • A PCF8591 IC at U1.
  • A thermistor that measures temperature at R6.
  • A photo-voltaic cell. This is a light sensitive resistor at R7.
  • A single turn trimmer potentiometer at R3.
  • Two LEDs: a red one that is on when the device has power; and a green one that increases brightness as the output voltage increases.
  • Three red jumpers that apply the voltage sources – photo-voltaic cell, thermistor, and potentiometer, and to analog input channels AIN0, AIN1, and AIN3 respectively.
  • Connector pins for I2C (SDA and SCL), Vcc, and ground.
  • Connector pins for the Analog output AOUT, and pins for each of the three analog input channels.
  • A 4-wire ribbon cable is included with sockets suitable for the connector pins.


Figure 2: YL_40 Schematic

The jumpers control whether analog input channels of the IC are connected to the analog sources:

  • Jumper P4 for AIN1: The temperature sensed by the R6 thermister is provided to the ADC.
  • Jumper P5 to AIN0: The R7 photocell voltage (resistance drop) is provided to the DAC.
  • Jumper P6 to AIN3: The single turn 10K ohm trimpot voltage (resistance drop – brighter light, lower resistance).

Removing a jumper allows an input channel to be fed from one of the external pins, labelled accordingly.


I used the Arduino 1.0.1 IDE. I also used parts of the code from this website: (http://download.polytechnic.edu.na/pub4/download.sourceforge.net/pub/sourceforge/a/ar/arduinosources/PCF8591.pde). With the new Arduino IDE version, the I2C library changed somewhat and so the wire.send() and wire.receive() changed to wire.write() and write.read(). Note that the IC address of 0x9E was be changed to 0x90.

The DAC – Stepper Program

In the pcf8591DACTest3 program, the DAC is sent 8 bit bytes to set an output voltage from zero to 255 and back to zero again. The output voltage is the ratio of the value to the maximum of 256. The green LED then slowly brightens and then goes dark again as the cycle repeats.

   1: /**PCF8591 Module Digital To analog test program.

   2: Essentially, this tests the I2C communications to the chip.

   3: The chip address is 0x90.

   4: */


   6: #include <Wire.h>

   7: #define PCF8591 (0x90 >> 1)      // Device address = 0       

   8: #define PCF8591_DAC_ENABLE 0x40

   9: #define PCF8591_ADC_CH0 0x40

  10: #define PCF8591_ADC_CH1 0x41

  11: #define PCF8591_ADC_CH2 0x42

  12: #define PCF8591_ADC_CH3 0x43

  13: byte dac_value=0;

  14: void putDAC(byte dac_value)

  15: {

  16:   Wire.beginTransmission(PCF8591);    //Calls the 8591 to attention.

  17:   Wire.write(PCF8591_DAC_ENABLE);    //Send a DAC enable word.

  18:   Wire.write(dac_value);            //Send the desired DAC value (0-255)

  19:   Wire.endTransmission();

  20: }

  21: void setup()

  22: {

  23:   Serial.begin(19200);    //Be sure to check the computer port's speed for this to work.

  24:   Wire.begin();

  25: }

  26: void loop()

  27: {            //The IC is stepped by one notch on each loop. The green LED should slowly increase in brightness

  28:   putDAC(dac_value);

  29:   delay(10);

  30:   Serial.println(dac_value);        //This goes to a terminal program

  31:   dac_value++; 

  32:   delay(200);

  33: }

The ADC Read Program

The program uses analog channel AIN3 which is jumpered to the trimpot. Adjusting that pot will change the output value between zero and 255. In the “void loop()” function the codes calls a subroutine to get data from the ADC. In “getADC()”, the IC is sent commands to return two ADC bytes. That starts the ADC process itself. Then the bytes are read; only the final byte contains the 8-bit unsigned result of conversion. That value is then printed out.

   1: /**PCF8591 Module Analog to Digital test program.

   2: Essentially, this tests the I2C communications to the chip.

   3: The chip address is 0x90.

   4: */

   5: #include <Wire.h>

   6: #define PCF8591 (0x90 >> 1)      // Device address = 0       

   7: #define PCF8591_DAC_ENABLE 0x40

   8: #define PCF8591_ADC_CH0 0x40

   9: #define PCF8591_ADC_CH1 0x41

  10: #define PCF8591_ADC_CH2 0x42

  11: #define PCF8591_ADC_CH3 0x43

  12: byte adc_value;

  13: byte getADC(byte config)

  14: {

  15:   Wire.beginTransmission(PCF8591);

  16:   Wire.write(config);

  17:   Wire.endTransmission();

  18:   Wire.requestFrom((int) PCF8591,2);

  19:   while (Wire.available()) 

  20:   {

  21:     adc_value = Wire.read(); //This needs two reads to get the value.

  22:     adc_value = Wire.read();

  23:   }

  24:   return adc_value;

  25: }

  26: void setup()

  27: {

  28:   Serial.begin(115200);

  29:   Wire.begin();

  30:   Serial.println("ADC Test");

  31: }

  32: void loop()

  33: {

  34:   adc_value = getADC(PCF8591_ADC_CH3); //Channel 3 is the pot

  35:   Serial.print(adc_value);

  36:   delay(200);

  37: }

Mini PCF8591 AD DA Shell Module V2.0

This module is shown in Figure 3 (schematic in Figure 4). I did not purchase nor test this device, but by examining the schematic and the board itself one can see that it is more versatile: It has jumpers to permit selection of one of the eight I2C addresses. The headers are complementary allowing other modules of similar physical forms to be daisy chained (on a buss). The trimpot is still useful for sensing a fraction of some external voltage.


Figure 3: Mini PCF8591 AD DA Shell Module V2.0


Figure 4: Schematic Mini PCF8591 AD DA Converter Module V2.0

The Mini PCF8591 can be programmed using the same software as for the YL-40 version.

Posted in Technology
14 comments on “PCF8591 YL-40 AD DA Module Review
  1. miguelill0 says:

    iGreat work! I’ts great you managed to figure out YL-40. I’ve been looking for the datasheet but couldn’t find it. Where did you get the schematics from? Thanks a lot!

  2. Mike says:

    To anyone else who has used these YL-40 modules: have you managed to get any “useful” (I know, it’s only 8-bit, but still) data from the integrated thermistor? I realize that this is basically a “demo” board for the PCF8591, not really intended to be “useful” w/the “on-board” sensors, but anyway …

    On mine, everything else seems to work just fine (on-board sensors as well as all using external, at least w/a trimpot wired to each, and the output seems appropriate), but the built-in thermistor doesn’t seem to respond, much.

    For a ~25°F (~15°C) temperature drop, it doesn’t give more than a few “bits” increase on the data channel to my Raspberry Pi (~211 up to ~216). I’ve also measured the voltage through AIN1 (seems appropriate relative to Vcc), as well as the resistance while powered off (not entirely sure this measurement is “valid”): the YL-40’s thermistor (same conditions as previously mentioned) only increases by about 350ohms; for comparison, an old Radio-Shack thermistor (10Kohm, also “bead” type, unfortunately no longer sold, but you could look it up #271-0110) jumps almost 15Kohms !

    So, I’m thinking I’ve either got a YL-40 with a “bad” thermistor, or the thermistor is just completely “not suitable” for this “application” …

    Again, is ANYONE getting “reasonable” data from the thermistor on a YL-40 ?

    If so, am I missing something? As I mentioned, I can get “data” (such as it is, but “responsive”) for everything else except the thermistor (using either I2CTools, or my own Python scripts

    Thanks in advance for any help!


    • bremme says:

      I recently ordered two of these YL-40 boards as well. I didn’t get proper temperature readings at first. But when I had a closer look on the board I noticed that R6 (which is the thermistor) wasn’t connected to ground. Once I soldered a little wire from R6 to ground, the thermistor seemed to work properly.

      I tested both with Steinhart (Tkelvin = 1 / (A + B ln(R) + C ln(R)^3), A=1.129148E-03, B=2.34125E-04, C=8.76741E-08) and the simplified B parameter equation (Tkelvin = 1 / (1/B * ln(R/R0) + 1/T0), B=3900, T0=25, R0=10000). For calculating the analog reading (0-255) to the current thermistor resitance I used Rt = Rseries / ( (255 / adcReading) – 1).

      I just tested this like 5 min ago, so I might come up with better coefficient, but for now it seems to work pretty good.

  3. John Wiggins says:

    I just got a Mini PCF8591 from WaveShare (I also have WaveShare’s DVK511; pretty neat) anyway, I have it up and running (I can include some C source if anyone wants) The values I’m getting are the opposite of what I’m wanting though (i.e. the light sensor returns 255 if complete darkness and lower numbers as light increases)

  4. Rene Olsthoorn says:

    Thanks to your suspicion about the green LED on module YL-40 taking too much current I disabled it. With 3.3V supply the maximum DAC output rose to from 2.88V to 3.24 !

    On the back of my module was a trace running from the LED D1 to resistor R4. Cutting that trace with a knife did the trick.

  5. gerald woollard says:

    if I had 2 of these YL-40 and using the sda for digital in and out put,
    how can I set one for input and one for output,
    I think it is to do with the scl connection but I want to do this
    as hard wired not programmed .

  6. gerald woollard says:

    O,K it’s me again, I’m not doing very well here ! If I take one l2C connect ICL & SDA pins via 10k resister to VCC with the 3 address links in and connected to a 6volt supply when adjusting the on board pot I’d expect D1 (A out) to dim up and down, but mine don’t what am I doing wrong ??

  7. Hi! Someone in my Myspace group shared this site with us so I came to check it out. I’m definitely loving the information. I’m bookmarking and will be tweeting this to my followers! Wonderful blog and terrific design.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: