MCP3008: Am Raspberry Pi analoge Signale auslesen

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.

53 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
  11. Hallo Felix…

    Wie mach ich das denn mit dem mcp3208?
    Kann ich die mcp3008 klasse auch für den mcp3208 verwenden?
    Da ich höhere Spannungen messen möchte (über entsprechende Spannungsteiler) hätte ich auch gern 5V am Referenzeingang..
    Reicht das wenn ich zwischen den Raspi & dem mcp3208 nen pegelwandler schalte?
    Oder kann vref auch größer als vdd sein?
    Wie kann ich dann zwischen mehreren mcp3208 umschalten?

    Gruß

    Antworten
    • Ja, der MCP3008 sollte auch mit 5V zurecht kommen, allerdings musst du über einen Pegelwandler o.ä. dann sicherstellen, dass an die GPIOs nur 3.3V kommen.

      Antworten
      • Hallo Felix..
        Bei mir geht es um den MCP3208, der hat ne höhere Auflösung…
        Es geht mir erstmal um die Klasse die du oben beschrieben hast.. Da du die ja für den MCP3008 geschrieben hast, bin ich mir nicht sicher ob sie auch für den MCP3208 funktionieren würde..

        Das ich am Ende bei der Berechnung nen anderen wert als 1023.0 verwenden muss ist mir dabei klar…

        Gruß

      • Den MCP3208 habe ich noch nicht verwendet, daher kann ich dir das nicht pauschal sagen. Was für Daten hast du bereits ausgelesen?

  12. Hi Felix..

    Bisher leider noch gar nix.. Bin erst heute mal dazu gekommen den MCP3208 auf ein breadboard zu stecken & mit dem Raspi zu verbinden.. (Schande über mein Haupt)
    Nichts desto trotz hängt es dann mal wieder an der Klasse…
    Die muss wohl für den Gebrauch von mehreren mcp3208 erstmal entsprechend angepasst werden..
    Und wie genau funktioniert das mit dem ChipSelect??

    Und wenn mich nicht alles täuscht, muss man beim umrechnen des ADC Wertes mit 4095 rechnen.. (12 Bit Auflösung)
    also (adc Value / 4095) x Spannung.

    Ich hoffe ich hab das soweit erstmal richtig verstanden…

    Gruß Skipper

    Antworten
    • Mehr als zwei SPI Geräte kannst du nicht verwenden (zwei Chipselects). Richtig, bei 12 Bits musst du durch 4095 (bzw. (Wert+1)/4096) teilen.

      Antworten
  13. Hi Felix…
    Nur 2 SPI Devices? Oje, das wird wohl nicht ausreichen…
    ich brauch genug Eingänge um 11 Gleichspannungen und 17 Ströme (über Stromwandler) einlesen zu können… Mach quasi eine Anzahl von 4 MCP3208 wovon beim 4. nur 50% belegt sein wird…
    Aber zum Glück gibts den SC18IS602B (gerade mal gegoogelt und das teil gefunden)…
    Das ist ein I2C to SPI Converter, der es ermöglicht bis zu 4 SPI Devices an den I2C Bus zu hängen.. (Perfekt geeignet)
    Und da bis zu 8 I2C Devices am I2C Bus hängen können, geht für diese 4 SPI Devices auch nur eine I2C Adresse drauf.. Bleiben also noch 7 Adressen für die MCP23017 um die GPIO´s zu erweitern…
    #MonsterProjekt

    Wär doch evtl. was für Deine Tutorials, oder?

    Gruß Skipper…

    Antworten
  14. Hallo Felix,
    vielen Dank für die Anleitung! Leider funktioniert das Auslesen mit deiner Vorgehensweise bei mir nicht. Ich habe mich auf systematische Ursachenforschung begeben:
    – SPI aktiv (/dev/spidev0.0 und /dev/spidev0.1) vorhanden
    – analoges Sensorsignal mit Multimeter überprüft
    – Auslesen des MCP mit der adafruit-Bibliothek (https://learn.adafruit.com/raspberry-pi-analog-to-digital-converters/mcp3008) funktioniert

    –> Ich schließe somit Hardware- und Anschlussfehler aus…hast du eine Idee warum deine Anleitung nicht funktioniert?

    Beste Grüße, Georg

    Antworten
      • Danke für die Antwort! Das könnte sein, ich habe ein frisches Raspbian Stretch verwendet…da das Auslesen der Analogsignale mit der anderen Bibliothek funktioniert, werde ich es selbst nicht weiter verfolgen, wäre aber über detaillierte Informationen dankbar.

        Beste Grüße, Georg

  15. Prob
    Alles so aufgebaut, Software auch 1zu1 übernommen…

    Ohne angeschlossenen Sensor zeigt der Pi immer 3,3V Eingangsspannung an…
    Auch wenn ich den IC von der Stromversorgung trenne sagt der das trd noch.
    Dachte ich das könnte man bestimmt mit nem pull up/down Widerstand beheben…
    Aber,
    Wenn ich zb einen Lichtsensor anschließe sagt der ca 2,8V…und der Wert ändert sich nicht.
    Auch ein Poti erzeugt immer das gleiche Ergebnis.

    Liegt der Fehler bei mir/Software/Hardware?

    P.s. das gleiche Problem hatte ich bereits mit einem ADS1115(i2c…vllt kannst du zu dem Teil auch ein Tutorial machen, ist auch weit verbreitet), dass die Werte die rauskamen relativ zufällig waren auch wenn nix angeschlossen war.

    Antworten
    • Wenn selbst bei Potis der selbe Wert rauskommt, würde ich schwer davon ausgehen, dass entweder etwas mit der Verkabelung oder dem Sensor nicht stimmt.

      Antworten
  16. Hallo,
    ich habe leider noch keine Erfahrung mit python.
    ich habe jedoch das Beispiel so wie beschrieben umgesetzt und eine Spannung von 3.3V am Channel 0 angeschlossen.
    Leider bekomme ich als Ausgabewert immer nur „Anliegende Spannung 0.00“.
    Ich weiß nicht, woran dieses liegen könnte.
    Ich hoffe, mir kann jemand einen Tipp geben.
    Beste Grüße

    Antworten
      • Hallo Felix,
        vielen Dank für den Tipp. Ich habe es mir angeschaut und etwas rumgespielt. Ich bin mir jetzt sicher, dass das Programm funktioniert.
        Leider bekomme ich weiterhin keine plausiblen Werte. Ich habe Channel 1 und 4 mit 3.3V beschaltet. Ich bekomme jedoch immer die Werte 0 bzw. auf anderen Channel auch mal den Wert 0.82. Ich habe bereit den IC ausgetauscht. Leider ohne Veränderung. Könnte es an einer Konfiguration liegen?
        Ich habe die „SPI“ wie beschrieben aktiviert.

  17. Hallo Felix,

    erstmal vielen herzlichen Dank für dieses Tutorial! Leider bin ich noch kompletter Raspberry- und auch Python-Neuling und habe eine Frage, bei der du mir vielleicht weiterhelfen kannst.

    Wie „Skipper“ weiter oben, benutze ich den MCP3208, der sich vom MCP3008 nur dadurch unterscheidet, dass er12bit statt 10bit Auflösung hat. Ich habe alles so aufgebaut, wie von dir gezeigt und auch deinen Code benutzt. Als Testsignal habe ich einfach die 3.3V vom Raspberry an den Kanal CH0 gehängt. Jetzt würde ich erwarten, dass die Funktion adc.read für den ersten Kanal 1023 (oder 4095, wenn das mit den 12bit klappen würde) liefert und für alle anderen Kanäle 0. Was aber tatsächlich passiert, ist dass ich für drei der Kanäle den Wert 254 (obwohl nur an einem eine Spannung hängt!) bekomme und für die anderen 0. Wenn ich das 3.3V-Signal auch von CH0 wegnehme, bekomme ich entweder achtmal 0 oder achtmal 831, was ich ziemich überraschend finde.

    Ich habe den Testcode geringfügig angepasst:

    from MCP3008 import MCP3008
    adc = MCP3008()
    for i in range(8):
        value = adc.read( channel = i )
        print("Anliegende Spannung: %.2f" % (value ) )

    Deshalb meine Frage: muss ich in deiner Klasse noch irgendwas an der Bitschieberei ändern? Ist folgender Code evtl. nur für 10 bit Output geeignet und „verschluckt“ sich an den zusätzlichen 2 bit?

        def read(self, channel = 0):
            adc = self.spi.xfer2([1, (8 + channel) << 4, 0])
            data = ((adc[1] & 3) << 8) + adc[2]
            return data

    Vielen Dank schonmal!

    Antworten
    • Ich habe jetzt noch ein bisschen weiter getestet und festgestellt, dass achtmal 0, achtmal 831 (bin 1100111111) oder eine Mischung aus 0 und 254 (bin 0011111110) zufällig herauskommt, unabhängig davon, ob überhaupt an einem Kanal ein 3.3V-Signal hängt.

      Antworten
    • … und noch eine Nachmeldung von mir (sorry für den Mehrfachpost). Ich habe zwei Codes gefunden, in denen für den MCP3208 tatsächlich etwas andere Inputs berechnet werden:

      https://git.agocontrol.com/apagg/agocontrol-work/blob/93f7d9051aebf79c794e3d5fa4feea92c9221831/raspiMCP3xxxGPIO/MCP3208.py

      https://gist.github.com/yoggy/7096133

      Allerdings habe ich beide Codes ausprobiert und bekomme weiterhin für alle Channels merkwürdige Werte ausgegeben. Hat irgendjemand eine Idee, an was das grundsätzlich scheitern könnte bzw. wie ich den Fehler eingrenzen kann?

      Antworten
      • Hallo Felix,

        wo müsste denn dieser Pull-Down Widerstand hin? (sorry, ich bin Anfänger und weiß es tatsächlich nicht). Ich habe die Verkabelung für die Pins 9-16 wie in deinem Schema oben durchgeführt. Wenn ich an keinen der Eingänge (Pins 1-8) etwas anschließe, sollte ich doch 0 zurückbekommen oder?

        Die in meinem 3. Post verlinkten Codes, die bereits für den MCP3208 geschrieben sind, haben mich leider auch nicht weiter gebracht. Dort ist die Lesefunktion folgendermaßen definiert:
        def readadc12(adcnum):
        r = spi.xfer2([4 | 2 | (adcnum >> 2), (adcnum & 3) << 6, 0])
        adcout = ((r[1] & 15) << 8) + r[2]
        return adcout

        Aber auch damit steht der Output für mich in keinem erkennbaren Zusammenhang zu der an den Eingängen angelegten Spannung). Ich bin etwas ratlos, wie ich da jetzt am besten den Fehler eingrenze, z.B. überhaupt mal beurteilen kann, ob der MCP3208 vom Raspberry sinnvolle Kommandos bekommt.

        Vielen Dank und beste Grüße,
        Hinnerk

      • Hallo Hinnerk,
        ich habe das gleiche Ergebnis wie Du.
        Ich bekomme beim Anlegen eines Signals am Eingang des MCP3008 lediglich den Wert 0 bzw. 254 ausgegeben.
        Ich habe Felix Hinweis mit dem Pull-Down Widerstand ebenfalls ausprobiert. Leider hat sich das Ergebnis nicht geändert.
        Konntest Du mittlerweile herausfinde, woran es liegt?

  18. Hallo Sebi und Felix,

    ich habe das ganze inzwischen zum Laufen gebracht, indem ich folgenden Code modifiziert habe:
    https://git.agocontrol.com/apagg/agocontrol-work/blob/93f7d9051aebf79c794e3d5fa4feea92c9221831/raspiMCP3xxxGPIO/MCP3208.py

    Ich vermute, dass die wichtigsten Zeilen folgende sind:

                    self.conn = spidev.SpiDev(0, spi_channel)
                    self.conn.max_speed_hz = 1000000 # 1MHz

    Mein Code sieht nun folgendermaßen aus (damit kann ich erfolgreich alle 8 Kanäle einlesen):

    import spidev
    import time
    
    class MCP3208:
            def __init__(self, spi_channel=0):
                    self.spi_channel = spi_channel
                    self.conn = spidev.SpiDev(0, spi_channel)
                    self.conn.max_speed_hz = 1000000 # 1MHz
    
            def __del__( self ):
                    self.close
    
            def close(self):
                    if self.conn != None:
                            self.conn.close
                            self.conn = None
    
            def read(self, adc_channel=0):
                    # start bit, single end / diff bit (1/0), 3-bit channel number
                    cmd1 = 4 | 2 | (( adc_channel & 4) >> 2)
                    cmd2 = (adc_channel & 3) << 6
                    
                    # send 3 bytes command and get 3 bytes back from MC3208 - the last 12 bits are the measurement
                    reply_bytes = self.conn.xfer2([cmd1, cmd2, 0])
                    reply = ((reply_bytes[1] & 15) << 8) + reply_bytes[2]
    
                    return reply 
                
                
                
    
    if __name__ == '__main__':
            mcp3208 = MCP3208(0)
    
            val =  [0]*8
            volt = [0.0]*8
            count = 0
            N = 100
            while True:
                    count += 1
                    
                    for i in range(8):
                        val[i] += mcp3208.read(i)
    
                    if count == N:
                        for i in range(8):
                            val[i] /= N
                            volt[i] = val[i]*3.3/4095.0
                        count = 0
                        print(volt[0])
                        for i in range(8):
                            val[i] = 0

    Beste Grüße,
    Hinnerk

    Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

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