Analogwertverarbeitung mit dem MCP3008

Der Analog- / Digitalwandler MCP3008

Der Raspberry Pi hat von Haus aus keine analogen Ein- und Ausgänge. Alle verfügbaren Ausgänge sind digital.
Das bedeutet, man kann nur einen Wert von 0 oder 1 darstellen. Low oder High, An oder Aus.

Werte die dazwischen liegen, können also nicht abgebildet werden. Stellt Euch z.B. einen Drehregler vor, der die Lautstärke regeln soll. Dieser Regler soll auf kleinster Stufe 0% an den Raspberry Pi weitergeben, auf maximaler Stufe 100%. Alle dazwischenliegenden Schritte sollen so fein wie möglich erkennbar sein.

Dies schafft der Raspberry Pi nicht ohne externe Hilfe. Ein möglicher Kandidat wäre der
AD-Wandler MCP3008. Hierbei handelt es sich ebenfalls um ein Bauteil, welches über den SPI Bus kommuniziert. Das Bauteil wandelt analoge Spannungen an seinen acht Eingängen in binäre Daten um und überträgt sie per SPI zum Raspberry Pi.
Auch dies ist kein Hexenwerk und kann mit sehr geringem Python Programmieraufwand erledigt werden.

Sehen wir uns zuerst das Bauteil an. Das notwendige Datenblatt kann man sich hier ansehen:

http://ww1.microchip.com/downloads/en/DeviceDoc/21295d.pdf

Pinbelegung und Verdrahtung des MCP3008

Pinbelegung und Verdrahtung des MCP3008

Auf die Pins des Bauteils gehe Ich im einzelnen etwas genauer ein.

  • CH0 – CH7: Dies sind die acht verfügbaren Analogeingänge des Bauteils. Hier schließt Ihr
    die analogen Spannungen an. Im Schaltplan ist ein Poti eingezeichnet, über dem an CH0
    eine Spannung von 0 – 3,3 V abfallen kann.

  • VDD: Versorgungsspannung des Bauteils. Hiermit werden die interne Logik sowie die SPI Kommunikationstreiber versorgt. Das Bauteil verträgt eine Eingangsspannung von 2,7 V bis 5,5 V. Schließt hier allerdings immer 3,3 V an diesen Pin an, da die SPI Schnittstelle mit dem hier angelegten Pegel kommuniziert. Ein 5 V Pegel würde den Raspberry Pi zerstören!

  • VRef: Referenzspannung. Diese Spannung nutzt der AD-Wandler als Referenz für die anliegenden Eingangspannungen. Der Wert der Spannung ist sehr wichtig und sollte eine genaue stabile Spannung sein. Ebenfalls wichtig ist, dass der maximale Analogwert eines Eingangskanals die Referenzspannung niemals übersteigt. Daher nutze ich in diesem Beispiel die 3,3 V des Raspberry Pi als VDD, VRef sowie als maximalen Pegel am Eingangskanal.

  • AGND / DGND: Analoge und digitale Masse. Beide Anschlüsse legt Ihr in diesem Beispiel mit der Masse des Raspberry Pi zusammen.

  • CLK: Clock oder Serial Clock. Dieser Anschluss ist Teil des SPI Busses und wird mit dem SCLK Pin des Raspberry Pi verbunden

  • DOut: Data out. Hier sendet der MCP3008 die angefragten Bitwerte über den Bus.
    Angebunden wird dieser an den MISO Pin des Masters.

  • DIn: Data in. An diesem Anschluss empfängt der Baustein Daten des Masters und wird an MOSI des Raspberrys angeschlossen.

  • CS / SHDN: Chip Select / Shutdown. Hierbei handelt es sich wieder um den bekannten Chip Select Eingang. Beachtet, dass dieser Low-aktiv ist. Angeschlossen werden kann der Eingang an jeden freien GPIO Pin, oder an CE0 / CE1. Je nach genutzer Softwarefunktion.

Bevor wir mit dem Schreiben der Software beginnen, solltet Ihr Euch noch ein paar Gedanken über die erwarteten Daten machen.
Der MCP3008 hat eine Auflösung von 10 Bit. Dies bedeutet, dass die zu messende, analoge Spannung in 1024 Schritte unterteilt werden kann. Die kleinstmögliche Einheit errechnet Ihr mit folgender Formel:

VRef / 1024

In unserem Fall also:

3,3 V / 1024 = 0,003222 ~ 3,22 mV

Auflösung ausreichend? Macht Euch bewusst, ob diese Auflösung für Eure Zwecke ausreichend ist. Im Umkehrschluss bedeutet dies nämlich, dass Ihr Veränderungen die kleiner als 3,22 mV sind nicht wahrnehmen könnt. Ein Alternativbauteil wäre der MCP3208 mit einer Auflösung von 12 Bit. Führt Ihr die gleiche Rechnung mit 12 Bit durch, so kommt Ihr bereits mit zwei Bit höherer Auflösung und 3,3 V Referenzspannung, auf eine kleinstmögliche Einheit von 0,8 mV.

Die Nachfolgenden Abbildungen zeigen die notwendigen Informationen aus dem Datenblatt.
Der Ablauf einer Kommunikation wird in der Grafik Kommunikationsablauf verdeutlicht.

Bitfolgen für die SPI Kommunikation Quelle: Datenblatt des Herstellers

Bitfolgen für die SPI Kommunikation Quelle: Datenblatt des Herstellers

Kommunikationsablauf Quelle: Datenblatt des Herstellers 

Kommunikationsablauf Quelle: Datenblatt des Herstellers

 

 

 

 

 

 

 

Diese Informationen reichen um das Bauteil in der Software anzusprechen.

Ein Beispiel für CH0:

Zuerst muss das CS Signal auf Low gezogen werden,damit das Bauteil sich angesprochen fühlt.
Sofern Ihr xfer() oder xfer2() nutzt wird das bereits für Sie automatisch erledigt.
Nun senden wir zuerst das Startbit als 1. Darauf folgt das SGL/DIFF Bit ebenfalls in Form einer 1. Die nächsten drei Bit bestimmen den Kanal. Schaut dazu in Zeile 1 der Bitfolgentabelle aus dem Datenblatt. Für CH0 sendet Ihr 0 0 0. Alle darauffolgenden Bits sind “Don`t care”, also egal. Zuletzt sendet Ihr ein Dummybyte 0.
Daraus ergeben sich folgende Python-Funktionen als Beispiel für die unterschiedlichen, akzeptierten Schreibweisen:

# CH0 auslesen (Binär)
spi.xfer([0b0001, 0b10000000,0b0000])

# CH0 auslesen (Hex)
spi.xfer([0x01, 0x80,0x00])

# CH3 auslesen (Dezimal)
spi.xfer([1,176,0])

Es können Werte Binär, Dezimal, oder als Hexwert angeben.

Euer komplettes Python Programm für den im Schaltplan gezeigten Aufbau könnte nun wie folgt aussehen:

#!/usr/bin/python

import spidev
import time

spi = spidev.SpiDev()
spi.open(0,1)

while True:
antwort = spi.xfer([1,128,0])
if 0 < = antwort[1] <=3:
wert = ((antwort[1] * 256) + antwort[2]) * 0.00322
print wert ," V"
time.sleep(1)

Das Programm kurz möchte Ich kurz erläutern.
Die xfer() Funktion, fragt den Wert von CH0 an und speichert die drei zurückgegebenen Bytes in antwort.
Besonderheit bei SPI: Für jedes gesendete Byte wird eines empfangen, daher drei.

Diese liegen in der Variablen antwort als antwort[0] bis antwort[2],
Die Antwort des MCP3008 ist in zwei Byte gespeichert. Von den drei empfangenen Bytes,
benötigen wird die letzten beiden, Byte 0 interessiert uns nicht weiter. Das ergibt sich aus der Auflösung von 1024.
Ein Byte kann maximal einen Dezimalwert von 255 speichern. (Einschließlich 0).
Die Ausgabe des MCP3008 ist daher nach diesem Schema aufgeteilt:

Byte 1 Byte 2 Dezimalwert
0 10 10
0 195 195
0 255 255
1 10 266
1 200 456
2 0 512
3 255 1023

[Tabelle: Aufteilung von 1024 auf zwei Byte]

Ihr seht, dass der Wert von Byte 1 jeweils X × 256 zu Byte 2 hinzuaddiert werden muss um die den Maximalwert von 1023 darstellen zu können. Bedenkt, dass wir bei 0 mit dem
Zählen beginnen und der letzte Wert daher 1023 ist.

Während des Konvertierungsvorgangs, gibt das Bauteil teilweise willkürliche Werte für
Byte 1 aus. Wir wissen aber, dass dieses Byte mindestens 0, aber höchstens 3 sein darf.
Die if-Abfrage prüft genau dies ab. Liegt der Wert zwischen 0 und 3, so wird er mit 256
multipliziert. Byte 2 wird dem Produkt hinzuaddiert.
Durch die Muliplikation mit 0.00322 wird der Dezimalwert in die ensprechende Spannung umgerechnet.
Print gibt den Wert auf dem Bildschirm aus. Erwischt Ihr das Bauteil beim Abfragen allerdings während des Konvertierungsvorganges und Byte 1 beeinhaltet kurzzeitig einen willkürlichen Wert, so passiert nichts und die While-Schleife startet erneut. Die Ausgabe aktualisiert sich jede Sekunde.

[Ausgabe des Python Beispielprogammes. Im Screenshot wurde der Poti während den Abfragen im Wert verändert

[Ausgabe des Python Beispielprogammes. Im Screenshot wurde der Poti während den Abfragen im Wert verändert

Ihr könnt mit dem obigen Programm jeden der acht Eingänge abfragen, indem Ihr den entsprechenden Wert in der xfer() – Funktion ändert.

Erhältlich ist das kleine Bauteil z.B. bei Amazon oder etwas günstiger bei eBay.  Alternativ bieten sich Elektronikhändler wie Conrad oder Pollin an.

Dieser Beitrag stammt, etwas abgespeckt, aus unserem Buch Raspberry Pi – Das umfassende Handbuch. Im Buch finden sich neben der reinen Funktionsweise des Bausteins ebenfalls viele konkrete Anwendungsfälle, z.B. mit Sensoren. Zudem haben wir uns dort, unter anderem, den ebenfalls sehr hilfreichen ICs  MCP4811, MCP23017 oder dem digitalen Potenziometer MCP4132 gewidmet.

Ein Gedanke zu “Analogwertverarbeitung mit dem MCP3008

Kommentar verfassen