IO expander Library

I’ll wrote a library for the arduino that can communicate with a MCP23016 pin expander. That microchip works on the I2C bus and has 16 i/o ports. The library provides the user a interface just like the interface you use for the normal I/O ports.

This library uses the Two Wire library as base to communicate through the I2C bus. The rest of the class is really straight forward and simplistic, but it provides just the things you need to keep your code clean and tidy ;).



08-02-2011 – start of the project
19-02-2011 – v0.2 intial release
20-02-2011 – v0.3 improvements submitted by robtillaart, support added for the MCP23017 and MCP23018 (not tested yet)

Future work

Microchip also has the MCP23017, MCP23s17, MCP23018 and the MCP23s18. So far i know these are refined models and has essentially the same function. The communication is slightly diffrent and I think it would be nice if this library can become universal for this whole family of chips. In version 0.3 I’ve added the support necessarie for the other versions of the chip. I’ve did this from the datasheets and could’t test it.

I’m looking for someone who has one of these chips to test some things out!


This is the constructor, nothing more to tell.

bool init(uint8_t address, uint8_t device_type);
This function initializes the class, it has to be called before the class operates. The function parameter address is the i2c address the chip uses, the device_type can be set with the values (MCP23016, MCP23017 and MCP23018)

bool pinMode(uint8_t port, uint8_t pin, bool mode);
The rest of the functions are just like u used to on the arduino. The pinmode function sets a pin on output or input. Just call it like pinMode(0,1,OUTPUT); and pin 0.1 is a ouput port.

bool pinModePort(uint8_t port, bool mode);
Just like the pinMode function but then for a whole port, handy i think!

bool digitalWrite(uint8_t port,uint8_t pin, bool value);
Like u used to, call it with the HIGH and LOW as a value, that keeps your program readable! It only affects a pin when you set it to ouput mode

bool digitalWritePort(uint8_t port, bool value);
Same construction as with the pinMode, a handy function to write a whole port to a LOW or HIGH value at once! (keep in mind that the whole port has to be in output mode!!

int digitalRead(uint8_t port,uint8_t pin);
No need for any more info, gets the state of the pin. Returns also when the port is in output mode.

  1. May 17, 2011 at 11:36 am

    Thank you very much all is working.

  2. May 17, 2011 at 11:55 am

    Hey Romik,

    Good to hear! currently i’m so busy with my graduation that there is no time left to complete the future work that i’ve described. In about 3 months i’ll continue with completing this and adding more classes on this website.

  3. Rob
    August 12, 2011 at 4:13 pm

    i get that it says that that there is no comunication with the i/o expander 😦
    mcp23016 chip, got two, rebuild the schematic a few times, i don’t know what’s wrong 🙂
    any thoughts?

    • August 14, 2011 at 9:13 pm

      Hi Rob,

      Dit you try the example project that i’ve include with the source?
      This message comes directly from the wire library endTransmission function and means that the communication was unsuccessful. I’ve found a small flaw in my lib, the endTransmission function returns a error code, but my lib only gives a generic error back. I don’t think the error code will help a lot, but you could look into it.

      Dit you also place the capacitor from the schematic? I use a 33 pF capacitor and a 3K9 Ohm resistor.

      • Rob
        August 15, 2011 at 10:53 pm

        i build the schematic i found on the site where i bought the i/o expander, works perfectly now 🙂

      • August 16, 2011 at 6:56 am

        Nice to hear!
        Maybe you can share the sollution you’ve found?


      • Rob
        September 1, 2011 at 11:28 am

        well this is how i solved it:
        used the pdf called aansluitschema(pdf) and worked from there. 🙂

        by the way any chance of you implementing this function where you can send data like a shift register then shift out the data? i’ve seen in the data sheet that it’s possible 🙂

  4. gcaglion
    October 24, 2011 at 5:19 am

    Hey Koenwar,

    I’ve been using your library successfully so far with one MCP23016; now I need to add a second one to my board; how can I differentiate the commands I send through IOexpander, and should I use the same pins on the Arduino board to connect it?


    • October 24, 2011 at 6:18 am

      Hai Gcaglion,

      That’s the fun part of I2C! it’s a bus! just connect the scl and sda pins from the first mcp to the second mcp. Now change the adress of the second mcp bychanging the one of the adress pins a0,a1,a2 pins from negative to positive. By example, a0 “-” , a1 ” -” and 2 “+”. In the code you must make a second instance of the IOexpender class like this:

      IOexpander IOexp1;
      IOexpander IOexp2;

      IOexp1.init(0x20, MCP23016);
      IOexp2.init(0x21, MCP23016);



      I never tried this before, but it should work! let me know how it wend!


  5. gcaglion
    October 24, 2011 at 8:32 am

    Thanks gr,

    I’m trying to make this work, but so far, after connecting scl and sda, power and ground, the output pins of the second mcp seems to be synchronized with the first one…
    I’m not sure what you mean by changing the address of pin a0,a1,a2, however: should this be written in code, or what?


    • October 24, 2011 at 1:02 pm

      lol, no check the datasheet of the mcp23016, chapter “1.6 Address Decode”. the I2C address is hardwired on the outside of the chip on pin A0, A1 and A2!

  6. gcaglion
    October 25, 2011 at 6:41 am

    Thank you again;
    I have been trying to connect any combination of (a0,a1,a2) to vcc and ground, but every time I connect any of those pins to vcc, Arduino itself simply shuts off, as if there were a short circuit.
    I’ve also tried to put a 4k7 resistor between, say, a0 and vcc; in this case, everything reverts back to the original status (e.g., the two mcps are in sync)… Am I missing something else??

  7. October 25, 2011 at 7:02 am

    woow!!, yes you have to use a 4k7 resistor between vcc and the address ports!
    dit you tried to connect a1 to ground, a2 to ground and a0 with the 4k7 resistor to vcc? otherwise try it with a0 and a1 to ground and a2 to vcc (with the 4k7 😉 ) and set the address of the second chip on 0x24

    if you look in this file:

    Click to access 00245a.pdf

    you can see on page 14 that they use a 4k7 resistor of the a0 to a2 pins? so it should work!

  8. gcaglion
    October 25, 2011 at 8:28 am

    Yes, I’ve tried all possible combinations of a0,a1,a2 connecting to vcc and ground, always inserting a 4k7 resistor: every time, the 2nd mcp behaves exactly like the first one, and the code returns the error message about not being able to find the second mcp.

    At one pint I even thought I might have fried a0 on the second mcp, by connecting it to vcc without the 4k7, but then I tried to change the address of the first mcp (with the 4k7:-)), and it didn’t make any difference either (that is, the first mcp address is always 0x20).

    Not really sure at this point what is going on here…

  9. October 25, 2011 at 8:47 am

    how strange…i’m really curious what goes wrong here 😉
    something to test:
    1. change in the code the addr to something like 0x00. it should do nothing now 😉
    2. whats the voltage on the pins??

  10. gcaglion
    October 25, 2011 at 9:12 am

    AAAHHH! I rebuilt the breadboard from scratch, and just realized I had A0 of the second pin also touching the ground! (That also explains Arduino was shorting out when trying to connect A0 to ground…)
    Now everything works perfectly with these 16 LEDs; time to go on with the project and replace them with steppers dir and step pins!

    Thanks a lot koenwar, you have been really helpful!

  11. October 25, 2011 at 11:08 am

    lol haha! you’re welcome!
    Good to hear that you can use the lib for more than one ioexpender. I’ll graduate tomorrow, after that i’m planning to complete my work on this lib and get it on the arduino site!

  12. Robert
    November 23, 2011 at 12:40 am

    Did you graduate? Did you make it?
    If so Congratulations! 🙂
    Here is a Question that involves your Library and the mcp23016 i/o expander,
    Basically, I Am going to attempt to Write a Library of my own involving the mcp23016 i/o expander, with which I want to control a lcd over I2c, and well I wanted to ask if I may take a look at your library (at your code) and possibly use it 🙂
    since the mcp23016 has 16 i/o pins I’ll have something like 6 pins left with to do as one pleases 🙂
    And I might be wanting to use some piece’s of you library to make this easier on the user of the I2cLcd (me in this case). and That is why I ask you permission to maybe use some of you library code 🙂

    I’ll credit you off course, if I were able to get it to work, Then I’ll probably put it online as this maybe be very useful to other also 🙂

    My nick on is Duality,
    Greetings from,

    • November 23, 2011 at 7:43 am

      Hi Duality,

      Yes, graduated with honors, i’m very pleased! haha…
      But sure, off course you may use it. I wonder if you can get the timing right!! i’ve no idea how fast the ports react.

      greets Koen

      • November 25, 2011 at 11:51 am

        I can initialize the display, and blink a cursor
        so happy 😛

        greetings from,

  13. December 17, 2011 at 4:52 am

    I did it!
    My library works!
    It’s far from ready, but it does all the things it should do with a 16×2 screen,
    now going to Work on, So it gonna be compatible with some different sizes of screens.
    if you want to see it in action!
    Turn the volume down, it can be on high volume some times, crapy cam 🙂

    I hope that somewhere in the future I can remove some of the parts I used form you library,
    that it will be smaller.
    beside’s I am going to recommand your library for easy use with this expander,
    because I designed the Pcb in such a way it’s not only usable as Lcd, but also As IOexpander 🙂


  14. asdsad
    March 17, 2012 at 11:17 am

    link is down ?

    • March 18, 2012 at 12:16 pm

      i see, working on that now…

      • asdsad
        March 19, 2012 at 12:20 pm

        thank you,

        can you may provide a link on hotfile or something like that ?

        because i want to start working with your great lib

      • March 19, 2012 at 10:12 pm

        Hi, the source code is online again. I’m looking for a permanent sollution.


  15. Robert
    March 19, 2012 at 11:25 pm

    maybe you could put it online on github or something 🙂

  16. asdsad
    March 20, 2012 at 8:24 am

    thank you 😀

  1. February 18, 2011 at 11:48 pm

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: