How to Expand Arduino Ports with Shift Registers
Published: 2024-04-01 01:10:05

---
title: How to Expand Arduino Ports with Shift Registers
published: true
description: Simple tutorial with schematics demonstrating how arduino ports can be expanded using shift register ICs.
tags: 
# cover_image: ![Arduino 74HC165 and 74HC595](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5plymdtrpug5c9gwjj6r.png)
# Use a ratio of 100:42 for best results.
# published_at: 2024-04-01 00:37 +0000
---

A few days ago, I was searching for tutorials and documentation on how to expand Arduino ports using Shift Register ICs. While there are many available, I found that none of them were direct and straight to the point. That's precisely what this text aims to provide.

If you have an [Arduino](https://www.arduino.cc/) project which have to control a lot of components or ports, the dozens of your arduino ports may not be enough even if you have a board like Arduino Mega or Giga. Some ICs have the capability to receive serial data and transfer it through multiple of their pins. In this demostration, `74HC165` was used for input pins and `74HC595` was used for output pins.

The following example comes with a [SimulIDE](https://simulide.com/p/) schematics and Arduino C++ source code. This simulator is free and it is available for Linux 64, Windows (32 and 64) and MacOS. Besides being free, it have a feature to simulate Arduino boards with your compiled source code.

![Schematics](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5plymdtrpug5c9gwjj6r.png)

Please note that the simulator has omitted the VCC and Ground pins for the 74HC165 and 74HC595 ICs in order to simplify the simulation environment.

The firmware source code would be:

```cpp
// 74HC165 Connections
// PL pin 1
int load = 7;
// CE pin 15
int clockEnablePin = 5;
// Q7 pin 7
int dataIn = 4;
// CP pin 2
int clockIn = 6;


// 74HC595 Connections
// ST_CP pin 12
const int latchPin = 10;
// SH_CP pin 11
const int clockPin = 11;
// DS pin 14
const int dataPin = 12;


// Local vars
int outputState = 0;


void setup()
{
  
  // 74HC165 connections
  pinMode(load, OUTPUT);
  pinMode(clockEnablePin, OUTPUT);
  pinMode(clockIn, OUTPUT);
  pinMode(dataIn, INPUT);

  // 74HC595 connections
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);

  // Setup Serial Monitor
  Serial.begin(9600);
  Serial.println("started!");
}


void loop()
{

  // Input Shift registers here:
  // Write pulse to load pin
  digitalWrite(load, LOW);
  delayMicroseconds(5);
  digitalWrite(load, HIGH);
  delayMicroseconds(5);
  // Get data from 74HC165
  digitalWrite(clockIn, HIGH);
  digitalWrite(clockEnablePin, LOW);
  byte incoming = shiftIn(dataIn, clockIn, LSBFIRST);
  digitalWrite(clockEnablePin, HIGH);
  // Print to serial monitor
  Serial.print("Pin States:\r\n");
  Serial.println(incoming, BIN);



  // Output Shift registers here:
  outputState += 1;
  outputState = outputState == 256 ? 0 : outputState;
  digitalWrite(latchPin, LOW);  
  shiftOut(dataPin,clockPin,MSBFIRST, outputState);  
  digitalWrite(latchPin, HIGH);


  // Watchable delay
  delay(1000);
}
```

The code above can be compiled in the Arduino IDE. Once compiled, the resulting hex file can be loaded into the simulator. Simply right-click on the Arduino component in SimulIDE, and select 'Load firmware', then choose your `.hex` file.

This project was published in [this](https://github.com/misabitencourt/shift-registers) github repository where you can find both the simulator file and the source code.