Does anyone know of an MCP23017 library which can support chip(s) configured as outputs plus other chips configured as inputs that give interupts for both 'Offs' and 'Ons'?
It doesn't necessarily have to be a library, a stand-alone sketch giving that sort of functionality would be very welcome.
Basically I wish to monitor more than 20 door switches for being triggered when opened or closed, and be able to control several things in response.
There seem to be plenty of examples which can do one thing or another, but I haven't yet been able to find anything that can offer rising and falling interupts AND manage multiple chips.
The Adafruit library seems professional, but I can't find an arduino tutorial for it (only for their Ras Pi/ Beaglebone version), and in the arduino examples there is no mention of using multiple expanders, plus the interupt example suggests interupts are generated only when input buttons are pressed and not when they are released.
The Centipede library can handle multiple chips as inputs and outputs, and mentions a forthcoming interupt version, but it was promised long ago, and I can't find it.
Basically you need to read the data sheet of the chip. To use multiple chips just change the I2C address you are using and talk to the registers in the other chip. The three least significant bits of the address are given by the logic levels of the A0 to A2 pins on the chip.
I normally add a .h file with the register names to the Arduino Sketch:-
Then I use these two functions to read and write 16 bit values to the registers:-
void gpio_write(int address, int data, int reg) {
// Send output register address
Wire.beginTransmission(address);
Wire.write(reg);
// Connect to device and send two bytes
Wire.write(0xff & data); // low byte
Wire.write(data >> 8); // high byte
Wire.endTransmission();
}
int gpio_read(int address) {
int data = 0;
// Send input register address
Wire.beginTransmission(address);
Wire.write((byte)GPIO);
Wire.endTransmission();
// Connect to device and request two bytes
Wire.requestFrom(address, 2);
if (!Wire.available()) { } // do nothing until data arrives
data = Wire.read();
if (!Wire.available()) { } // do nothing until data arrives
data |= Wire.read() << 8;
Wire.endTransmission();
return data;
}
Then in the setup function I initialise them like this:-
// Setup I2C devices
Wire.begin(); // start the I2C interface
// initialise port expanders INT internal connected + open drain int
gpio_write(chip1Address, (MIRROR | ODR)<<8, IOCON);
gpio_write(chip2Address, (MIRROR | ODR)<<8, IOCON);
gpio_write(chip3Address, (MIRROR | ODR)<<8, IOCON);
gpio_write(chip4Address, (MIRROR | ODR)<<8, IOCON);