digital/analog conversion I2C

Hi everyone,
I’m trying to generate an analog waveform from a digital one with a PCF8591 (I2C) and an arduino ONE.
For this I´ll use “Fade” example, which generates a PWM with a variable pulse width.
I created a code but the output of PCF8591 gives 0 and do not know why. I am quite sure that the hardware connection is well done. I think it can be a problem of the code.
This is my script:

# Include <Wire.h>

       
int brightness = 0, / / ??how bright the LED is
int fadeAmount = 5 / / How Many points to fade the LED by


void setup () {

   Wire.begin ();
   Serial.begin (9600);
}


int wave ()
{
  
  brightness = brightness + fadeAmount;


  if (brightness == 0 | | brightness == 255) 
  {
    fadeAmount =-fadeAmount;
  }
 
  return brightness;
}

void loop ()
{
 int amplitude;

 amplitude = wave();
 
  
 Wire.beginTransmission (B10010010);
 / / 0.1 and 2 bits are A2, A1 and A0 respectively and are the device address
 / / Wire.write (B01000000) / / Control byte Configures and enables outputs Aout
 Wire.write (amplitude);
 Wire.endTransmission ();
}

The error must be in the Loop function which is what I have done.
Just want the uP send the signal to PCF8591 and this last device to convert it so you do not need to read anything with the uP.

Now I explain my doubts about the code.

  1. The library “wire.h” enables the outputs of the arduino A4 and A5 making it unnecessary for me to do it by changing bits in TWRC register ? If not, what should I write in this register?
  2. I guess I should have to somehow pick up the signal “Fade” generated by the uP (in pin 9) and send it to the A4 pin (SDA), shouldn´t I?
  3. I have seen some codes for other devices and they didn´t send the control byte. Is this because some of the libraries already configure the device or something like that?
  4. Can anyone see where is the fault in the code?

I hope you can help me.
Greetings.

float wave ()
{
  brightness = brightness + fadeAmount;

  if (brightness == 0 | | brightness == 255) {
    =-fadeAmount fadeAmount;
  }

  return brightness;
}

brightness and fadeAmount are both ints. Why does this function return a float?

What is that mess after the if test? That should change a positive fade amount to a negative fade amount. It does not.

void loop ()
{
 int brightness;

A local variable of the same name as a global variable. A VERY bad idea.

1) The library "wire.h" enables the outputs of the arduino A4 and A5 making it unnecessary for me to do it by changing bits in TWRC register ? If not, what should I write in this register?

Why do you think you need to write anything?

2) I guess I should have to somehow pick up the signal "Fade" generated by the uP (in pin 9) and send it to the A4 pin (SDA), shouldn´t I?

Only you know what you are trying to do. The code you posted appears to be sending data TO the uP.

3) I have seen some codes for other devices and they didn´t send the control byte. Is this because some of the libraries already configure the device or something like that?

That would be my guess. Vague references to other devices and libraries are meaningless.

4) Can anyone see where is the fault in the code?

Yes.

Ok, I´ve already corrected those faults and it still doesen´t work.

The code you posted appears to be sending data TO the uP.

Are you sure? It is based on “master writer” example:

#include <Wire.h>

void setup()
{
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 0;

void loop()
{
  Wire.beginTransmission(4); // transmit to device #4
  Wire.write("x is ");        // sends five bytes
  Wire.write(x);              // sends one byte  
  Wire.endTransmission();    // stop transmitting

  x++;
  delay(500);
}

What I want the uP to do is just to send the PWM positive width to the PCF8591 and this one to convert it to an amplitude.
Then how should the structure be?
Thanks for your help.

  Wire.beginTransmission(4); // transmit to device #4

Wire is not dealing with device #4. It is dealing with the device whose address is 4. Is that your chip's address?

  Wire.write("x is ");        // sends five bytes

What is your device going to do with this?

The second code I´ve posted is the "master writer" example. Just for you o see that I used that structure in my code. Suposedly using that structure the uP should send data to the converter but it doesen´t and I can´t find the reason. The converter´s adress is the one I wrote in the first code.

One last question, and then I can't help you any more. The value that you are sending is in the range 0 to 255. So, why is that stored in an int, rather than a byte? Perhaps your device only expects a byte. Sending an int, with 0 in the high byte, may confuse it.

The Wire library expects the I2C address as a 7bit value, so your line

 Wire.beginTransmission (B10010010);

should be

 Wire.beginTransmission (B1001001);

if you set the address line A0 (on the chip) to 5V and all the other address lines to GND. The read/write bit is set by the library, you mustn't supply it.

Hello PaulS, I´ve written "byte" in all variables type after seeing that, as you said, I didn´t need them to be so big but it still doesen´t work. Thanks for trying helping me anyway.

Pylon, I know that I only need 7 adress bit but I´ve tried in both ways and its ansqer is null. I´m desperated so I´ll try to get a new converter although I don´t think that´s the problem...

Can you post the code that you are actually expecting to work with the PCF8591.

The address you should be using is 0x48 if you have all the external address inputs A2, A1 and A0 wired to ground. You need to set bit 7 in the control register to a 1 to enable the analogue output, and then the byte that determines the output.

Finally you need a pull up resistor on both I2C lines to +5V, a value of 4K7 is good.

It already works!! I think that some days ago I tried sending the control byte but didn´t worked. I might didn´t send the right adress that day... Anyway I´m seeing a beautiful triangular wave in this moment so thank you so much everybody!