MCP23016 - I2C IO Port Expander

Hey,

Does anybody have some more information / tutorials / sample code for this particular chip -> MCP23016

I'm planning to "network" three of them to hoop up 40 buttons to a standard Arduino.

This guy -> i2c IO Expander - Arduino and everything related — LiveJournal
Said he wrote a library for it (interesting!) but I can't seem to find it anywhere.

Seems like a very interesting part tough.

Any wise advice?
Thanks in advance!

Greets,
Jim

http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en010412

Also, I noticed I put this topic in the Software forum.
Should be Hardware.
Sorry mods!

@Geggi
Thanks, but I got that far myself.
I was more looking for any hands-on experience.
I'm new into this whole I2C-communication deal...

I have a couple of those, and made an I2C LCD backpack from one.

What is the issue(s) you are having?

PS: I do a have a simple library for it. Still need to upload to online repo.

Ieppie!
Brilliant.

First off - how do I hook them up precisely?
(I have some caps and resistors here, which are needed)
I think I can get by with the information on the website I fount though.

But then - my biggest problem is,
how do I use them in my Arduino Code?

If you could provide me with that library,
It would be a great help I think.

I was planning to use them to read button inputs.
Do I have to use pull-down / up resistors for that?

Thanks!
Jim

I used them in this project:-
http://www.thebox.myzen.co.uk/Hardware/Pendulum.html
and also this one:-
http://www.thebox.myzen.co.uk/Hardware/MIDI_Footsteps.html

You can down load the code and see how I did it. There is no need for a library.

I have made a generic library for it (without the LCD interaction), I will supplied tonite.

The hooking up is quite easy. Only the RC part is 'hard'. As long as you get a frequency close to what they suggest, any combination should work.

To communicate, simply use the library, which uses the Wire library in turn. All very easy.

You will have to use pull ups for the button, as the MCP23016 does not support pull-up/down configurations.

I tried to use pull-downs for a joystick I tested, but could not get interrupts working like that. Manual reading was no issue though. But I strongly suggest pull-ups on buttons.

Hey Grumpy,

I'm hacking away at your code.
What do you use the "Defines.h" file for?

Somewhere in your code I read this:
if(digitalRead(sensorChange)==LOW) doSensor();

Does the chip pull one of it's pins low when it detects a change in one of it's input pins?

Thanks!

Here is the basic code:

void MCP23016::WriteReg(byte reg, byte bank0) 
{
  Wire.beginTransmission(addr);
  Wire.send(reg);
  Wire.send(bank0);
  Wire.endTransmission();
}

void MCP23016::ReadReg(byte reg, byte* bank0)
{
  Wire.beginTransmission(addr);
  Wire.send(reg);
  Wire.endTransmission();
  Wire.requestFrom(addr, (byte)1);
  if (Wire.available() == 1)
  {
    *bank0 = Wire.receive();
  }
}

Unfortunately, the chip has 3 different modes of doing things. You will need to read through the data sheet to understand how it works. It is quite important.

Hey Jim,

First off - how do I hook them up precisely?
(I have some caps and resistors here, which are needed)
I think I can get by with the information on the website I fount though.

Connect SDA and SCL on the MCP to SDA and SCL on the Arduino, use pull up resistors on the lines to 5v (I hear 1.8k is the best value for this).
Pin 9 has your 3.9k resistor to 5v and a 33pf cap to ground for the clock generator.
Pins 1,8,19 go to ground.
Pin 20 goes to 5v.
Then just hook up the GPIO lines to your buttons.

Hope that helps a little. With the code from leppie, you should be set. Basically, you're just sending the data 1 item at a time and waiting for an acknowledge bit from the device (arduino hides the waiting/acknowledge part) I2C works really well, so you shouldn't have issues.

Does the chip pull one of it's pins low when it detects a change in one of it's input pins?

Yes if you set up the pins you want to monitor in the correct register.

Grumpy,

What do these lines in your code do?

   // Initilise registers 
   gpio_write(sensorAddress, ddrSensor, I2CregisterConfig);       // Sensor Switches
   gpio_write(sensorAddress, ddrSensor, I2CregisterPolarity);    // invert switch inputs so 1 = detected
   gpio_write(sensorAddress, 0x0101, I2CregisterExpander);      // Fast response

I know you commented them.
But nothing seems to change when I comment them out.
I was interested in the switch inverter code, but that does not seem to do anything...

My code is here:
http://jimboproductions.be/server/projects/video_window

But nothing seems to change when I comment them out.

gpio_write(sensorAddress, ddrSensor, I2CregisterConfig); // Sensor Switches
sets up the DDR (Data direction register) for the pins to be inputs. The turn on default is an input so you might not notice if this is removed. However it should be included as good practice.

gpio_write(sensorAddress, ddrSensor, I2CregisterPolarity); // invert switch inputs so 1 = detected
If this is removed then a logic zero on the input of the chip will read as a logic zero through the device, with it a logic zero on the chip will read as a logic one.

gpio_write(sensorAddress, 0x0101, I2CregisterExpander); // Fast response
This responds to signal changes faster but uses more power. With out this there will be a slight lag before the change pin goes low. You wouldn't notice this unless you were measuring it or had a time critical application.
for all of these see the data sheet for full details.