Three wires to rule them all: CD4094 & CD4021 shift register tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
so what do you do when your microcontroller doesn't have enough pins today I want to show you that 14 pins is way more than you need with only three wires you can control as many LEDs as you like and with three more wires you can read out as many push buttons as you like as well the main idea is to use shift registers and in this video we will first go through all the basics of how both of these types of shift registers work and then build a full circuit that allows us to control 16 LEDs and read out 16 push buttons I will show you in detail what you need how you can build the circuit on a breadboard step by step and we will learn how to write the code that sends out data to the LEDs and reads out the status of the push buttons and as an extra bonus you will be able to use Simple handheld game controllers just like this one right here because guess what they use shift registers of the same type so let's get started and learn everything about output and input type shift registers and all of that with just three wait what three wires to rule them all one trip to drive them thank you one trip to read them all and on the breadboard hi my name is Jensen I believe that everybody can learn electronics and if you want to follow along today's tutorial then here's what you need 16 LEDs push buttons 220 ohm and 4.7 kilo ohm resistors to 830 pin breadboards a 4.5 volt battery pack and the pix16 f1455 microcontroller two cd4094 output shift registers and two cd4021 input shift registers five 100 nanofarad ceramic capacitors and one chunky 100 microfarad capacitor you also need the picket 3 a 5 terminal connection cable and some single stranded wire that is a lot of stuff I know so I made a detailed list for you on friendlywire.com where you can find links and data sheets for anything you need for this tutorial just click the link in the description so here is the main idea of our circuit today this here is our microcontroller with only a few pins the LEDs that we want to control are connected to an output type shift register and the push buttons we want to read out are connected to an input type shift register at this point we don't really save any pins or wires at all because each LED and each button needs to be connected separately to its own register but a shift register itself only needs three wires to talk to our microcontroller and those are the precious connections we want to keep as few as possible so with three wires you can control 8 LEDs and with another three you can read out 8 buttons as well but it gets even better than that you can change shift registers of the same type behind each other so that in theory it's possible to control an unlimited amount of LEDs and read out an unlimited amount of buttons with just three wires each this works because shift registers turn so-called parallel data which is the snapshot of the state of all LEDs or the state of all buttons all at a common time into so-called serial data which is a sequence of individual bits one after the other for each LED and push button but before we get ahead of ourselves let's back up for a moment and learn how these two types of shift registers work on the inside an output type shift register like the cd4094 has three inputs called Data clock and strobe and it has eight outputs called q12q8 and another output called Q Prime s in our application data clock and strobe are the three wires that we connect to the microcontroller so for now let's keep the clock and strobe input at a logical zero but let's imagine we want to send this byte here into the register and we will do that from left to right so at first we have to put a logical one on the data input if you now pulse the clock pin from 0 to 1 and back to zero again it acts a bit like a Minecraft piston and after that our first bit falls into place the next bit is a0 so let's apply a0 at the data input and pulse clock again now the previous bit gets shifted to the next position and the zero falls into that place and if we do this six more times eventually we have our whole ID stored in the register now we can set data back to zero and instead pulse strobe this sends the current status of the register to the eight outputs imagine now that we send in another bit and pulse clock again then what was previously at Q8 falls out of the register and appears as an output signal on the Q Prime s pin if we now add another shift register in series connect the Q Prime s output of this one to the data input of the next one and connect clock and strobe in parallel we can now send out 16 bits because the information just gets passed along to the next register over the Q Prime s pin and we can add even more registers the very same way to control as many LEDs as we like so now we know how these guys here work but what about the other ones to read out our buttons we need a different type of shift register a so-called input type shift register like the cd402 2-1 it also has three inputs called Data clock and latch P1 through p8 are the eight inputs where we connect our buttons and q6 Q7 and Q8 are the three outputs in our case clock latch and the Q8 output are the three wires we need to connect to our microcontroller now let's imagine that somebody presses the button so that this bit pattern here is at the inputs P1 through p8 and we want to read out that status into our microcontroller at the beginning of each cycle we keep latch and clock at a logical zero first we have to pulse latch a single time and that pushes the state of the inputs into the register all at once and P6 p7 and p8 appear on the outputs q6 Q7 and Q8 our microcontroller is connected to Q8 so it can read out that first bit already then we pulse clock and the data gets put along one position so that the microcontroller can read out the next bit and so on and so on and so on until we have read out all information now the the data input on the left is for adding another shift register to this chain and this is how it looks like just like before clock and ledge are connected in parallel and the Q8 output of the previous shift register gets connected to the data input of our shift register right here this way the data doesn't get lost but simply travels along the chain for as many push buttons as you like and now I want to show you how to do all of this with a pick microcontroller now if this is your first time working with a pick microcontroller it can be a little bit confusing but it only takes about 20 minutes to get set up with these things and I have a detailed video that walks you through all of these steps so go watch that later if you're interested but for now let's have a look at this schematic in the middle is the pix16f1455 connected to the 4.5 volt battery pack and the two capacitors C1 and C2 let's stabilize the circuit this up here is the picket 3 programmer and it is connected to the circuit with the two power connections vdv and ground and with the three programming connections master clear program data and program clock this triangle here is also on the pick kit 3 in real life and it helps us to identify which pin is the master clear pin to build this place the 830 pin breadboard in front of you and make sure Row 1 faces to the left and insert the pix16 f1455 in Row 3 with the notch facing to the left as well connect with the at Pin 1 and ground at Pin 14 and insert the 100 nanofarad bypass capacitor C1 between pins 1 and 14 close to the chip the bulk capacitor C2 can go into the power rail around row 43 just make sure its negative terminal is really connected to the negative power rail and is not switched around because they really don't like that then connect the positive power rails on both sides of the breadboard together as well as the negative ones now it's time to plug in the picket 3. it's vdd and ground connections can be connected directly to the power rail master clear goes to pin 4 program data to pin 10 and program clock to pin 9. connect the battery pack to the power Rail and last connect the other end of the picket 3 to your computer and on there start the mplap IDE and create a new Standalone project click on next and select the pix16 f1455 as your device and under Tools select show all and then select the pick kit 3. click on next and on next again and select the xc8 compiler from this list here before clicking on next again give your product a name and then click on finish after some time on the left side right click on source files then on new and then on main.c choose main as the file name and then click on finish this file here is we will now write our source code so let's do that next first click on window then on target memory views and then on configuration bits down here select these options out of the drop down list and when you're done click on this button here generate source code to Output move the panel all the way down and copy the source code from the output Tab and paste it into the code window like this all that this code does is to tell our microcontroller to use its internal oscillator and that's that line right here and the rest is not really critical then inside the main function we add a loop that will run forever and this is a very common structure for microcontroller programs for now we will leave this main Loop empty just to see if everything is working on our end here on the computer and to do that up here click on the Broom symbol to compile this code into a hex file after a few seconds it should say build success successful and after deciphering all his texts down here you realize that you can find the hex file that we just created in the dist default production folder right here we need to get this hex file onto the controller using the picket3 and to do that we start the mplab ipe under device select again the pix16 f1455 and under tool the pickkit 3 should already be selected because we plugged it into our computer just a few minutes ago click on connect and after a few seconds our pick should be recognized under hex file click on browse and select the hex file we just created and then click on program this should all go through without any problems and the hex file is now on our controller but of course when you look at the breadboard right now nothing happens yet because the main Loop of our program is empty and we haven't connected anything to our microcontroller yet so let's change that and start adding stuff one by one until we understand how everything works here's our previous bare bone schematic so let's first add one cd494 output shift register to control our first set of 8 LED the data clock and scroll pins are connected to three pins of the pix16 f1455 like this they share some lines with the pick kit 3 but that's not really important because in the end we can remove the Picker 3 permanently the cd494's output enable pin right here is always held high because otherwise the outputs of the cd494 would be turned off speed speaking of the outputs we are showing the state of each output with a small LED and the symbol at the bottom left here just means that we connect power to the cd494 at Pin 16 and 8 with C3 here acting as a bypass capacitor on the breadboard first disconnect the power just to be safe then insert the cd494 in row 12 with its not facing to the left connect vdd at Pin 16 ground at Pin 8 and insert its bypass capacitor C3 between pins 8 and 16 and if you're doing it like this make sure the metal doesn't short out any of the chips pins connect pin 15 to vdd as well and now it's time for the LEDs starting in row 22 and then moving to the right like this their cathodes are all pointing to the right so let's connect them to ground with the current limiting resistors R1 to R8 like this wiring up the LEDs anodes to the 8 outputs q12 Q8 can take some time but I think it works best to do that in pairs like this this way the four lower LEDs are q1 to Q4 and the four upper LEDs are Q5 2qa 8 and last connect data at Pin 2 to pin 10 of the pick clock at Pin 3 to pin 9 and strobe at Pin 1 to pin 8. now reconnect the power and we can think about how to send out some data to our first shift register back inside the mplab IDE let us first Define the location of the data clock and draw pins for the cd494 that we just connected and I really like to use the Define command for that then in the main function we need to set all of these ports to be outputs and we also need to disable all the analog features on these ports because they can also be used as analog to digital converter inputs which we don't want in this case so let's just disable this now let's think about how to send out data to the cd494 and we will do this in two dedicated functions called cd494 underscore send and cd494 underscore load here is how I want it to look like in the main Loop the here are our 8 Bits that we want to send out to the shift register with the aptly named send function this is just a particular way to write a number between 0 and 255. in decimal this would be 128 plus 64 plus 1 which is 193 so we could write that 2 and it would make any difference but I like the binary notation because it makes it clear which bits are set and which ones aren't so that's why I went with it and we're almost done with the main Loop we just have to make sure that these bits here show up on the register outputs and I opted for a separate load function that has to be called after the send function and you will see later white makes sense to have these S2 separate functions so all that these two lines do is to send out this binary number to our cd4094 register but of course we still have to code those functions so let's do that next let's start with the load function because it's so simple it really just pulses this strobe line from 0 to 1 and then back to zero again and that's really all that it does the send function is much more interesting because we want to send data this function has an argument B that we can pass to it it takes 8 Bits which is one byte and our xc8 compiler calls this thing an unsigned character then we need to go through all eight bits of our byte B and send them out one by one so let's write a for Loop for that first we can get the bit number I with this expression here and we just put that on the day line directly and then we pulse clock and that's it now we start this loop at 7 and count backwards because we have to send out the most significant bit first and all the way at the top in our main Loop the most significant bit is this one right here towards the left and if we write this code exactly this way then this here is output Q8 of the cd494 this here is Q7 this is q6 and so on all the way to q1 on the right then we can compile this code and Flash it onto the pix16f1455 and when the program starts this is what happens and that matches exactly with our pattern here that we are sending out for example this one here is this LED and this zero here is this led and now that we can control one cd494 output type shift register let's add a second one or a third or a fourth and so on and it's actually not that difficult now the really nice thing about this is that you do not have to add any extra wires to the pick microcontroller so let's have a look at that next adding a second cd494 to our existing setup is really not that difficult clock and strobe are wired in parallel and the data input of the second cd494 is connected to the Q Prime s output of the first one this way when we send out data it keeps traveling through the registers what we send out first ends up in the rightmost register and what we send out last only makes it the first register of the chain so we have to keep that in mind for later and down here we add another capacitor C4 to stabilize this circuit back on the breadboard first disconnect the power then insert the next cd494 in row 39 again with its Notch facing to the left connect vdd at Pin 16 ground at Pin 8 and insert the bypass capacitor C4 between pins 8 and 16 and can connect pin 15 to vdd the LEDs are inserted just as before together with their current limiting resistors are 9 through R16 and then we need to connect the LEDs anodes to the shift register outputs just like before now it's time to connect the data input of our second shift register at Pin 2 to the Q Prime s output of the first shift register at Pin 10. clock at Pin 3 and strobe at Pin 1 are connected in parallel to pins 3 and 1 of the first shift register and now we can plug the power back in back in the mplab IDE all that we have to do now is to duplicate the send function really that's it and this is why I wanted the load function to be a separate function it just makes our life so much easier and if you have more than two registers in series just add more calls to the send function this one here is run first and then this one below is run second this means that this number here will show up on the shift register that is further down the chain and once we compile the code we can Flash it onto the controller and you can stare at the code and the LEDs for a minute and you can really see that these numbers correspond exactly to this led pattern so it's all working as intended and you can imagine that it's not that difficult to add a third register or even more now the only thing to keep in mind is the refresh rate say you have like a couple of dozen registers and you want to change one LED but one LED only now you have to rewrite the entire information to just get to that one LED and if you have a lot of registers that can take a lot of time so sometimes it's good to divide your registers into different branches which can still share the data in clock line but they have different strobe lines attached and that can optimize the refresh rate but of course you need slightly more wires but now that we understand all of that let's think about the opposite how do we read out push buttons but also with shift registers adding an input shift register CD4 to 1 to read out our first set of eight buttons is not so difficult the three wires data clock and latch are connected from the pix16 f1455 to the Q8 clock and latch pins of the cd421 all inputs p12 p8 of the cd4021 are connected to a vdd with a pull-up resistor and two ground with a push button this way when a button is open its input will read as high and when it is pressed it will read as low the power supply for the cd421 is at Pin 16 and 8 and we added another capacitor C5 for stability on the breadboard first again remove the power now we finally ran out of space so let's add another breadboard like this and first let's make sure that its power rails are connected properly like this for now let's forget about the upper part and focus on the lower part here we can insert the ct4 to 1 in Row 3 with its Notch facing to the left connect vdd at Pin 16 grounded pin 8 and insert the bypass capacitor C5 between pin 16 and 8. now insert the 8 push buttons starting in row 13. make sure that you plug in the buttons exactly like this and not rotate it by 90 degrees because that won't work I found it the easiest solution to plug in the pull up resistors R17 to r24 directly at the cd421 inputs like this and then connect one end of each button to ground the other side of each button then gets connected to the cd421 and again I worked in pairs to keep it manageable this way the four lower buttons are p12 P4 and the four upper buttons are P5 to p8 now we need to connect the CD4 to one shift register to our pix16 f1455 its Q8 output at Pin 3 goes to pin 5 of the pick clock at Pin 10 goes up to pin 6 and latch at Pin 9 goes up to pin 7 at the controller and now that we have done that we can reconnect the power and think about programming again and actually we will do that in a way that is very similar to what we have done before first let's add the data clock and latch pins to our code with a Define command again and then let's make sure that data is an input and clock and latch are outputs and of course we also have to deactivate the analog stuff on pin rc3 then again we add two functions that we will call cd4021 underscore read and cd4021 underscore load and we will store what the cd421 sends to us in a variable called V1 scrolling down further into the main Loop we read out the state of our eight buttons with these two lines like this the load function loads the status of all buttons into the cd401 and then we read them out with the read function like this and store the result in our variable V1 that we defined just a few seconds ago then we can send out this information to the LED so we can replace our fixed pattern from before with V1 but because we have 16 LEDs we can also send out the inverted version of V1 and that's what this tilde here does inverting the input values actually makes a lot of sense in this case if you think about it because of the pull up resistors the load function is again very simple it just pulses the latch line from 0 to 1 and then back to zero again and that's it the read function is more interesting because this time we are not sending but receiving let's call the variable that will contain the result B and we'll make it an unsigned character same as the function itself then we again write a backwards for Loop starting at 7 because the first bit that comes out of the CD4 to 1 is bit number seven and because we are calling the load function before calling the read function this bit is already waiting for us so we take the status of the data pin and store it in the leftmost position of our byte B like this then we can pulse the clock line to get to the next bit and so on and so on and so on and after the for Loop we just return R byte B that now contains the exact status of each bit in our cd421 register and that's it now we can compile the code and Flash it onto our controller so you see when you press a button the LED pattern changes on the left side we display the inverted data and on the right side we display the data exactly as it is received and you can see that the update speed is very fast and there is no visible DeLay So this works great for many applications and if you want to read out more push buttons you can just add another register in series now how do we do that well I'm glad that you asked to chain another cd421 in series with the first one the clock and latch pins are connected in parallel and the Q8 output of the second register gets connected to the data input of the first one this way we read out the information of the first register but the information of the second register is passed along right after that and just as before we do not actually need any new wires to the microcontroller just the three that we started with and we can read out a whole more set of buttons to build this on the breadboard first again disconnect the power the second register goes in row 35 again with its Notch facing to the left after connecting the vdd and ground pins of the cd4021 and inserting the bypass capacitor C6 between pins 16 and 8. we can plug in the second set of push buttons like this together with their pull up resistors just as before on the left connect one side of these buttons to ground and the other side to the inputs of our shift register now we need to feed its output Q8 at Pin 3 into the data input of the previous register at Pin 11 like this clock and ledge are again connected in parallel to pins 10 and 9 and that's it plug-in power and back into the code and you may have already guessed the first thing we do is to define a second variable called V2 to store the information about our second set of 8 buttons then we just duplicate this line here and change V1 to V2 and in the output part we change the V1 to a tilde V1 and this V1 here to av2 and after compiling and flashing every LED shows the status of one individual push button and we are inverting both of the values because the pull-up resistors invert the logic of the push buttons and of course you can add many many more of those registers in the series if you have even more push buttons that you want to read out just keep in mind that the longer the chain becomes the longer it's going to take to read out the information of every single button just because the data has to travel through all of the registers in that chain now it's probably a better idea in this case to break up that long one chain into smaller but several chains and then each of these chain gets their own data input but they still share clock and latch so you have to spend a little bit more microcontroller pins but you get that faster refresh rate so that's completely up to you of course but now that we understand all of this let's have a look at this little controller here yes this entire part here at the bottom is almost exactly what is included in a vintage SNES game controller almost exactly because these controllers have 12 buttons in total and not 16 but everything else is really exactly the same I am using a newly made controller here for this video but you can use a vintage one too this is the plug of the controller and here you connect VB and ground and you guessed it R3 Wireless clock latch and data to make a little adapter I cut and strip an extension cable and use my continuity tester to figure out which color goes to which pin and to show that this really works we can leave the source code in the microcontroller completely unchanged and just replace the lower part of the breadboard first we again disconnect the battery and then detach the data clock and latch connections like this remove the vdd and ground connection as well and then get rid of the lower breadboard altogether now plug in the wires of the SNES adapter cable that we fabricated a few minutes ago vdd and ground go directly into the power rail its green data output goes to pin 5 of the pick the yellow clock wire goes to pin 6 and the blue LED wire gets connected to pin 7 at the controller and that's it it just works without any additional coding just plug it in turn on the power press the controller buttons and it just works I love that inside the mplab IDE we can now add lines to our existing code that check if a specific button is pressed for example the a button lights up LED 16 which means that it is the eighth bit of the right shift register and if you want to check for this bit we just write this line here and then inside the if statement you can put whatever you want to happen if a is pressed and here is how that looks like for all the other buttons as well and of course you can download this entire code in the companion article on friendlywired.com now all of these if statements are completely empty of course so you have to put in whatever you want to happen when say the button a is pressed but that's the true magic of having your own microcontroller projects because you can program to make them do exactly what you want them to do and with these shift registers at your disposal you're actually really free to create really cool interesting designs and if you do please make sure to share them with me on social media now I want to say two more things the first thing is if this whole microcontroller programming thing scares you it scared me at first it's very normal I have a very detailed pick introduction video that I really invite you to check out right here it goes through all the basics at the end we make our first led blink and it's really the basic of all of these products on my channel so if you understand that one video you can do a whole lot more so I really encourage you to give that a try the second thing I wanted to mention is that the cd494 is really not an LED driver it's actually just a shift register now we can add these small five millimeter LEDs to each of its outputs and that's kind of okay but any bigger LED well it just doesn't work and the chip is not strong enough to actively drive them and if you are looking in for an LED driver chip then check out the TLC 5916 and I have a whole detailed video on just that chip here on my channel as well alright well I hope I could inspire you to use these shift registers in your future projects and if you do again please share with me on social media I would love to see your Creations let me know what else you want to learn thank you so much for watching and I will see you next time
Info
Channel: FriendlyWire
Views: 11,684
Rating: undefined out of 5
Keywords: CD4094, CD4021, PIC16F1455, shift register, shift register microcontroller, shift register tutorial, input shift register, output shift register, CD4094 shift register, CD4021 shift register, CD4094 circuit, CD4021 circuit, CD4094 explanation, CD4021 explanation, CD4094 tutorial, CD4021 tutorial
Id: 7RWaDvTeG7Y
Channel Id: undefined
Length: 26min 47sec (1607 seconds)
Published: Sat Dec 17 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.