Increase I/O pins of Arduino/ESP8266 –MCP23017
Introduction-
A port expander is an IC that can increase I/O ports on your Arduino/ESP8266.I/O expanders sometimes have more current output per pin than Arduino/ESP8266.
MCP23017
A 28 pin DIP IC. Its 16-bit serial expander (In simple words 16 I/O port expander). It uses I2C Communication.I2C Basics
A communication protocol in which only 2 wire is used. Up to 128 devices can be connected through 2 pins unless their addresses are different.
Communication Steps
- A data packet is sent from a microprocessor to all devices connected to i2c port.
- Data packet contains address of the desired slave device.
- Each slave compares address received to its own address , if matches, replies ACK (acknowledge) bit.
- Then sending and receiving of data proceeds.
Wiring and Circuit
MCP is divided into two parts PORT A (GPA Pins) and Port B (GPB Pins)
Note-
For ESP8266 you have to connect a 4.7K resistor between pin SDA and 3.3v (or VCC).In above circuit, you can connect LEDs (in series with a resistor if required ) to “GP” pins only.
Addressing – Address of MCP23017 will change according to the connection of A0 A1 A2 pins on MCP.
Coding
Without External/Additional Library
It is a difficult task to control this IC without a library . So we will be talking about basics not real coding in Arduino IDE.To set port A (i.e GPA ports) to output
Wire.beginTransmission(0x20); //This line will begin transmission at address 0x20. This is the address of MCP23017 according to ciruit. Wire.write(0x00); // IODIRA register Wire.write(0x00); // set entire PORT A to output Wire.endTransmission(); //This will end transmissionThen to set port B to outputs, we use
Wire.beginTransmission(0x20); // MCP address Wire.write(0x01); // IODIRB register Wire.write(0x00); // set entire PORT B to output Wire.endTransmission();To control Port A , this will be in void loop()
Wire.beginTransmission(0x20); Wire.write(0x12); // address port A Wire.write(X); // value to send Wire.endTransmission();To control Port B , this will be also in void loop()
Wire.beginTransmission(0x20); Wire.write(0x13); // address PORT B Wire.write(X); // value to send Wire.endTransmission();Here X is a byte of data which will tell MCP to turn on or off specific pins. Each bit of data (i.e 0 or 1) will specify state of pin . Each place of bit corresponds to pin number.
For example to set pin 0 – high, 1-high, 2-High and all low , we have to send 11100000 which translates to 224 in decimal. So X = 224.
To use Port B as Input
Wire.beginTransmission(0x20); Wire.write(0x13); // address PORT B Wire.endTransmission(); Wire.requestFrom(0x20, 1); // request one byte of data byte input=Wire.read(); // store incoming byte into "input"This is how MCP23017 works , a Library seems really necessary here, so we have.
With Library
Install Adafruit MCP23017 Library from inside Arduino IDE. Click here to know how to install Library.The code below is self-explanatory.
#include <Wire.h> // Wire.h #include <Adafruit_MCP23017.h> Adafruit_MCP23017 mcp; void setup() { mcp.begin(); // use default address 0 mcp.pinMode(1, OUTPUT); //This is pin GPA0,so pin 2 will be GPA1, pin 7 will be GPA7, pin 8 will be GPB0 mcp.pinMode(0, INPUT); mcp.pullUp(0, HIGH); // turn on a 100K pullup internally pinMode(13, OUTPUT); // use the Arduino internal LED as debugging } void loop() { digitalWrite(13, mcp.digitalRead(0)); // The LED will 'echo' the button //Blinking on GPA0 mcp.digitalWrite(1,HIGH); delay(1000); mcp.digitalWrite(1,LOW); delay(1000); }
No comments