MCP3008: Am Raspberry Pi analoge Signale auslesen

21. Juli 2016
28 Comments

Viele der ursprünglich für den Arduino entwickelten Sensoren bieten keine digitale Schnittstelle und sind nur analog auslesbar. Das Problem dabei besteht, dass der Raspberry Pi mit seinen GPIOs keine analogen Signale auslesen kann, weshalb man einen Analog-Digital Converter (ADC) wie den MCP3008 benötigt. Damit können bis zu 8 analoge Eingänge über den SPI Bus am Raspberry Pi ausgelesen werden.

In diesem Artikel gibt es eine Erklärung sowie eine Python Klasse, womit die Signale aller analogen Sensoren und Module ausgelesen werden können.

Eine Möglichkeit besteht natürlich darin einen Arduino mit dem Raspberry Pi zu verbinden, da dieser auch analoge IO Pins hat und somit ohne ADC jene Signale auslesen kann. Wie das funktioniert ist ausführlich im verlinkten Tutorial beschrieben. Der Nachteil darin besteht allerdings darin, dass man zum einen noch einen weiteren Mikrocontroller hat und dass dieser nicht über Python ansprechbar ist. Da Python sich vor allem als Einsteiger Programmiersprache eignet, nutzen auch die meisten Tutorials dieser Seite Python. Ein Arduino hingegen wird mit C++ programmiert.

 

Mögliches Zubehör

Neben dem MCP3008 ADC solltest du noch Jumper Kabel und ein Breadboard haben.

 

 

Darüber hinaus gibt es sehr viele Sensoren bzw. Module, welche nur analog augelesen werden können, wie z.B.:

Zu den meisten dieser Module findest du auf dieser Website auch ausführlichere Anleitungen und/oder Projekte, welche diese verwenden. Wenn du diesem Tutorial folgst wirst du allerdings auch jeden anderen analogen Sensor / Modul auslesen können.

 

Unterschiede zwischen Analog und Digital

Bei digitalen Signalen gibt es immer nur zwei Zustände: AN/HIGH oder AUS/LOW (1 oder 0). Wenn man von einer maximalen digitalen Eingangsspannung von 5V ausgeht so würde jeder Wert zwischen 0V und 0.4V als LOW Pegel erkannt und ein Wert zwischen 2.4V und 5V als HIGH Pegel. Alle Werte dazwischen sind undefiniert. Legt man eine solche Spannung an würde das Signal zufällig als 0 oder 1 erkannt werden. Da das aber nicht konsistent ist, sollte ein digitales Signal nie in dieser Grauzone liegen.

Im Gegensatz zu digitalen Signalen kann ein analoges Signal auch Zwischenwerte annehmen, es ist also nicht eindeutig definiert. So können z.B. prozentuale Werte angegeben werden (Wert ÷ anliegende Spannung), was viele analoge Sensoren ausnutzen.
Um diese Spannung am Raspberry Pi auslesen zu können, muss ein Analog-Digial Wandler wie der MCP3008 verwendet werden. Dieser gibt jedoch keine Werte in Volt an, sondern eine Zahl zwischen 0 und 1023, was 10 Bit entspricht (2^10). Dabei kann man die Spannung wie folgt feststellen:

(ADC Wert ÷ 1023) * Spannung

Wird der analoge Sensor mit einer Spannung von 3.3V betrieben und ein Wert von 789 wurde ausgelesen, so entspricht die anliegende Spannung 2.54 Volt.

 

 

Verbindung zwischen Raspberry Pi und MCP3008

Raspberry Pi MCP3008 Pinout

Auf der linken Seite des MCP3008 befinden sich die 8 analog auslesbaren Kanälen.

Die einfachste Methode einen Analog-Digital Konverter anzusprechen ist den SPI Bus zu verwenden. Hierbei können alle 8 anliegenden Signale mit einer Abfrage ausgelesen werden und umgewandelt werden können.

Wie im Datenblatt zu sehen ist, verträgt der ADC eine Eingangsspannung zwischen 2.7V und 5V. Da die GPIOs mit 3.3V arbeiten und bei höherer Spannung kaputt gehen könnten, sollte der MCP3008 auch nur mit 3.3V betrieben werden. Solltest du ein analoges Modul verwenden, welches eine höhere Eingangsspannung als 3.3V hat (und diese auch weitergeben kann) musst du unbedingt sichergehen, dass diese den ADC nicht erreichen. Dafür können z.B. Vorwiderstände verwendet werden und dies ggf. im weiteren Verlauf (Berechnungen etc.) beachtet werden.

Die Verbindung zum Raspberry Pi ist recht einfach, da nur jene GPIOs verwendet werden, welche auch für den SPI Bus sind:

RaspberryPi MCP3008
Pin 1 (3.3V) Pin 16 (VDD)
Pin 1 (3.3V) Pin 15 (VREF)
Pin 6 (GND) Pin 14 (AGND)
Pin 23 (SCLK) Pin 13 (CLK)
Pin 21 (MISO) Pin 12 (DOUT)
Pin 19 (MOSI) Pin 11 (DIN)
Pin 24 (CE0) Pin 10 (CS/SHDN)
Pin 6 (GND) Pin 9 (DGND)

 

Schematisch sieht die Verbindung dann wie folgt aus, wobei ich explizit keinen Sensor auf die rechte Seite gestellt habe, da alle digitalen Signale so ausgelesen werden können:

Raspberry Pi MCP3008 ADC Anschluss

 

Vorbereitung

Bevor die Werte nun ausgelesen werden können, müssen die Packetquellen aktualisiert werden und eine Bibliothek für SPI installiert werden und natürlich der SPI Bus aktiviert werden, da dieser standardmäßig in Raspbian deaktiviert ist.

Fangen wir damit an die Pakete zu aktualisieren und die Python Developer-Tools zu installieren:

sudo apt-get update 
sudo apt-get upgrade
sudo apt-get install python-dev

Anschließend können wir die SpiDev Bibliothek herunterladen, entpacken und installieren:

wget https://github.com/doceme/py-spidev/archive/master.zip 
unzip master.zip
cd py-spidev-master
sudo python setup.py install

Zu guter Letzt muss der SPI Bus noch aktiviert werden, falls noch nicht geschehen. In Raspbian Jessie (und anderen darauf basierenden Betriebssystemen) kann mittels sudo raspi-config die Konfiguration des Raspberry Pi’s verändert werden. Unter dem Punkt „Advanced Options“ findet sich die Option „SPI“. Dort aktivierst du SPI und startest anschließend das System neu (falls keine entsprechende Abfrage kommt: sudo reboot).

 

 

Python Klasse für den Raspberry Pi ADC MCP3008

Die folgende Klasse ermöglicht er dir einfach auf den MCP3008 ADC zuzugreifen. Entweder kannst du die Datei dazu hier downloaden oder mittels sudo nano MCP3008.py erstellen und folgenden Code einfügen:

 

Du kannst diese Datei nun in alle deine Projekt Ordner einfügen und einfach einbinden:

Anschließend muss die Klasse einmal initialisiert werden und die 8 analogen Channels können ausgelesen werden:

Nun sollte nichts mehr im Wege stehen alle möglichen Arduino / Genuino Module auch am Raspberry Pi zu betreiben.

28 Kommentare

  1. Sehr schönes tutorial,
    Frage zu: „… so würde jeder Wert zwischen 0V und 0.4V als LOW Pegel erkannt und ein Wert zwischen 2.4V und 5V als HIGH Pegel.“
    Wieso denn 0.4V ?? Gruß und Danke

    Antworten
  2. Hallo,
    es wäre schön, wenn man auch noch einen Schaltplan dazu machen könnte, damit man das besser versteht. Aber sonst ist alles sehr gut erklärt. Übrigens der Link zum Datenblatt funktioniert nicht.

    Gruss
    Berthold

    Antworten
  3. Warum wird hier nicht das GPIOZERO verwendet. Finde ich am einfachsten.
    Ist im Magpi Juli auch gut erklärt.

    Antworten
    • Hallo Olli,
      Für SPI Sensoren brauchst du den MCP3008 nicht, da SPI bereits digitale Signale liefert. Allerdings habe ich bereits einige Tutorials mit SPI Sensoren gemacht 🙂

      Antworten
  4. Hi felix,
    man kann ja 2 spi „geräte“ ansteuern???

    wenn ich den mcp3008 an ce1 also gpio7 anschließe, muss ich dann nur bus=1 und device=1 ändern

    Hauschi

    Antworten
  5. was bedeutet (Anschließend muss die Klasse einmal initialisiert werden und die 8 analogen Channels können ausgelesen werden)

    Antworten
  6. Kann man den Wert auch in einem PHP Skript abrufen, bzw. gibt es einen einfachen Weg diesen Wert zu übergeben?

    Antworten
  7. Hallo und danke für das Tutorial,
    ich habe ein merkwürdiges Verhalten mit diesem Aufbau.
    Ich nutzte den MCP3008 um die analoge Signale eines Feuchtigkeitssensor für Erde auszulesen.

    An dem Sensor sind LEDs um den Status zu erkennen (Power, digital Messung). Um Strom zu sparen bzw. um den Sensor zu schonen schalte ich den ein und aus. Jedoch leuchten o. klimmen die genannten LEDs wenn ich eine gemeinsame Masse (GND) mit dem MCP3008 habe.

    Bzw. ist das normal der der MCP3008 auch ohne Masse Funktioniert ? Es wird mir zwar ein Wert geliefert diese ist jedoch um ca. 0,4V unterschiedlich mit Masse.

    Ich hoffe meine Erläuterung kann man Verstehen ^^.
    Kann mir jemand dieses Verhalten erklären.

    Viele Grüße
    reisman

    Antworten
  8. Hallo Felix,

    ich habe von meiner Lüftersteuerung noch analoge Temperatursensorn übrig und in meinem WaKü-Kreislauf sind auch analoge Inline-Sensoren verbaut. Im Gegensatz zu deiner Skizze haben diese jedoch nur zwei Leitungen. Die VCC- und die DATA-Leitung. Beide haben keine GND-Leitung.
    Lasse ich in diesem Fall die GND-Leitung einfach weg, oder ist der Aufbau komplett anders ?

    Gruß, Sven

    Antworten
  9. Hi Felix , ich habe einen Raspberry Pi Zero w und habe mehrere Sensoren wie in deinen Tutorials beschrieben programmiert und die Programme gespeichert. Zum Beispiel habe ich am mcp3008 (der wie hier beschrieben programmiert ist ) einen Joystick , einen photowiderstand und einen photointerrupter angeschlossen . Des weiter habe ich einen Poti , den PIR , einen Taster und den mpu6050 Beschleunigungssensors angeschlossen und wie in den Tutorials programmiert.
    Zu meiner Frage :
    Wie kann ich in einem Programm , ( welches optimaler Weise beim booten startet ) alle diese Programme aufrufen und starten , sodass alle Sensoren aktiv sind und ich die Messwerte auslesen kann und wie kann ich mit den ausgelesenen werten weiter „arbeiten“ ?
    Mein Plan ist es , die Werte der Sensoren, MIDI Befehlen zuzuweisen , welche ich an mein MacBook sende und welche dann zum Beispiel effektparameter eines Synthesizers steuern. Ich habe schon irgendwo gelesen dass die Anwendung pygame Midi werte senden kann, allerdings weis ich nicht wie. Ich hoffe du kannst mir weiterhelfen und bedanke mich im Voraus .
    Gruß Ronnie

    Antworten
    • Wenn alle Module am MCP3008 hängen brauchst du nur ein Skript. Wenn du Python nutzt, so binde einfach die Klasse ein und frage die entsprechenden Kanäle ab. Ansonsten kannst du auch ein Skript erstellen, dass den Kanal als Eingabe bekommt und entsprechend den Wert abfragt. Mit Hilfe dieses Skripts kannst du ebenfalls in anderen Programmen arbeiten.

      Antworten
      • Und wie kann ich die abgefragten werte zu Midi befehlen wandeln ?

        Vielen Dank schonmal für deine schnelle Antwort

  10. Hallo,
    tolle Anleitung, Installation verlief erfolgreich. Ein erster Test mit einem Python-Skript namens „Read_from_MCP3008.py“ brachte einige Fehlermeldungen.
    Inhalt des Skripts sind die oben genannten Zeilen:

    from MCP3008 import MCP3008
    adc = MCP3008()
    value = adc.read( channel = 0 ) # Den auszulesenden Channel kannst du natürlich anpassen
    print(„Anliegende Spannung: %.2f“ % (value / 1023.0 * 3.3) )

    Beide Dateien (Read_from_MCP3008.py und 3008.py) liegen im selben Verzeichnis /root.

    Die Ausgabe lautet:

    root@raspberrypi:~# bash Read_from_MCP3008.py
    from: can’t read /var/mail/MCP3008
    Read_from_MCP3008.py: Zeile 2: $’\r‘: Kommando nicht gefunden.
    Read_from_MCP3008.py: Zeile 3: Syntaxfehler beim unerwarteten Wort `(‚
    ‚ead_from_MCP3008.py: Zeile 3: `adc = MCP3008()
    root@raspberrypi:~#

    Woher kommt der Verweis auf /var/mail/MCP3008 ?
    Sollte hier die Datei MCP3008.py liegen?
    Hab ich probiert, ändert aber nix daran.

    Wer kann helfen?
    Danke!

    Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!