3

EDIT 4/2/18: The Arduino tutorial schematics have been corrected! See https://github.com/arduino/Arduino/issues/6433 for that issue.

I have a project where I am trying to load a 16-bit number onto an EEPROM using an Arduino hooked up to two 74HC595 Shift registers.

I'm loosely following this Arduino tutorial: https://www.arduino.cc/en/Tutorial/ShiftOut, but I'm getting unexpected outputs depending on the number I try to load into the register. I've reduced everything to as simple a setup as I can, and have spent several hours trying to figure out what the heck is going wrong... obviously to no avail.

Here is the schematic - with the exception that I moved the capacitor off of ST_CP (why would they put that in the tutorial?) to between power and ground:

Schematic

Here is my code:

#define SHIFT_DATA 2
#define SHIFT_CLK 3
#define SHIFT_LATCH 4

void setup() {
  pinMode(SHIFT_DATA, OUTPUT);
  pinMode(SHIFT_CLK, OUTPUT);
  pinMode(SHIFT_LATCH, OUTPUT);

  int address = 0b1111111111111111;  // Case 1
//int address = 0b0000000000000000;  // Case 2
//int address = 0b0101010101010101;  // Case 3
//int address = 0b1010101010101010;  // Case 4
//int address = 0b0101100110101110;  // Case 5

  shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, (address >> 8)); // Load first 8 bits
  shiftOut(SHIFT_DATA, SHIFT_CLK, MSBFIRST, address);        // Load second 8 bits

  digitalWrite(SHIFT_LATCH, LOW);
  digitalWrite(SHIFT_LATCH, HIGH);
  digitalWrite(SHIFT_LATCH, LOW);
}

void loop() {
  // none
}

Here is a picture of my breadboard setup with Case 1 loaded:

Breadboard setup

And here follows my test cases.

  1. All 1's (1111111111111111). Looks good.
  2. All 0's (0000000000000000). Looks good.
  3. Repeated 01's (0101010101010101). Looks good.
  4. Repeated 10's (1010101010101010). Output: 1010101000000000. First 8 bits match, last 8 are zeros. Huh?
  5. Random sequence (0101100110101110). Output: all over the place. Initially the first 8 bits match as in Case 4, but on repeated resets of the Arduino the output changes, with some weird momentary flickering going on for some of the LEDs. If I press it enough times I can get it back to the initial output, but never what I expect. I am completely stumped. Here is an animated gif of this behavior running on the breadboard: http://i.imgur.com/KEwpSXe.gifv.

What could my problem be? I assume it's something very simple and I'm being an idiot.

  • 3
    One of the other serious (though more subtle) faults with that poor Arduino tutorial is the resistors are too low. Turn on too many LEDs and you draw more current through the 74HC595 chip than it can cope with. You can potentially try and draw up to approx. 109mA with those values but the 74HC595 can only manage 70mA total. – Majenko Aug 31 '17 at 9:57
  • @Majenko If we instead had, say, 40 LEDs and 5 daisy chained shift registers, what resistor and capacitor values would be appropriate to not blow out the shift registers? Thanks! – Joe Flip Dec 12 '17 at 17:57
  • 1
    @JoeFlip The same as for one. Each shift register is a discrete self contained block. – Majenko Dec 12 '17 at 18:07
4

You should change your capacitors.

You only have 0.1µF instead of 1µF for the bulk capacitor (which really wants to be 10µF). In addition you should add 0.1µF (100nF) capacitors directly across the power pins of each chip:

enter image description here

  • My god, that actually worked. 10 uF across the power rails makes the output rock solid. Shows me how much to trust in a Nano's voltage regulation. Thank you! – Scott Sep 1 '17 at 2:26
  • It's not the Nano's regulation, it's the internal switching in the '595. The 0.1uF helps with the transient surges. TPIC6B595 sinking current thru LEDs is also a much better chip to use here. Shift a 1 in to turn on an output. – CrossRoads Apr 4 '18 at 15:52
3

I have forum post about the 595 chip and a question and answer about SPI.

You can use SPI to do the transfer. This is faster and simpler than shiftOut. Also you need to bring the latch low before transferring the data.

Simple example sketch:

#include <SPI.h>

const byte LATCH = 10;

void setup ()
{
  SPI.begin ();
}  // end of setup

byte c;
void loop ()
{
  c++;
  digitalWrite (LATCH, LOW);
  SPI.transfer (c);
  digitalWrite (LATCH, HIGH);
  delay (20);
}  // end of loop
  • 3
    Actually not true re the latch - the latch is edge triggered (a simple RS-type flip-flop per bit) and loads the data from the shift register D-type flip-flops into the output latch RS flip-flops on a rising edge. It doesn't matter when it goes low as long as it goes from low to high at the point you want the outputs to change their state. Simple double buffering. True, it doesn't hurt to set it low early like that, but it's not a requirement. The only thing to watch is the minimum LOW or HIGH period of the RCLK (ST_CL on the diagram above) must be more than 20ns at VCC=4.5V. – Majenko Aug 31 '17 at 9:52
  • 1
    I thought it was great how you used c as your variable -> c++ – sa_leinad Aug 31 '17 at 12:43
  • I haven't tried your code before heading off to work for the day, but it's worth noting that I don't see a change in behavior by either setting the latch low before shifting out data, or adding a delay(20) before and after each latch change of state. – Scott Aug 31 '17 at 13:20
  • @sa_leinad Thanks! Unintentional however. :) Scott: I can't reproduce your problem using actual hardware and your original code. However Majenko's suggestion of the 0.1µF capacitors could explain the problem. – Nick Gammon Sep 1 '17 at 2:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.