I am trying to cascade 3 shift registers (74HC595) to run 3 large seven segment display (4 inches each). I am using ULN2003 as display drivers between the 7 segments and each shift register. I have been successful in running the first digit. However, when I hook up the second 74HC595, it even messes up the output of the first digit which was previously working fine.
I have done a fair bit of debugging and here is a list of when I have checked without any success:
GND and VCC (drawn from 7805) of each IC is correctly connected.
The serial out of the first IC is connected to data of second.
CLK and LATCH pins are common in both ICs.
I have tried putting on 220nF disk caps next to each 74HC595 (I saw this on other threads but it appears to not help in my case).
I am sharing the schematic and relevant part of code. I am open to all suggestions. Please share your thoughts!
Ps. I am using ESP32. But, I think it should not make much difference.
Thanks,
Usman
int strobePin = 27; //Pin connected to Strobe
int dataPin = 14; //Pin connected to Data
int clockPin =26; //Pin connected to Clock
int shiftOutBuffer[3]={0};
byte segChar[]={ //.gfedcba 0, 1, 2, .. 9, all off
0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101,
0b01111101, 0b00000111, 0b01111111, 0b01101111, 0b00000000,
};
int counter = 231;
void update_display()
{
digitalWrite(strobePin, LOW);
delay(100);
shiftOut(dataPin, clockPin, LSBFIRST, segChar[shiftOutBuffer[0]]);
shiftOut(dataPin, clockPin, LSBFIRST, segChar[shiftOutBuffer[1]]);
shiftOut(dataPin, clockPin, LSBFIRST, segChar[shiftOutBuffer[2]]);
delay(100);
digitalWrite(strobePin, HIGH);
// Serial.println("updated data successfully");
}
void update_shiftOutBuffer(){
shiftOutBuffer[2] = counter % 10;
shiftOutBuffer[1] = (counter / 10) % 10;
shiftOutBuffer[0] = (counter / 100) % 10;
}
void setup(){
update_shiftOutBuffer();
update_display();
}
void loop(){
}
Thanks for the basic information in your first post.
Do you have a DMM.
Measure the 5V supply and the 12V supply when the problem occurs?
What value capacitors do you have at the 7805, consult the data sheet for info, place them as close to the regulator leads as possible.
What are you using for your 12V power supply?
Do you have this on protoboard, or have you made a PCB?
I am using ceramic capacitors but won't 220nF have almost same effect as 100nF. I have updated the schematic. The caps are attached between Vcc and GND of the 74595 close to the IC. I am attaching a picture to show how close and you can judge the length of the cap wires.
The sketch remains the same throughout. I think the problem is with the hardware. I have tested multiple codes but the same issues appears although the exact digits displayed may change.
I am using 220nF ceramic on 9V input of the 7805 and 0.1uF on the output of 7805.
I have read about tpic6b595 and looks a good option but it's not available in my city.
You're suggesting 3.3V directly from MCU? How could using 3.3V help?
I have placed the caps around 7805 fairly close. On the input side (9V), it is 220nF (ceramic) and on output side, it is 0.1uF (electrolytic). Both are fairly close. Please check the picture shared.
The 9V is a adjustable bench top power supply. It is rated for 15V 2A and my circuit only takes 200-250mA. I have a PCB.
I would think it's probably ok, so only change those later if nothing else works. But 0.1uF is normal, so I would always use those from the beginning.
Are these the values recommended in the 7805 data sheet? They don't sound big enough to me, unless you meant 0.1mF = 100uF?
0.1uF are not normally electrolytic.
Also please clarify the input voltage. You mentioned 9V a couple of times but your schematic shows 12V. That doesn't make any difference to the cap values you are using in the input (as long as the cap's rated voltage exceeds the input voltage) but it will affect the power dissipation in the regulator (higher input voltage == higher power dissipation == more heat).
Yes, might be worth trying. The 74hc595 are powered with 5V, so their inputs are expecting a 5V signal, but the esp pins only output 3.3V signals. In theory, this should be ok, but it's possible that it's right on the edge of working, so that with one '595 connected it just about works but with 2 it doesn't quite work. Powering the '595 with 3.3V would fix that, and because the Uln inputs are sensitive (high gain) and current driven, I don't think 3.3V signals would be a problem there.
If course, trying this is not so easy on a PCB. So, again, try this only as a last resort. I always prototype on breadboard, and test the circuit is working as close as I possibly can to the final version before designing a PCB.
Of course 220 nF is better than 100 nF! You apparently missed the reference to "disk caps" in the OP. I am not aware of (or cannot recall) disk capacitors other than ceramic. The capacitors are not as close to the 74HC5895s as you would prefer but do not seem too likely to be a problem.
Unfortunately we do not seem to have the actual code to check, so we do not know whether the three control pins have actually been set as OUTPUT.
Can't image what the delay(100); is supposed to do!
If you replace the Arduino shiftOut() function with your own code, then you choose how the clock and data timing is. Then you can even make it very slow to be able to measure the signals with a multimeter.
I checked with the code and figured out it was fine! @PaulRB, @TomGeorge: I figured out that the problem was either on the shift register side or on the 7805 side. To isolate the two, I removed the 7805 and instead used my laptop usb to power the ESP and used the same 9V from the bench top supply to power the displays.
The good part is it worked with the usb power. That means something is wrong on the 7805 side. I have checked the data sheet and it says 0.33uF on the input and 0.1 uF on the output. I have tried 0.22uF on both input and output but that hasn't worked. I am going out to procure 0.33uF and 0.1uF ceramic and see if these work. The goal is to make it work with the 7805. I think we are getting close!
Thanks for your suggestions guys. Open to hear more!
Ok, then I would put those ceramic caps in, but also add a couple more electro caps, perhaps 10uF on input and output and see if that helps. If not, try 100uF. If that still does not work, maybe replace the 7805 in case it's faulty.
Is there any ground plane on the back of the board? With traces that long and thin, you may have some ground loop and supply loop issues due to resistance and inductance in the traces...
Also, where is the 3.3V-5V level shifter between the SR's and the ESP? There is a risk of damage to the ESP pins without them. Also you lose a significant amount of noise immunity without them.
A lower valued bypass capacitor is better at filtering higher frequencies. Here, on page 15, it says:
Each VCC pin should have a good bypass capacitor to prevent power disturbance. For devices with a single supply, 0.1 μf is recommended; if there are multiple VCC pins, then 0.01 μf or 0.022 μf is recommended for each power pin. It is acceptable to parallel multiple bypass caps to reject different frequencies of noise. A 0.1 μf and a 1 μf are commonly used in parallel. The bypass capacitor should be installed as close to the power pin as possible for best results.
The difference in 0.1uF and 1uf or even 10uF, is type of capacitor.
0.1uF has better capacitor type properties at high frequencies.
1uF or 10uF, usually electrolytic are lousy high frequency capacitors, but good a low frequencies to DC.
Good Dave Jones Tutorial.
In your update_display function, you have long delays relative to the speed of the IC. Although not creating an issue, there's an opportunity to significantly shorten them.
More importantly, I think its better to pulse the latch signal when ready rather than letting it sit high for a period of time while other code is processing. In other words, make it normally low, then pulse it high-low when ready to latch the output register.
Why would they be in any way necessary? We are dealing with HCMOS shift registers, not old CMOS. Particularly since the digitalWrite function does not code to a single machine instruction anyway - or does it?