I2C is een mooie mogelijkheid om de Arduino meer dingen te kunnen laten doen dan er poorten zijn. Ook over de basis I2C is veel vermeldt op het internet en ik ga dat allemaal niet herhalen. Wat ik wil delen zijn de dingen waar ik tegenaan gelopen ben en die me tijd hebben gekost om uit te zoeken.
Ik ben heel dankbaar met de uitleg die ik kreeg op de Arduino werkgroep van de SMG. Als ik daar niet aangesloten was had ik niet in twee jaar tijd zoveel opgepikt.
Mijn grootste struikelpunt was eigenlijk het IC 8591(8 bits data) die 4x Analoog in en 1x Analoog uit via I2C kan lezen/sturen.
A0 A1 en A2 zijn hardwarematige adressen van het IC. Maar elk I2C type IC heeft ook nog een eigen deel van het adres. Zo heeft de 8591 een extra adres 9x. Bij de mini kan je dus daarvan maken 90 t/m 97. 8 IC's van het type 8591. Bij de vierkante versie alleen 90.
Die 9 kan je dus niet veranderen maar moet je wel opnemen in je adressering.

De 3 jumper P4 P5 en P6 zijn voor:
P4-AIN1 de temperatuur sensor (R6) is verbonden met ADC
P5-AIN0 de R7 lichtcel is verbonden met DAC
P6-AIN3 de 10K potmeter is aangesloten .

AIN0 t/m AIN3 zijn de analoge poorten die je in kan lezen. Met de waarde tussen 0 en 5 volt,m min. 0 max 255.

Aout is de analoge uitpoort die je dus trapsgewijs aan kan sturen.
Er is ook een mini versie PCF 8591 die geen jumpers heeft om de lichtcel, temperatuur sensor en potmeter af te koppelen maar wel 3 jumper om het adres aan te kunnen passen.
De potmeter zit er vast op om de analoge waarden in te stellen.
#include <Wire.h>// Wire library t.b.v. I2C
#include <LiquidCrystal.h> // voor het display

Arduino zend 7 bits uit voor het adres en je hebt 8 bits nodig. Er moet dus met bits geschoven worden.
1001 Moet altijd voor IC herkenning en dan 3 bits hardware adres en als laatste om te lezen een 0 en te schrijven een 1
Het adres wordt dan 1001xxx1 om te lezen
of 1001xxx0 om te schrijven.
Het vreemde is dat volgens de info van de Arduino dit automatisch zou moeten gebeuren bij het verzenden van de data door
de Arduino. Bij mij blijkt echter dat als ik gewoon adres 90 gebruik het proces niet goed te verlopen.
Er zijn 3 bytes nodig om alles goed te laten verlopen:
1e byte adres
2e byte de configuratie (zie datasheet.
3e byte de te schrijven of te lezen data.
De 2e en 3e byte mogen 8 bits zijn.
*/
#include // Wire library t.b.v. I²C
#define pcf8591_lees 0x90>>1
#define pcf8591_schrijf 0x91>>1
#define pcf8591_A_in 0x01
#define pcf8591_B_in 0x02
#define pcf8591_C_in 0x03
#define pcf8591_D_in 0x04
#define pcf8591_led_aan 0xFF
#define pcf8591_led_uit 0x00
#define pcf8591_led 0x0F
int(ledwaarde)=90;
void setup()
{
Serial.begin(19200);
Wire.begin();
// led aan op halve kracht
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(0x44); // instellingen om te schrijven 2e byte analooginput aan
Wire.send(pcf8591_led); // waarde voor led 3e byte
Wire.endTransmission();
// om het een beetje zichtbaar te maken op de pc
Serial.print("IC adres:");
Serial.print("\t");
Serial.print("Led waarde: ");
Serial.print("\t");
Serial.print("waarde A:"); // print the character
Serial.print("\t");
Serial.print("waarde B:"); // print the character
Serial.print("\t");
Serial.print("waarde C:"); // print the character
Serial.print("\t");
Serial.println("waarde D:"); // print the character
delay(500);
//
}

void loop()
{
// led aan
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(0x40); // 2e byte analooginput aan
Wire.send(ledwaarde); // waarde voor led 3e byte
Wire.endTransmission();

//data lezen
delay(500);
// lees eerste adres
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(pcf8591_A_in); // instellingen om te schrijven 2e byte analooginput aan
Wire.endTransmission();
//
Serial.print(pcf8591_schrijf,BIN);
Serial.print("\t");
Serial.print("\t");
Serial.print(ledwaarde);
Serial.print("\t");
Serial.print("\t");
//
Wire.requestFrom(pcf8591_lees, 1); // aantal bytes die we willen lezen
byte waardeCH0 = Wire.receive(); // receive a byte
Wire.endTransmission();
//
Serial.print(waardeCH0,HEX); // print the character
Serial.print("\t");
Serial.print("\t");
//lees 2e
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(pcf8591_B_in); // instellingen om te schrijven 2e byte analooginput aan
Wire.endTransmission();
// v Wire.requestFrom(pcf8591_lees, 1); // aantal bytes die we willen lezen
byte waardeCH1 = Wire.receive(); // receive a byte
Wire.endTransmission();
//
Serial.print(waardeCH1,HEX); // print the character
Serial.print("\t");
Serial.print("\t");
// lees 3e
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(pcf8591_C_in); // instellingen om te schrijven 2e byte analooginput aan
Wire.endTransmission();
//
Wire.requestFrom(pcf8591_lees, 1); // aantal bytes die we willen lezen
byte waardeCH2 = Wire.receive(); // receive a byte
Wire.endTransmission();
// Serial.print(waardeCH2,HEX); // print the character
Serial.print("\t");
Serial.print("\t");
//
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(pcf8591_D_in); // instellingen om te schrijven 2e byte analooginput aan
Wire.endTransmission();
//
Wire.requestFrom(pcf8591_lees, 1); // aantal bytes die we willen lezen
byte waardeCH3 = Wire.receive(); // receive a byte
Wire.endTransmission();
//
Serial.print(waardeCH3,HEX); // print the character
Serial.print("\t");
Serial.print("\t");
// De led weer uit zetten
Wire.beginTransmission(pcf8591_schrijf); // I2C adres 1e byt2
Wire.send(0x40); // instellingen om te schrijven 2e byte analooginput aan
Wire.send(pcf8591_led_uit); // waarde voor led 3e byte
Wire.endTransmission();
//
Serial.print("\t");
Serial.println("LED is nu uit ");
delay(10);
if (ledwaarde>=0xFF)
{ledwaarde=90;
}
ledwaarde=ledwaarde+10;

}

bronnen:
brainfyre pcf8591-yl-40-ad-da-module-review