MCP23017 I2C I/O Port Expander

Auch wenn ein einfacher Arduino schon reichlich Ports hat, kann es doch mal sein das man entweder noch mehr Ports benötigt, ein Arduino Mega zu viel Platz wegnimmt oder man I/O Ports auslagern will. Mit dem MCP23017 Input-Output Port Expander ist das möglich.

MCP23017

Der MCP23017 besitzt insgesamt 16 wechselbare I/O Ports (8 auf jeder Seite) und es können durch die drei Hardware Adressen Pins (A0-A2) bis zu 8 Geräte an einem I2C Bus betrieben werden. Wie bei einem Arduino kann ein interner Pull-Up Widerstand aktiviert und so eine vereinfachte Schaltungen ermöglicht werden. Mit einem ULN2803A Darlington Transistor Array kombiniert, können sogar größere Lasten geschaltet werden.

MCP23017 I2C IO Port Expander - Pinbelegung

Die Schaltung

Zuerst verbinden wir die Pins für die Spannungsversorgung (Pin 9 VDD = +5V / Pin 10 VSS = GND), Reset (Pin 18 RESET = +5V) und für I2C (Pin 12 = SCL / Pin 13 = SDA) vom MCP23017 mit dem Arduino.

Arduino SDA SCL
Uno A4 A5
Mega 20 21
Micro Pro 2 3

Jetzt sollten noch die Pins für die Hardware Address (Pin 15 = A0 /Pin 16 = A1 /Pin 17 = A2) mit GND oder HIGH verbunden werden. Wenn alle grauen Kabel wie auf dem nachfolgenden Bild auf GND gesteckt sind, wird die erste mögliche Hardware Adresse 0x20 gewählt. Ich habe gelesen, wenn die Pins nicht auf GND oder +5V gelegt werden, sind die Pins im Zustand floating bzw. undefiniert und das kann zu Problemen führen.
MCP23017 I2C IO Port Expander - Steckplatine Minimum
Natürlich kann auch eine andere Adresse eingestellt werden. Der Status (GND = 0 / +5V = 1) der Hardware Address Pins ergeben folgende Adresse.

A0 A1 A2 Adresse
0 0 0 0x20
1 0 0 0x21
0 1 0 0x22
1 1 0 0x23
0 0 1 0x24
1 0 1 0x25
0 1 1 0x26
1 1 1 0x27

Library und Sketch

In dem nachfolgenden Beispiel habe ich zwei MCP23017 eingebaut damit man besser sieht, wie die Ansteuerung weiterer MCP23017 Port Expander funktioniert.

MCP23017 I2C IO Port Expander - Steckplatine Beispiel

 

Es gibt diverse Beispiele wie man den MCP23017 direkt über I2C ansprechen kann, ich habe mich aber für die Adafruit MCP23017 Library entschieden. Damit lassen sich die einzelnen I/O Pins fast wie normale Pins ansteuern.

33 Gedanken zu „MCP23017 I2C I/O Port Expander

      1. Hallo Stefan , danke für dein Tutorial
        Mein deutsch ist nicht so gut,ich hätte eine Frage .
        Ich habe von — Adafruit MCP23017 Library– heruntergeladen
        jetz versuche ich den Sketch, auf mein arduino uno aufzuspielen,
        haber er gibt mier die fehlermeldung
        //
        Arduino: 1.6.8 (Windows 10), Board: „Arduino/Genuino Uno“
        Bibliothek Wire in Version 1.0 im Ordner: C:\Users\Salvatore\AppData\Local\Arduino15\packages\arduino\hardware\avr\1.6.17\libraries\Wire wird verwendet
        //

        danke

        1. Hallo Salvatore,

          das sieht mir mehr nach einer Info und nicht nach einem Fehler aus? Wird noch mehr ausgegeben?

          Viele Grüße
          Stefan

          1. Hallo Stefan,entschuldigung für meine späte rückmeldung, ich habe das
            problem gelöst. Ich hätte eine andere Frage mit den Arduino 2560 Mega kann man nur
            maximum mit acht MCP23017 komunizieren , oder gibt es ein andere
            möglichkeit das man mer als acht MCP23017 mit Arduino 2560 komunizieren
            kann?

            Viele Grüße
            Salvatore

    1. Hallo David,

      ich habe die Links zu Aliexpress gelöscht, da der erste schon nicht mehr funktioniert. Ein paar Beispiele und Libraries findet man zwar, aber die Unterstützung der beiden I2C Chips PCF8574 (8 I/O Pins) und PCF8575 (16 I/O Pins) die auf den Platinen verbaut sind, könnte sicherlich besser aussehen.

      Du musst aber schauen ob die Spezifikationen für dein Projekt ausreichend sind. Für mich war beim MCP23017 unter anderem wichtig, dass interne Pull-Up Widerstände vorhanden sind und ausreichend Leistung für ULN2803 vorhanden ist. Ob einer der beiden I2C Chips für dich passt, kann ich dir leider nicht sagen. Ich habe bisher noch keine Erfahrung damit gesammelt.

      Viele Grüße
      Stefan

  1. Hallo,

    ich benutze folgenden Code für ein mcp:

    #include
    #include „Adafruit_MCP23017.h“

    Adafruit_MCP23017 mcp;

    void setup() {
    mcp.begin(0); // use default address 0
    mcp.pinMode(7, INPUT);
    mcp.pinMode(8, OUTPUT);
    mcp.pinMode(9, OUTPUT);

    }

    void loop() {
    if (mcp.digitalRead(7) == HIGH)
    {
    mcp.digitalWrite(8, HIGH);
    mcp.digitalWrite(9, HIGH);

    }
    else
    {
    mcp.digitalWrite(8, LOW);
    mcp.digitalWrite(9, LOW);
    }

    }

    Das Problem ist, dass 8 und 9 sehr lange brauchen (20 Sek) bis die von High auf Low wechseln (Wenn ich also 7 von High auf Low wechsle) Woran liegt das?

    1. Hallo Thomas,

      kann es sein das dein Taster kein sauberes LOW zurück gibt? Ich kenne deinen Aufbau nicht aber wenn du den Taster direkt gegen GND verbindest, benötigst du noch folgende Zeile damit der Interne Pull-Up Widerstand aktiviert wird.

      mcp.pullUp(7, HIGH); // Activate Internal Pull-Up Resistor

      Melde dich gerne nochmal ob es dein Problem gelöst hat.

      Viele Grüße
      Stefan

  2. Hallo Stefan
    Habe Dein Beispiel problemlos auf 3 MCP23017 erweitert.
    Danke für Deine verständlichen Erläuterungen.
    Setze es für mein Projekt Rolladensteuerung ein.
    Wenn interesse könnt Ihr Euch ja melden.
    Grüße Reinhold

    1. Hallo Reinhold,

      freut mich das es bei dir so gut geklappt hat! Habe dir direkt eine Mail geschickt.

      Ich habe um dich vor Spam zu schützen deine E-Mail Adresse aus dem Kommentar entfernt. Du bekommst aber aktuell automatisch (wie von dir eingestellt) eine Info wenn sich jemand zu diesem Beitrag meldet.

      Viele Grüße
      Stefan

      1. Hallo Stefan,
        Habe versucht MCP23017 an arduino pro mini anzuschliessen,
        dabei habe ich a2 , a3 für SCL und SDA genommen. Bei Arduino uno sind es ja
        A4, A5. Hat nicht geklappt. Hast Du vielleicht eine Idee????
        Grüße Reinhold

        1. Hallo Reinhold,

          beim Arduino Pro Mini sollten es die Pins A4 und A5 sein?! Diese sind nicht beschriftet und es kann schnell zu einer Verwechslung kommen. Schräg über Pin A2 liegt A4 (SDA) und über Pin A3 liegt A5 (SCL).

          Viele Grüße
          Stefan

          1. Super danke werde noch 2 Pins einlöten und dann testen, müßte funktionieren.
            Ist meinen Augen geschuldet, dass ich es nicht gesehen habe.

  3. Hallo,

    ich habe ein kleines Problem:
    Mein Nano hat auf den Adafruit offensichtlich keine Lust.
    Folgende Fehler: (Es sei gesagt, dass ich alle Librarys habe)
    hat einer vielleicht eine Idee???? Vielen Dank schon einmal

    ccOlqtoZ.ltrans0.o:(.text.startup+0x8c): undefined reference to Adafruit_MCP23017::begin(unsigned char)'

    ccOlqtoZ.ltrans0.o:(.text.startup+0x98): undefined reference to Adafruit_MCP23017::pinMode(unsigned char, unsigned char)‘

    ccOlqtoZ.ltrans0.o:(.text.startup+0xa4): undefined reference to Adafruit_MCP23017::pinMode(unsigned char, unsigned char)'

    ccOlqtoZ.ltrans0.o:(.text.startup+0xb4): undefined reference to Adafruit_MCP23017::digitalWrite(unsigned char, unsigned char)‘

    ccOlqtoZ.ltrans0.o:(.text.startup+0xc0): undefined reference to Adafruit_MCP23017::digitalWrite(unsigned char, unsigned char)'

    ccOlqtoZ.ltrans0.o:(.text.startup+0x11a): undefined reference to Adafruit_MCP23017::digitalWrite(unsigned char, unsigned char)‘

    ccOlqtoZ.ltrans0.o:(.text.startup+0x126): undefined reference to `Adafruit_MCP23017::digitalWrite(unsigned char, unsigned char)‘

    collect2.exe: error: ld returned 1 exit status

    exit status 1

    1. Hallo Chris,

      hast du mal versucht ein mitgeliefertes Example aufzuspielen oder einfach mal einen Uno auszuwählen (es gibt nur eine Meldung das dieser nicht erreichbar ist) und geschaut was dann passiert? So könntest du deinen Sketch und den Nano ausschließen.
      Ich glaube aber eher das es an deiner Umgebung liegt. Verschiebe doch mal den libraries Ordner, erstelle einen neuen Ordner und installiere nur die Adafruit_MCP23017. Vielleicht ist es wirklich nur ein Konflikt zwischen zwei Libraries?!

      Viele Grüße
      Stefan

      1. Hallo Stefan,

        vielen Dank. Ich habe alles ausprobiert….nichts geht, auch die Beispiele nicht.
        Immer die selbe Fehlermeldung.
        Mit der Lib von kasperskaarhoj/MCP23017-Arduino-Library
        scheint es zu gehen….aber so Dinge wie mit Button arbeiten sind wohn nicht möglich.
        PullUp gibt es in der Lib nicht.
        Vielleicht noch eine Idee??

        Danke und Grüße
        Chris

        1. Hallo Chris,

          wirklich sehr seltsam! Du glaubst mir sicherlich auch ohne Screenshots das bei mir das Button Beispiel der Adafruit_MCP23017 Library für den Arduino Nano erfolgreich kompiliert wird?!

          Wenn du alles (andere Libraries entfernen und Board wechseln) ausprobiert hast, kann es eigentlich nur noch an deinem System liegen?! Wenn du die Möglichkeit hast, prüfe es doch mal an einem anderen Gerät. Ich bin mir sicher da funktioniert es!

          Viele Grüße
          Stefan

    1. Hallo Claudius,

      da ich bisher noch mit keinem Teensy gearbeitet habe, kann ich dir dazu leider keine genaueren Infos geben. Nach einer kurzen Google Recherche würde ich sagen, dass es sogar mit der Adafruit Library funktionieren sollte.

      Viele Grüße
      Stefan

  4. Hallo Stefan, Hallo Reinhold,
    ich bin auch gerade dabei mir eine Rollo/Raffstore-Steuerung zu bauen.
    Aber es scheitert leider an meinen Programmier-Kenntnissen.
    @Reinhold, kannst du mir vielleicht Tipps geben wo ich ein Skript finde welches ich mir anschauen könnte. Ich würde nämlich auch gerne verstehen wie die Zusammenhänge sind.
    Ich hätte es gerne so, dass ich die Rollos über das Handy steuern kann – mittels HTML-Seite auf meinem Raspberry. Wenn ich dann am Handy auf Rollo_Wohnzimmer_hoch klicke, soll dann eben das entsprechende Pin und somit das Relais schalten. Mein großes Problem ist eigentlich das einzelne Ansteuern der einzelnen PIN’s.
    Danke und Grüße
    Ben

    1. Hi Aakash,

      i think the mcp23s17 (SPI Version from mcp23017) is also possible. I haven`t testet it so far but found some examples.

      Best regards
      Stefan

      1. Will the same code work for spi23s17?
        If no then can you please suggest anything how to code with that? Because i found that SPI is faster and efficient than I2C. Please reply.

  5. o_O hi

    ich komme bei der „pinMode(…“ nicht so klar, da Pin 7 des MCP23017 doch GB6 ist, oder verstehe ich da was falsch? GPA7 ist doch auf Pin 28 oder ist die Pinbelegung von Adafruit völlig anders deklariert?

    LG Maya

    1. Hallo Maya,

      ich musste mich auch erst kurz wieder einlesen, aber eigentlich ist es ganz einfach. Du zählst einfach von GPA0 (0) bis GPA7 (7) und dann weiter mit GPB0 (8) bis GPB7 (15) durch. Die Zahlen in den Klammern sind die, die du auch in der Arduino IDE für die MCP23017 Adafruit Library benötigst. Pin 28 ist GPA7, die Zahl wird aber nicht verwendet. Es ist nur eine Beschriftung.

      Viele Grüße
      Stefan

  6. Hilfe…

    Mein Arduino Nano V3 will das Programm nicht.
    Wenn ich den Sketch, so wie er hier ist, erst überprüfe und dann hochladen will, kommen nur fehlermeldungen :
    „Arduino: 1.8.3 (Windows XP), Board: „Arduino Nano, ATmega328″
    sketch_aug05a:109: error: stray ‚\302‘ in program

        mcp3.digitalWrite(15, LOW);
    sketch_aug05a:109: error: stray ‚\240‘ in program
    sketch_aug05a:109: error: stray ‚\302‘ in program
    sketch_aug05a:109: error: stray ‚\240‘ in program
    sketch_aug05a:109: error: stray ‚\302‘ in program
    sketch_aug05a:109: error: stray ‚\240‘ in program
    sketch_aug05a:3: error: expected unqualified-id before numeric constant
    #define mcp1 0x20 // I2C Adresse des 1. Portexpanders MCP23017
    Adafruit_MCP23017 mcp1; // Create MCP 1
    sketch_aug05a:4: error: expected unqualified-id before numeric constant
    …“

    …ich weiss net weiter….

  7. …“und plötzlich drohte Thors Hammer…“ funtzt…

    ??? keine Ahnung wieso, aber ich hab im sketch die Wire.h Library entfernt, weil ich „schritt für schritt“ erstmal nur einen MCP und dann weitere zufügen wollte. Da das Projekt (LED Uhr mit 72 einzelne LEDs) einen RTC (DS23..) nutzt und daher neben den Adafruit MCP.. libary auch die Wire benötigt.
    Zusätzlich klemmte ich den nano ab und einen mega 2560 dran.
    Warum läuft das jetzt mit dem mega 2560 und ohne Wire.h? Verstehe ich nicht….

    PS: dein Captcha zeigt keine Wörter an… (nur nach mehreren versuchen)

  8. Hallo,
    ich würde gerne 4 Stück verwenden, komm aber nicht weiter bei der Verdrahtung.
    Bei allen Beispieln werden immer nur ein oder zwei angeklemmt.#
    Hat da jemand Erfahrung?

    Gruß Robin

    1. Hallo Robin,

      womit genau hast du denn Probleme? Kommst du mit der Adressierung nicht weiter oder werden nicht alle MCP23017 richtig erkannt? Die Adressierung von bis zu 8 Modulen ist als Tabelle im Beitrag oder im Datasheet zu finden. Grundsätzlich solltest du A0, A1 und A2 entweder mit GND oder +5V verbinden und nicht unbeschaltet lassen. Wenn du 0x20 bis 0x23 für deine 4 Module vergeben hast, solltest du am besten nochmal mit einem I2C Scanner Sketch prüfen welche erreichbar sind.

      Viele Grüße
      Stefan

      1. Hallo Stefan,
        ich habe heute morgen den Artikel nochmal gelesen und gemerkt, dass ich mich nur blöd angestellt habe. Habe jetzt gesehen, dass nur mit drei Pins der Binärcode geschaltet wird.
        Wer lesen kann ist halt klar im Vorteil 😉

        Gruß Robin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.

*

code