色々なセンサーである程度遊び検証し終わって、他に何か検証するものはないかなと部品入れを探していたら、以前購入したパーツセットに
ICみたいなやつが入っている。なにかと調べたら、シフトレジスタ(74HC595N)というものらしい。何に使うのかというと・・・ラズパイを用いて色々なセンサー、LED等を制御する場合、GPIOピンに接続する。I2CやSPI対応センサーのようなシリアル通信対応だと複数つないで制御できるが、そうでないものは信号線分のGPIOピンを割かなければならない。特にLEDを1つ1つ制御する場合はLEDの数だけGPIOピンが必要となってしまうからGPIOが27本なので27個が限界となってしまう。それを3本の信号線でシリアルデータを送り、パラレルに制御できるようにする部品(74HC595Nは1個で同時に8つ)で、しかも複数つないで増やせるので大量にLEDを制御できるらしい。
とりあえず、参考サイトを探してみると・・・
で詳しく接続方法とPythonコードが紹介されているので、早速まねて動かしてみました。とりあえず、実行する前にデータシートを確認。電源電圧は3.3Vで利用可能。使用してない入力はVccまたはGNDにつなげろと書いてあります。次に、絶対最大定格をみて制限抵抗の計算。
制限抵抗の決め方として、74HC595の最大は70mA、一個あたり(1ピン当たり)のLEDは大体35mAの制限がある。8ピンを同時にLEDに接続するには8.5mA程度に抑える必要がある。6mA/LED一個程度で点灯させたいので下のサイトで計算すると216Ω、抵抗は220Ωをつけておけばよさそう。
(追記11/18)1ピン3.3vの最大電流値が一番引っ掛かりそうで考慮していなかった(汗。3.3vの1ピンと17ピン合計で最大電流値は50mAの制限がある。74HC595の最大よりも少ないため、こちらを優先に考えると50÷8=6.25mA程度なので、6mAだとギリギリとなってしまう。4mA程度で納めておいたほうが良さそうなので330Ωの抵抗が望ましい。74HC595の消費電力は4μA程度なので無視できると思う。
ちなみに、220Ωの抵抗でどのくらいの電流が流れているかの動画も掲載します。結果として5mA/1LEDぐらいだったのでトータル40mAだったんだけど、シフトレジスタを2個つけてLEDつけるとやっぱりオーバーは免れないので、5Vからとったほうがよさそう。
ちなみに多くの電流(1ピン当たり35mA[QA~QH]↑ or トータル50mA↑)を流したい場合は、トランジスタでスイッチングする必要があると思う。とりあえず、許容以内で流して動作を確認する。
まずは、ブレッドボードにラズパイと74HC595に直接つなげる前に、電源ボードを刺しこんで点灯チェック。
全部のLEDが点灯するのを確認。そのあと、74HC595とラズパイに接続する(ワイヤーの処理が汚いw)
参考サイトにあるled.pyを動かしてみる。
とりあえず、正常に動作ししている模様。ここで終わっては2番煎じとなってしまうので、お決まりのライブラリーを探してみる。どちらにせよ二番煎じ・・・どころかそれ以降w
上のライブラリを見つけたのでインストールして、よりパーリィー感を出してコードを書いてみる。python3で行うので以下でインストールを行う
1 |
pip3 install git+https://github.com/marsminds/shiftr_74HC595.git |
インストールをしたら、以下のコードを実行してみた。ライブラリのexampleにの変更点は、ピンモードが実ピンモード(GIPO.BOARD)からGPIO番号を指定するモード(GPIO.BCM)に変えたくらい。ループの中は0.05秒毎にLEDをつけて、0.05秒毎に消していくのを繰り返すようにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
import RPi.GPIO as GPIO from shiftr_74HC595.shiftr_74HC595 import ShiftRegister from time import sleep # GPIO.setmode(GPIO.BOARD) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) # data_pin = 40 #pin 14 on the 75HC595 # latch_pin = 38 #pin 12 on the 75HC595 # clock_pin = 35 #pin 11 on the 75HC595 data_pin = 21 # シリアルデータ latch_pin = 20 # ラッチクロック clock_pin = 19 # シフトレジスタクロック shift_register = ShiftRegister(data_pin, latch_pin, clock_pin) try: while 1: for i in range(8): shift_register.setOutput(i, GPIO.HIGH) shift_register.latch() sleep(0.05) for i in range(8): shift_register.setOutput(i, GPIO.LOW) shift_register.latch() sleep(0.05) except KeyboardInterrupt: shift_register.setOutputs([GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW]) shift_register.latch() print ("Ctrl-C - quit") GPIO.cleanup() |
てな感じ。とりあえず、ちょっとパーリィー感がでた。
次に、明るさ調節ができるとの情報が載っているサイトをみかけた。
上の接続だど74HC595の10番ピン(SCLR)は3.3V(HIGH)につないでいるが、これをPWMで制御することで明るさを調整できるらしい。10番ピンを3.3Vから外して、GPIO4に接続して下のコードを実行してみた(反射的に書いたコードなんで・・・定義とかしてません)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
import RPi.GPIO as GPIO from shiftr_74HC595.shiftr_74HC595 import ShiftRegister from time import sleep # GPIO.setmode(GPIO.BOARD) GPIO.setmode(GPIO.BCM) GPIO.setwarnings(False) GPIO.setup(4, GPIO.OUT) data_pin = 21 # シリアルデータ latch_pin = 20 # ラッチクロック clock_pin = 19 # シフトレジスタクロック shift_register = ShiftRegister(data_pin, latch_pin, clock_pin) try: shift_register.setOutputs([GPIO.HIGH, GPIO.HIGH, GPIO.HIGH, GPIO.HIGH, GPIO.HIGH, GPIO.HIGH, GPIO.HIGH, GPIO.HIGH]) shift_register.latch() pwm = GPIO.PWM(4, 490) pwm.start(0) while 1: for i in range(255): pwm.ChangeDutyCycle(i*100/255) sleep(0.01) for i in range(255): pwm.ChangeDutyCycle((255-i)*100/255) sleep(0.01) except KeyboardInterrupt: shift_register.setOutputs([GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW, GPIO.LOW]) shift_register.latch() print ("Ctrl-C - quit") GPIO.cleanup() |
参考サイトではArduinoでanalogWriteを使っていて、リファレンスを読むと
周波数は490Hzでデューティ比は0-255で表現するらしいので、GPIO用にざっくり換算して上のコードを書いてみた。動作確認の動画は以下です。
まとめての明滅はできるけど、一つ一つのコントロールはできないとおもう・・・(なんかあるのかな。とりあえずは、ここまでしかわからなかった。
今後は「複数の74HC595をつなげての制御」を調べて検証していきたい。