Using MCP23008 8-bit I2C IO Expander on the Raspberry Pi


This project is to use the MCP23008 8-bit IO Expander with I2c interface on the Raspberry Pi. The software is written in C.

Using the Starter Kit-C wire up the breadboard as shown. Note, the cathode of the LED is the short lead which connects to ground.


Now download the software by:


Unpack the tar file and change into directory by:

tar xf mcp23008.tar
cd mcp23008

Start the example by:

sudo ./mcp23008_demo

To stop the program running press CTL-C

The main program is mcp23008_demo.c to edit this program use:

sudo nano mcp23008_demo.c

You can try and change the value of the delay. The default is 200. Press CTL-X Y to save and exit.

To compile the program:

make all

Now you can run it again.

Parts List



Short URL:

Tags: ,

18 Responses to Using MCP23008 8-bit I2C IO Expander on the Raspberry Pi

  1. Wayne Greenslade on 05/10/2012 at 09:31

    was wondering what you are using to generate these pictures?
    Might use the same thing if possible for my project.


  2. admin on 05/10/2012 at 09:34

    We use the software from with the library from Adafruit.

  3. Wayne Greenslade on 05/10/2012 at 10:53

    thank you very muchly have downloaded and installed that will be this weekend booked out!!!

  4. David Brown on 19/10/2012 at 15:38

    Any chance of sample Python code to get this working. I’ve tried following the guide for the MCP23017 and hoped to modify that but I’m stuck

  5. Alan Childs on 24/10/2012 at 16:58

    I couldn’t get the program to work at first (using Redsleeve instead of Raspian,) but managed to find out that I had to add the following to /etc/rc.local:

    /sbin/modprobe i2c_bcm2708
    /sbin/modprobe i2c_dev

  6. Tom on 08/01/2013 at 00:00

    Built the beast, checked the voltages, but it’s not working for love nor money. The software appears to be running, i.e. I get a ‘Start’ on my Putty session, but there’s no activity on the board.

    I’ve triple checked the pin-outs on the breadboard and I’m pretty sure I’ve laid things out correctly, so I’m figuring it’s the software that’s not installed properly.

    the mcp23008 directory is hanging off the Desktop as is the RPi.GPIO software. Is that where I’ve boobed? Should these directories be hanging off the root folder instead?

    • admin on 08/01/2013 at 00:09

      Make sure you got the polarity of the LED correct. The short leg should go to ground and the long leg to the resistor.

      It doesn’t matter where you put the directory. Is there any error message on the screen?

      • Tom on 08/01/2013 at 18:56

        As it happens, I’ve tried the LED’s both way around ;o)

        No errors, but having tried the {i2cdetect -y 0} command, I can see that the RPi least the GPIO / i2c is up. It cant ‘see’ the chip though. I would expect there to be an indicator on the response to show which address was being poled, but there’s nothing being detected.

      • Tom on 08/01/2013 at 22:37

        Got it!

        Two problems.

        First a schoolboy error with a link: I’ve got the super-sized large breadboard that comes with the Starter Kit-C. Unlike the diagram above, the power bus, both +ve and -ve buses, are split mid way down the unit. A simple jumper to ensure the ground bus continuity across the width of the whole breadboard is required to make the hardware functional.

        Secondly, I’ve got a second generation board. command doesn’t work, because the I2C is on port 1! works a treat, and reveals the chips availability as anticipated.

        So… What I need is to modify the code so that it’s driving the correct port. Can you help with that?

        • Tom on 08/01/2013 at 22:38

          Doesn’t work: sudo the i2cdetect -y 0
          Works: sudo the i2cdetect -y 1

        • Tom on 08/01/2013 at 23:32

          sudo i2cdetect -y 1

          0 1 2 3 4 5 6 7 8 9 a b c d e f
          00: — – — – — – — – — – — – –
          10: — – — – — – — – — – — – — – — –
          20: 20 — – — – — – — – — – — – — – –
          30: — – — – — – — – — – — – — – — –
          40: — – — – — – — – — – — – — – — –
          50: — – — – — – — – — – — – — – — –
          60: — – — – — – — – — – — – — – — –
          70: — – — – — – — –

          • Tom on 09/01/2013 at 07:29

            And fully functional!

            To make the project work with the newer Revision 2 Raspberry Pi boards, you’ll need to make a change to the following line in the mcp23008.c file. In the the mcp23008 directory:

            sudo nano mcp23008.c

            Line that Reads fd = i2c_init(“/dev/i2c-0″);
            Change to read fd = i2c_init(“/dev/i2c-1″);

            Save it, then recompile using the command:

            make all

            Then execute and enjoy.

  7. Kevin Cook on 03/03/2013 at 17:30


    All wired up but nothing. I have a Rev 2 board but cannot understand which changes i should make to your wiring? I’m using pins 3 and 5 but nothing. Pi people say Rev2 i2c pins have changed. I’ve followed Tom’s changes but they don’t work either, there are 3 of us on diff machines but nothing as yet! Any advice?

  8. Kevin Cook on 04/03/2013 at 11:54


    All sorted now. Had to add

    “i2c-bcm2708″ and

    Works fine now.

  9. Kevin Cook on 20/03/2013 at 16:01

    Should this chip run very hot?

  10. Dick Haight on 11/10/2013 at 02:28

    I got your code to work after making the Rev 2 change in mcp23008.c. I had only wired up a single LED on GP0. So I changed the …_demo.c program to just write to the single port–
    mcp23008_write(2); // originally the arg I used in the hope of turning the LED off was “0″

    When …write(0) didn’t turn the LED off, I changed it to “2″. How DO you turn ports OFF?
    So: is
    mcp23008_write(017) all ports ON?
    mcp23008_write(020) all ports OFF?

  11. Dick Haight on 23/11/2013 at 17:20

    Starting from your demo code I have written a program that handles all 8 ports at once. Here it is:

    #include “mcp23008.h”

    int main(int argc, char *argv[])
    short int i, mask=0;
    char str[20];
    /* for mcp23008.h, each port is a bit position: 1 thru 8 below */
    unsigned short int c[] = {0×01,0×02,0×04,0×08,0×10,0×20,0×40,0×80};

    if(argc != 2) { /* */
    printf(“usage: 12c8 (8: 0 | 1)\n”);
    strcpy(str, argv[1]);
    for(i = 0; i < 8; ++i) {
    if(str[i] == '1') {
    mask |= c[i];
    mcp23008_write(mask); // Write to port
    sudo ./i2c8 11110000 # turns first 4 ports on, last 4 off

    Except with a Sain relay board when the codes are reversed (1=off, 0=on)
    More at my blog.

  12. Dick Haight on 27/11/2013 at 14:44

    I’d like to read the state of the 23008 chip. Your statement–
    makes the ports writeable. How do you make them readable and then read them?