I/O Expander für Raspberry Pi

I/O Expander für Raspberry Pi Titelbild

I/O Expander am Pi

Der Chip ist groß und lang und hat viele Pins. Damit du weißt wo oben ist, gibt es auf der einen Seite eine halbrunde Kerbe. Achte darauf, dass diese nach oben zeigt. Um den Chip am Pi zu verwenden, brauchen wir nur zwei GPIO Pins für die SPI-Daten, dazu 3,3V und GND. Schließe den Chip so an, wie auf dem Bild zu sehen ist und orientiere dich an der Tabelle, falls etwas unklar ist.














Raspberry Pi I/O ExpGroundander
3,3V Bein 9 unten, Bein 11 oben
GND Bein 10 unten, Bein 12,13,14 oben
SDA Bein 13
SCL Bein 12

SPI aktivieren

Öffne die Raspberry Pi Konfiguration mit dem Befehl sudo raspi-config und aktiviere unter Punkt 5 Interfacing Options die Option P5 I2C .

Nach dem Anschließen des Chips an unseren Pi testen wir, ob dieser erkannt wurde. Dafür nutzen wir den Befehl

i2cdetect -y 1

Die Ausgabe sollte so aussehen:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: 20 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                       

Die 20 zeigt uns an, dass der Chip erkannt wurde und welche ID das i2c Device des Chips hat. Das brauchen wir gleich, um ihn anzusprechen.

Jetzt legen wir los und schauen uns die Pins des Chips an. Auf der linken Seite haben wir die Pins GPB und auf der rechten Seite sind die Pins GPA . Von beiden gibt es acht Stück, insgesamt 16 Pins.

Wie gesagt, links befinden sich die acht GPB Pins, nummeriert von 1 bis 8. Auf der anderen Seite sind die GPA Pins, bei denen von unten nach oben gezählt wird, also von 21 bis 28. Die jeweils acht Pins werden binär angesprochen, also mit 0 oder 1. Das bedeutet, dass wir keinen Pin einzeln steuern können, sondern den Zustand aller acht Pins übergeben müssen. Die Pins können daher nur an (1) oder aus (0) sein.

Sollen alle Pins aus sein, wäre dies also 00000000 Pin 1 an ist 00000001 Pin 2 an ist 00000010 Pin 8 und 7 an ist 11000000

Die acht GPA und acht GPB Pins können wir unabhängig voneinander schalten.

Zum Testen nehmen wir eine LED und schließen diese an GPB0 und GND (Ground) an.

LED I/O Chip
Langes Bein Pin 1
Kurzes Bein GND

Bevor wir diese jetzt schalten können, müssen wir dem Chip sagen, wie er die Pins behandeln soll, als Eingang oder als Ausgang.

i2cset -y 1 0x20 0x01 0x00
i2cset -y 1 0x20 0x00 0x00 

Mit diesen beiden Befehlen legen wir fest, dass alle Pins Ausgänge sind. Bitte beachte, dass du diese beiden Befehle nach jedem Neustart eingeben musst, um den Chip zu aktivieren ! Wie der Befehl aufgebaut ist, erklären wir gleich, denn den selben Befehl nutzen wir auch, um die Pins zu schalten.

Mit i2cset steuern wir den Chip. Der Befehl ist wie folgt aufgebaut.

i2cset -y I2CBUS CHIP-ADDRESS DATA-ADDRESS VALUE
i2cset -y 1 0x20 0x15 0x01


Die 1 steht für das i2c Device am Pi. Die alten Modelle bis B+ verwenden anstatt der 1 bitte die 0. Die CHIP-ADDRESS ist die Adresse des Chips, die wir oben mit dem Befehl i2cdetect -y 1 ermittelt haben. DATA-ADDRESS ist der Bereich, den wir schalten wollen und VALUE ist der Zustand aller acht Pins, den wir als Hex-Wert übergeben.

Unsere 16 Pins unterteilen sich in GPB und GPA GPA hat die DATA-ADDRESS 0x14 GPB hat die DATA-ADDRESS 0x15

Unsere LED haben wir an GPB0 angeschlossen. Um diese nun zum Leuchten zu bringen, wäre der Befehl also folgender:

i2cset -y 1 0x20 0x15 0x01

Eine LED an GPA Pins können wir mit dem Befehl ì2cset -y 1 0x20 0x14 0x01 aktivieren. Jetzt weißt du, wie man die GPA und GPB Pins ansteuert. Wir senden über unser i2c Device, 1 an den Chip 0x20 für die GPB Pins 0x15 die Werte 0x01. Das 0x01 ist der Hexadezimalwert von 00000001 . Pin 1 ist an, und der Rest der acht Pins ist aus. Die Darstellung in 1 und 0 heißt binär und begegnet uns ständig in der IT-Welt. Da diese Werte aber sehr lang sind und teilweise umständlich zu lesen, werden sie gerne in hexadezimal ausgegeben.

Damit wir verstehen wie das funktioniert, schauen wir uns das im Detail an.

Der binäre String wird in hexadezimal an unseren Chip übergeben. Wir müssen also unsere Zahlen umwandeln in einen Hexadezimalwert. Zum Glück gibt es dafür schon eine Funktion in Python. hex(). Unser Wert ist 00000001 . Das ist keine Zahl, sondern eine folge von AUS und AN. Jeder dieser Werte ist ein Bit. Ein Bit kann 0 (aus) oder 1 (an) sein. 8 bit ergeben ein Byte. Python denkt dass 00000001 eine Zahl ist und Python3 stört sich an den führenden Nullen. Deswegen müssen wir Python sagen, dass es sich um Bits handelt. Das machen wir über eine Integer Definition. Dabei definieren wir nicht nur die Variable als Integer, sondern setzen auch den base Wert. Dieser definiert die Anzahl möglicher Zeichen, die benutzt werden. Ein Base-Wert von 1 würde bedeuten, dass nur 0 benutzt werden kann. Base 2 sind 1 und 0, also genau das, was wir brauchen. Jetzt werden die 0 auch nicht mehr ersetzt, sondern sind ein valider Wert.

int(“00000001”,2)

Diesen Integer wollen wir in hexadezimal umrechnen. Schreibe dir ein kleines Script mit folgendem Inhalt:

print (hex(int("00000001",2)))

Wenn du das Script ausführst, ist das Ergebnis

0x1

Leider gibt es dabei ein kleines Problem bei der Ausgabe. Wir brauchen den Wert mit vier Stellen, zum Beispiel 0x01 für 00000001 . Die hex() Funktion gibt uns aber 0x1, das ist auch richtig, aber wir brauchen eine 0 mehr.

Man könnte sich eine Tabelle machen oder alle Werte auswendig lernen, aber wir wollen es eleganter lösen. Dafür schreiben wir uns eine kleines Script mit Python.

hexwert = input("Bitte Wert eingeben: ")

hexwert = (hex(int(hexwert,2)))
print (hexwert)
if len(hexwert) != 4 :
 hexwert = hexwert.replace("x", "x0")
print (hexwert)

In Zeile eins definieren wir den Wert von der Variable hexwert als Benutzer-Eingabe. Das, was der Benutzer eingibt, wandeln wir dann um in den Hexadezimalwert. Diesen geben wir in Zeile vier aus. In Zeile fünf prüfen wir mit der if Funktion, ob die Länge len(hexwert) != (also nicht) vier Zeichen lang ist. Wenn die Länge nicht vier ist, ersetzen wir mit der Funktion hexwert.replace(“x”, x0”) das x durch x0 Am Ende geben wir die Variable noch einmal aus.

Wow, was für ein Aufwand! Aber dieses kleine Script macht unsere Arbeit viel einfacher. Wenn du jetzt die Pins schalten möchtest, musst du dir nur den binären Wert überlegen und mit dem Script übersetzen. Kommen wir zurück zu unserem I/O Expander Chip.



Wir wollen LEDs leuchten lassen!

Verbinde mehrere LEDs mit den GPB Pins und GND und nutze den folgenden Befehl, um die LEDs leuchten zu lassen.

i2cset -y 1 0x20 0x15 0x01

Das 0x01 kannst du frei ersetzen durch die Werte aus deinem Script. 0xff schaltet zum Beispiel alle Pins an. Das wäre der Binärwert 11111111.

i2cset -y 1 0x20 0x15 0xff

i2cset ist ein Programm, das wir im Terminal aufrufen. In unserem Python Programm wäre das umständlich, daher wollen wir das anders lösen. Dafür gibt es eine fertige Bibliothek und das übergeben der Daten ist genauso wie bei i2cset.

import smbus
bus = smbus.SMBus(1)
bus.write_byte_data(0x20, 0x15, 0x00)

Zeile eins lädt die Bibliothek. Zeile zwei definiert den MSBus, für alte Modelle bis B+, benutzt du bitte bus = smbus.SMBus(0). Zeile drei übergibt die drei Werte in den Klammern genauso wie bei i2cset.

Jetzt weißt du, wie man den Chip anspricht und kannst alle Pins in beliebiger Konstellation ansprechen. Im nächsten Schritt nutzen wir das, um unsere zwölf LEDs als Stundenanzeige zu programmieren.

Noch Fragen oder Feedback?

Bevor du eine Frage stellen kannst musst du dich zuerst Anmelden oder Regestrieren!