Arduino, I2C mit dem PCF8574

DSC06639

Den I2C-Chip nach dieser Youtube-Anleitung  an meinen Arduino Uno zu klemmen ging zuerst  einmal mächtig schief.

die richtige Adresse

Der dort verlinkte i2c-Scanner lies sich nicht kompilieren und so stellte sich die Frage: Welche Adresse soll ich in den Sketch eintragen?

Nun gibt es für den Chip ein Datenblatt. Dort steht unter Punkt 7.1. “0 1 0 0 A2 A1 A0 0″ also 01000000 wenn man die drei Adresspins auf die Masse klemmt.  Funktionierte aber nicht weil – Zitat aus der Wire-Referenz:

Die Wire-Library benutzt durchweg 7-Bit-Adressen. Wenn in einem 
Datenblatt oder einem Beispielcode 8-Bit-Adressen verwendet 
werden, kann man das niederwertigste Bit einfach löschen

Soweit einleuchtend, nur sollte man das Löschen nicht wörtlich nehmen. 0100000 ist auch falsch.
Beim Suchen fand ich dann hier (Reply #6) einen anderen I2C-Scanner. Der gab mir 0×20 aus, was nach dieser Liste binär 00100000 ist. Klar, man muss das rechts gelöschte Bit links wieder anhängen.
Daraus ergibt sich aber noch eine Änderung. Klemmt man nun den Pin 1 des PCF8574 auf Plus um eine andere Adresse zu erhalten, ist diese nicht 00100010 wie man laut Datenblatt vermuten könnte (das letzte Bit entscheidet dort ob Lese oder Schreibzugriff) sondern 00100001

Etwas Verwirrung ergibt sich auch aus der Frage, ist PCF8574 und PCF8574P das Gleiche? Ja, ist es. Das P steht nur für die Bauform. Allerdings gibt es da noch den PCF8547A und den PCF8547AP mit einer anderen Adresse.

den PCF8574 verdrahten

Soweit wie in dem Video:

PCF8574 – Arduino Uno

Pin 8 – GND
Pin 16 – 5V
Pin 15 – A5
Pin 14 – A4
Pin 1, 2, 3 – GND

Die LED kann an einen beliebigen freien Pin (außer Pin 13) geklemmt und über einen Vorwiderstand an 5V angeschlossen werden.

den PCF8574 beschreiben

Der Beispielsketch beschreibt alle PINs im Sekundentakt mit Null oder Eins. Klemmt man eine LED an einen beliebigen Port ergibt das einen Blinker.

i2c-blinker-Sketch

den PCF8574 auslesen

Nun wird an Pin 5 und GND ein Taster angeschlossen.

DSC06640-1024x768

Der folgende Sketch wurde um den Befehl Wire.requestFrom(expander, 1); erweitert. Die Eins bedeutet das ein Byte Daten angefordert wird.
Der übermittelte Wert wird in einen Array zerlegt und über den Serial Monitor ausgegeben. Zu beachten ist hier das in dem Array keine Zahlen (0,1) stehen sondern die Ansii-Werte für 0 und 1, also 48 und 49.

Die Zeilen:

int x6 = binstr[6];
Serial.print(x6);

verdeutlichen das. Daher die if-Abfrage nach ==48.

i2c-auslesen-Sketch

den Interrupt auslösen

Der PCF8574 besitzt an Pin 13 einen Interruptausgang der bei einer Veränderung an den Eingängen gegen Masse durchschaltet. Der Arduino Uno widerum besitzt an jeweils Pin 2 und 3 einen Interrupteingang. Es liegt also nahe die beiden zu verbinden.

Leider schwankte das Ergebnis bei meinen Versuchen zwischen Interrupt löst nicht aus und Interrupt löst unvorhersehbar oft mehrmals hintereinander aus, da ich zunächst einen normalen Taster verwendet habe.

Den ganzen Ärger mit prellenden Schaltern kann man sich aber prima sparen, durch Verwendung eines Hall-Sensors. Hier ein TLE4905L.

hallsensor-tle4905l-1024x768

Die Beschaltung ist ganz einfach. Linker Pin an +5V, mittlerer Pin an GND, rechter Pin an einen Eingang des PCF8574.  Pin +5V und Pin Signal mit einem 1,2KOhm Widerstand verbinden (der 800 Ohm auf dem Bild tut es auch)

p.s. wer gerade keinen Magneten im Haus hat kann auch schnell von der Tankstelle diese GIZEH-Blättchen besorgen, da ist ein kleiner Magnet dran.