Raspberry Pi Interfaces - [Teil 2]

Die Schnittstellen des Raspberry Pi - [Teil 2]

Nachdem wir im ersten Teil gesehen haben, wie man in der Konfiguration des Raspberry Pi anstelle der einfachen Ein- und Ausgänge (GPIOs) schnelle elektronische Bussysteme aktiviert, möchte ich an dieser Stelle den Schwerpunkt auf das „Serial Peripheral Interface (SPI) legen. Dieser Bus benötigt insgesamt vier Datenleitungen zwischen Raspberry Pi und dem elektronischen Baustein, der angeschlossen werden soll. Diese Anschlüsse haben so einprägsame Namen wie MOSI, MISO, CLK und CE.

MOSI steht dabei für Master Out Slave In, es ist also eine Datenleitung vom Master (Raspi) zum Slave (z.B. MCP3008). Dieser Anschluss liegt an Pin 19, GPIO10 ist dann deaktiviert.

MISO steht für Master In Slave Out, es ist die Datenleitung vom Slave zum Master. Dieser Anschluss liegt an Pin 21, GPIO09 ist dann deaktiviert.

CLK steht für Clock. Der Master gibt die Datenrate bzw. Übertragungsgeschwindigkeit vor. Die Datenübertragung erfolgt synchron. Dieser Anschluss liegt an Pin 23, GPIO11 ist dann deaktiviert.

Während beim I2C-Bus die Adresse des Geräts, mit dem der Datenaustausch stattfinden soll, als erstes Byte gesendet wird, signalisiert der SPI-Master dem Slave die Verbindungsaufnahme durch Aktivieren der vierten Leitung, die unter verschiedenen Namen bekannt ist: Chip Enable CE, Chip Select CS oder Slave Select SS, gefolgt von einer Zahl. Am Raspberry Pi können wir an CE0 (Pin 24) und CE1 (Pin 26) jeweils unterschiedliche Slaves anschließen.

Einen ersten Einblick in die Einstellmöglichkeiten und Protokolle von SPI kann man bei Wikipedia nachlesen. https://de.wikipedia.org/wiki/Serial_Peripheral_Interface  
Der Entwickler von elektronischen Bausteinen muss sich sicherlich auch mit Datenblättern quälen, aber als Anwender wird uns heute weitestgehend geholfen, so dass wir nur auf die richtigen Anschlüsse achten müssen.

Der MCP3008 ist beispielhaft ein Analog-Digital-Wandler (ADC) aus einer großen Familie von ICs, die sich durch die Anzahl der integrierten Wandler (hier 8) und ggf. durch die Auflösung (8 Bit=256 Schritte, 10 Bit=1024 Schritte oder 12Bit=4096 Schritte) unterscheiden.

 


Die von mir verwendeten MCP3004 (mit 4 Kanälen) und MCP3008 (mit 8 Kanälen) haben eine Auflösung von 10 Bit, d.h. bei einer Referenzspannung von 3,3V messen sie auf ca. 3mV genau. Mit einem Spannungsbereich von 2,7V bis 5,5V ist der Chip sowohl für die Raspberry Pi-Familie als auch die Arduinos geeignet (aber die haben ja analoge Eingänge).

Auf dem ersten Bild erkennen wir sofort die analogen Eingänge (Kanäle) mit den Bezeichnungen CH0 bis CH3 bzw. CH0 bis CH7. Etwas schwieriger sind die übrigen Bezeichnungen. Wir haben zweimal zwei Pins für Spannungseingänge: VDD und DGND sind für die Spannungsversorgung des ICs; VREF und AGND sind die Eingänge für die Referenzspannung. Im Beispiel schließen wir VDD und VREF an 3,3V und DGND und AGND an GND des Raspi, aber man hat die Option auf eine unterschiedliche Referenzspannung.

Die Pins mit den Bezeichnungen CLK, DOUT, DIN und CS/SHDN werden mit der SPI-Schnittstelle des Raspi verbunden: CLK mit Pin 23 (SPI_CLK), DOUT (also slave data out) an Pin 21 (MISO), DIN (slave data in) an Pin 19 (MOSI) sowie CS/SHDN (Chip Select/Shutdown) an Pin 24 (CE0).

In einem praktischen Beispiel möchte ich die Farbe einer RGB-LED mithilfe von drei Potentiometern einstellen. RGB steht für die jeweiligen Farbanteile Rot, Grün und Blau. Tatsächlich sind drei LEDs auf engstem Raum verbaut, so dass man bereits in kurzer Entfernung nur noch die gemischte Farbe sieht.



 
Achtung: Es gibt zwei grundsätzlich verschiedene Ausführungen von RGB-LEDs, die man insbesondere an den einfachen Ausführungen nicht erkennen kann. Gemeinsam ist beiden Ausführungen, dass das längste der vier Beinchen der gemeinsame Anschluss für die drei Farbanteile ist. Das einzelne Beinchen (hier oberhalb des längsten Beinchens) ist der Anschluss für Rot.  Also von oben nach unten Rot – Common (der gemeinsame Anschluss) – Grün – Blau. Nun zu dem Unterschied: Es gibt Common Anode und Common Cathode RGB-LEDs. Im ersten Fall ist das längste Beinchen der gemeinsame Pluspol, im zweiten Fall der gemeinsame Minuspol. Bei der SMD-Variante auf dem Breakoutboard erkennt man deutlich das Minuszeichen, also Common Cathode.

Hier nun der Schaltplan für den Versuchsaufbau:


Die Drehpotentiometer liegen jeweils zwischen 3,3 V und GND. Sie sollten deshalb mindestens 1 kOhm groß sein, gerne auch mehr. Und selbstverständlich benötigt auch die RGB-LED Vorwiderstände für alle drei Farbanschlüsse (220 bis 330 Ohm).

Und hier der Python-Code, der dank des Programm-Moduls gpiozero sehr kurz ausfallen kann. gpiozero ist eine junge Programmbibliothek und für mich ein Musterbeispiel für Objekt-orientiertes Programmieren (OOP). Wir importieren zunächst die Klassen gpiozero.RGBLED und gpiozero.MCP3008.

gpiozero.RGBLED erbt zunächst die Eigenschaften und Methoden von der Klasse DEVICE und ergänzt sie um die spezifischen Methoden für die RGB-LED. Anstelle der häufig verwendeten Farbwerte zwischen 0 und 255 bzw. hexadezimal 0xFF geben wir für die Farbkanäle normierte Werte zwischen 0 und 1 an. Und auch die Methode value aus der Klasse gpiozero.MCP3008 liefert uns normierte Werte der Potentiometer im Bereich 0 bis 1. Wir brauchen deshalb nicht darüber nachzudenken, den 10‑Bit-Wert der Spannung am Poti-Abgriff in einen 8‑Bit‑Wert für den Farbanteil umzurechnen/zu skalieren.

Nach dem Import der Klassen werden die Objekte led für die RGB-LED, red_pot, green_pot und blue_pot für die drei Potentiometer instanziiert. In einer Endlosschleife wird den jeweiligen Farbanteilen der Wert (value) des dazu gehörigen Objekts zugeordnet. Mit der Befehlsfolge try: und except: wird verhindert, dass das Programm nach dem sogenannten Keyboard Interrupt (Strg + C) mit einer Fehlermeldung endet.

 
from gpiozero import RGBLED, MCP3008

led = RGBLED(red=17, green=27, blue=22)
red_pot = MCP3008(channel=0)        # oder MCP3008(0)
green_pot = MCP3008(channel=1)      # oder MCP3008(1)
blue_pot = MCP3008(channel=2)       # oder MCP3008(2)

try:
    while True:
        led.red = red_pot.value
        led.green = green_pot.value
        led.blue = blue_pot.value

except KeyboardInterrupt:
    print("... und tschüß!")

 

Link zur Dokumentation gpiozero:
https://readthedocs.org/projects/gpiozero/downloads/pdf/stable/

Zum Schluss noch ein bisschen Theorie zu den Farbanteilen, die wir mischen wollen. Jede Farbe kann einen Wert zwischen 0 und 255 (bzw. hexadezimal 0xFF) annehmen, also je Farbkanal 2 hoch 8 Möglichkeiten. Hier ein paar einfache Kombinationen:

Rot-Anteil

Grün-Anteil

Blau-Anteil

Mischfarbe

FF

00

00

rot

00

FF

00

grün

00

00

FF

blau

FF

FF

00

gelb

FF

00

FF

magenta

00

FF

FF

cyan

FF

FF

FF

weiß


Bei gleichmäßigen Farbanteilen erhalten wir 256 Graustufen zwischen schwarz (0x000000) und weiß (0xFFFFFF). Wer schnell rechnen kann, weiß schon, dass es grundsätzlich 16,7 Millionen (2 hoch 24) Möglichkeiten gibt. Bitte erwarten Sie das nicht von unserer RGB-LED. Die kann nicht mithalten mit den Farbvariationen auf dem Bildschirm, z.B. bei

https://www.w3schools.com/colors/colors_rgb.asp

Soviel zum Serial Peripheral Interface als Schnittstelle des Raspberry Pi zur analogen Welt. Eine andere Einsatzmöglichkeit werde ich in einem Blog über Spiele-Controller vorstellen.

Einen Kommentar hinterlassen

Alle Kommentare werden vor der Veröffentlichung moderiert