Three 74HC595 daisy chained, third acts like first

Hello everyone, this is my first Arduino project attempt after completing the Arduino Starter Kits Project book, so please bear with me.

I have an Arduino Uno R3, with a breadboard and three 74HC595s. The goal is to make a LED clock with 17 LEDs. The maximum LED count with two 74HC595s is 16, so, I need another one for the 17th. I know from the forums that there are other ways to do this, and I know that it's recommended to have 0.1µF decoupling capacitors. I don't have those, I should order them I guess.

Anyway, I had everything working fine with two 74HC595s, was able to animate the LEDs. But then I added the third 74HC595 and... for some reason it's doing the same as the first one. Here's a picture. of my setup with no LEDs attached.

I have followed this schematic, it seems pretty intuitive (and I used 3, not 4 chips):

When I blink a single LED, pin 15 on the third (top on my picture) 74HC595, acts the same as pin 15 on the first (bottom) 74HC595.

I have tested it using the following code:

#include <ShiftRegister74HC595.h>
const int numberOfShiftRegisters = 3; // number of shift registers attached in series
const int serialDataPin = 2; // DS
const int clockPin = 3; // SHCP
const int latchPin = 4; // STCP
ShiftRegister74HC595<numberOfShiftRegisters> sr(serialDataPin, clockPin, latchPin);

void setup() {
  sr.setAllLow();
}

void loop() {
  sr.set(0, HIGH);
  delay(100);
  sr.set(0, LOW);
  delay(100);
}

What am I doing wrong? Note: using sr.set(16, HIGH) does nothing to pin 15 on chip 3.

What is wrong for a start is that you have no supply decoupling on each shift registers chip. This is a 0.1uF ceramic capacitor places between the 5V and ground as close to the chip as you can get it, with as short a lead on the component as possible.

These are missed off many projects on the internet because they are written by people who don't know what they are doing.

You might have other errors but this is the first one that needs doing before you ok at the rest of the circuit.

Okay. I also barely know what I'm doing. The chips are connected to 5V and ground twice per chip. So where do I put the ceramic capacitor? I'll pick up a batch tomorrow. I don't understand what you mean with "as short a lead on the component as possible" maybe because I'm not a native English speaker.

(edit: ok the leads are the wires. These have to be short. Got it.)

A 100nF ceramic capacitor, with short leads, are to be on all Vcc pins to GND.

These capacitors must be installed very close to these power pins and GND.

Alright. I'll get on it as soon as I have them.

Why do the leads (these are the metal pins yes?) need to be as short as possible?

When they are long they add too much inductance which then defeats the purpose of using them.

image

image

2 Likes

Alright. That is really helpful. Now I understand.

Are there any other capacitors you would recommend? Browsing around looking for information, I saw people suggest 0.1µF (same as you) and 10µF capacitors? The drive to the shop is a bit long so I'd better buy some extra.

If they are ceramic construction, .1uF to 1uF should be more than enough.
BTW .1uF is 100nF

10uF is fine if we were talking about SMD ceramics or the newer polymer Tantalums.
However a solderless breadboard and SMDs don’t work well :wink: .


Always buy extras ! :+1:


Actually, you can use SMDs on a breadboard:

You might find the other 900 posts on the above thread interesting too.

2 Likes

BTW .1uF is 100nF

that part I understood :grin: but good that you say this, because these uncommon units (micro, nano, pico) are so uncommon. It looks like the Arduino Starter Kit has 5x100nF, and 5x100pF. For three HC595s I need 6x100nF but ok, at least I can experiment a bit with these 5. I'll make a picture.

What is 100pF commonly used for?

Actually, you can use SMDs on a breadboard

hey, that's cool!

Have a read of this
http://www.thebox.myzen.co.uk/Tutorial/De-coupling.html

It tells you the theory about it.
The 0.1uF is the standard value but it has to be ceramic, any other types will not work.
The 10uF is not a ceramic type, these are electrolyte types, meaning they must be connected the correct way round are often used in parallel to the smaller ceramic types to smooth the low frequency noise.

No they are very common in many field of science. The units of milli is ten to the minus three, micro is ten to the minus six, nano ten to the minus nine and Pico ten to the minus twelve.

1 Like

I'll check out that link, much thanks.

Turns out that the starter kit has 100pF ceramic but the 100nF are not, those are blue squares, probably some type of plastic from what I can tell.

I have so much respect for you guys' patience when dealing with noobs like myself :sweat_smile:

Correct, both the same value but you would use the plastic ones ( polyester or polypropylene) are much better for audio applications as they are more stable. Where as a ceramic has good high frequency responses they tend to change there value slightly with the voltage across them. This doesn't matter for decoupling but do not produce a flat response for audio.

Okay, so, let's pretend that my 100µF capacitors are 0.1µF ceramic, and they have short leads (lol). Would it be correctly connected in the following way?

Aside of the capacitors... can it be you only shift 16 bits?
As i understood you want to use it for a clock (wordclock perhaps?) i ripped a few sentences from my own wordclock-sketch and renamed the words so you might understand what i'm doing here.. Display 1-3 are the 595's 1 to 3 and ONE to TWENTYFOUR are the outputs
No library needed.. Should work instantly with your setting...


#define DATA        2
#define LATCH      3
#define CLK           4

#define ONE         Display1 |= (1<<0)
#define TWO         Display1 |= (1<<1)
#define THREE       Display1 |= (1<<2)
#define FOUR        Display1 |= (1<<3)
#define FIVE        Display1 |= (1<<4)
#define SIX         Display1 |= (1<<5)
#define SEVEN       Display1 |= (1<<6)
#define EIGHT       Display1 |= (1<<7)

#define NINE        Display2 |= (1<<0)
#define TEN         Display2 |= (1<<1)
#define ELEVEN      Display2 |= (1<<2)
#define TWELVE      Display2 |= (1<<3)
#define THIRTEEN    Display2 |= (1<<4)
#define FOURTEEN    Display2 |= (1<<5)
#define FIFTEEN     Display2 |= (1<<6)
#define SIXTEEN     Display2 |= (1<<7)

#define SEVENTEEN   Display3 |= (1<<0)
#define EIGHTEEN    Display3 |= (1<<1)
#define NINETEEN    Display3 |= (1<<2)
#define TWENTY      Display3 |= (1<<3)
#define TWENTYONE   Display3 |= (1<<4)
#define TWENTYTWO   Display3 |= (1<<5)
#define TWENTYTHREE Display3 |= (1<<6)
#define TWENTYFOUR  Display3 |= (1<<7)

byte Display1 = 0, Display2 = 0, Display3 = 0;

/****************************************************/
void setup() {
  pinMode(LATCH, OUTPUT);
  pinMode(DATA, OUTPUT);
  pinMode(CLK, OUTPUT);
  welcome();
}
void loop() {
}
/****************************************************/
void welcome() {
  LedsOff(); WriteLEDs();
  ONE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWO; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  THREE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  FOUR; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  FIVE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  SIX; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  SEVEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  EIGHT; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  NINE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  ELEVEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWELVE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  THIRTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  FOURTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  FIFTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  SIXTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  SEVENTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  EIGHTEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  NINETEEN; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWENTY; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWENTYONE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWENTYTWO; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWENTYTHREE; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
  TWENTYFOUR; WriteLEDs(); delay(150); LedsOff(); WriteLEDs();
}
/****************************************************/
void LedsOff() {
  Display1 = 0;
  Display2 = 0;
  Display3 = 0;
}
/****************************************************/
void WriteLEDs() {
  digitalWrite(LATCH, LOW);
  shiftOut(DATA, CLK, MSBFIRST, Display3);
  shiftOut(DATA, CLK, MSBFIRST, Display2);
  shiftOut(DATA, CLK, MSBFIRST, Display1);
  digitalWrite(LATCH, HIGH);
  delay(2);
}
1 Like

Thank you. That code is something worth checking out, and btw, the idea of making a word clock is awesome so thanks for that too. :grin:

Well, it could be that it shifted 16 bits (who knows) but with that library's numberOfShiftRegisters set to 3, you'd imagine that it would work properly - or at least not in the way it did.

I also tested it with a different piece of code, which I found on the forums, and I didn't have any luck there either: the third IC's first LED-connected pin acted exactly like the first IC's first LED-connected pin.

Code was as follows:

// Found: https://forum.arduino.cc/t/im-having-trouble-daisy-chaining-two-shift-registers-together-and-executing-a-s/263283/2

int datapin = 2;
int clockpin = 3;
int latchpin = 4;

unsigned long data[18]= {
  0b11111111111111111,
  0b01111111111111111,
  0b00111111111111111,
  0b00011111111111111,
  0b00001111111111111,
  0b00000111111111111,
  0b00000011111111111,
  0b00000001111111111,
  0b00000000111111111,
  0b00000000011111111,
  0b00000000001111111,
  0b00000000000111111,
  0b00000000000011111,
  0b00000000000001111,
  0b00000000000000111,
  0b00000000000000011,
  0b00000000000000001,
  0b00000000000000000
};

void setup()
{
  pinMode(datapin, OUTPUT);
  pinMode(clockpin, OUTPUT);
  pinMode(latchpin, OUTPUT);
  Serial.begin(9600);
}


void loop()
{
  manyOnAtATime();       // Scroll down the line
}


void shiftWrite(unsigned int desiredPins)
{
  shiftOut(datapin, clockpin, MSBFIRST, highByte(desiredPins));
  shiftOut(datapin, clockpin, MSBFIRST, lowByte(desiredPins));
  digitalWrite(latchpin, HIGH);
  digitalWrite(latchpin, LOW);
}

void manyOnAtATime()
{
  int i;
  int delayTime = 1000;
  for (i = 0; i < 17; i++)   // Note: I also tried i < 18 to no avail -- Mark
  {
    shiftWrite(data[i]);  // turn LEDs on
    delay(delayTime);   // pause to slow down the sequence
    Serial.print("i: ");
    Serial.print(i);
    Serial.print( ", data[");
    Serial.print(i);
    Serial.print("]: ");
    Serial.print(data[i]);
    Serial.println(".");
  }
}

Just a little anekdote: I've been a Linux system administrator for close to 23 years. In my teens I worked at a computer shop where people would often bring their computer with the old "it doesn't work." They'd report all kinds of erratic problems. But when we connected them in our shop and tested it inside and out, often we could not find any problem. So then the question we asked the customer was, "is your computer power connection at home grounded (earth wire)?" In many many cases it was not. So when they tried a different wire, for example from the kitchen where ground wires are mandatory, their PC would stop acting up.

So, that's why I have no doubt about lack of capacitors causing my problem. This is a house built in the 70s, in a pretty old village. in the house I have LED lightbulbs on a dimmer. Especially at night, they have kind of the same flickering as an old diesel car in the freezing cold. I was told by the power company that this is probably due to a nearby-ish factory's current demands. So we probably have unstable power here that is especially noticeable on these low-voltage projects like LEDs. That's my newbie guess at least.

as i can see from that code, and interprete it right, it is also 16 bits.. Try my code.. i have it working here without any decoupling..
Maybe you have to renumber CLOCK LATCH and DATA ...

Yes, if those were 100nF and had short leads.

But remember, solderless breadboards are quite bad since they are not designed for high speed stuff and are often intermittent in nature.

image


image

A capacitor on pin 16 would suffice.

Alright: "here be dragons."

A capacitor on pin 16 would suffice.

For pin 10 and 13 just take out that capacitor but leave the connection to 5V and GND?

No problem. I'm connecting it back to how it was and then I'll give your code a try.

Wiring stays, the cap between 10 & 13 not necessary.

Ceramic capacitor between 16 & GND is needed.

1 Like