How To Use An Expander
Port expanders can be used to create extra GPIO pins on the Arduino. In this tutorial, we volition larn how to use port expanders past building a project using the MPC23017 port expander to create two additional 8-flake ports and read and write to them using I2C on the Arduino. We will create some running lights and use bitwise actions to read input switches and display them on the serial monitor.
MPC23017 Port Expander
A port expander is like the extension cord (in the non-estimator world) that allows more than one device to connect to a single port on a computer. However, at that place'south still a downside to information technology. For example, a 3Gbit/s port might take a hub or expander installed and now exist able to adapt half dozen devices, but at a maximum of 3Gbit/southward throughput bandwidth divided by the said 6 devices, or by however many are plugged in and being used.
The MPC23017 contains two 8-chip bi-directional ports which can be connected to the Arduino with an I2C interface. Its wire library takes care of the communication. And the chip has three selectable accost lines so we can set up it upwardly with two3 = viii possible addresses, or put additional MPC23017 fries on the same ItwoC line.
Bitwise Arduino Mini-Tutorial
If you have spent some time programming the Arduino, you lot may be very familiar with reading and writing to ports in a fleck by flake manner, due east.g. digitalWrite(12, HIGH)
. Information technology's piece of cake to forget that they are actually 8-bit wide ports. In this projection, we are confronted with 2 byte-wide ports that can only be written/read in a port-wide or byte-wide style. Past that, I mean you lot read all 8 bits at once and then accept to single out the scrap or pin you lot wanted. We will look at some seldom-used tools to do that.
Please notation that & is very different from &&, as is|(OR) is different from ||. The symbols >> or << are not used to indicated greater or less than either; it is used to indicate a shift to the right or to the left. Some other useful tool is to display bytes on the serial monitor in a binary manner. For example, Serial.println(29, BIN); prints: 11101
(note: there are 3 zeros missing on the left-mitt side). Information technology would be overnice if it showed us all of the 8 $.25, but there is no unproblematic Arduino function to do it. Alternatively, nosotros can use a uncomplicated role illustrated below.
void loop() { printBin(29); } void printBin(byte inByte){ for (int b = 7; b >= 0; b--) Serial.impress(bitRead(inByte, b)); //now prints: 00011101 Serial.println(); }
Allow'southward say we wanted to fetch a pin from port A but we are only interested in flake 2 (3rd flake from the right). Assume the byte contains 11110100.
We volition utilize a "scrap mask". This is a byte of 0'south merely a 1 in the position where we want to extract a single flake. If you AND a bit with 0, the upshot will ever be 0 because 1 AND 0 is 0. Bitwise AND is & NOT && which is logic AND. The Serial.println(B11110100 & B00000100)
will result to 00000100 which is 4 because 0100 is 4 DEC. To get our bit as Loftier or LOW, we use: Serial.println((B11110100 & B00000100) >> 2)
. This has used the mask to screen out the junk as before, and shift to the right by 2 places to get the result as a 1 or 0.
Actually there is an easier manner. Call up that bits are numbered 0 to vii. Refer to the code below:
byte mybyte = B11110100; Series.println(bitRead(mybyte, 2)); // prints 1 Serial.println(bitWrite(mybyte, 3, HIGH), BIN); // prints 11111100 Serial.println(bitClear(mybyte, 3), BIN); // prints 11110100
Wiring Up the Project
In this example project we will use the MCP23017 port expander to control eight LEDs depending on the input from an 8 channel DIP switch.
These are the parts you will need to build this project:
- Arduino Uno
- MPC23017 port expander
- Eight position DIP switch
- Viii LEDs
- Eight 680 Ohm resistors
- Viii 10K Ohm resistors
- One ii.2K Ohm resistor
- Jumper wires
- Breadboard
Follow the wiring diagram below to build the projection:
The values of the current limiting resistors connected to the LEDs are 680 Ohms. The resistor continued to pin 18 of the MCP23017 is two.2K Ohms, and the pull-upwards resistors continued to the DIP switch are 10K Ohms.
If y'all want to learn more nearly the Arduino, check out our Ultimate Guide to the Arduino video course. You'll learn basic to avant-garde Arduino programming and circuit edifice techniques that will ready you lot to build whatsoever project.
Arduino Code
In one case everything is continued, upload this code to the Arduino. This program volition output the bit value created by the DIP switch in raw and decimal format:
//unproblematic read and write to MCP23017 port expander #include <Wire.h> byte byteVal=0; byte chipAddr = 0x27; byte GPIOA = 0x12; // PortA reg addr byte GPIOB = 0x13; // PortB reg addr byte IODIRA = 0x00; // PortA direction reg addr byte IODIRB = 0x01; // PortB management reg addr void setup(){ Series.begin(9600); Wire.brainstorm(); Wire.beginTransmission(chipAddr); Wire.write(IODIRA); // IODIRA dir register Wire.write(0x00); // set entire PORT A as output Wire.endTransmission(); Wire.beginTransmission(chipAddr); Wire.write(IODIRB); // IODIRB dir annals Wire.write(0xff); // set entire PORT B as input Wire.endTransmission(); } void loop(){ Wire.beginTransmission(chipAddr); Wire.write(GPIOB); // read the inputs off PORT B Wire.requestFrom(chipAddr, ane); // ask for 1 byte byteVal = Wire.read(); // read information technology Wire.endTransmission(); // write that input to PORT A Wire.beginTransmission(chipAddr); Wire.write(GPIOA); // address PORT A Wire.write(byteVal); // PORT A Series.print(byteVal,BIN); Serial.print(" "); Serial.println(byteVal, DEC); Wire.endTransmission(); filibuster (200); }
Explanation of the Lawmaking
In the first section, nosotros include the wire library, then we declare the chip address, and then the port A and B data registers followed by the direction registers. This is similar to setting pinMode()
in the normal style.
In setup()
, nosotros make port A an output port, and port B an input port. It is worth mentioning that y'all don't take to brand the whole port output or input. For example, byte IODIRA = B0101010101
would make alternate input and output pins. In the loop()
section we just read off port B and re-create it to port A.
The serial window will show something like this, depending on the position of your input switches:
Code for LED Running Lights
Upload the code below to make the LEDs turn on, one after the other. Here nosotros are using left shift << to move a bit to the left, causing the LEDs to move:
#include <Wire.h> // Wire.h byte inByte=i; byte chipAddr = 0x27; byte GPIOA = 0x12; // PortA reg addr byte GPIOB = 0x13; // PortB reg addr byte IODIRA = 0x00; // PortA management reg addr byte IODIRB = 0x01; // PortB direction reg addr byte i = 1; void setup(){ Serial.brainstorm(9600); Wire.brainstorm(); Wire.beginTransmission(chipAddr); Wire.write(IODIRA); // IODIRA dir register Wire.write(0x00); // fix entire PORT A equally output Wire.endTransmission(); Wire.beginTransmission(chipAddr); Wire.write(IODIRB); // IODIRB dir register Wire.write(0xff); // ready entire PORT B as input Wire.endTransmission(); } void loop(){ i=i<<1; if(i==0) i=1; Wire.beginTransmission(chipAddr); Wire.write(GPIOA); // address PORT A Wire.write(i); // PORT A delay (500); Wire.endTransmission(); Serial.println(i); }
Output on the Serial Window
Promise you enjoyed this tutorial on how to aggrandize the Arduino's GPIO pins with a MCP23017 port expander! Exist certain to let us know in the comments below if you have any questions.
How To Use An Expander,
Source: https://www.circuitbasics.com/how-to-use-an-mpc23017-port-expander-on-the-arduino/
Posted by: webbageres.blogspot.com
0 Response to "How To Use An Expander"
Post a Comment