Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

I2C - PCF8591 - 8-bit A/D and D/A converter

  • kdebu

    kdebu - 2014-05-29

    Hello everybody,

    I need some help! I'm preparing library for I2C PCF8591 (A/D and D/A converter). It doesn't work....

    Data sheet: PCF8591

    I think the problem might be writing the control byte...

    Lib, device description and project are attached to this post.

    Does anyone have any suggestions or finds an error?


    PCF8591.zip [282.45 KiB]

    PCF8591.rar [254.77 KiB]

  • kdebu

    kdebu - 2014-05-30

    Nobody any suggestions?

  • switcher

    switcher - 2014-05-31


    You are writing 00 into Control register after init. I think that you have to enable analog output (bit 7 in control register), so you have to write:

    write8(control, 16#80); // Control Byte

    Device address 4F is ok if you have A0,A1,A2 connected to Vdd. Please check this.

    Because you only set channel number in control register to 00, you can only read AIN0.

    I hope this will help.
    Please report the result.


  • kdebu

    kdebu - 2014-05-31

    Hi Zdenko,

    To enable the DAC i have to write 0x40 (0100 0000) into the control register.

    Reading AIN0: 0x00 (or 0x40 with enabled DAC) - single ended input
    Reading AIN1: 0x01 (or 0x41 with enabled DAC) - single ended input
    Reading AIN2: 0x02 (or 0x42 with enabled DAC) - single ended input
    Reading AIN3: 0x03 (or 0x43 with enabled DAC) - single ended input

    The device address 0x4F must be correct. A0, A1 and A2 are connected to Vdd. I checked this also with i2c-tools.

    Reading the ADC-inputs and writing into the DAC-register still does not work correctly. The read ADC-values and the DAC-output voltage (measured with a multimeter) are not correct.

    I checked the function of my board with a c- and python-script. The PCF8591 worked correctly... So it must be a "CODESYS-problem".


  • switcher

    switcher - 2014-05-31

    Hi Kdebu,

    yes, you are right. To enable DAC you have to write 0x40 into control register. I missed one bit.

    But in your case, you are not writing this value in the device control register nowhere. Please make sure that write value to control register will be performed before reading/writing DAC/ADCs.


  • kdebu

    kdebu - 2014-06-06

    Hello Zdenko,

    i updated my project (see attached file(s)) but it still doesn't work...

    I think the program logic should be correct... Please take a look again.


    PCF8591.zip [275.49 KiB]

  • eschwellinger

    eschwellinger - 2014-06-07


    we need more description, what exactly does not work,
    any screenshot of debugging it, would be great.


  • christos

    christos - 2015-09-25

    I have the same problem i cant get PCF8591 to send a signal from my potentiometer

    im useing this code in a ST POU

    PROGRAM PCF8591_Test
    Potentiometer : LREAL;

    PCF8591.CNF := 16#40;
    Potentiometer := BYTE_TO_LREAL(PCF8591.IN_A);


  • christos

    christos - 2015-09-29

    I just wrote a program in python and tried out the PCF8591 with a potentiometer connected to the first port and the program ran nicely everything worked. So i know now the ic works 100%. But i can still not get it to work in codesys Ive added an i2c master and under that the device PCF8591 wich i downloaded from the forum. Part of the problem is i cant understand the functionblock 100% as I understand it know you want me to send the init byte to PCF8591.CNF and that will activate the ports to be able to recive data. Right now im running and ST program that looks like this:

    PCF8591.CNF := 16#48;

    Potentiometer := BYTE_TO_LREAL(PCF8591.IN_A);
    Potentiometer1 := BYTE_TO_LREAL(PCF8591.IN_B);
    Potentiometer2 := BYTE_TO_LREAL(PCF8591.IN_C);
    Potentiometer2 := BYTE_TO_LREAL(PCF8591.IN_D);

    Im out of ideas, so i hope someone on the forum have any.


  • christos

    christos - 2015-09-29

    I solved it forgot to write an address on my PCF8591 device.

    Address the device you add under the I2C master with the value 16#48

    and just make an ST POU and write:

    input0 := BYTE_TO_REAL (PCF8591.IN_A);

    and you should get a value on IN_A if you connected something to the first port on the IC.


  • klima

    klima - 2018-11-27

    Ok im only can read from one input like

    PCF8591.in0 or 1 or 2 or 3 switching to PCF8591.control :=16#40/41/42/43

    How to read all ?

  • abner

    abner - 2021-05-22

    Hi, did you could work with the Analog Output?
    I can´t find the way to work with it.
    I am using a pre-configured module, now I can read the 4 Analog Inputs but I can´t write anything to the AOut...
    What I am doing is setting a value of 255 on variable "out", the unique thing that I see is that change the value of my AN0,AN1,... but I get 0V on the Output...
    I don´t know if it is something bad in the Library


Log in to post a comment.