Abfrage Taster beim MCP23017 mit I2C Bus

  • Hall(o

    versuche mit einem MCP23017 am I2C Bus Taster abzufragen. Am Port A (A0-A7) liegen LEDs. Am Port B (B0-B7) liegen Taster. Die Taster schalten nach GND. Alle LEDs kann ich ohne Problem schalten, Leider funktioniert das bei den Tastern nicht. Verwende folgenden Code dazu:

    Alles ohne Int. Hat jemand eine Idee dazu?

    achim

  • Hallo,

    ich würde an deiner Stelle versuchen etwas fertiges zu nutzen, vielleicht helfen dir folgende Links:

    https://github.com/mcauser/micropython-mcp23017

    https://forum.micropython.org/viewtopic.php?t=7450

    https://github.com/ShrimpingIt/micropython-mcp230xx

    Bzw. du kanns mal schauen wie die das da machen und mit deinem Code vergleichen.

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Hallo Dennis

    Die meisten Programme im Netz beziehen sich auf das schreiben an den Ports. Zum lesen der Taster habe ich bisher kaum was gefunden. Wenn ich mein Programm mit den Quellen vergleiche ist eine sehr grosse übereinstimmung mit der Datei mcp23017.py vorhanden. Leider kann ich dieser Datei nicht dazu entnehmen. Die ganzen Register werden genauso genommen wie ich es auch mache. Habe diesen IC bereits mit AVR ohne Problem in den Griff bekommen. Doch leider unterscheidigt sich der Code doch etwas in Python.

  • Muss natürlich so aussehen. Habe was vergessen:

    Hatte bei else die : nicht kopiert oder vergessen

  • Hm, also von den drei Links, wenn du den letzten nimmst und runter scrollst dann steht da:

    Zitat


    For example, the following will set the output values of pins 10-15 and read the logic value (True or False) of pins 0-9

    Ist dass nicht das, das du suchst?

    Du drückst deinen Taser und, je nach dem wie du den angeschlossen hast, ist dein Pin high oder low und entsprechend True oder False.

    Oder verstehe ich dich vielleicht auch nicht richtig?

    Grüße

    Dennis

    🎧 With the music execution and the talk of revolution, it bleeds in me and it goes 🎧

  • Ja das steht da.

    "For example, the following will set the output values of pins 10-15 and read the logic value (True or False) of pins 0-9"

    in DE:

    "Zum Beispiel werden die Ausgangswerte der Pins 10-15 gesetzt und der logische Wert (Wahr oder Falsch) der Pins 0-9 gelesen"

    Es ist auch ein Progamm dazu:

    Leider passt der Code nicht zu meinem. Scheint auch Python zu sein, aber anders.Warum?

  • Das sieht nicht gut aus. In dem Code ist keinerlei Angaben zum Bus drin. Damit kann es schon mal nicht funktionieren. Das andere sieht eher nach einer ähnlichen Datei zu mcp23017.py aus. Die Register habe ich ja schon mit drin. Wahrscheinlich ist der Vergleich welche Taste gedrückt wurde etwas falsch oder das auslesen des MCP.

  • Das geht leider nicht. Sind zu viele. Dieser Code geht scheinbar nicht für meine Hardware. Im Code ist eine Bus Adresse angegeben. Teilweise verwende ich 3 bis 5 verschiedne Adressen am Bus. Wo kann ich diese eingeben. Ansonsten hat es sehr viel ähnlichkeit mit mcp23017.py. Dort sind z.B. alle register angegeben und viel mit "def". Kontte auch keine Angabe zu den genutzten Ports finden um Taster oder LEDs anzugeben. Mein Code den ich oben angegeben habe schaltet ja die LEDs. Nur die Abfrage der Taster funktioniert nicht. Leider ist im Netz zu der Abfrage sehr wenig zu finden. Hatte gehofft ein kleines Beispiel zu finden.Leider nicht.

  • Mir ist jetzt nicht ganz klar, welche Bibliothek du jetzt nutzt.

    Ist das die von Dennis89 in #7 verlinkte Bibliothek?

    Du musst dir anschauen, was in dem importieren 'mcp' passiert:

    https://github.com/ShrimpingIt/mi…b/master/mcp.py

    Da hast du eine Klasse :

    Damit kannst du eigentlich mehrere Instanzen erstellen.

    Code
    mcp_1 = MCP(address=0x20)
    mcp_2 = MCP(address=0x21)
    mcp_3 = MCP(address=0x22)

    und dann kannst du die Objekte einzeln nutzen:

    Code
    mcp_1.setup(pin=1, value=IN)
    mcp_2.setup(pin=3, value=OUT)
    mcp_3.setup(pin=2, value=IN)
    
    if mcp_1.input(pin=1)
        #mach was
    if mcp_3.input(pin=2)
        #mach was anderes
    
    mcp_2.output(pin=3, value=TRUE)

    Zumindest ist das jetzt meine Vorstellung. Leider habe ich keinen Pico bzw. MCP und kann das leider nicht testen.

  • Kannst du C++ Lesen ?

    https://github.com/DerKleinePunk/…er/MCP23017.cpp

    i2c.writeto(MCP_Address, bytearray(confA)) # Port A als Ausgang

    Das in meinen Augen falsch du schreibst nur eine 1 in das Register wenn ich das noch richtig weiß muss da ein F rein wenn alle Pins Inputs sein sollen am Port a oder b oder halt das bit musster das deine Taster beschreibt.

    a = i2c.readfrom(MCP_Address, 8)
    wenn das den Status lesen soll fehlt mir da was leider kenne ich den Syntax nicht aber du muss wie in deinen Defs definiert das Register 0x12 bzw 0x13 lesen um raus zu bekommen ob der Taster gedrückt ist oder nicht.

    Vielleicht hilft dir das ja

  • Moinsen,

    es gelten die gleichen Grundregeln wie beim PCF8574.
    Er braucht einen Pool in der Objektklasse die im Zwischenspeichert welcher Port welches Registers A oder B als Input verwendet wird. Dann muss er auf eine der beiden INT_A oder INT_B reagieren, und das entsprechende PORT-Register auslesen. Dann muss er einen Vergleich mit dem INPUT-Zwischenspeicher-Pool ( Array , LIST ) machen, welcher Port in dem Moment auf LOW gefallen ist. Fertig werden. Der MCP23x17/18 triggert genauso wie der PCF8574 bei Port -Pegel- Falling mit einem INT_A oder INT_B Signal. Um dieses jedoch als Unterscheidungsmerkmal nutzen zu können muss der Taster über einen Pull-Up den Port auf LOW ziehen, das kann intern, wie auch durch eine externe Beschaltung erfolgen.

    Franky

  • Guten morgen

    Es gibt einige Unterschiede zum PCF8574. Arbeite im Moment vollkommen ohne INT.

    i2c.writeto(MCP_Address, bytearray(confA)) # Port A als Ausgang

    Das in meinen Augen falsch du schreibst nur eine 1 in das Register wenn ich das noch richtig weiß muss da ein F rein wenn alle Pins Inputs sein sollen am Port a oder b oder halt das bit musster das deine Taster beschreibt.

    Habe eso im Code:

    Code
    # Achtung Angabe der Pins in Hex
    confA = [MCP_IODIRA, 0x00]  # Steuert die Richtung der Daten am Port A, 0 Ausgang, 1 Eingang
    confB = [MCP_IODIRB, 0xff]  # Steuert die Richtung der Daten am Port B, 0 Ausgang, 1 Eingang
    confC = [MCP_GPPUB, 0xff]   # Schaltet Pull-up-Widerstände für Port B auf 5V
    confD = [MCP_GPIOB, 0xff]   # Spiegelt den Wert am Anschluss B wider
    
    i2c.writeto(MCP_Address, bytearray(confA)) # Port A als Ausgang
    i2c.writeto(MCP_Address, bytearray(confB)) # Port B als Eingang
    i2c.writeto(MCP_Address, bytearray(confC)) # Schaltet Pull-up-Widerstände für Port B auf 5V
    i2c.writeto(MCP_Address, bytearray(confD)) # Spiegelt den Wert am Anschluss B wider.

    Habe durch messen der Eingänge festgestellt das die 5V nicht anliegen. Nach Suche im DB habe ich festgestellt das die Angaben in HEX sein müssen. Dadurch kann man an einem Port auch eine gemischte Anordnung machen.

    Das Auslesen des Ports ist doch drin:

    Code
    confD = [MCP_GPIOB, 0xff]   # Spiegelt den Wert am Anschluss B wider
    MCP_GPIOB = 0x13     # Spiegelt den Wert am Anschluss B wider.
    i2c.writeto(MCP_Address, bytearray(confD)) # Spiegelt den Wert am Anschluss B wider.

    Es liegt jetz 5V an allen Pins von B, die Taster schalten die Ports nach GND.

    Code
    a = i2c.readfrom(MCP_Address, 0xf0)
        print(a)

    Damit sehe ich das ein Pins geschaltet wird. Leider funktioniert die Auswertung nicht wie sie soll.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!