Raspberry Pi Shift Register Model


I purchased a set of 74HC595 shift registers from Adafruit. This was my first experience doing anything with an IC so I wasn’t sure what to expect. With some help from a real engineer, I figured out the pin pattern and was able to build a php model to make it all work.

Let’s start with a simple LED example on the breadboard.
File: shift_register_model.php

* Shift Register Model.
* This file has all the methods required for using a shift register with the Raspberry Pi
* PHP 5
* Copyright 2012, J.C. Highlight Productions (http://jchighlightpro.com)
* Licensed under The GNU GPL
* This  program  is  free  software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the  Free Software Foundation; either version 3 of the License, or (at your
		* option) any later version. This program is distributed in the hope that it
* will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* Public License for more details.
* @copyright     Copyright 2012, J.C. Highlight Productions (http://jchighlightpro.com)
* @link          http://www.jchighlightpro.com/home-automation/
* @license       GNU GPL License (http://www.gnu.org/licenses/gpl.html)
class shift_register_model extends gpio_model{

	var $_serPin;
	var $_oePin;
	var $_rclkPin;
	var $_srclkPin;
	var $_bits;

	var $_current_state;

	function __construct($bits, $serPin,$oePin,$rclkPin, $srclkPin){
		$pins = array($serPin=>'out', $oePin=>'out',$rclkPin=>'out',$srclkPin=>'out',);
		echo("\nShift Register Loading...");

		$this->_bits			= $bits; // How many bytes can the shift register handle
		$this->_serPin			= $serPin;
		$this->_oePin			= $oePin;
		$this->_rclkPin			= $rclkPin;
		$this->_srclkPin 		= $srclkPin;
		$this->_current_state	= 0; //initialize to all off


		//echo("serPin: ".$this->_serPin." oePin: ".$this->_oePin." rclkPin: ".$this->_rclkPin." srclkPin: ".$this->_srclkPin."\n");

	 * Takes a number and shifts it through the dataPin. Must be less than or equal to the total bits the shift register will allow.
	 * @param int $number
	function shift_out($number){

		$this->set_value($this->_rclkPin, LOW);		// make sure the clock lines are in the correct state, make no assumptions.
		$this->set_value($this->_srclkPin, LOW);

		$bin_num = decbin($number);

			$comp_val = pow(2,$i);
			if(($number & $comp_val) == $comp_val)  { $this->pulse_data(HIGH); } else{ $this->pulse_data(LOW); }

		$this->set_value($this->_rclkPin,HIGH); 	// latch shift registers to the outputs.
		$this->set_value($this->_rclkPin, LOW); 	// Just for clean up.


	 * Brings clock pin high, sets data pin to $value, brings clock pin low.
	 * @param int $value
	function pulse_data($value){

		$this->set_value($this->_serPin,$value);	// 0 or 1
		$this->set_value($this->_srclkPin,HIGH);	// data is read on the positive clock edge.
		//usleep(50000);							// got to let the data line settle. temp included in set_calue
		$this->set_value($this->_srclkPin,LOW);		// set the clock back for next bit

	 * Brings the oePin High which will disable the output on the shift registers.
	public function disable_outputs(){

	 * Brings the oePin Low which will enable the outputs.
	public function enable_outputs(){

	 * Change the state of a pin.
	 * @param int $pin
	 * @param constant $state HIGH or LOW
	public function set_pin($pin,$state){

		if($state == HIGH){
			$this->_current_state = $this->_current_state | pow(2,$pin); //or
			$this->_current_state = $this->_current_state ^ pow(2,$pin); //xor

This depends on the GPIO model I posted earlier and should be able to support any number of output channels on daisy chained shift registers.

The first step is to initialize the model. There are 5 parameters. The first is the number of bits the shift register array can handle. In this case we are just using one 8 channel shift register. The next is SER or the serial pin. This is the data pin and we are using GPIO4. Next, OE is the Output Enable pin – GPIO22. When it is HIGH, the output is disabled. Low enables the output. Technically, the OE pin can be shorted to 3.3v if you have to save a pin and don’t mind not being able to turn the outputs on or off.

The RCLK is the storage register clock – GPIO21. SRCLK is the serial register clock – GPIO17.

$shiftr = new shift_register_model(8,4,22,21,17); //numb_bits, SER, OE, RCLK, SRCLK

There are two main ways to use the shift register class. The first is using the shift_out function to set the binary value of the integer you pass to the functions



File: shift_reg_test.php

#!/usr/bin/php -q


define("HIGH", 1);
define("LOW", 0);

$shiftr = new shift_register_model(8,4,22,21,17); //numb_bits, SER, OE, RCLK, SRCLK

$shiftr->set_pin(4, HIGH);
$shiftr->set_pin(2, HIGH);
$shiftr->set_pin(0, HIGH);
$shiftr->set_pin(7, HIGH);
$shiftr->set_pin(2, LOW);

	echo("Step $i Complete\n");

To get more outputs you can daisy chain more than one shift register. Wire everything together just like you did for the first shift register except use the Qh’ pin from the first register as your input to the serial pin of second register.

I am working on a circuit diagram on circuits.io. Take a look at my project: Raspberry Pi Digital Output Expander

Leave a Reply

Your email address will not be published. Required fields are marked *

6 − two =

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>