Arduino or Node MCU has limited digital pins and if you are using multiple sensors then there is chance that you may exaughst out of the digital input/output pins. In order to solve this issue, thank god we have Shift Registers. These shift registers can be used to increase the number of digital input and output pins. In this blog I will show you two shift registers which are used to increase digital input and output pins.
CD4021: This is parallel to serial shift in register. Using this shift register you can use upto 8 digital input. Also, this collects the input information asynchronously and all at once. You can call it Input Shift Register. Basically you can connect different digital inputs and collect the information.
74HC595: This is serial to parallel shift out register. You can use 8 digital output.This works in synchronous serial communication.
![]() |
Schematic for 74HC595, CD4021BE and Node MCU |
PIN Description is as below,
CD4021 | Node MCU | 74HC595N |
Parallel Serial Controller (P/SC) (PIN: 9) | D1 (GPIO5) | |
CLOCK (PIN: 10) Clock PIN | D5 (GPIO14) | SCK/SRCLK/SH_CP (PIN: 11) CLOCK PIN |
Q8 (PIN: 2) | D2 (GPIO4) | |
D3 (GPIO0) | RCK/SH_CP/RCKL (PIN: 12) LATCH | |
D7 (GPIO13) | SER/DS (PIN: 14) DATA | |
GND | GND | G/OE |
VCC | VCC | SCL/MR/SRCLR |
pinMode(LATCHOUT_PIN, OUTPUT);
pinMode(LATCHIN_PIN, OUTPUT);
pinMode(CLOCK_PIN, OUTPUT);
dataIn = 0;
dataIn = This is variable which stores the out values. For exampple, out of 8 output pin, you can set any bit and send signal to output shift registers.
Once Initialization is complete, then next step is to record Input/output values.
Set the output to 74HC595 output pins as below,
digitalWrite(CLOCK_PIN, LOW);
digitalWrite(LATCHOUT_PIN, LOW);
shiftOut(DATAOUT_PIN, CLOCK_PIN, variableData);
digitalWrite(LATCHOUT_PIN, HIGH);
Intial data out value is set as below,
byte dataOut = 0xFF;
Change the bit as per requirement and set theDigital pin out value.
Below code value is used to read the value from Input Shift Register.
digitalWrite(CLOCK_PIN, HIGH);
digitalWrite(LATCHIN_PIN, HIGH);
delayMicroseconds(5);
digitalWrite(LATCHIN_PIN, LOW);
dataIn = shiftIn(DATAIN_PIN, CLOCK_PIN);
Both Shift IN and Shift out functions are standard provided at link,
https://www.arduino.cc/en/Tutorial/ShiftOut
https://www.arduino.cc/en/Tutorial/ShiftIn
Please find complete program as below,
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "Arduino.h" | |
//Pin connected to ST_CP of 74HC595 | |
//D3 | |
#define LATCHOUT_PIN 0 | |
//Pin connected to SH_CP of 74HC595 | |
//D5 | |
#define CLOCK_PIN 14 | |
////Pin connected to DS of 74HC595 | |
//D7 | |
#define DATAOUT_PIN 13 | |
//D2 | |
#define DATAIN_PIN 4 | |
//LATCH IN PIN to P/S C of CD4021BE | |
//D1 | |
#define LATCHIN_PIN 5 | |
byte dataOut = 0xFF; | |
byte dataIn = 0; | |
void setup() | |
{ | |
Serial.begin(115200); | |
initializeDigitalPIN(); | |
} | |
// The loop function is called in an endless loop | |
void loop() | |
{ | |
setDigitalPININ(); | |
delay(1000); | |
setDigitalPINOut(dataOut); | |
} | |
void initializeDigitalPIN() { | |
//set pins to output because they are addressed in the main loop | |
pinMode(LATCHOUT_PIN, OUTPUT); | |
pinMode(LATCHIN_PIN, OUTPUT); | |
pinMode(CLOCK_PIN, OUTPUT); | |
dataIn = 0; | |
} | |
void setDigitalPINOut(byte variableData) { | |
digitalWrite(CLOCK_PIN, LOW); | |
digitalWrite(LATCHOUT_PIN, LOW); | |
shiftOut(DATAOUT_PIN, CLOCK_PIN, variableData); | |
digitalWrite(LATCHOUT_PIN, HIGH); | |
} | |
void setDigitalPININ() { | |
digitalWrite(CLOCK_PIN, HIGH); | |
digitalWrite(LATCHIN_PIN, HIGH); | |
delayMicroseconds(5); | |
digitalWrite(LATCHIN_PIN, LOW); | |
dataIn = shiftIn(DATAIN_PIN, CLOCK_PIN); | |
} | |
/* | |
* Sample from arduino tutorial website | |
*/ | |
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); | |
delayMicroseconds(0.2); | |
temp = digitalRead(myDataPin); | |
Serial.print(temp); | |
Serial.print(" = "); | |
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(pinState); | |
//Serial.print(" "); | |
//Serial.println (dataIn, BIN); | |
digitalWrite(myClockPin, 1); | |
} | |
//debuging print statements whitespace | |
/*Serial.println(); | |
Serial.println(myDataIn);*/ | |
//Serial.println(" "); | |
return myDataIn; | |
} | |
/* | |
* Sample from arduino tutorial website | |
*/ | |
void shiftOut(int myDataPin, int myClockPin, byte myDataOut) { | |
// This shifts 8 bits out MSB first, | |
//on the rising edge of the clock, | |
//clock idles low | |
/*Serial.print("Data Before: "); | |
Serial.println(myDataPin);*/ | |
//internal function setup | |
int i = 0; | |
int pinState; | |
pinMode(myClockPin, OUTPUT); | |
pinMode(myDataPin, OUTPUT); | |
//clear everything out just in case to | |
//prepare shift register for bit shifting | |
digitalWrite(myDataPin, 0); | |
digitalWrite(myClockPin, 0); | |
//for each bit in the byte myDataOut� | |
//NOTICE THAT WE ARE COUNTING DOWN in our for loop | |
//This means that %00000001 or "1" will go through such | |
//that it will be pin Q0 that lights. | |
for (i = 7; i >= 0; i--) { | |
digitalWrite(myClockPin, 0); | |
//if the value passed to myDataOut and a bitmask result | |
// true then... so if we are at i=6 and our value is | |
// %11010100 it would the code compares it to %01000000 | |
// and proceeds to set pinState to 1. | |
if (myDataOut & (1 << i)) { | |
pinState = 1; | |
} else { | |
pinState = 0; | |
} | |
//Sets the pin to HIGH or LOW depending on pinState | |
digitalWrite(myDataPin, pinState); | |
//register shifts bits on upstroke of clock pin | |
digitalWrite(myClockPin, 1); | |
//zero the data pin after shift to prevent bleed through | |
digitalWrite(myDataPin, 0); | |
/* Serial.print("myDataPin: "); | |
Serial.print(myDataPin); | |
Serial.print(" myClockPin: "); | |
Serial.print(myClockPin); | |
Serial.print(" myDataPin: "); | |
Serial.println(myDataPin);*/ | |
} | |
//stop shifting | |
digitalWrite(myClockPin, 0); | |
//Serial.print("74HC595 Data: "); | |
//Serial.println(myDataPin); | |
} |
No comments:
Post a Comment