I've been working on project that connects a long chain of 4021be shift registers into an Arduino, and - you guessed it - at some point around the 35th shifter, I believe I am exceeding the fanout capabilities of the Arduino (I'm using an Uno). It was suggested to me to use some cd4049 inverting hex buffers on the clock line to fix this problem, however, I don't believe I've hooked them up correctly.
It's too messy to take a picture of, but basically I'm taking the clock out from one of the 4021be shift register boards and putting it into pin3 of the first 4049, then connecting pin2 of the first 4049 to pin 3 of the second 4049 (have to invert twice to get the original signal, yes?) then out of pin3 on second 4049 and into the clock input on the next shift register. I'm using the same 5V and gnd lines that I use for the shift register IC's for the 4049's (pin1 is 5v, pin 8 is gnd) - I don't see how that would be a problem, but it might be.
Basically what I'm witnessing is that all the bits after the buffers are always logic high (1), when they should be 0 - the readings from the other shift registers in the chain are normal. I've also tried hooking up 2 and 3 sets of inverters thinking I wasn't slowing down the clock enough, but the result did not change.
Any help or suggestions would be most appreciated!
Input current on those things are tiny. So unless you have lots of capacitance on the line, or are driving them at super high speed, you are not going to run out of the fan out capabilities of the mcu.
I cannot follow your description - a graphic presentation, even hand drawn, would be helpful.
you are not going to run out of the fan out capabilities of the mcu.
Yes you are, after about 20 inputs you start running out of speed.
you guessed it - at some point around the 35th shifter,
Understandable.
The way you do it is to take the clock and put it into one inverter. Then put that output into the inputs of all the other 5 buffers. You can then take each of the outputs to a group (20 Max) of shift registers.
Mike - I follow until the 'take each of the outputs to a group (20 Max) of shift registers' part - does this mean to replace the clock line (that's currently being passed/chained) with one of the outputs from the inverting buffer every 20 boards or so? What do I do with the 'outbound' clock line between the 20th/21st boards?
Or do you mean take the clock line strait from the Arduino and put it into the buffer? And then distribute the outputs to groups of 20?
Hi Mike - I tried what I believe you said to do, and it is not working (I get a solid string of 1's). Does it matter if I don't use all five of the remaining buffers on the 4049? I've attached a schematic of my shift register pcb's - I've been attaching the buffered clock line from the 4049 to the CLK pin on the right side of the pcb's. Also, the circuit for the 4049 has no resistors or caps on it - do there need to be any?
I am decoupling on all the shift register boards, so hopefully that's not it.
I've attached a schematic of the 4021 shifter boards, as well as a (really crappy, sorry I'm not an artist) drawing of how I have the system connected currently.
I'm still getting a solid string of 1's from the shifters. Thank you all for your help.
Well it is not what I showed you to do. You can do it with one 4049 not two. However the circuit looks right. Have you wired up the power correctly? This chip is unusual in that the +ve is on pin 1 and the ground on pin 8.
It sounds like you have not got it wired correctly. You need a scope to see if the signals are getting through your buffers.
I have to say that I have a hard time understanding your schematic.
I would tie all the clock pins (pin 10) together to your sck pin; all the latch / par / ser pins (pin 9) together to your latch pin; 1st cd4021's serial output pin (pin 3) to the 2nd cd4021's serial input pin (pin 11). The last cd4021's serial output pin to your mcu's serial input pin.
the rest of the code would be something like this:
unsigned char cd4021_read(void) {
unsigned char mask = 0x80;
unsigned char tmp=0;
do {
digitalWrite(SCK, LOW);
if (digitalRead(SDIN)) tmp |= mask;
else tmp |= 0;
digitalWrite(SCK, HIGH);
mask = mask >> 1;
} while (mask);
return tmp;
}
void cd4021_sample(void) {
digitalWrite(LATCH, HIGH);
digitalWrite(LATCH, LOW);
}
...
in your user code,
...
cd4021_sample(); //load parallel bits into the shift registers;
tmp3 = cd4021_read(); //tmp3 has the bits from the last cd4021;
tmp2 = cd4021_read(); //tmp2 has the bits from the 2nd to last cd4021
tmp1 = cd4021_read(); //tmp1 has the bits from the 1st cd4021
...
You can certainly put it in a loop if you have lots of registers to read.
I would be surprised if you run out of fan-out capabilities when you wire up the chips correctly.