Subscribe to Arduino Academy and start learning today for FREE!

Shift Registers – Unlimited Inputs With Only 3 Data Lines?

Last week we demonstrated how to use an output shift register (74HC595) to control 8 LED’s with only 3 data lines. Since shift registers can be daisy chained, the number of LED’s can be virtually unlimited. This week we wanted to show how to use an input shift register, the CD4021. 8 push button switches can be polled and used to input data or control devices, with only 3 data lines, And as with the output shift register, multiple chips can be daisy chained with no additional i/o lines needed. See the video below!


Become the Maker you were born to be. Try Arduino Academy for FREE!

Pin 3 of the CD4021 goes to Arduino Pin 9
Pin 9 of the CD4021 goes to Arduino Pin 8
Pin 10 of the CD4021 goes to Arduino Pin 7

Pins 1, 4-6, & 13-5 of the CD4021 go to push button switches and Gnd. The other side of each switch goes to +5v.

Data sheet:


//  Name    : shiftIn Example 1.1                              //
//  Author  : Carlyn Maw                                        //
//  Date    : 25 Jan, 2007                                      //
//  Version : 1.0                                               //
//  Notes   : Code for using a CD4021B Shift Register     //
//          :                                                   //

//define where your pins are
int latchPin = 8;
int dataPin = 9;
int clockPin = 7;

//Define variables to hold the data 
//for shift register.
//starting with a non-zero numbers can help
byte switchVar1 = 72; //01001000

void setup() {
//start serial

//define pin modes
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);


void loop() {

//Pulse the latch pin:
//set it to 1 to collect parallel data
//set it to 1 to collect parallel data, wait
//set it to 0 to transmit data serially

//while the shift register is in serial mode
//collect each shift register into a byte
//the register attached to the chip comes in first
switchVar1 = shiftIn(dataPin, clockPin);

//Print out the results.
//leading 0’s at the top of the byte
//(7, 6, 5, etc) will be dropped before
//the first pin that has a high input
Serial.println(switchVar1, BIN);

//white space
//delay so all these print satements can keep up. 


//————————————————end main loop

////// —————————————-shiftIn function
///// just needs the location of the data pin and the clock pin
///// it returns a byte with each bit in the byte corresponding
///// to a pin on the shift register. leftBit 7 = Pin 7 / Bit 0= Pin 0

byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
int pinState;
byte myDataIn = 0;

pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);
//we will be holding the clock pin high 8 times (0,..,7) at the
//end of each time through the for loop

//at the begining of each loop when we set the clock low, it will
//be doing the necessary low to high drop to cause the shift
//register’s DataPin to change state based on the value
//of the next bit in its serial information flow.
//The register transmits the information about the pins from pin 7 to pin 0
//so that is why our function counts down
for (i=7; i>=0; i–)
digitalWrite(myClockPin, 0);
temp = digitalRead(myDataPin);
if (temp) {
pinState = 1;
//set the bit to 0 no matter what
myDataIn = myDataIn | (1 << i);
else {
//turn it off — only necessary for debuging
//print statement since myDataIn starts as 0
pinState = 0;

//Debuging print statements
//Serial.print(” “);
//Serial.println (dataIn, BIN);

digitalWrite(myClockPin, 1);

//debuging print statements whitespace
//Serial.println(myDataIn, BIN);
return myDataIn;

Become the Maker you were born to be. Try Arduino Academy for FREE!

More Info:

Video (still processing, try back in an hour):

Notify of
Inline Feedbacks
View all comments


Would love your thoughts, please comment.x