Can't get second 74HC595 shift register working!

Not sure what I’m doing wrong here. I’m following this tutorial:

I’ve checked the wiring several times, and as far as I can tell, I’ve got it wired right. The only difference between my setup here and the one shown in the diagrams is that I’m not using all 16 LEDs - I have 4 connected to the first register and 1 connected to the second.

The first register works great, the LEDs light up one at a time in order. But, the second register just lights up the single LED I have connected to it immediately and doesn’t change. No matter what output pin on the register I connect that LED to, it just goes HIGH right away and stays there.

If I disconnect the Serial-Out connection from the first register, eventually the LED on the second register will go dark (it goes dark right away if I touch the jumper, which makes me think if the Serial-In on the second register gets pulled LOW, the LED goes off). If I reconnect the Serial-Out, however, the LED just goes back to HIGH and stays there. How do I get the second register to work?

Here’s the code I’m using, also lifted from the tutorial:

//**************************************************************//
//  Name    : shiftOutCode, Dual One By One                           //
//  Author  : Carlyn Maw, Tom Igoe                               //
//  Date    : 25 Oct, 2006                                       //
//  Version : 1.0                                                //
//  Notes   : Code for using a 74HC595 Shift Register            //
//          : to count from 0 to 255                             //
//**************************************************************//

//Pin connected to ST_CP of 74HC595
int latchPin = 8;
//Pin connected to SH_CP of 74HC595
int clockPin = 12;
////Pin connected to DS of 74HC595
int dataPin = 11;

//holder for infromation you're going to pass to shifting function
byte data = 0; 



void setup() {
  //set pins to output because they are addressed in the main loop
  pinMode(latchPin, OUTPUT);

}

void loop() {

  //function that blinks all the LEDs
  //gets passed the number of blinks and the pause time
  blinkAll_2Bytes(1,500); 

  // light each pin one by one using a function A
  for (int j = 0; j < 8; j++) {
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //red LEDs
    lightShiftPinA(7-j);
    //green LEDs
    lightShiftPinA(j);
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    delay(1000);
  }

  // light each pin one by one using a function A
  for (int j = 0; j < 8; j++) {
    //ground latchPin and hold low for as long as you are transmitting
    digitalWrite(latchPin, 0);
    //red LEDs
    lightShiftPinB(j);
    //green LEDs
    lightShiftPinB(7-j);
    //return the latch pin high to signal chip that it 
    //no longer needs to listen for information
    digitalWrite(latchPin, 1);
    delay(1000);
  } 

}

//This function uses bitwise math to move the pins up
void lightShiftPinA(int p) {
  //defines a local variable
  int pin;

  //this is line uses a bitwise operator
  //shifting a bit left using << is the same
  //as multiplying the decimal number by two. 
  pin = 1<< p;

  //move 'em out
  shiftOut(dataPin, clockPin, pin);   

}

//This function uses that fact that each bit in a byte
//is 2 times greater than the one before it to
//shift the bits higher
void lightShiftPinB(int p) {
  //defines a local variable
  int pin;

  //start with the pin = 1 so that if 0 is passed to this
  //function pin 0 will light. 
  pin = 1;

  for (int x = 0; x < p; x++) {
    pin = pin * 2; 
  }
  //move 'em out
  shiftOut(dataPin, clockPin, pin);   
}


// the heart of the program
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) {
  // This shifts 8 bits out MSB first, 
  //on the rising edge of the clock,
  //clock idles low

  //internal function setup
  int i=0;
  int pinState;
  pinMode(myClockPin, OUTPUT);
  pinMode(myDataPin, OUTPUT);

  //clear everything out just in case to
  //prepare shift register for bit shifting
  digitalWrite(myDataPin, 0);
  digitalWrite(myClockPin, 0);

  //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);

    //if the value passed to myDataOut and a bitmask result 
    // true then... so if we are at i=6 and our value is
    // %11010100 it would the code compares it to %01000000 
    // and proceeds to set pinState to 1.
    if ( myDataOut & (1<<i) ) {
      pinState= 1;
    }
    else {	
      pinState= 0;
    }

    //Sets the pin to HIGH or LOW depending on pinState
    digitalWrite(myDataPin, pinState);
    //register shifts bits on upstroke of clock pin  
    digitalWrite(myClockPin, 1);
    //zero the data pin after shift to prevent bleed through
    digitalWrite(myDataPin, 0);
  }

  //stop shifting
  digitalWrite(myClockPin, 0);
}


//blinks both registers based on the number of times you want to 
//blink "n" and the pause between them "d"
//starts with a moment of darkness to make sure the first blink
//has its full visual effect.
void blinkAll_2Bytes(int n, int d) {
  digitalWrite(latchPin, 0);
  shiftOut(dataPin, clockPin, 0);
  shiftOut(dataPin, clockPin, 0);
  digitalWrite(latchPin, 1);
  delay(200);
  for (int x = 0; x < n; x++) {
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 255);
    shiftOut(dataPin, clockPin, 255);
    digitalWrite(latchPin, 1);
    delay(d);
    digitalWrite(latchPin, 0);
    shiftOut(dataPin, clockPin, 0);
    shiftOut(dataPin, clockPin, 0);
    digitalWrite(latchPin, 1);
    delay(d);
  }
}

Forget that crappy tutorial and learn how to use SPI or shiftOut() with your shift registers.

Hi,
Google

arduino 74hc595 library

Tom.. :slight_smile:

Long standing errors in the breadboard view of that page.
The cap should not go on the data line, but from 595 VCC to ground.
Schematic view seems to be correct.
Leo..

SPI actually seems to make it worse. The original code I posted successfully drives the first shift register, causing each LED to light one at a time in a loop (the only problem is the second shift register is always putting out HIGH).

If I use this block of code (borrowed from a tutorial) that uses SPI, neither shift register works. All LEDs on the first register go LOW and the second stays HIGH.

#include <SPI.h>

// define pins and other variables
const int latchPin = 8;
const int clockPin = 13;
const int dataPin  = 11;

// setup the correct pins and initialize SPI library
void setup() {
 // setup pins
 pinMode(latchPin, OUTPUT);
 pinMode(clockPin, OUTPUT);
 pinMode(dataPin,  OUTPUT);
 
 // setup SPI library
 SPI.setBitOrder(MSBFIRST);
 SPI.setDataMode(SPI_MODE0);
 SPI.setClockDivider(SPI_CLOCK_DIV2);
 SPI.begin();
}

void loop() {
 for(int i =0; i < 16; i++){
   turnOnLed(i);
 }
}

// turn on correct LED using 595's
void turnOnLed(int ledNr) {
 digitalWrite(latchPin, LOW);

 if (ledNr >= 8) {
   SPI.transfer(1<<ledNr-8);
   SPI.transfer(0);
 }
 else {
   SPI.transfer(0);
   SPI.transfer(1<<ledNr);
 }

 digitalWrite(latchPin, HIGH);
}

Remember, no hardware changes between these! What gives??

FWIW I worked around this by just using 3 more pins for the second shift register and controlling it that way. So, not as sexy, but I'm using 6 pins to drive 16 LEDs. I'm going to experiment to see if I can share a couple more (maybe I can share the clock, for instance?)

You still use absolutely crappy code in the data transmission. Sending 2 bytes in sequence to daisy chained shift registers will deposit the first byte in the most distant register, and the last byte in the first register. Any attempt to transmit anything but bytes will result in bogus.

Care to give me an example of what non-crappy code would look like here? I'm just pulling straight from published tutorials.

Either you continue following crappy tutorials, or you start reading the Arduino Resources and start playing with the IDE examples. After understanding the SPI examples you should be able to solve all your problems.

Maybe it’s your wiring. Post a picture of your setup.
Using a breadboard with split power rails is a common trap.
Leo…

Hi,
Have you tried what I said in post #2.
Find a library that will do all the bit bashing for you.

A picture and a hand drawn schematic of your project will help.
Reverse engineer what you have on your protoboard to get your schematic.

@Wawa is suggesting you protoboard may have this type of config.
protobreak.jpg
Tom... :slight_smile:

protobreak.jpg