PR

シフトレジスタをRaspberryPiで使ってみよう【74HC595】

shiftragister-eyecatch

今回はRaspberryPiでシフトレジスタ(型式:74HC595)を使って、

3個のPinから、8個分のPinの制御をする方法についてご紹介します。

配線も複雑ですが、そもそもPythonのコードもなかなかなれないとつらい….

シフトレジスタの使いこなし方をメインにお話していきます。

シフトレジスタの原理などについては他に詳しく解説してくれている方がいますので、

そちらを参考にしてください。

この記事を読むことでわかること

自己紹介

東証一部上場企業でサラリーマンしてます。

主に工場(生産現場)で使用する検査装置のアプリケーション開発してます。

ヒトの作業を自動化して簡略化するアプリケーションを日々開発中。

2022年5月に転職。現役バリバリの技術者です。
現在は超大手企業の新規事業分野で装置の研究・開発をしています。

Youtubeチャンネルにさまざまな動画を上げています

↓↓↓こちらからYoutubeチャンネルにアクセス!! ↓↓↓

シフトレジスタとRaspberryPiの配線

それでは早速配線図を紹介します。

今回は、

  • GPIOは23,24,25番を使用する。
  • 74HC595(シフトレジスタ)の最大(8点)まで使用する。
  • 動作に使用するのはLED

という感じでやっていきます。

raspberrypi-shiftregister
ラズベリーパイとシフトレジスタを使ってLEDを点灯させる配線図

配線に使用するジャンパーワイヤーも多いので注意して下さい。

また、74HC595の向きにも注意してください。

切り欠きのような半円が左を向いた状態で配線しないとピン番号が一致しません。

最悪ラズパイが壊れる可能性もあるので注意です。

今回LEDを使用しますが、

単体で光らせるときに使用するくらいの抵抗を必ず入れるようにしてくださいね。

抵抗を入れないと最悪LEDが壊れます。

RaspberryPi側でやること

RaspberryPiは基本使うプログラミング言語はPythonですので、

今回もPythonでソースコードを書いていきます。

先ほども書きましたが、

今回使用するGPIOピンは23番、24番、25番です。

まずは全てのLEDをONOFF切り替えるプログラムです。

import RPi.GPIO as GPIO
import time
LSBFIRST = 1
MSBFIRST = 2
# 74HC595(シフトレジスタ)のそれぞれのピンをRaspberryPiのGPIOと接続する。
dataPin = 23 #GPIO23にデータピンを設定
latchPin = 24 #GPIO24にラッチピンを設定
clockPin = 25 #GPIO25にクロックピンを設定
lednum=8
highlow=True
def setup():
    GPIO.setmode(GPIO.BCM) # GPIO番号で指定するためにBCMモードにする。
    # シフトレジスタにつながっているピンをすべてOUTに設定する。
    GPIO.setup(dataPin, GPIO.OUT)
    GPIO.setup(latchPin, GPIO.OUT)
    GPIO.setup(clockPin, GPIO.OUT)
 
def shiftOut(dPin,cPin,order,val2):
    # 7seg+1dotなので8個のLEDそれぞれのONOFFを制御する。
    for i in range(0,8):
        # いったんクロックピンをLOWにする。
        GPIO.output(cPin,GPIO.LOW)
        # 上記で決めた固有値はMSBFIRST用で決めたモノなのでMSBFIRSTしか使わない。
        if(order == LSBFIRST):
            GPIO.output(dPin,val2 and GPIO.HIGH or GPIO.LOW)
        elif(order == MSBFIRST):
            GPIO.output(dPin,val2 and GPIO.HIGH or GPIO.LOW)
        # クロックピンをHIGHに戻す。
        GPIO.output(cPin,GPIO.HIGH)
def loop():
    while True:        
        highlow=True
        # いったんラッチピンをLOWにする。
        GPIO.output(latchPin,GPIO.LOW)
        # ここでshiftout関数でbyteに変換した文字列をデータピンに送る。
        shiftOut(dataPin,clockPin,MSBFIRST,highlow)#Output the figures and the highest 
        # ラッチピンをHIGHに戻す。
        GPIO.output(latchPin,GPIO.HIGH)
        time.sleep(0.5)       
        highlow=False
        # いったんラッチピンをLOWにする。
        GPIO.output(latchPin,GPIO.LOW)
        # ここでshiftout関数でbyteに変換した文字列をデータピンに送る。
        shiftOut(dataPin,clockPin,MSBFIRST,highlow)#Output the figures and the highest 
        # ラッチピンをHIGHに戻す。
        GPIO.output(latchPin,GPIO.HIGH)
        time.sleep(0.5)    
            
def destroy(): 
    GPIO.cleanup()
if __name__ == '__main__': # Program starting from here 
    print ('Program is starting...' )
    setup()
    try:
        loop() 
    except KeyboardInterrupt: 
        destroy()

ポイントとなるのは、

  • データピン
  • ラッチピン
  • クロックピン

この3つです。

この3つのピンをLOW/HIGHにして信号を作り出しています。

どのピンをいじるか制御の流れ
ラッチピンLOW
クロックピンLOW
データピンHIGHorLOW←これは自分で決める
クロックピンHIGH
↑クロックピンとデータピンのLOW/HIGHはピン数分必要
ラッチピンHIGH

順番を守ってあげるのが重要です。

それから、面倒ですが全ピンの状態をLOWなのかHIGHなのか指定する必要があります。

8ピンあるなら、クロックピンとデータピンのHIGH/LOWは8セット必要です。

ちょっと複雑にしてみる

それでは、すべてのLEDをON/OFFだけではつまらないので、

1つずつONしていき、すべて点灯したら1つずつOFFしていくプログラムを紹介します。

import RPi.GPIO as GPIO
import time
LSBFIRST = 1
MSBFIRST = 2
# 74HC595(シフトレジスタ)のそれぞれのピンをRaspberryPiのGPIOと接続する。
dataPin = 23 #GPIO23にデータピンを設定
latchPin = 24 #GPIO24にラッチピンを設定
clockPin = 25 #GPIO25にクロックピンを設定
lednum=8

def setup():
    GPIO.setmode(GPIO.BCM) # GPIO番号で指定するためにBCMモードにする。
    # シフトレジスタにつながっているピンをすべてOUTに設定する。
    GPIO.setup(dataPin, GPIO.OUT)
    GPIO.setup(latchPin, GPIO.OUT)
    GPIO.setup(clockPin, GPIO.OUT)
 
def shiftOut(dPin,cPin,order,ledNo,highlow):
    # 7seg+1dotなので8個のLEDそれぞれのONOFFを制御する。
    for i in range(0,8):
        # いったんクロックピンをLOWにする。
        GPIO.output(cPin,GPIO.LOW)
        # 上記で決めた固有値はMSBFIRST用で決めたモノなのでMSBFIRSTしか使わない。
        if(order == LSBFIRST):
            GPIO.output(dPin,ledNo>i&highlow and GPIO.HIGH or GPIO.LOW)
        elif(order == MSBFIRST):
            if(highlow):
                if (ledNo>i):
                    GPIO.output(dPin,GPIO.HIGH)
                elif(ledNo<=i):
                    GPIO.output(dPin,GPIO.LOW)
            else:
                if (ledNo<=i):
                    GPIO.output(dPin,GPIO.HIGH)
                elif(ledNo>i):
                    GPIO.output(dPin,GPIO.LOW)            
        # クロックピンをHIGHに戻す。
        GPIO.output(cPin,GPIO.HIGH)
def loop():
    while True:
        highlow=True
        # num(0~F)を順番に点灯させる。
        for i in range(0,lednum):
            # いったんラッチピンをLOWにする。
            GPIO.output(latchPin,GPIO.LOW)
            # ここでshiftout関数でbyteに変換した文字列をデータピンに送る。
            shiftOut(dataPin,clockPin,MSBFIRST,i,highlow)#Output the figures and the highest 
            # ラッチピンをHIGHに戻す。
            GPIO.output(latchPin,GPIO.HIGH)
            time.sleep(0.5)       
            # num(0~F)を順番に点灯させる。
        highlow=False
        for i in range(0,lednum):
            # いったんラッチピンをLOWにする。
            GPIO.output(latchPin,GPIO.LOW)
            # ここでshiftout関数でbyteに変換した文字列をデータピンに送る。
            shiftOut(dataPin,clockPin,MSBFIRST,i,highlow)#Output the figures and the highest 
            # ラッチピンをHIGHに戻す。
            GPIO.output(latchPin,GPIO.HIGH)
            time.sleep(0.5)    
def destroy(): 
    GPIO.cleanup()
if __name__ == '__main__': # Program starting from here 
    print ('Program is starting...' )
    setup()
    try:
        loop() 
    except KeyboardInterrupt: 
        destroy()
                                    

ポイントは、loop関数の中でLEDの数だけ

ループさせて1個ずつ点灯/消灯させていることろです。

まとめ

今回はシフトレジスタを使って3つのGPIOだけで8個のLEDを制御してみました。

単純計算で使用できるGPIO番号が表示上27までありますから、

すべてにシフトレジスタを接続すれば8*27/3で72点まで制御できることになります。

72点も制御といわれてもはっきり言ってそんなに制御するものないですよね…

使ったとしても1個か2個だと思いますが、本気を出せば結構ラズパイでも

制御可能なピン数が増やせるシフトレジスタのお話でした。

コメント

タイトルとURLをコピーしました