Odd behaviour from a string of 74HC595 in the first few seconds following start

Hi All,

I have an Arduino Pro Mini 5V driving 4 series 74HC595 which in turn drives a 12 x 12 common cathode LED matrix using the SPI interface. I am wasting 4 bits of 2 shift registers but at the moment I don't have a 16 x 16 matrix. The last 12 bits of the last 16 bits are column selectors and drive BC337 transistors through 4k7 resistors to the base. The common cathodes of each column connect to the collectors of each of these transistors. The rows are driven from the last 12 of the first 16 bits. Current limiting resistors are 470R. I have based the design on the information which can be found here: Gammon Forum : Electronics : Microprocessors : Using a 74HC595 output shift register as a port-expander. (thanks Nick - yet another great post)

The clock rate of the SPI interface is maxed out at SPI_CLOCK_DIV2 however it turns out this does not affect my problem. Any clock rate same effect.

The circuit is bypassed reasonably well with the use of 4x1uF electros + 4x 0u1F ceramics as close as possible to being across the 74HC959 power pins as is achievable on a breadboard. I hate breadboards as they are as noisy as you can get. I don't think this is a noise problem though. They don't go away. I accept this circuit is running fast and the power will be bouncing about but why should it cure itself?

The code I am running simply cycles a lit up column left to right at 100mS intervals. On startup the display cycles as expected BUT there are a few flickery LEDS in a couple of columns ( column 4 and 5 actually which are driven from the last bit of the third 74C595 in the chain and the first bit of the fourth 74HC595 in the chain) which should be solidly out except for when the column is on. The flickery LEDS seem to be in rows 4 and 5 (need to verify this) which would also correspond to the boundary of the first and second 74HC595 - maybe there is a theme here.

After about 30 seconds of operation the circuit goes rock solid and the problem goes away until the next start up. The circuit has to be off for at least 5 minutes or so before the problem re-exhibits. Power off and immediately on all works well.

Nothing here is working hard. The Arduino is running from a 1 Amp power supply hard connected to its 5 volt input. It can't be heat surely??? Problems usually get worse with heat anyway. In any case nothing feels hot. Over sensitive transistors in a couple of the columns?? Not satisfactory really.

I hate things that go bump in the night. Any ideas why the circuit misbehaves in the first 30 seconds?

Here is code, please excuse the quantity of commented out sections.

#include <TimerOne.h>
#include <SPI.h>

byte column_counter;
byte r1[12], r2[12];
int test_row;

const byte LATCH = 9;

void setup ()
  SPI.begin ();
  test_row = 0;
  column_counter = 0;
  for ( int i = 0; i <= 11; i++)
        r1[i] =  r2[i] =  0;            // bottom row  = row 0

// alternating patter not used  
  r1[0] =  0x5; r2[0] =  0x55;            // bottom row  = row 0
  r1[1] =  0xa; r2[1] =  0xaa;            // row 1
  r1[2] =  0x5; r2[2] =  0x55;            // row 2
  r1[3] =  0xa; r2[3] =  0xaa;            // row 3
  r1[4] =  0x5; r2[4] =  0x55;            // row 4
  r1[5] =  0xa; r2[5] =  0xaa;            // row 5
  r1[6] =  0x5; r2[6] =  0x55;            // row 6
  r1[7] =  0xa; r2[7] =  0xaa;            // row 7
  r1[8] =  0x5; r2[8] =  0x55;            // row 8
  r1[9] =  0xa; r2[9] =  0xaa;            // row 9
  r1[10] = 0x5; r2[10] = 0x55;            // row 10
  r1[11] = 0xa; r2[11] = 0xaa;            // row 11 top row
}  // end of setup

void transfer_data()
  byte c1,c2;
  switch (column_counter)
    case 0:
       c1 = 0x8; c2 = 0x00;
    case 1:
       c1 = 0x4; c2 = 0x00;
    case 2:
       c1 = 0x2; c2 = 0x00;
    case 3:
       c1 = 0x1; c2 = 0x00;
    case 4:
       c1 = 0x0; c2 = 0x80;
    case 5:
       c1 = 0x0; c2 = 0x40;
    case 6:
       c1 = 0x0; c2 = 0x20;
    case 7:
       c1 = 0x0; c2 = 0x10;
    case 8:
       c1 = 0x0; c2 = 0x08;
    case 9:
       c1 = 0x0; c2 = 0x04;
    case 10:
       c1 = 0x0; c2 = 0x02;
    case 11:
       c1 = 0x0; c2 = 0x01;
// this reduces inter LED interference probably due to slow transistors switching off
  digitalWrite (LATCH, LOW);
  SPI.transfer (0);
  SPI.transfer (0);
  SPI.transfer (0);
  SPI.transfer (0);
  digitalWrite (LATCH, HIGH);
// the actual write
  digitalWrite (LATCH, LOW);
  SPI.transfer (c2);
  SPI.transfer (c1);
  SPI.transfer (r2[column_counter]);
  SPI.transfer (r1[column_counter]);
  digitalWrite (LATCH, HIGH);
  if (column_counter > 11)
     column_counter = 0;

void loop ()
    for ( int i = 0; i <= 11; i++)
        r1[i] =  r2[i] =  0;            // bottom row  = row 0
r1[test_row] =  0xf;
r2[test_row] =  0xff; 

if (test_row > 11)
   test_row = 0;

How long are the wires? Are you running ground wire alongside the signal wires?
You might be getting a poor clock signal if wiring is long or straggly, unreliable
clocking could cause failure at the far end of the string. If the 595's are running off the
same supply as the LEDs put more like 220uF on that rail as well as the existing decoupling,
switching LEDs needs serious decoupling as the total currents are high and switching
as fast as a logic chip.

Make sure power is applied to the LED end of the circuit so high currents are kept
away from the Arduino supply (in particular you don't want fast switching high
ground currents on the ground wire(s) between Arduino and LED matrix)

You're sure that all the 74HC595 /MR pins are securely connected to 5V, and all the /OE pins are securely tied to OV ?

Something floating could possibly explain the time dependency that you are observing...

Thanks for the suggestions. For interest here is what I tried.

Are the leads too long? Are the switching currents in the way? On a breadboard the leads are always too long but in checking I found that the LED matrix ground wires at the wrong end of the breadboard so that all of the LED sink current passed through the 74HC595 ground path. Aha I thought, so I adopted a strict "star" approach so that there was a central point that both ground and Vcc radiated from. Absolutely no effect. The circuit would fail for upwards of a minute then run straight as a die until I turned it off.

Bypass issues?? I had a look at the bypassing and doubled it. a 0.1uF Cap at each end of each 74HC595 and added a 4700uF at the star end and a 470 uF at the end of the shift register chain. That should do it!, but no change in behavior.

Were the OE hard low and the master reset hard high?? Definitely worth a look. I took the opportunity to change the way the circuit works to disable the outputs to prevent "inter-LED bleed" rather than the technique in the original post where I wrote all zeroes out to the shift register chain before the next lot of real data. This works by alternating the behavior of the timer interrupt routine. On the "first " call it disables the output by using another pin on the Pro Mini and sets the flag for the "second" call. On the second call it writes the new data and then re-enables the output and reverts the flag back to the "first" call. All this worked perfectly as seen on my 'scope. Master reset is rock solid high. BUT no change in behavior.

I thought I might be overloading the 595's. My 470R current limiting resistors are driving white LEDs with a forward voltage of about 2.3 or so. Vcc is about 5, so I am asking the 595's to peak source about 5mA which is close to the spec. Now the LEDs are almost never all on at once so the 595's do get a break, but just in case I swapped out the 470R for 1k. And of course this caused no change in behavior.

So when you have eliminated everything else, what is left is the cause. And all there is left is the 595's.

I was getting increasingly suspicious of my 595's. They are low cost ebay jobs. The manufacturer marking looks to me like AXZ written vertically but it might not be an A. Could be Omega?? (as in the Greek symbol sometimes used for Ohms) or an O. And I was increasingly disliking the look of them. I have tried to capture an image of the chip markings, difficult at the best of times. Made impossible by the manufacturer's choice to use ink almost the same colour as the chip surface. So all I can see on the image is the 74HC595 which is not at that useful.

In any case I went to my local retailer and bought 4 STI 595's. I replaced the first 595 in the chain (on the basis that if it is bad then all subsequent bits will be interfered with) and the problem vanished. Are they all bad or marginal? I will have to do some testing.

Thanks, for the thoughts, Regards, Fred.

Hi All, So here's an update.

I had 25 units in my original purchase and now I have tried all of them. I have found 3 which consistently exhibit the problem. So I have a defect rate of about 1 in 8. These 3 are marked and quarantined. So far I have not found other defects but I am on the lookout for odd behavior. The chips in question are being driven hard on the SPI port at maximum speed.

I also think the chips are used or second-hand and have been removed from piece of equipment. Most new DIP ICs have splayed pins and require to be bent inwards to fit a socket or breadboard. It did not dawn on me except to absent-mindedly think that these chips are easy to insert until I tried all of them without bending one. These have parallel pins already. There is no sign of being de-soldered, they were socketed I think. A case of caveat emptor for me.

By changing lighting and camera settings I have managed a decent image which I wanted to attach but the uploader says it is full.

Thanks again for suggestions, Regards,

595 outputs don't have a guaranteed state on power up.
Have you tried implementing an initialisation routine, a "once through", where all data registers are asserted off?

I am wonder if 0x0 is good. I guess it is. If you have run out of other ideas, try 0x00. In fact, you should probably re-arrange that whole switch statement. The other thing I wonder, is if you are having the latch signal high for long enough.

First of all, my apologies to all readers for the delay in responding to the thread. The board I am about to describe is intended to control a LED array probably 32 wide by 24 high. It is presently driving a small test array only 8x8 and has the shift registers fitted to match.

I decided to eliminate the uncertainties related to bad connections and doubtful bypassing that a prototyping board inevitably entails by building a dedicated board with solid power rails and ensuring sufficient bypassing. A purpose designed board was probably ideal but I don’t have the facilities to do that so I stared with a generic type designed to have DIL circuits mounted on it. The one I used came from Jaycar, an Australian electronics retailer, and has the Jaycar number of HP9558. Boards using this concept have been around for some time and I am sure that alternatives are available from other suppliers should Jaycar be unavailable to you and you wish to duplicate the idea.

The copper side looks like this:

To make the Power and earth rails more evident here is a drawing highlighting them:

I have over-laid the power rails in red and the ground in green. I have edited this image as well in order to try and increase the contrast between the phenolic paper of the board and the copper, perhaps not entirely successfully. The first image is much more representative of the color of the board.
I really wanted the power rails of this board solid so I decided to parallel each rail with copper wire on the copper side. I did this by placing tightly strung tinned copper hookup wire, often used for links on single sided circuit boards, in parallel over the copper side of each of the power and earth rails, thereby increasing their ability to carry current and lower intrinsic impedances. At present this is unsoldered except at the ends and where a component pigtail joins the trace. However I am considering soldering the wire to the trace solidly along its length.

I should note that my construction of this circuit was hampered by an unexpected short circuit between the power and ground rails on my board. I hope that this is limited to my board in particular as a generic problem of this type is most undesirable. Because of the layout this was a real problem to find and since I didn’t test before I started adding the hookup wire I really could not take it back. After detailed examination and a few trace cuts to localize the problem I eventually found an un-etched sliver of copper between the rail traces. Annoying!, and a warning to anyone else using this type of board. Moral of the story: Check it first before you touch it. Use a meter to verify the connections where they should be and should not be.

When complete my circuit uses 10 serially connected 7CHC595 and 2 74HC238 as decoders driven from the “first” 74HC595. The first shift register contains column selection data while the remaining 9 shift registers contain single bit data to drive 3 vertical groups of 8 rows of tri-colour LEDS. The three 74HC595 in each group hold the red, green and blue control respectively, just on or off, there is no grayscale capability. Since these drive bipolar transistors, with some level of current, solid ground and power rails are essential to stop noise interfering with data propagation from one device to another. The LED matrix itself was sufficient challenge and I will write concerning it later.

The following photograph shows the completed but only partially populated board. The cables snaking away go to the test 8x8 tricolor LED matrix. The insulated wire peeking out from the bottom supplies the LED matrix with the power to turn on the LEDs which are not driven directly from each 74HC595 as these units cannot supply enough current for the brightness I want.

The board is currently powered from a 5 volt 1A regulated plug pack which also runs the LED matrix. However the LED matrix is intended to be be run from a higher voltage to drive the LED rows brighter and the design voltage is actually 12 volts which leads to a very bright matrix. There are driver transistors on the matrix to accommodate this. You will note that the signal wiring is all wire-wrapped with the power wiring underneath. Each row of chips has the following bypass caps:
2 x 10uF electrolytic at each end
2 x 0.1uF ceramic in the middle
1x 470uF at one end
1 x 220 uF at the other end.

This was a bit based on the idea to have different resonant frequencies for each cap and what I had to hand. This is supplemented by a large cap intended to deal with large chances in demand, being a 4,700uF electrolytic.

This is what the board looks like underneath:

The cable off to the LED matrix is much more visible in this view. The jumper wires are used to put the odd placed output on the 74HC595 into a consistent row for ease of use to connect to the LED matrix. The additional wires added to supplement the power can be clearly seen. Here is a close up of one row rotated so that the image takes up less space:

So I duly plugged in the TI chips (see my earlier post) installed the74HC238 and connected the LED matrix. I applied power and it worked perfectly immediately. Straight off the bat, without problem. When I plugged in the earlier chips (follow my earlier post) they misbehaved for a few minutes then never again until the next substantial power cycle.

So I have gone to a substantial effort to solve a problem which remains unsolved. I still think there is a subtle problem with the original shift registers but I remain as uncertain as ever as to what that is exactly.

The program running is a game of life. I am sending far more data than I have devices to use it, however that is to ensure that the matrix is bright enough with the actual duty cycle expected. The code is traditional except that the life “game boards” are not Boolean as is often used. These are arranged so that each cell is represented by a bit, so getting a cell status is more difficult than it might be. However to display the cells is very efficient. I'll post the code if there is interest.

And for reference here is a picture of the LED matrix both off and a random shot of it working.

And lit:

This photo isn’t great, but this is hard to photograph.

Thanks too to those who have commented.

Runaway Pancake commented that the 595 output are undefined at start-up. This is true and correctly reflects the way the 74HC595 works, but not important in my case. I don’t enable the outputs until the data has rattled through the 595 string AND transferred to the output stage BEFORE I enable the output. Therefore the first data presented is correct. OE is held high by a resistor at start up. Some odd data is still possible I guess as the processor starts and outputs are potentially undefined but not over any length of time. The suggestion is a valid one if the output enable is not under software control.

As to the suggestion by michinyon that 0x0 is problematic is not correct. It is no different to writing 9 instead of 09. The 0x simply tells the compiler that the number following is in hex. The compiler has no idea how big the number might be and it will only worry about it once it sees what the user wants to do with it in terms of the size context of the rest of the line in question. 0x09 and 0x9 are equivalent as would be 0x0000000000000000009. Silly, but equivalent. Anyway, it always good to look at these matters.

As to my switch stament the code shown was thrown together and some level of optimization and improvement is accepted. I do defend the switch statement in general though; I am very fond of programming through state machines and I contend that the switch statement helps make state machine implementation crystal clear in a manner that spaghetti if then else simply cannot. I agree that switch case can be a nightmare of uneven execution times but for contiguous examples switch case can be both efficient and readable. I will concede that use of switch case in interrupt routines requires special care.

I’ll post a longer article about how the LED matrix was designed and built when I get some time.

Hope this helps someone and if anyone has a flash or brilliance as to why a set of 595's would fail to behave on power up and then settle out to work perfectly I am all ears.

Regards, Fred.

PS: edited to correct and resize a picture.