Der PCF8574 ist ein 8-Bit Expander mit I2C-Bus. Übersetzt heißt das, über den I2C-Bus kann ich 8 Pins setzen oder lesen. Die 8 Pins sind Open-Collektor, die wahlweise als Ein- oder Ausgang geschalten werden können. Sollte der Pin als Eingang genutzt werden, muss ein sogenannter Pull-Up-Widerstand gegen UCC (Betriebsspannung) geschalten werden, damit dieser einen logischen (High) Pegel hat.
Die 8 Pins können nur gleichzeitig als ein Byte gelesen bzw. geschrieben werden. Gegebenenfalls muss man erst den Ist-Stand lesen und dann das eine Bit dazu addieren oder wegnehmen um wirklich nur das eine Bit zu modizifieren.
Anbei der Hinweis: im Internet (z.B. Ebay) wird alles unter PCF8574 verkauft - auch der PCF8574A. Ich bekam mal den einen mal den anderen. Wem es darauf ankommt, welche Adressen genutzt werden können, sollte das ggf. vorab abklären.
Jumper A0-A2 dienen zur Adressierung des Expanders.
Für den PCF8574 gilt.
0x40 + A[2:0]*2 + R(ead)\W(rite)-Bit.
Tools lassen
das R\W-Bit bei der Adressierung weg. Es gilt dann bitweise
0 1 0 0 A2 A1 A0, somit als Basisadresse in Hexidezimal 0x20
D.h. je nach Jumper sollten die I2C im Adressraum 0x20-0x27 ansprechbar
sein.
Mit 3 Jumper lassen sich also maximal 2^3 = 8 Expander an einem I2C-Bus einsetzen. Aber es gibt ähnliche Expander, wo nur der Adressraum anders liegt.
So gilt z.B. für den PCF8574A gilt folgende Adressierung
Ich bin kein Elektroniker. Daher sind die Einstellungen nur Erfahrungswerte, wie die Hardware bei mir funktionierte. Es gibt sicher tolle Formeln, allerdings liegen mir ja nicht mal alle Datenblätter zu den einzelnen Modulen vor.
Ich nutzte bisher folgende Pull-Up-Widerstände als Eingang von folgenden Sensoren
Bei der Nutzung als Ausgang fand ich folgendes im Internet
Typ Open Collector sind und nur bei LOW große Ströme schalten können.
D.h. ein Ausgang zur LED sollte mit Vorwiderstand (bei mir 220 Ohm) gegen die Betriebspannung
geschalten werden. Dadurch ist der Pegel negiert zu betrachten. Sprich
geschaltenes "On" schaltet die LED aus und umgekehrt.
Einfach an den Expander anschließen. UCC des Expanders zum 5Volt UCC vom Raspberry Pi
Die Module i2c-bcm2708
und spi-bcm2708
müssen aus der Ausschluss-Liste entfernt werden.
Dazu muss man in der Datei
/etc/modprobe.d/raspi-blacklist.conf
die entsprechenden Einträge auskommentieren.
-
in der Kommandozeile unter Linux als Root angemeldet.
- modprobe i2c-bcm2708
- modprobe i2c-dev
- apt-get install i2c-tools
optional kann die Baudrate angegeben werden. Der I2C läuft maximal bis 400kHz, bei 30 Metern Kabellänge sollte man aber eher runtertakten. Hier im Beispiel auf 20 KHz
- modprobe i2c-bcm2708 baudrate=20000
Wenn alle Jumper default gelassen wurden, dann sollte
das hier die Belegung der Ein/Ausgänge zeigen.
Die 1 beim Aufruf von i2cdetect -y 1
ist in dem Fall der Adressbus.
(Bei anderen Versionen des Raspberry PI kann es durchaus ein anderer sein.)
Im Ergebniss sieht man, dass ein I2C-Expander unter Port 0x20 gefunden
wurde.
Der Expander hat einen Interrupt-Pin. Dieser wird geschalten, sofern sich an einen der 8 Pins etwas tut. Wenn man das Interrupt-Signal auf eine GPIO-Pin des Raspberry Pi legt, könnte man also direkt auf eine Änderung reagieren.
Theoretisch habe ich 8 Kanäle im Kabel, allerdings nutze ich diese als 4x2, um den Kabelwiderstand so gering wie möglich zu halten. Außerdem benötige ich ohnehin schon sehr viele GPIOs vom Raspberry für die weitere Haus-Steuerung, so dass jeder GPIO wertvoll ist.
So habe ich mich auf die weniger elegante Methode des Pollings entschieden. Sprich das Signal wird aller Sekunden abgefragt. Bei 20.000 KHz Takt dürfte das zu verkraften sein.
# setze Bus auf 1define raspBerryBus RPII2C 1
# setze den entsprechenden (in dem Beispiel den Expander in der Küche) PCF8574 auf Adresse 0x20
define kuecheExpander I2C_PCF8574 0x20
# teile dem PCF8574 den Bus mit
attr kuecheExpander IODev raspBerryBus
# Eingabe-Ports definieren, dadurch erscheinen Änderungen am Port auch im Logfile
attr kuecheExpander InputPorts 7 6 5
# setze Polling auf 0.02 Minuten (ca. aller 1,2 Sekunden),
attr kuecheExpander poll_interval 0.02
# nur Event wenn sich auch der Status, Port7, Port6, Port5 sich wirklich ändernattr kuecheExpander event-on-change-reading state,Port7,Port6,Port5
# hier Beispiele wie Logfiles aussehen könnten
define FileLog_kuecheExpander FileLog ./log/kuecheExpander-%Y.log kuecheExpander
define FileLog_LichtKueche FileLog ./log/LichtKueche-%Y.log kuecheExpander.*:Port7.*
# hier wie ich die LED am Port0 anschalte
set KuecheExpander Port0 off
# hier wie ich die LED am Port0 abschalte
set KuecheExpander Port0 on
# prüfe ob der Lichtsensor angeschalten ist
ReadingsVal("KuecheExpander","Port6","") eq "off"