MCP 3008 funktioniert nicht mit Python 3

  • Hallo OSchubert,


    es gibt da ein ganz tolles Programm zum Zeichnen elektronischer Schaltung.


    Es heißt "Fritzing" und lässt sich auf Räscheknäschten verschiedenster Betriebssysteme installieren.


    Unter Linux z.B. durch

    Code
    1. sudo apt-get install fritzing

    installierbar.


    Dort bitte DEINE Schaltung einpflegen und als .PNG oder .JPG hier posten.



    EDIT: Rein interessehalber: Wo hast Du denn diese blaue Arbeitsplatte her? Ich habe sowas ähnliches für einen Arduino mit Steckbrett. Aber die Kombination mit einem Raspberry und Steckbrett zum Aufkleben gefällt mir...



    Beste Grüße


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Mh, nicht schön, aber für den Moment reicht es (oder?):


    pi@raspberrypi:~ $ nano MCP3008Soft.py

    GNU nano 2.7.4 File: MCP3008Soft.py


    #Python Timerklasse importieren

    import time

    #Python Raspberry Pi GPIO Klasse importieren

    import RPi.GPIO as GPIO


    # Festlegung der Nutzung der vorgegebenen Nummerierung der GPIOs

    GPIO.setmode(GPIO.BCM)


    HIGH = True # 3,3V Pegel (high)

    LOW = False # 0V Pegel (low)


    # SCI Funktion

    def getAnalogData(adCh, CLKPin, DINPin, DOUTPin, CSPin):

    # Pegel definieren

    GPIO.output(CSPin, HIGH)

    GPIO.output(CSPin, LOW)

    GPIO.output(CLKPin, LOW)


    cmd = adCh

    cmd |= 0b00011000 # Kommando zum Abruf der Analogwerte des Datenkanals adCh


    # Bitfolge senden

    for i in range(5):

    if (cmd & 0x10):

    GPIO.output(DINPin, HIGH)

    else:

    GPIO.output(DINPin, LOW)

    # Clocksignal negative Flanke erzeugen

    GPIO.output(CLKPin, HIGH)

    GPIO.output(CLKPin, LOW)

    cmd <<= 1 # Bitfolge eine Position nach links verschieben


    # Datenabruf

    adchvalue = 0

    for i in range(11):

    GPIO.output(CLKPin, HIGH)

    GPIO.output(CLKPin, LOW)

    adchvalue <<= 1 # 1 Postition nach links schieben

    if(GPIO.input(DOUTPin)):

    adchvalue |= 0x01

    time.sleep(0.5)

    return adchvalue


    # Konfiguration Eingangskanal und GPIOs

    CH = 0 # Analog/Digital-Channel

    CLK = 18 # Clock

    DIN = 24 # Digital in

    DOUT = 23 # Digital out

    CS = 25 # Chip-Select


    # Pin-Programmierung

    GPIO.setup(CLK, GPIO.OUT)

    GPIO.setup(DIN, GPIO.OUT)

    GPIO.setup(DOUT, GPIO.IN)

    GPIO.setup(CS, GPIO.OUT)


    while True:

    print getAnalogData(CH, CLK, DIN, DOUT, CS)


  • Dort bitte DEINE Schaltung einpflegen und als .PNG oder .JPG hier posten.

    OK, aber das wird exakt so aussehen wie im Tutorial...

    EDIT: Rein interessehalber: Wo hast Du denn diese blaue Arbeitsplatte her? Ich habe sowas ähnliches für einen Arduino mit Steckbrett. Aber die Kombination mit einem Raspberry und Steckbrett zum Aufkleben gefällt mir...

    Zum Beispiel hier: https://www.amazon.de/dp/B01MQSWUGY/ref=cm_sw_em_r_mt_dp_U_k9rrAb2FBJWFG (Affiliate-Link)

  • Bitte Code-Tags für den Code verwenden, wegen der Lesbarkeit.

    Mir fällt auf, dass DGND nicht angeschlossen ist, gehört das so ?

    Oh, das war der TSSOP vergiss es.


    Wieviel kOhm hat dein Poti ?


    P.S. Ein Bild von über dem Chip wäre gut, damit man die Reihen besser sieht. ;)

  • Hallo OSchubert,


    auf den ersten Blick fällt mir auf:

    Code
    1. GPIO.setup(DIN, GPIO.OUT)
    2. GPIO.setup(DOUT, GPIO.IN)

    Bist Du Dir damit sicher?


    Die Pins für die SPI-Schnittstelle kannst du ja prinzipiell beliebig belegen und benennen. Aber einen Pin, auf dem (vielleicht?) eine Eingabe erfolgen soll, als Ausgang zu belegen und umgekehrt verhindert jegliche Kommunikation zwischen Software und Hardware...


    Was des einen sein Eingang ist, ist des anderen sein Ausgang.


    OK, aber das wird exakt so aussehen wie im Tutorial...


    Meinst Du?


    Wenn ich eine Schaltung aufgebaut habe, die absolut nicht so will, wie ich mir das dachte, dann zeichne ich die Software mit Fritzing - und stelle dann meistens fest, das mindestens eine von folgenden Sachen fehlt oder nicht richtig ist:

    • - kein geschlossener Stromklreis
    • - keine gemeinsame Masse
    • - irgendeine Strippe fehlt (meistens die, von der irgendwas ausgelesen werden soll)
    • - alle Strippen richtig (wie ausgedacht) - aber die Software steuert ganz andere Pins an
    • - ...

    Und wenn ich gerade das aktuelle Problem ins Forum kippen möchte, fällt mir der "Fehler" auf.



    Beste Grüße


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Edited 3 times, last by Andreas ().

  • Vielen Dank für die Hilfe - bin unterwegs, kann es also noch nicht testen, aber habe folgendes gefunden:


    Code
    1. The linux-raspberrypi kernel update to 4.9.43 included a change to the
    2. default reported max speed of the linux spidev, from 100KHz to 125MHz.
    3. kernel: BCM270X_DT: Set spidev spi-max-frequency to 125MHz.
    4. See raspberrypi/linux#2165.

    Habe den Verdacht, dass der MCP3008 nur 100MHz verträgt, würde "das große Schweigen" des Chips erklären, wenn ich also zurück bin, werde ich mal schauen, wie die Frequenz des SpiDev eingestellt werden kann, von vermutlich 125 MHz (seit Kernel 4.9.43) zurück auf 100 MHz.

  • Hallo OSchubert,


    hast Du Dir schon mal das Datenblatt zum MCP 3008 angeschaut? Dort wird sehr anschaulich beschrieben, wie die Kommunikation zwischen einem abfragenden Device und dem MCP3008 erfolgen muss.


    Dort ist von Pegelwechseln die Rede und wie Bits als gesetzt und nicht gesetzt zu deuten sind. Ein Programmierbeispiel habe ich mal zur Veranschaulichung hier gepostet.


    Die Frequenz auf die Du jetzt hinaus willst, ist die Frequenz, die seitens der CPU des Raspberry Pi SPI-Kommunikation maximal unterstützt wird. Das hat aber mit dem MCP3008 gar nichts zu tun. Der haut Bits raus, wenn dazu aufgefordert. Schneller als angegeben geht's halt nicht. Aber daraus zu folgern, dass die sich mit unterschiedlicher Frequenz zu unterhalten versuchen, ist eine unzutreffende Folgerung.


    Ich vermute weiterhin Schaltungsfehler als Ursache einer nicht erfolgenden Kommunikation.




    Beste Grüße


    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    • Icon-Tutorials (IDE: Geany) - GPIO-Library - µController-Programmierung in Icon! - ser. Devices - kein Support per PM / Konversation

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Edited 3 times, last by Andreas ().

  • Hab den Artikel nur überflogen und mich mit der Hardware des RasPi noch nicht intensiv auseinander gesetzt, aber da auch ein Kumpel von mir mit der bekannten Verdrahtung und den üblichen Beispiel-Codes auch keinen Erfolg hatte bis er einen anderen RasPi benutzt hat (wo es dann sofort klappte, vermutlich wegen einem "älterem" Kernel), tippe ich auf das 100 bzw. 125 MHz Frequenz-Problem, wie hier beschrieben:


    https://github.com/bulletmark/…2d66b5f395227d9785221ff21


    Die Verdrahtung haben wir zigmal gegenseitig überprüft, die kenne ich schon fast auswendig, ist kein Hexenwerk - beim "älteren Pi" bekommt er, ja nach Quell-Code, die bekannten zufälligen Schwankungen bei Anschlüssen die nicht Genullt sind, ist fast nie genau Null, im Gegensatz zu den zwei anderen, aktuelleren Pi's die exakt Null ausgeben - aber wie gesagt, werde am Wochenende alle Tipps ausprobieren.


    Hintergrund ist übrigens, dass ich meine Solaranlage die bisher mit Resol gesteuert wird selbst managen will, da ein Holzbrenner zusätzlich zum Ölbrenner dazugekommen ist und kein Programm des Resol Systems damit klar kommt.

  • Problem behoben, lag wohl tatsächlich an der Frequenz, Beispiel Code um spi.max_speed_hz = 1000000 erweitert, nun klappt es wieder, auch mit aktuellen Kernel. Werde bei zukünftiger Gelegenheit mal die Details klären, aber für den Moment reicht es mir, dass es wieder funktioniert.


    Danke für Eure Hilfe!

  • Problem behoben, lag wohl tatsächlich an der Frequenz, Beispiel Code um spi.max_speed_hz = 1000000 erweitert, nun klappt es wieder, auch mit aktuellen Kernel. Werde bei zukünftiger Gelegenheit mal die Details klären, aber für den Moment reicht es mir, dass es wieder funktioniert.


    Danke für Eure Hilfe!

    Ich habe ein ähnliches Problem. Könntest du mir vlt. sagen, an welcher Stelle im Code du "spi.max_speed_hz = 1000000" hinzugefügt hast? Denn egal, was ich ausprobiere, es will nicht funktionieren, bzw. richtige Werte liefern.

    Eigentlich wollte ich damit ein intelligentes Bewässerungssystem bauen, wie teilweise im Tutorial ( https://tutorials-raspberrypi.…-dem-raspberry-pi-messen/ ) beschrieben. Allerdings bringt es bei mir immer nur den Output 1023 und bei meinem Freund 0 bzw. The Value is zero.

    Ich bin deshalb ehrlich gesagt sehr ratlos. :conf:

    Hättest du/hättet ihr eine Idee, woran das liegen könnte und wie man dies beheben kann?


    Zur Info, ich habe einen Raspberry Pi 3b und mein Freund einen Raspberry Pi 3b+ verwendet, außerdem den MCP3008 Analog-Digital Wandler, einen normalen, analogen Wasser-/Bodenfeuchtigkeitssensor. Das Tutorial habe ich 1 zu 1 befolgt und die Software des Raspis ist aktuell. Und der MCP3008 kann auch nicht defekt sein, da ich zwei davon getestet habe...


    Wäre echt nett, wenn ihr da ne Idee hättet.

    Thx

    :conf::helpnew::danke_ATDE:

  • wäre ein I2C MCP nicht leichter anzusteuern?

    Wer braucht denn das Tempo vom MHz?

    lasst die PIs am Leben !
    Energiesparen:
    Das Gehirn kann in Standby gehen. Abschalten spart aber noch mehr Energie, was immer mehr nutzen. Dieter Nuhr
    (ich kann leider nicht schneller fahren, vor mir fährt ein GTi)

  • Z3R0 die nette Suchmaschine meiner Wahl hat bei einer Suche nach "spi.max_speed_hz = 1000000" diese Seite ans Tageslicht befördert: https://pinout.xyz/pinout/spi.


    Dort zu finden ist folgendes Beispiel:


    Python
    1. import spidev
    2. spi = spidev.SpiDev()
    3. spi.open(0, CHIP_SELECT_0_OR_1)
    4. spi.max_speed_hz = 1000000
    5. spi.xfer([value_8bit])

    Das solltest du anpassen können.

    :wink:

  • Noch eine Anmerkung am Rande. Der Sample and Hold Kondensator des MCP3x08 wird ab etwa 1,5MHz Clock nicht mehr vollständig geladen, was sich dann in einer falschen Messung niederschlägt. Bei halber Aussteuerung betrug der Fehler bei meinen Messungen ein LSB, bei 4MHz waren es schon über 10. Aber wie jar schon schrieb, wer benötigt all diese MHze? Eine Hüllkurve latcht man sowieso nicht mit einem Betriebssystem als Basis ab...

  • Hallo erstmal,

    Z3R0 die nette Suchmaschine meiner Wahl hat bei einer Suche nach "spi.max_speed_hz = 1000000" diese Seite ans Tageslicht befördert: https://pinout.xyz/pinout/spi.


    Dort zu finden ist folgendes Beispiel:


    Python
    1. import spidev
    2. spi = spidev.SpiDev()
    3. spi.open(0, CHIP_SELECT_0_OR_1)
    4. spi.max_speed_hz = 1000000
    5. spi.xfer([value_8bit])

    Das solltest du anpassen können.

    Danke dafür, an sich ahtten wir dies bereits in den Code eingebaut, aber einen kleinen Fehler gemacht. Außerdem noch "spi.xfer" zur "spi.xfer2" umgeändert und es funktioniert. :danke_ATDE:


    Zur Info: Wir haben auch noch ne andere Verkabelung von ner anderen Website getestet (gleiche Schaltung, also handelte es sich höchstwahrscheinlich um ein defektes Jumperkabel oder nen Wackelkontakt) mit welcher der neue korrigierte Code einwandfrei funktioniert.


    Nochmals danke für eure Hilfe.

    :conf::helpnew::danke_ATDE:

    Edited 3 times, last by Z3R0 ().

  • Könntest du mir vlt. sagen, an welcher Stelle im Code du "spi.max_speed_hz = 1000000" hinzugefügt hast?

    Der Quelltext den ich benutze ist dieser hier, hoffe es hilft:


    #!/usr/bin/python

    from spidev import SpiDev

    from time import sleep


    class MCP3008:

    def __init__(self, bus = 0, device = 0):

    self.bus, self.device = bus, device

    self.spi = SpiDev()

    self.spi.open(self.bus, self.device)


    # Dies ist nötig, weil ab Kernel 4.9 die Frequenz des SPI von 100 auf 125 MHz geändert wurde (OST: 20180102)

    self.spi.max_speed_hz = 1000000


    def read(self, channel = 7):

    adc = self.spi.xfer2([1, (8+channel)<<4, 0])

    data = ((adc[1] & 3) << 8 ) + adc[2]

    return data


    def ConvertVolts(data,places):

    volts = (data * 3.3) / float(1023)

    volts = round(volts,places)

    return volts



    DELAY = 0.5


    try:

    print('Reading MCP3008 values, press Ctrl-C to quit...')

    # Print nice channel column headers.

    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*range(8)))

    print('-' * 57)

    while True:

    adc = MCP3008()

    values = [0]*8


    for i in range(8):

    values[i] = adc.read( channel = i )

    print('| {0:>4} | {1:>4} | {2:>4} | {3:>4} | {4:>4} | {5:>4} | {6:>4} | {7:>4} |'.format(*values))

    sleep(DELAY)

    except KeyboardInterrupt:

    GPIO.cleanup()


    Quelltext ENDE.


    EDIT: Ach so, lese gerade, dass es sich bereits erledigt hat, freut mich das es jetzt klappt, viel Spaß!

    Edited once, last by OSchubert ().

  • Hoi,


    ich hab den Code von OSchubert noch formatiert, einfach als "spi-test.py" speichern und mittels folgendem Befehl ausführen:

    Wenn der aktuelle Benutzer in der Gruppe "spi" ist (prüfen mit: `id`) dann geht das auch ohne root Rechte. Ansonsten zum testen und ausschließen der Berechtigungen einfach erst Mal mit Root Rechten ausführen.

    Ich habe noch hinzu gefügt dass die Spannung in Volt auf allen Kanälen ausgegeben wird, damit man leicht nachmessen kann ob das so auch korrekt ist.


    Vielen Dank an alle beteiligtem im Thread, dank euch habe auch ich den Fehler (Kernel default von 100kHz auf 125MHz fürs SPI Interface) gefunden und korrigiert.

    Edited 5 times, last by flow171 ().