Quick2Wire Port Expander Tested
With the Quick2Wire board and port expander both assembled and liberally photographed I decided to set about testing, specifically, the Port Expander board. It interests me more than the vanailla Quick2Wire board, which is basicaly not much more than a method of protecting the Raspberry Pi's GPIO and providing a platform to hook up all the useful stuff.
The Port Expander offers 16 additional inputs/outputs through the great little MCP23017 chip. Each IO pin can be individually assigned as an input/output, can have a weak pull-up resistor enabled and can handle interrupts. It's a very fully-featured chip and you should read the datasheet to learn more. It really isn't all that hard to understand.
I used a handful of methods to get i2c up and running, from Quick2Wire's own Python library, which worked well but frustrated me with Pythonness. Diving over to Ruby I first used system calls to i2cset, expressed Port A and Port B of the MCP23017 as two bytes in a 16bit integer and used bitwise operations to turn on/off pins and extract the relevant byte of information for each port. This lead to ugly things like: "0x%x" % ( ( @leds & FIRST_BYTE ) >> 8 )
After much effort, I then decided to look for a Ruby i2c library and stumbled across Andec's WiringPi-compatible i2c library for Ruby which was much cleaner to use.
Using the i2c library I was able to ressurect my Ruby Binary Clock example and patch it to work with the MCP23017 using this drop-in, but by no means feature-complete, replacement for "gpio.rb":
class Gpio require 'i2c' @i2c = I2C.create('/dev/i2c-1') @mcp = I2C::Drivers::MCP23017.new(@i2c,0x20) def self.mode( pin, mode ) @mcp.mode( pin, mode ) end def self.write( pin, value ) @mcp.write( pin, value ) end end
The MCP23017 driver in Andec's i2c library is beautifully easy to use. It needs only an instance of I2C and a device address, and will then expose PortA and PortB as a single continous series of pins numbered 0 to 15. A quick tweak of the pin numberings in my clock example, and it was up and running perfectly. I used 14 of the 16 available pins on the Port Expander, and will have to experiment with adding buttons on the remaining two.
The Quick2Wire Port Expander is a brilliant board that will save you having to fiddle with shift registers or other ICs to expand your IO.
My only gripe with it is the arrangement of the PortA and PortB headers, which are a little close together for comfortably stuffing jump wires into. Personally I'd prefer them either side of the board, or arranged in a single row.
The MCP2307 is extremely easy to understand and program once you get over the initial setup hurdle, although the Quick2Wire python examples are a little thin on the ground. It took Gordon Drogon's C example before I really grokked the chip and how to use it.
Download my mcp-clock.rb binary clock example. You will need 14 LEDs coupled with suitable resistors and connected to pins 2-15 of the Port Expander to see it in action. You can use the ground connection on the GPIO header of the main Quick2Wire board.