SPI

Raspberry Pi Hier zeige ich euch wie ihr das SPI Interface eures Raspberry Pis verwenden könnt. Das SPI Interface stellt neben dem I²C Bus eine weitere Möglichkeit dar um zusätzliche Bausteine oder Mikrocontroller an den kleinen Computer anschließen zu können.

-> SPI aktivieren:

Vor der eigentlichen Softwareinstallation wird erst einmal die bereits vorhandene Software auf dem Raspberry Pi aktualisiert:

Als nächstes muss das SPI Modul von der Blacklist gestrichen werden. Dazu wird einfach der Befehl

eingegeben und der Eintrag blacklist spi-bcm2708 gelöscht. Danach wird die Datei gespeichert und geschlossen.
Um das SPI Modul im Kernel zu aktivieren, müsst ihr folgenden Befehl eingeben:

Anschließend kann das Modul verwendet werden. Da das Modul nach jedem Neustart erneut aktiviert werden muss, ist es ratsam diesen Vorgang zu automatisieren (ich habe den Befehl dafür einfach in die Datei /etc/rc.local geschrieben).
Für die Einbindung des SPI-Moduls in ein Programm verwende ich das Python Modul spidev, welches sich wie folgt installieren lässt:

Für die Installation werden noch Python Entwicklungswerkzeuge benötigt, welche ihr ggf. vorher installieren müsst:

Jetzt ist der SPI-Bus einsatzbereit. Schauen wir mal wie man den SPI verwendet, indem wir versuchen einen SPI-DAC anzusteuern.

-> Der erste Versuch mit dem SPI-DAC MCP4812:

Der DAC wird wie folgt mit dem Raspberry Pi verbunden:SPI(1) Für den Chip Select des DAC kann wahlweise ein normaler GPIO oder  der Pin CE0 bzw. CE1 verwendet werden.
Werden die Pins CE0 oder CE1 verwendet, können die Daten später mit den Python Methoden xfer1() oder xfer2() versendet werden.
Wird ein normaler GPIO für den Chip Select verwendet wird, muss dieser händisch auf Masse gezogen werden, was einem aber die Möglichkeit gibt mehr als zwei SPI-Bausteine an das Raspberry Pi anzuschließen.
Für mein Beispiel verwende ich den GPIO 25 als Chip Select.
Im ersten Schritt wird der SPI-Bus 0.0 initialisiert und verfügbar gemacht:

Jetzt können auch direkt schon Daten gesendet werden. Als erstes ziehe ich den Chip Select auf Masse damit der DAC weiß, dass die nächsten Daten für ihn bestimmt sind:

Danach kann ich den DAC mit Daten füttern. Die Daten sind in einer Liste, welche aus zwei 1 Byte Einträgen besteht, gespeichert.

Das erste Byte ist das MSB (Most Significant Byte) und das zweite Byte ist das LSB (Least Significant Byte).

Die übertragenen Daten sind wie folgt aufgebaut: SPI(2) Ich konfiguriere den DAC also wie folgt:

  • Kanal A
  • GA = 0, d.h. Sel = 2
  • Active mode operation
  • Dann kommen vier Bits für die Spannung und das erste Datenbyte wäre damit voll.
  • Zu letzt werden die restlichen Bits für die Spannung übertragen. Ich setze hier einfach alle Bits auf 1, wobei die letzten beiden niedrigsten Bits ohnehin ignoriert werden. Die können genau so gut auch 0 gesetzt werden ohne das sich was an der Spannung ändert

Die Spannung, die der DAC ausgibt, kann nach folgender Formel berechnet werden:

Latex formula

Die Werte sind wie folgt vergeben:

  • VRef = Interne Spannugnsreferenz von 2,048V
  • Sel = 1, bei GA = 0 und 2, bei GA = 1 gesetzt wird.
  • Spannung = Der digitale 10-Bit Wert, der an den DAC übertragen wird.

Nach dem Übertragen der Daten kann der Chip Select wieder auf High gezogen werden, wodurch die Übertragung beendet wird:

Jetzt kann das Programm gestartet werden. Das Programm läuft einmal durch und konfiguriert den DAC:

SPI(3)
Der DAC gibt darauf hin eine Spannung aus, die so lange gleich bleibt bis ein neuer Wert in den DAC geschrieben wird.
Mit eurem Multimeter solltet ihr jetzt eine Spannung von etwa 2,04V messen können. Je nach Multimeter werdet ihr etwas mehr oder etwas weniger messen. Das kommt auf die Genauigkeit des Messmittels an.

 

Dokumentation:

 

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

15 thoughts on “SPI
  1. Hallo !
    Bist Du mit dem SPI Bus weitergekommen ? Ich habe den Portexpander MPC23s17 mit dem Raspberry verbunden. Ich möchte gerne eine Webschnittstelle wie Webiopi verwenden. Hast Du hier eine Lösung ?

    >Schöne Grüße
    Thomas

    • Hey,

      ja, ich hatte schon ein paar Versuche gemacht (allerdings mit einem DAC).
      Als Programmiersprache habe ich Python benutzt. Brauchst du dabei Hilfe?

      Gruß
      Daniel

  2. Hallo,
    Ich versuche auch an den SPI Bus einen ADC und einen CAN Controller anzuschließen. Habe als CS jedoch die vorgesehenen CS des RPI benutzt. Leider kommt bei mir nichts raus. Deswegen die Frage ob bei dem Befehl
    SPI.open(0, 1)
    der CS automatisch auf Low gezogen wird, oder muss ich das noch manuell machen?

  3. Hallo,

    habe mir im Dez. 2014 einen Raspberry geholt und wollte die SPI-Schnittstelle nutzen. Dabei bin ich hier auf deine Internetseite gestoßen. Ich habe nun alle Schritte bis „$ sudo python setup.py install “ gemacht. Auch den Schritt danach, da er beim setup mit einem Error abbricht. Nun habe ich weiter gesucht und auf manchen Seiten ein Problem mit der SPI-Schnittstelle gefunden. Kann das auch bei mir das Problem sein? D.H. funktioniert das Skript nur bei älteren Modelen?
    Danke!
    DAVE

    • Hallo Dave,

      kannst du mir einen Screenshot des Fehlers schicken? (am besten per Mail)
      Dann schaue ich mir das mal an. Ich habe bisher noch von keinen SPI Problemen gehört…

      Gruß
      Daniel

      • Hi Kampi,
        Mit dem ADC MAX192 klappts auch ganz gut :-)
        Datasheet
        (Kostenlose Muster gibt’s bei Maxim für Selbstständige)

        Er misst 0V – 4,095V (Vref) – Kondensatoren am Vref nicht vergessen.
        Er benötigt 5V und daher einen Spannungsteiler an MISO (Master in Slave out)

        Gesendet wird ein Statusbyte res1 = ‚1xxx 1111‘ und 2x ‚0000 0000‘ mit Antwort res2 und res3. Wobei xxx die Wahl des Analogeingangs ist und res2 und res3 den Messwert enthalten.

        Einzig den CE0 GPIO8 kann ich mit spi.xfer2 oder spi.xfer nicht nutzen. Wie kann ich es machen, dass er erst nach den 3 Byte den CE schaltet? Bin Python-Neuling.

        ralphi

        • Hey Ralphi,

          in diesem Fall musst du den IO einfach händisch schalten, sprich per IO-Lib auf High und Low setzen :)
          Damit sollte das problemlos gehen.

          Gruß
          Daniel

Schreibe einen Kommentar

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

Time limit is exhausted. Please reload CAPTCHA.