I²C

Raspberry Pi

Hier zeige ich euch wie ihr den I²C Bus des Raspberry Pi nutzen könnt.
Wichtig ist das ihr auf die richtigen Pegel achtet!
Das Raspberry Pi nutzt 3,3V Pegel und deswegen dürft ihr NIEMALS mit 5V Signalen auf das Board gehen, da ihr es sonst zerstört!

-> I²C aktivieren:

Als aller erstes muss der I²C vom Raspberry Pi aktiviert werden.
Dies geschieht durch folgende Zeilen:

Die Zeilen

laden die für den I²C notwendigen Module und stellen den Takt vom I²C auf den Wert Wert ein (default ist 100kHz).
Die Zeilen 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

werden die notwendigen Tools installiert um auf den I²C zugreifen zu können.
Anschließend könnt ihr mittels

prüfen ob der I²C funktioniert. Wenn er dies tut und ihr ein I²C Device angeschlossen habt wird so ein Bild ausgegeben:

I2Cdetect

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).

-> I²C per Konsole verwenden:

Wenn ein Device am Bus erkannt wurde könnt ihr mit den beiden Befehlen

per I²C Bus auf das Device zugreifen. Wenn ihr von dem Device lesen wollt, müsst ihr den Befehl i2cget verwenden und falls ihr schreiben wollt verwendet ihr i2cset.
Ein vollständiger Befehl zum lesen sieht z.B. bei mir so aus:

Das i2cget -y sagt dem Raspberry Pi das von einem I²C Device gelesen werden soll. Die „0“ ist der I²C Bus den man verwendet (das Raspberry Pi hat auch noch einen anderen I²C Bus, aber der Bus der auf den 26-pol Connector rausgeführt ist ist der Bus 0) und die 0x20 ist die Adresse von dem Device.
Als Rückgabewert erhält man dann auf der Konsole das ausgelesene Byte.
Wenn nun in das Device geschrieben werden soll, so sieht der Befehl so aus:

Mit i2cset -y wird dem Raspberry Pi nun mitgeteilt, dass man auf ein I²C Device schreiben möchte und die 0 ist wieder der zu verwendende Bus.
Die 0x20 ist die Deviceadresse und die 0x00 ist das Datenbyte welches in das I²C Device geschrieben werden soll.

-> Auslesen eines EEPROMs:

Die Kommunikation mit einem EEPROM (24C128) sieht so aus:

Die erste Zeile spricht das EEPROM mit einem Writebefehl an und überträgt alle Adressen und Daten, die daraufhin in das EEPROM geschrieben werden.
Die 0x50 ist die Adresse des EEPROMs, die zwei 0x00 sind die Datenbytes für den Adresspointer im EEPROM und die 0x10 sind die Daten die in das EEPROM geschrieben werden sollen.
Das i wird verwendet damit das Raspberry Pi weiß das mehr als die üblichen drei Bytes gesendet werden. 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 0 gesetzt werden, bevor die Zelle gelesen werden kann.
Dies erledigt die Zeile:

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

ausgelesen werden.
Das Raspberry Pi sollte nun 0x10 ausgeben.
Als letztes zeige ich euch noch ein paar Anwendungen, welche ich mit Hilfe des I²C realisiert habe:

-> Eine DS1307 als Uhr verwenden
-> Externer ADC & CapSense
-> I²C über Web
-> I²C Luftdrucksensor

 

-> Zurück zu den Basteleien mit dem Raspberry Pi

42 thoughts on “I²C
  1. 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

  2. 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 ;)

    • 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

  3. 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

    • 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

  4. 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 ! ! !

  5. 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

  6. 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

  7. Hey

    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

  8. 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

    • 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

  9. 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

  10. 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

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

Time limit is exhausted. Please reload CAPTCHA.