Der MCP23017 ist ein 16-Bit I/O-Expander, der über das serielle Protokoll I²C angesteuert wird. Dieser IC besitzt 16 Pins, die als Ein- und Ausgänge unabhängig voneinander programmiert werden können. Die Betriebsspannung liegt zwischen 1,8V bis 5,5V, d.h. die Stromversorgung vom Arduino (3V bzw. 5V) kann benutzt werden. Die I²C-Schnittstelle kann ebenfalls auf einem 5V-Pegel betrieben werden.
Betriebsspannung | 1,8V bis 5,5V |
---|---|
Stromverbrauch (Leerlauf) | 1mA |
Stromverbrauch (Standby) | 1µA |
Max. Stromstärke des IC |
150mA Wenn der MCP23017 im Betrieb warm/heiß wird, könnte das ein Anzeichen sein, dass zuviel Strom durch den IC fließt! |
Max. Stromstärke pro Pin | 25mA |
I²C-Addressen | 0x20 bis 0x27 |
Pin | PDIP | Pin type | Function | Arduino Uno |
---|---|---|---|---|
GPB0 | 1 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB1 | 2 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB2 | 3 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB3 | 4 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB4 | 5 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB5 | 6 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB6 | 7 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
GPB7 | 8 | I/O | Bidirectional I/O pin. Can be enabled for interrupt-on-change and/or internal weak pull-up resistor. | - |
VDD | 9 | P | Power | 3V / 5V |
VSS | 10 | P | Ground | GND |
NC/CS | 11 | I | NC (MCP23017), Chip Select (MCP23S17) | - |
SCL/SCK | 12 | I | Serial clock input | A5 |
SDA/SI | 13 | I/O | Serial data I/O (MCP23017), Serial data input (MCP23S17) | A4 |
NC/SO | 14 | O | NC (MCP23017), Serial data out (MCP23S17) | - |
A0 | 15 | I | Hardware address pin. Must be externally biased. | GND oder 5V (siehe Adressen) |
A1 | 16 | I | Hardware address pin. Must be externally biased. | GND oder 5V (siehe Adressen) |
A2 | 17 | I | Hardware address pin. Must be externally biased. | GND oder 5V (siehe Adressen) |
RESET | 18 | I | Hardware reset. Must be externally biased | GND oder 5V |
INTB | 19 | O | Interrupt output for PORTB. Can be configured as active-high, active-low or open-drain. | - |
INTA | 20 | O | Interrupt output for PORTA. Can be configured as active-high, active-low or open-drain. | - |
GPA0 | 21 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA1 | 22 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA2 | 23 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA3 | 24 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA4 | 25 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA5 | 26 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA6 | 27 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
GPA7 | 28 | I/O | Bidirectional I/O pin. Can be enabledfor interrupt-on-change and/or internal weak pull-up resistor. | - |
Die I²C-Adresse des MCP23017 kann über die Pins A0, A1 und A2 variiert werden:
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 |
Die I²C-Schnittstelle benötigt zwei Leitungen, über die die Daten und das Clock-Signal übertragen werden.
Über SDA werden Daten vom Master zum Slave und in umgekehrte Reihenfolge gesendet. Aus diesem Grund müssen
die Pins dieser Datenleitung sogenannte Open-Drain-Ausgänge (offener Kollektor) sein.
Damit die Leitungen trotzdem ein Spannungslevel besitzen, werden die Pullup-Widerstände (hier: 4,7 kΩ) benötigt.
Werden diese Pullup-Widerstände nicht verwendet, dann wirken nur die internen Pullup-Widerstände des Arduinos.
Dies hat zur Folge, dass das Signal nicht mehr ordentlich übertragen wird.
Das folgende Schaltbild zeigt die Basis-Schaltung zwischen Arduino und dem MCP23017. Die I/O-Pins werden hier noch nicht verwendet.
GPA0 bis GPA7 (=A-Register) bzw. GPB0 bis GPB7 (=B-Register) bilden geweils ein Register, welches durch
die Wire.h-Library angesprochen werden kann. Um alle Pins des A- und B-Registers auf
OUTPUT zu setzen, kann man folgenden Code verwenden (normalerweise im setup()
:
Wire.beginTransmission(0x20);
Wire.write(0x00); // IODIRA register
Wire.write(0x00); // set all of port A to outputs
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x01); // IODIRB register
Wire.write(0x00); // set all of port B to outputs
Wire.endTransmission();
Will man nun beispielsweise im loop()
einige der Output-Pins schalten verwendet man folgenden Code:
Wire.beginTransmission(0x20);
Wire.write(0x12); // address port A
Wire.write(??); // value to send
Wire.endTransmission();
Wire.beginTransmission(0x20);
Wire.write(0x13); // address port B
Wire.write(??); // value to send
Wire.endTransmission();
Die ?? werden durch die gewünschten Binär-, Hexadezimal. oder Dezimal-Werte ersetzt. Man kann sich sozusagen jeden Pin als ein Bit vorstellen, welches mit 0 (LOW) und 1 (HIGH) beschaltet werden kann. Alle zusammen als Zahl zusammengefasst werden nun an den MCP23017 geschickt. Will man z.B. Pin 7 und Pin 1 mit HIGH ansteuern, so muss die Zahl 10000010 lauten, was in hexadezimal 0x82 und in dezimal 130 ist.
Der MCP23017 ist standardmäßig schon auf Eingabe gesetzt, daher müssen keine zusätzlichen Einstellungen
vorgenommen werden.
Im folgenden Beispiel verwenden wir die oben beschriebene Basis-Schaltung und ergänzen sie mit 4 Mikrotastern,
welche an den Pins GPB0, GPB1, GPB2 und GPB3 verbunden werden.
#include "Wire.h"
byte inputs=0;
void setup()
{
Serial.begin(9600);
Wire.begin(); // wake up I²C bus
}
void loop()
{
Wire.beginTransmission(0x20);
Wire.write(0x13); // set MCP23017 memory pointer to GPIOB address
Wire.endTransmission();
Wire.requestFrom(0x20, 1); // request one byte of data from MCP20317
inputs = Wire.read(); // store the incoming byte into "inputs"
if (inputs > 0) {
// if a button was pressed
Serial.println(inputs, BIN); // display the contents of the GPIOB register in binary
delay(200); // for debounce
}
}
Da ja gleichzeitig alle Pins gelesen werden, kann auch das Drücken mehrerer Knöpfe zur selben Zeit ermittelt werden.
Der folgende Sketch benutzt die Library Adafruit_MCP23017 und läßt alle 16 Pins abwechselnd blinken:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp;
void setup()
{
mcp.begin(0); // Init MCP23017 at address 0x20
for (byte i=0; i<16; i++) {
mcp.pinMode(i, OUTPUT);
}
}
void loop()
{
for (byte i=0; i<16; i++) {
mcp.digitalWrite(i, HIGH);
}
delay(500);
for (byte i=0; i<16; i++) {
mcp.digitalWrite(i, LOW);
}
delay(500);
}
Man kann über verschiedene Adressen auch mehrere MCP23017-ICs pro Arduino ansteuern, dies soll der folgende Schaltplan und Sketch demonstrieren. Wiederum blinken alle Output-Pins diesmal von zwei MCP-Chips:
#include <Wire.h>
#include <Adafruit_MCP23017.h>
Adafruit_MCP23017 mcp1;
Adafruit_MCP23017 mcp2;
void setup()
{
mcp1.begin(0); // Init MCP23017 at address 0x20
mcp2.begin(1); // Init MCP23017 at address 0x21
for (byte i=0; i<16; i++) {
mcp1.pinMode(i, OUTPUT);
mcp2.pinMode(i, OUTPUT);
}
}
void loop()
{
for (byte i=0; i<16; i++) {
mcp1.digitalWrite(i, HIGH);
mcp2.digitalWrite(i, HIGH);
}
delay(500);
for (byte i=0; i<16; i++) {
mcp1.digitalWrite(i, LOW);
mcp2.digitalWrite(i, LOW);
}
delay(500);
}
zurück