Project 016 - Arduino I2C 32ch Digital I/O Extender Board
This is my first Arduino shield. The "IanJ I2C 32ch Digital I/O Extender Board".
Specifications/Info:-
- 32 digital I/O channels, each configurable as input or output.
- Configured as inputs, you can assume internal pull up resistors on each channel.
- I2C addresses configurable via DIP switches.
- +5vdc supply from Arduino main board (see note 1).
- Interrupt line available to tie back to main Arduino
Note 1:-
Each output is capable of 25mA sink, however, with 32 possible outputs this is 800mA (0.8A)
and so an external 5vdc supply must be used.
See the board I/O diagram below (coming soon) for info on selecting this mode.
With a relatively low current consumption expectation, such as when using a lot of inputs, you can use the Arduino +5vdc supply to power the board.
References:
For more information on usage of the interrupt line, how to independently assign each pin as input or output, driving high current loads, or learn about the I2C commands, refer to:
http://www.nxp.com/documents/data_sheet/PCA8574_PCA8574A.pdf
http://www.arduino.cc/en/Reference/Wire
Here's a partial 3D rendered interpretation of the board (missing the pushbutton & the screw terminals).

And here's a photo of the 1st prototype, minus the switches:-

Demo sketch:-
There are many ways to pass data via I2C and to manipulate bits/bytes of data. This sketch offers a minimal demo (showing how easy it is!) on how to control the board.
1/*2 Demo program for "IanJ I2C 32ch Digital I/O Extender Board"3 V1.0 - By Ian Johnston, Feb 2010.4 The Pcb has 4off IC's, designated U1, U2, U3 & U4.5 In this demo sketch:-6 U1 = All 8 channels set for digital output7 U2 = All 8 channels set for digital input8 U3 = All 8 channels set for digital output9 U4 = All 8 channels set for digital input10*/11 12#include <wire.h>13 14// Setup I2C addresses for the 4off IC's. These are 7-bit addresses.15// 4off bits internal to IC, last 3 bits via switches on pcb, i.e. 0100 [A1] [A2] [A3]16// Note: An 8th bit sets direction, however Wire.h takes care of this automatically.17byte U1_ADDR = 33; // B0100001 = Pcb Switch setting = 00118byte U2_ADDR = 34; // B0100010 = Pcb Switch setting = 01019byte U3_ADDR = 35; // B0100011 = Pcb Switch setting = 01120byte U4_ADDR = 36; // B0100100 = Pcb Switch setting = 10021 22// Setup variables23byte I2C_dataTx; // Data to outputs IC's24byte I2C_dataRx; // Data from input IC's25int I2C_TxAddr; // IC Address holder for output26int I2C_RxAddr; // IC Address holder for input27int i=0; // Demo variable only28int delaytime=100; // Demo variable only29 30void setup() {31 32 Wire.begin();33 34}35 36void loop() {37 38 // DIGITAL OUTPUT - A few examples on how to drive outputs39 40 // Demo turn all outputs on in one go, on U141 I2C_dataTx = B11111111; // Make up byte to be sent from binary data of port P7,P6,P5,P4,P3,P2,P1,P042 I2C_TxAddr = U1_ADDR; // Set 7-bit I2C address to send to43 I2C_Send(); // Run subroutine and send data to I2C bus44 delay(delaytime);45 46 // Demo turn all outputs off in one go, on U147 I2C_dataTx = B00000000; // Make up byte to be sent from binary data of port P7,P6,P5,P4,P3,P2,P1,P048 I2C_TxAddr = U1_ADDR; // Set I2C address to send to49 I2C_Send(); // Run subroutine and send data to I2C bus50 delay(delaytime);51 52 // Demo rotate round all 8off bits on U1 turning them on one by one53 I2C_TxAddr = U1_ADDR; // Set I2C address to send to54 for(i = 0; i < 7; i++) {55 bitSet(I2C_dataTx, i);56 I2C_Send(); // Run subroutine and send data to I2C bus57 delay(delaytime);58 }59 60 // Demo rotate round all 8off bits on U1 turning them off one by one61 I2C_TxAddr = U1_ADDR; // Set I2C address to send to62 for(i = 0; i < 7; i++) {63 bitClear(I2C_dataTx, i);64 I2C_Send(); // Run subroutine and send data to I2C bus65 delay(delaytime);66 }67 68 69 // DIGITAL INPUT - A few examples on how to read inputs70 71 // Demo receive data from U272 I2C_RxAddr = U2_ADDR; // set I2C address73 I2C_Receive(); // Run subroutine and receive data from I2C bus, data appears in var I2C_dataRx74 75 // Now do something with one of the bits, let's speed up the whole main loop a bit. Note: inputs are normally high so test for 076 if (bitRead(I2C_dataRx, 0) == 0) { // Check bit 077 delaytime=50;78 }79 80 // And one of the other bits, let's speed up the whole main loop a lot81 if (bitRead(I2C_dataRx, 1) == 0) { // Check bit 182 delaytime=25;83 }84 85 // And one of the other bits, reset the speed back to default86 if (bitRead(I2C_dataRx, 2) == 0) { // Check bit 287 delaytime=100;88 }89 90}91 92void I2C_Send() {93 // I2C send routine94 Wire.beginTransmission(I2C_TxAddr); // setup I2C address to send to95 Wire.send(I2C_dataTx); // send byte to that address96 Wire.endTransmission(); // end send97}98 99void I2C_Receive() {100 // I2C receive routine101 Wire.requestFrom(I2C_RxAddr, 1); // request 1 byte from I2C address102 if (Wire.available()) I2C_dataRx = Wire.receive();103}Codequote by Ian Johnston

