Tuesday, 19 January 2016

Raspberry PI - Adding more outputs using the 74HC595 shift output chip

Connecting the Raspberry PI to a shift output board uses less GPIO pins and giving you eight digital outputs. To connect this you need to enable the SPI (Serial Peripheral Interface) chip interface. The chip commands eight parallel outputs from a serial data stream. It is possible to chain more than one chip to increase the amount of outputs or use the another chip for inputs (74HC165) or analogue inputs (MCP3008).


Install and enable the SPI interface

  1. First make sure the system is up to date
    sudo apt-get update
    sudo apt-get upgrade
    sudo reboot
  2. To install the development software that includes spi_dev type the following command. Note:Raspberry PI needs internet connection for this to work.
    sudo apt-get install python-dev python3-dev
    The command will indicate the package size before installing. Then install the spidev for Pyhon with the below commands.
    cd ~
    git clone https://github.com/doceme/py-spidev.git
    cd py-spidev
    make
    sudo make install

  3. Enable the SPI interface 
  4. sudo raspi-config select Advanced the enable SPI and set to load by default.
  5. Reboot the Raspberry PI
  6. sudo reboot
  7. To check that the interface is enabled type lsmod and check that spi_bcm2835 is listed.

74HC595 connections





















Pin
Signal
Description
1
Q1
Parallel data output 1
2
Q2
Parallel data output 2
3
Q3
Parallel data output 3
4
Q4
Parallel data output 4
5
Q5
Parallel data output 5
6
Q6
Parallel data output 6
7
Q7
Parallel data output 7
8
GND
Ground
9
Q7S
Serial data output
10
MR
Master reset
11
SHCP
Shift clock input
12
STCP
Storage clock input
13
OE
Output enable
14
DS
Data serial input
15
Q0
Parallel data output 0
16
VCC
Positive supply voltage

How the SPI interface works
























SHCP is the constant clock used for processes. MR will reset all shift registers to low (This can be held High to be disabled). Serial data is sent to DS. When OE is enabled (This can be fixed low) and STCP is high shift registers are transferred to outputs. STCP storage clock can be connected to the Raspberry PI chip select of the SPI interface.


Wiring Connections







































Diodes are connected to Q0 to Q8 with 500Ω resistor to limit the voltage. The other connections are to the Raspberry PI.


Pin
Signal
Description
GPIO
RPI Pin
8
GND
Ground
GND
6
10
MR
Master reset
3.3 Volts
1
11
SHCP
Shift clock
SCLK
23
12
STCP
Storage clock
CS1
26
13
OE
Output enable
GND
6
14
DS
Serial data input
MOSI
19
16
VCC
Positive supply voltage
3.3 Volts
1


The SPI interface sequence and timming is taken care of buy the Raspberry PI SPI interface. The code required is as below.


import spidev
import time

spi = spidev.SpiDev()
A=0

def spiWrite(channel,OutValue):
    spi.open(0,channel) # Port 0 , Chip Select 1
    spiValue = spi.xfer2([1,OutValue])
    time.sleep(2)
    spi.close()
    return spiValue

while True:
    print ("Output Value = {}".format(A))
    resp = spiWrite(1,A)
    A=A+1
    if (A>254):

        A=0

This program will write values of 0 to 255 to chip. The output LED's will show the binary values of the integer. So for example when A =11 lights 1,2 and 4 will be on 1+2+8 as below.
Output No      1  2  3  4  5  6  7  8
Decimal value  1  2  4  8  16 32 64 128

4 comments:

  1. I think your black GND cable is in wrong GPIO pin. Anyway, thanks for tutorials!

    ReplyDelete
    Replies
    1. You are right great catch I will change that. Lucky that the pin numbering is correct.
      Thanks for letting me know :)

      Delete
    2. I have updated the picture now the GND is in the correct position.

      Delete
  2. Using Raspberry Pi Zero... I can bit bang the 595N... but can't seem to get SPI work. Here is the bit bang code example that works. I think this validates I have the hardware setup right.

    #!/usr/bin/python2
    #
    #

    import RPi.GPIO as GPIO
    import time
    import sys

    # MOSI (SPI0)... M74HC595N DIP Pin 14... BCM 10...
    DATA=10

    # CE0/CS1 (SPI0)... M74HC595N DIP Pin 12... BCM 8...
    #STCP=8
    # CE0/CS1...
    STCP=7
    LATCH=STCP

    # SCLK (SPI0)... M74HC595N DIP Pin 11... BCM 11...
    SHCP=11
    CLOCK=SHCP

    #

    def pulseClock():

    GPIO.output(CLOCK, GPIO.HIGH)
    time.sleep(.01)
    GPIO.output(CLOCK, GPIO.OUT)

    def serLatch():

    GPIO.output(LATCH, GPIO.HIGH)
    GPIO.output(LATCH, GPIO.LOW)

    def ssrWrite(value):

    for x in range(0,8):
    temp=value & 0x80
    if (temp == 0x80):
    GPIO.output(DATA, 1)
    else:
    GPIO.output(DATA, 0)

    pulseClock()
    value=value << 0x01
    serLatch()

    def convBinary(value):

    binaryValue='0b'
    for x in range (0,8):
    temp=value & 0x80
    if temp == 0x80:
    binaryValue=binaryValue + '1'
    else:
    binaryValue=binaryValue + '0'
    value=value << 1

    #

    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    GPIO.setup(LATCH, GPIO.OUT)
    GPIO.output(LATCH, GPIO.LOW)

    GPIO.setup(CLOCK, GPIO.OUT)
    GPIO.output(CLOCK, GPIO.LOW)

    GPIO.setup(DATA, GPIO.OUT)
    GPIO.setwarnings(True)

    # LEDs...
    #
    # 12345678
    # ******** 255
    # * 1

    #

    NUMBER=8
    #while 1:
    temp=1
    for j in range(0,NUMBER):
    ssrWrite(temp)
    temp=temp << 1
    time.sleep(.2)

    for j in range(0,NUMBER):
    temp=temp << 1
    ssrWrite(temp)
    time.sleep(.2)

    #

    GPIO.cleanup()

    ReplyDelete

Thank you fro reading my page.
Let me know if there is anything that I could add or change.
Please let me know if this information is helpful.