PWM signal on output enable pin of shift register

Hi,

I'm trying to make a numitron (IV-9) clock using a barebone Atmega328P and four 74HC595N shift registers. Everything worked great until I tried to adjust the brightness by applying a PWM signal on the output enable pin of the shift registers.

Below a minimal version of the code that results in the error.

#define latch_pin 2
#define blank_pin 5
#define data_pin 3
#define clock_pin 4

byte num_table[11] = {0b00001000, 0b00111110, 0b01010000, 0b00010010, 0b00100110, 0b10000010, 0b10000000, 0b00011110, 0b00000000, 0b00000010};

void setup() {
  pinMode(latch_pin, OUTPUT);
  pinMode(data_pin, OUTPUT);
  pinMode(clock_pin, OUTPUT);

  analogWrite(blank_pin, 100);
  digitalWrite(latch_pin, LOW);
}

void loop() {
  for(int k=0; k<10; k++){
    output(k*11, k*11);
    delay(500);
  }
}

void output(byte hr, byte m){
  digitalWrite(latch_pin, LOW);
  
  shiftOut(data_pin, clock_pin, LSBFIRST, num_table[m%10]);
  shiftOut(data_pin, clock_pin, LSBFIRST, num_table[m/10]);
  shiftOut(data_pin, clock_pin, LSBFIRST, num_table[hr%10]);
  shiftOut(data_pin, clock_pin, LSBFIRST, num_table[hr/10]);

  digitalWrite(latch_pin, HIGH);
}

This code loops through the digits 0-9 on all four numitrons. This works fine when I use digitalWrite(blank_pin, LOW); instead of the analogWrite. Using the PWM signal results in the numitrons being stuck at a certain digit while occasionally jumping to a different random digit or just complete gibberish.

Below you can find my schematic (yes, I know it's made in Fritzing but I hope it's still readable).

To me it seems as if there is interference between the output enable pin and the latch pin. I would greatly appreciate your opinion on this and, if there is indeed interference, how I would go about resolving this issue.

Some notes and things I've already tried:

  • Yes, I'm using a capacitor between the latch pin and ground as is stated in the arduino shift register tutorial and I know this tutorial isn't correct but when I remove this capacitor nothing works at all.
  • I've tried setting the output enable pin to high while shifting out the data but this has no noticeable effect.
  • Apart from what is shown in my schematic, I've also got a RTC ds1307 module and some capacitive touch sensors connected to the Atmega. I think these aren't the source of the problem as it still occurs when I disable them.
  • I have some experience with shift registers and barebone Atmega chips from previous projects but I have never experienced anything like this problem before.

Have you got bypass capacitors near every chip, between Vcc and Ground? That's all I can think of.

In code you apply PWM to the blank_pin (SRCLR?) not OE? This will clear the register most of the time, not synchronized to register load.

That is because the error in that tutorial is that capacitor. It is providing parasitic decoupling. Do as @johnwasser says and connect instead to the 5V, and do it on each chip.

The name blank pin is indeed not accurate but it is connected to the output enable pin (pin 13) of the shift register not the master clear as the name would suggest. So this should be correct.

About the bypass capacitors, now that you mention it, I did add those near every chip in another project so that could be the problem. Would 10nF capacitors be suited for this?

So if I understand correctly: remove the capacitor on the latch pin and add one near each register between ground and 5V.

If you still have a problem with PWM then please check for analogWrite(0) what should permanently enable the output. Then increase the duty cycle until you find a problem. Then try increasing the cap on the chip power lines what could help in switching the output drivers. Bigger caps do no harm, try 100nF at least.

I added 100nF capacitors near each register and at first it seems to work fine but after about 20 seconds all segments of the numitrons start to light up and won't turn off anymore. I have to wait a couple of minutes for it to work again only to have the same thing happen after 20 seconds of running the code. The segments don't light up simultaneously after 20 seconds but gradually, as if the shift register cannot latch 1's anymore and only accept incoming zero's, if you know what I mean.

And the chips are hot? Check the data sheet of your shift registers, there exist variations with different output circuits and current limits.

The chips are not hot, but from the datasheet it seems I'm above the max "continuous current through Vcc or Ground" when more than 3 segments are on at the same time. So I guess I need higher rated shift registers when using numitrons.

TPIC6B595

Thanks, I will look into that one.

Just to be certain, there is no other way to still use the 74hc595 registers? Because, due to my own incompetence, I already installed and soldered all the components without properly testing everything.

In the datasheet of the 74hc595 it states the following:

and the numitrons have a typical current per segment of 19.5 mA.

I'm not really sure what to look at in the datasheet so any help would be appreciated.

You could use 4x uln2003 (or uln2803 if you want to use the decimal points). One between each 74hc595 and a numitron tube. These chips are an old design and drop a significant voltage. This may make your numitrons dim.

Another idea would be to use transistors. You could use ordinary npn like bc337. Unfortunately you would need 28 or 32 of them, each with a resistor to limit the base current.

By the time you have soldered up either of the above, you could probably have started over with the tpic6b595.

The limiting factor is that 70mA through Vcc or ground, as you said in post #11.

Using the TPIC6B595 indeed seems to be the best approach.

Thanks for all the helpful information and fast replies!

That would be why I made the suggestion. :grin: