Hier zeige ich, wie der I2C Bus des Raspberry Pi genutzt werden kann. Der Raspberry Pi nutzt 3,3 V Pegel und deswegen dürften NIEMALS 5 V Signalen auf das Board gegeben werden, da es ansonsten zu Schäden am Prozessor kommen kann.
I2C aktivieren:
Als aller erstes muss der I2C vom Raspberry Pi aktiviert werden. Dies geschieht durch folgende Zeilen:
$ sudo modprobe i2c-bcm2708 baudrate="WERT $ sudo modprobe i2c-dev $ sudo apt-get install i2c-tools
Die Zeilen
$ sudo modprobe i2c-bcm2708 baudrate="WERT $ sudo modprobe i2c-dev
laden die für den I2C notwendigen Module und stellen den Takt vom I2C auf den Wert
Wert
ein (Default ist 100 kHz).
Die durchgeführten Befehle müssen bei jedem Neustart neu ausgeführt werden und deswegen ist es empfehlenswert diese Befehle in die Datei
/etc/rc.local
zu schreiben. Mit der Zeile
$ sudo apt-get install i2c-tools
werden die notwendigen Tools installiert um auf den I2C zugreifen zu können. Anschließend kann mittels
$ sudo i2cdetect -y 0
geprüft werden ob der I2C funktioniert.
Dadurch zeigt euch das Raspberry Pi die Adressverteilung der Devices am Bus an. Bei mir ist z. B. ein Device mit der Adresse 0x20 angeschlossen (ein PCF8574).
I2C per Konsole verwenden:
Wenn ein Device am Bus erkannt wurde, kann mit den beiden Befehlen
$ sudo i2cget $ sudo i2cset
per I2C Bus auf das Device zugreifen werden. Wenn von dem Device gelesen werden soll, muss der Befehl
i2cget
verwenden und falls geschrieben werden soll i2cset
verwendet werden. Ein vollständiger Befehl zum Lesen sieht z. B. folgendermaßen aus:
$ sudo i2cget -y 0 0x20
Mittels
i2cget -y
soll von einem I2C Device gelesen werden, wobei die 0 der I2C Bus ist, der für den Zugriff verwendet werden soll (das Raspberry Pi hat auch noch einen anderen I2C Bus, aber der Bus der auf den 26-pol Connector rausgeführt ist ist der Bus 0). Der Wert 0x20 ist die Adresse von dem I2C-Device auf das Zugegriffen werden soll. Als Rückgabewert erhält man dann auf der Konsole das gesendete Byte vom I2C-Device.
Wenn nun in das Device geschrieben werden soll, so sieht der Befehl folgendermaßen aus:
$ sudo i2cset -y 0 0x20 0x00
Mit
i2cset -y
wird ein Schreibzyklus eingeleitet, wobei die 0 ist wieder der zu verwendende Bus ist und die 0x20 ist die Deviceadresse, gefolgt von einer 0x00, welche das zu sendende Datenbyte darstellt.
Auslesen eines EEPROMs:
Dieses Vorgehen soll Beispielhaft an einem EEPROM (24C128) gezeigt werden:
$ i2cset -y 0x50 0x00 0x00 0x10 i $ i2cset -y 0x50 0x00 0x00 $ i2cget -y 0x50
Die erste Zeile spricht das EEPROM mit einem Schreibbefehl an und überträgt alle Adressen und Daten, die daraufhin in das EEPROM geschrieben werden. Dabei stellt der Wert 0x50 ist die Adresse des EEPROMs dar, die zwei 0x00 sind die beiden Datenbytes für den Adresspointer im EEPROM und die 0x10 sind die Daten die in das EEPROM geschrieben werden sollen.
Der Parameter i gibt an, dass es sich bei dem gesendeten Werten um Integer handelt, also die Adresse und die Daten aus je zwei Bytes bestehen.. Es muss bei Übertragungen von 4 Bytes oder mehr hinzugefügt werden. Da der Pointer im EEPROM nach jedem Schreibbefehl um eins inkrementiert wird, muss dieser jetzt erst wieder auf 0x00 gesetzt werden, bevor die Zelle gelesen werden kann.
$ i2cset -y 0x50 0x00 0x00
Auch hier ist die 0x50 wieder die Deviceadresse vom EEPROM und die zwei 0x00 sind die Adresse für den Pointer.
Anschließend kann die Zelle mit dem Befehl
$ i2cget -y 0x50
ausgelesen werden. Die Konsole gibt nun den Wert 0x10 aus.
Nachfolgend noch ein paar Beispielanwendungen mit dem I2C.
→ Eine DS1307 als Uhr verwenden
→ Externer ADC & CapSense
→ Servo ansteuern mittels PCA9685
Sämtliche Codebeispiele stehen in meinem Raspberry Pi Repository zum Download bereit.
Hi,
ne schöne Seite haste da gebastelt. Du schreibst, man soll nie mit 5V-Pegeln auf den Bus der Himbeere gehen, speziell der DS1307 arbeitet aber nur mit 5V Betriebsspannung. Wie hast Du die I2C-Pegel angepasst, um die Himbeere nicht in den Siliziumhimmel zu schicken?
Gruß
Kurt
Hallo Kurt,
I²C funktioniert mittels Open-Collector Eingänge. Sprich der Bus führt keine eigenen Pegel und deswegen werden die Pull-Ups benötigt.
Die DS1307 wird mit einer Spannung von 5V betrieben aber der I²C vom Raspberry Pi wird mittels Pull-Ups, die sich auf dem Board befinden, auf 3,3V gezogen. Dadurch führt der Bus 3,3V Pegel. Die DS1307 kann diese Pegel lesen (glaube 2V ist Minimum bei der). Deswegen kann ich die RTC an den Pi anschließen. Ich missbrauche die Pull-Up Widerstände quasi als Pegelwandler.
Gruß
Daniel
Danke für die schnelle Antwort. Dann werde ich mich mal ans Basteln machen :-)
Ok, I2C läuft :). Allerdings ist bei den neuen Himbeeren mit 512MB der zweite I2C-Bus auf die Pin-Leiste verdrahtet.
Die Ansteuerung ändert sich daher geringfügig, statt
„i2cget -y 0 0x20“ muß man den Bus 1 wählen, also „i2cget -y 1 0x20“.
In Programmen sollte man also irgendwie ermitteln, welcher Bus aktiv ist.
Gruß
Kurt
Super das es funktioniert :)
Wie man das ermittelt weiß ich leider nicht (ich wusste auch nicht mal das bei der 512 MB Variante ein anderer Bus verwendet wird :D)
Aber in so einem Fall muss man einfach mal gucken welcher I²C verdrahtet worden ist.
Danke auf jeden Fall für die Anmerkung!
Hallo Kurt,
ich habe nun auch eine 512MB Version vom Raspberry erhalten.
Du kannst über /proc/cpuinfo die Daten zu dem Pi auslesen und alles was über Revision 2 ist, hat I2C-1.
Für C-Programme o.ä. kannst du ja einfach testweise den Bus öffnen und gucken ob du ihn a) öffnen und b) auch was dadrüber verschicken kannst.
Wenn es nicht geht probierst du einen anderen Bus aus.
Alternativ kannst du auch den Ordner /dev durchsuchen, welcher I2C dort vorhanden ist.
Es gibt einige Möglichkeiten es herauszufinden.
Ist nur mit etwas Arbeit verbunden ;)
Am einfachsten ist es die Revision der CPU auszulesen ^^mehr dazu in Google
Hey,
klar das ist der einfachste und universellste Weg ;)
Gruß
Daniel
Beim Rev.2-Board ist der „1er“-Bus auf dem (großen) P1-Stecker (26-polig) und laut http://elinux.org/RPi_Low-level_peripherals ist eine 2. I²C-Gruppe („0-er“-Bus) auf dem P5-Stecker.
Dies wäre eine bessere Möglichkeit – somit lässt man eher P1 frei für andere Zwecke ohne die vielen durch den P1-Stecker verdeckt und ungenutzten GPIO’s.
Ansonsten, vielen Dank, habe jetzt 2×16-Ports extra über MCP23017 für wenig Geld
Hey,
ja genau. Ich glaube im Artikel habe ich das nicht erwähnt, weil es sich in erster Linie nur um den 26-pol Stecker handelt.
Aber dank dir für den Hinweis :)
Gruß
Daniel
Hi Kami,
super Tutorials haste hier zusammengestellt. Ich habe noch eine Verständnisfrage bzw. konnte dazu nichts im Netz bisher finden. Ist es möglich 1wire und I²C-Devices gleichzeitig mit dem Pi anzusprechen, bzw welche Pins sind hierfür bei der 256mb Version maßgeblich?
Vielen Dank & Grüße
Marc
Hallo Marc,
ich wüsste jetzt nicht warum das nicht gehen sollte. Für I²C werden die GPIO0 und 1 verwendet und für 1Wire sollte irgendein GPIO verwendet werden können (ist ja soweit ich weiß nur ein Übertragungsprotokoll).
Oder was genau meinst du?
Gruß
Daniel
Hi Daniel,
danke für die rasche Antwort. Du hast recht die Schnittstelle für das 1wire-Protokoll ist so wie ich das verstanden habe frei wählbar, bei quellcodeanpassung standardmäßig auf gpio4.
Gruß
Marc
Hey Marc,
ich wollte jetzt mal selber bisl mit 1Wire experimentieren aber irgendwie läuft
mein Pi nicht mehr…..keine Ahnung woran es liegt ^.^
Aber wenn ich weiß wie das mit dem 1Wire funktioniert schreibe ich es dir und
auf die HP :)
Gruß
Daniel
Hi,
Klasse anleitungen die du hier hast!!!!
Ist es mödlich I2C-Befehle über die Webseite zu senden und empfangen?
Gruß Dieter
Hey,
ja es sollte prinzipiell möglich sein I²C über eine Website zu steuern.
Ich würde aber eher ein Programm z.B. zum Auslesen eines EEPROMs schreiben und dieses Programm mittels Website aufrufen.
Die Ausgabe kannst du dann in PHP anzeigen lassen.
Gruß
Daniel
Hallo,
ist es möglich ein an den I2C Bus angeschlossenes LCD direkt mit dem Befehl
i2cset einen Text anzeigen zu lassen?
Hey,
nein das geht nicht, weil du den Text und die Initialisierung seriell, sprich nacheinander schicken musst.
D.h. du musst die Initialisierung händisch machen und anschließend händisch jeden Buchstaben senden und ob das geht weiß ich nicht.
Gruß
Daniel
ich hab ein wenig rumgespielt aber viel mehr als die Hintergrundbeleuchtung ein und wieder auszuschalten hab ich nicht hinbekommen. Nun benutze ich LCDproc… das läuft richtig gut!!
! ! ! Vielen Dank für die Antwort ! ! !
Ist es nicht auch möglich den I2C-Bus über eine website zu steuern?
Hättest du da evl. Lösungsansätze??
mfg Tobias
Ps. Super tutorials haben mir echt geholfen^^
Hey,
theoretisch sollte es gehen.
Gemacht habe ich es bisher noch nicht selber (mal schauen vielleicht kommt es mal :) ).
Von daher habe ich noch keinen konkreten Ansatz.
Gruß
Daniel
Falls es jemanden interessiert. Man kann mit
modprobe i2c-bcm2708 Baudrate="WERT"
z.B. 10000 den Standardwert von 100kHz überschreiben, um beispielsweise eine stabilere Übertragung bei einem längeren Bus zu erreichen.Gruß
Daniel
baudrate="WERT"
Baudrate natürlich klein geschrieben. :DHey
erstmal echt tolle Seite.
Ich habe nur leider ein Problem und zwar es klappt alles so weit nur ich habe Probleme die richtige Adressen zu finden. Ich bin zu blöd um die Erklärung aus dem Daten Blatt zu verstehen und den anderen Beiträgen im Internet. Könntest du mir vielleicht eine kleine list gegeben wo drine steht 0x43 Heist Ausgang 1 schreiben. Oder wenn das zu viel ist ich möchte erst mal zum testen 2 relais ansteuern die liegen an dem Pin 4, 5 laut Datenblatt Ausgang P0, P1 und habe an dem P2 (pin 6) einen Taster den ich gerne auslesen möchte. Wäre supa wenn mir da jemand helfen könnte.
Danke
Hey,
kein Problem.
Was für einen Chip verwendest du den? Dann kann ich dir da etwas genauer weiterhelfen.
Gruß
Daniel
Ohh sorry den PCF 8574 P
Hi! Ich komm hier nicht weiter: ich habe zwei Sensoren auf 0x0e und 0x1d. Bei verwendung von i2cget -y 1 0x0e bzw. i2cget -y 1 0x1d bekomme ich in beiden fällen 0x00. Kann das stimmen? Ich befürchte, dass ich deshalb die Verbindung zu Matlab nicht herstellen kann. Der dritte Sensor gibt einen Zahlenwert aus und dort klappt die Verbindung. Welches Register wird ausgelesn wenn man keine weitere Adresse angibt?
Vielen Dank!
Hey,
ich nehme an, dass du mittels i2cdetect schon überprüft hast ob die Verbindungen da sind.
Du musst als erstes mit i2cset die Registeradresse schreiben:
i2cset -y 1 Adresse Registeradresse
Erst danach kannst du das Register auslesen.
Gruß
Daniel
Ist es möglich den I2C mittels java auf der RPi aufzurufen?
Hallo Kevin,
ob es eine Lib dazu gibt weiß ich nicht, aber du kannst den I²C zur Not einfach über den Treiber /dev/i2c aufrufen.
Gruß
Daniel
Ich bin neu mit dem rasberry pi.
frage: kauf ich den rasberry pi ohne betriebssystem oder mit?
lg
peter
Hallo Peter,
meinst du mit SD-Karte oder ohne?
Im Grunde kannst du dir eine fertige SD-Karte kaufen. Das spart etwas Arbeit und eine SD-Karte brauchst du so oder so ;)
Gruß
Daniel
Ist auf der sd karte das betriebssystem?
Hallo,
ja, das Betriebssystem befindet sich auf der SD-Karte. Die Karte ist im Grunde die „Festplatte“ des Rechners.
Gruß
Daniel
wo kann ich so eine sdkarte erwerben, kannst du mir da bitte einen tip geben??
lg
Peter
Hallo Peter,
du kannst dir z.B. diese hier kaufen:
http://www.amazon.de/F%C3%BCr-Raspberry-Pi-Inklusive-ArchLinux/dp/B008MLRJ5I/ref=sr_1_4?ie=UTF8&qid=1412245897&sr=8-4&keywords=raspberry+pi+sd+karte+noobs
Da sind alle großen Betriebssysteme drauf und du kannst bequem zwischen den Betriebssystemen wählen und so alle ausprobieren.
Gruß
Daniel
Hallo Daniel,
von der alten C-Control habe ich noch ein Touchdisplay eDIP240-7 übrig, und das wollte ich jetzt mit dem Raspi über I2C ansprechen. Es hat unter C-Control mit I2C-Anbindung funktioniert. Es gelingt mir allerdings nicht es zum laufen zu bringen. Lesen kann ich, aber nicht schreiben. Bekomme immer Input/output Error. Die Anleitungen in Deinem Buch bringen mich leider nicht weiter.
Gruß Lush
Hallo Lush,
mmh schwierig…was sitzt den auf dem Display drauf? Weil ich hatte mal mit meinem Mikrocontroller experimentiert und da auch diesen Fehler bekommen.
Mittlerweile habe ich aber auch herausgefunden, dass der I²C im Pi einen Hardwarefehler besitzt.
Ggf. kann dieser Fehler sich beim Schreiben bemerkbar machen:
http://www.advamation.com/knowhow/raspberrypi/rpi-i2c-bug.html
Gruß
Daniel
Hallo Daniel,
weist du zufällig wie viele Portexpander man maximal an den Pi anschließen kann?
Würde ca 132 Ports benötigen. Ist das mit diesen Chips rauszuholen?
Gruß Gerald
Hallo Gerald,
der Portexpander hat drei Adresspins, d.h. du kannst 8 (2^3) verschiedene Portexpander an einem Bus anschließen.
Gruß
Daniel
Hallo Daniel,
und genau da liegt mein Problem wenn ich 8 Portexpander anschließen kann komme ich bei 16 Ports pro Chip auf 128 Ports. Mein Problem ist nur das ich 4 Ports mehr benötigen würde. Gib`s die evtl auch mit mehr Ports am Chip? Habe bisher leider noch keine mit mehr als 16 Ports gefunden.
Gruß Gerald
Hallo Gerald,
schau dir mal den hier an:
http://www.ti.com/product/pcf8575
Gruß
Daniel
Hallo zusammen,
habe da ein kleines „Verständigungsproblem“, wenn ich über sudo i2cdetect -y 1, zeigt es mir folgendes an:
sudo i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: — — — — — — — — — — — — —
10: — — — — — — — — — — — — — — — —
20: — — — — — — — — — — — — — — — —
30: — — — — — — — — — — — — — — — —
40: 40 — — — — — — — — — — — — — — —
50: — — — — — — — — — — — — — — — —
60: 60 — — — — — — — — — — — — — — —
70: — — — — — — — —
jedoch, wenn ich den Sensor ansprechen möchte:
sudo i2cget -y 1 0x40
Kommt mir nur dieser Error: Read failed.
Meines Wissens, habe ich alles installiert was ich müsste, habt Ihr mir einen kleinen Typ.
Merci schon mal, Gruss Urs
Hallo Urs,
um was für einen Sensor handelt es sich? Wird der Sensor vielleicht noch von was anderem (ein Programm etc.) ausgelesen?
Gruß
Daniel