DEV Community

Misael Braga de Bitencourt
Misael Braga de Bitencourt

Posted on

How to Expand Arduino Ports with Shift Registers

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 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 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

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:

// 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);
}
Enter fullscreen mode Exit fullscreen mode

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 github repository where you can find both the simulator file and the source code.

Top comments (0)