Hi,
I am currently on a I2C mission and after my success with creating the I2CLcd module from the playground I was encouraged to use a MCP23008 to try and control a shift register (74hc595) to extend outputs.
The shift register has three pins that control it namely latch, clock and data. Latch goes low to start transmission, data pin is set accordingly and clock is taken high and then low to 'shift'. Transmission complete is signalled by latch pin going high. These pins are normally controlled by the Arduino.
The circuit I built works with three of the MCP23008 output pins connected to the three control pins on the 74hc595 but I am not having any joy.
The shift register part of the circuit works when I connect the three control pins to the arduino and run the Shifout sample and the MCP23008 does flash LEDs on the corresponding data pins when tested so I believe the circuit is good.
I have triple verified that the output pins from the MCP23008 correspond with the correct control pins on the 74hc595.
My guess is that the MPC23008 output pins 'float' every time it's register is set which confuses the 74hc595 since the latch pin must stay low for the duration of the transmission. :-?
Anyone got any ideas on this?
Here is the code:
#include <Wire.h>
int ADDR = 0xA6;
int ledPin = 3;
/*
I2C Implementation of Shifout uses MCP23008 and 74HC595
Last Binary Digit Controls Latch on 74hc595
Second Last Binary Digit Controls Clock on 74hc595
Third Last Binary Digit Controls Data on 74hc595
--
Use first Bindary Digit to Flash a MCP23008 connected LED to indicate transmission - Debug only
--
Wiring of 74hc595 as per Shiftout example
Wiring MCP23008 as per 12cLCD example
*/
void setup()
{
Serial.begin(9600);
Wire.begin(); // join i2c bus (address optional for master)
setMCPReg(ADDR,0x05,0x0C); // set CONFREG (0x05) to 0 initialise MCP
delay(5);
setMCPReg(ADDR,0x00,0x00); // set IOREG (0x00) to 0 initialise MCP
delay(5);
setMCPReg(ADDR,0x0A,0x00); // set all output pins to low
delay(5);
setMCPReg(ADDR,0x0A,B00000001); // set latch high
delay(500);
// Test starts here, should light up 3 leds on data pins 1,2,3 on 74hc595
shiftOutI2C(B00001000);
delay(800);
shiftOutI2C(B00001010);
delay(800);
shiftOutI2C(B00001110);
// debug - set all high
delay(800);
shiftOutI2C(B11111111);
// debug - set all low
delay(800);
shiftOutI2C(B00000000);
}
void loop()
{
}
void setMCPReg( byte deviceAddr, byte reg, byte val ) {
Wire.beginTransmission(deviceAddr);
Wire.send(reg);
Wire.send(val);
Wire.endTransmission();
}
void shiftOutI2C(byte myDataOut) {
// Adaptation of example Shiftout from Arduino Wiki
//internal function setup
int i=0;
byte pinState;
byte pinState2;
// digitalWrite(myDataPin, 0);
// digitalWrite(myClockPin, 0);
setMCPReg(ADDR,0x0A,B10000000); // set latch low , clock and data low ** start of transmission
delay(5);
//for each bit in the byte myDataOut?
//NOTICE THAT WE ARE COUNTING DOWN in our for loop
//This means that %00000001 or "1" will go through such
//that it will be pin Q0 that lights.
for (i=7; i>=0; i--) {
// digitalWrite(myClockPin, 0);
setMCPReg(ADDR,0x0A,B10000000);// latch stays low, clock and data low
delay(5);
if ( myDataOut & (1<<i) ) {
pinState= B10000100; // latch stays low - clock pin low - data pin high
pinState= B10000110; // latch stays low - clock pin high to 'shift' register - data pin high
}
else {
pinState= B10000000; // latch stays low - clock pin low - data pin low
pinState2= B10000010; // latch stays low - clock pin high to 'shift' register - data pin low
}
//Sets the pin to HIGH or LOW depending on pinState
//digitalWrite(myDataPin, pinState);
setMCPReg(ADDR,0x0A,pinState);
delay(5);
//register shifts bits on upstroke of clock pin
// digitalWrite(myClockPin, 1);
setMCPReg(ADDR,0x0A,pinState2); // clock pin goes high, with whatever was on datapin - latch still low ** register shifts
delay(5);
//zero the data pin after shift to prevent bleed through
// digitalWrite(myDataPin, 0);
setMCPReg(ADDR,0x0A,B10000010); // latch stays low - clock stays high - data pin low
delay(5);
}
//stop shifting
//digitalWrite(myClockPin, 0);
setMCPReg(ADDR,0x0A,B10000000); // latch stays low - clock moves to low - data pin stays low
delay(5);
setMCPReg(ADDR,0x0A,B00000001); // latch changes to high - clock stays low - data stays low ** end of transmission - commit register
delay(5);
}
Note I have left as comments most of the original 'digitalwrite' statement from the Shiftout function as reference..
Any help is greatly appreciated.