前回記事で作成したデジタル時計ですが、いかんせん配線が多い。
ラズパイ使って別のもの作るのにトライしたいけれど、この配線を外したら二度と復元できない自信がある。
そしたら購入してたこのセットに入ってるじゃないですか。
配線をスッキリさせれるという代物が。
8ビットシフトレジスタ
やれること
シリアル→パラレル変換ができます。
・・・こちとら初心者。こんな説明じゃ何にも分かりません。
とりあえず各ピンが担っている役割を調べてみる。
ピンの位置と番号と役割
四角の縁がポコンと欠けてる所を目印にこんな感じで16個のピンが配置されてます。
ピン番号 | 種類 | 役割 | 記号 |
---|---|---|---|
1 | パラレル出力 | 2番目の出力 | QB/Q1 |
2 | パラレル出力 | 3番目の出力 | QC/Q2 |
3 | パラレル出力 | 4番目の出力 | QD/Q3 |
4 | パラレル出力 | 5番目の出力 | QE/Q4 |
5 | パラレル出力 | 6番目の出力 | QF/Q5 |
6 | パラレル出力 | 7番目の出力 | QG/Q6 |
7 | パラレル出力 | 8番目の出力 | QH/Q7 |
8 | グラウンド | 接地(アース) | GND |
9 | シリアル出力 | シフトレジスタを何個も繋げる時に使う | QH' |
10 | マスターリセット | シフトレジスタのリセット | SRCLR |
11 | シフトレジスタクロック | データの入力先を次のアドレスに移動 | SCK/SHCP |
12 | ラッチクロック | 8ビットのデータを送信順に出力 | RCK/STCP |
13 | ハイインピーダンス状態設定 | 全パラレル出力が切断状態になる | G/OE |
14 | シリアル入力 | 唯一の信号入力 | SER/DS |
15 | パラレル出力 | 1番目の出力 | QA/Q0 |
16 | 電源接続 | +5Vに接続する | Vcc |
たくさんピンがあるので混乱するけれど、シフトレジスタの肝となる動作で必要なのは以下だけです。
- シリアル入力
- パラレル出力
- シフトレジスタクロック
- ラッチクロック
基本的にはこの4種類を駆使してシリアルなデータをパラレルなデータに変換する事がシフトレジスタなるものの目的になります。
シフトレジスタの処理イメージ
で、パラレルなデータというのは結局どんなもんなんだい?
色々なサイトで勉強させてもらって飲み込んだ結果、シフトレジスタの概念は競馬の出走ゲートみたいな感じだなと思うことにしました。
(詳しくないから実際の競馬とは違うかもです)
###ストーリー
競馬のレースが始まるまでを例に処理順序を解説します。
太字がシフトレジスタで行っている処理になります
つまり、シリアル→パラレル変換とは・・
1列(直列)に来る入力データを蓄積し、並列データとして一気に出力するという事になります。
このイメージに従い、出走した馬(送出されたデータ)を7セグメントLEDの数字を表すピンに接続すればこれまで通りに想定の数値を表示する事ができました。
###マスターリセットのピンについて
ここまでの説明に登場してませんが、10番ピンのマスターリセットが初心者にはクセモノだと思います。苦労しました。
こいつの性質はLOW(切断)にするとレジスタの内容をリセットするという事のようです。
逆に言うと、常に通電(HIGH)していないとレジスタにデータを保持する事ができません。
参考にしたサイトのお師匠さんたちは常識の範疇なのか「使用しないのでとりあえずVCCにつなぐ」という書き方をしているものばかりでしたが、このような仕組みのため意識して使ってなくてもVCCにはつながないとダメです!
素人的には使わないなら線もつながなくていいんだべと思っちゃってハマリました。
##シフトレジスタと7セグメントLEDを使用しての時計表示スクリプト
こんな感じでLEDの左側に経由するシフトレジスタを用意しました。
###ラズパイ - シフトレジスタ - 7セグメントLEDの接続
イカした接続図を載せたいとこですが、相変わらず初心者ゆえ分からず!
またまた表形式でご覧下さい。
ラズパイGPIO | シフトレジスタ ピン | 7セグLED ピン | 用途 |
---|---|---|---|
( |
16 | - | VCC(電源) |
(GND) | 8 | - | グラウンド |
( |
10 | - | マスターリセット |
18 | 14 | - | シリアル入力 |
14 | 11 | - | シフトレジスタクロック |
15 | 12 | - | ラッチレジスタクロック |
- | 15 | 1 | パラレル出力 1番目 |
- | 1 | 2 | パラレル出力 2番目 |
- | 2 | 3 | パラレル出力 3番目 |
- | 3 | 4 | パラレル出力 4番目 |
- | 4 | 5 | パラレル出力 5番目 |
- | 5 | 7 | パラレル出力 6番目 |
- | 6 | 10 | パラレル出力 7番目 |
- | 7 | 11 | パラレル出力 8番目 |
- | 9 | - | シフトレジスタ増設用(未使用のため接続なし) |
- | 13 | - | ハイインピーダンス(未使用のため接続なし) |
4 | - | 6 | 7セグLED 1桁目指定 |
17 | - | 8 | 7セグLED 2桁目指定 |
27 | - | 9 | 7セグLED 3桁目指定 |
22 | - | 12 | 7セグLED 4桁目指定 |
###pythonスクリプト
前回記事のコメント欄でクラスの利用についてアドバイスを頂いたので参考にしてみました。
GPIOピンの定義、ON/OFF動作はすべてクラスGpioOutputPinに持たせてやることでメイン処理がすっきりしました。
import RPi.GPIO as GPIO
import time
interval_time = 0.001
GPIO.setmode(GPIO.BCM)
class GpioOutputPin:
def __init__(self, pin):
self.pin = pin
GPIO.setup(pin, GPIO.OUT)
@property
def val(self):
return self.pin
def low(self):
GPIO.output(self.pin, GPIO.LOW)
def high(self):
GPIO.output(self.pin, GPIO.HIGH)
def flash(self,interval=0):
self.high()
time.sleep(interval)
self.low()
SCK = GpioOutputPin(14)
RCK = GpioOutputPin(15)
SI = GpioOutputPin(18)
DEG1 = GpioOutputPin(22)
DEG2 = GpioOutputPin(27)
DEG3 = GpioOutputPin(17)
DEG4 = GpioOutputPin(4)
REGPINS = (SCK,RCK,SI)
DIGITS = (DEG1,DEG2,DEG3,DEG4)
NUMBERS = {
' ': (0, 0, 0, 0, 0, 0, 0, 0),
'0': (1, 1, 1, 0, 1, 0, 1, 1),
'1': (0, 0, 1, 0, 1, 0, 0, 0),
'2': (1, 0, 1, 1, 0, 0, 1, 1),
'3': (1, 0, 1, 1, 1, 0, 1, 0),
'4': (0, 1, 1, 1, 1, 0, 0, 0),
'5': (1, 1, 0, 1, 1, 0, 1, 0),
'6': (1, 1, 0, 1, 1, 0, 1, 1),
'7': (1, 1, 1, 0, 1, 0, 0, 0),
'8': (1, 1, 1, 1, 1, 0, 1, 1),
'9': (1, 1, 1, 1, 1, 0, 1, 0),
}
def reset():
for pin in REGPINS:
pin.low()
for pin in DIGITS:
pin.low()
try:
# GPIO pins reset
reset()
while True:
# get time and display number
for timeStr, digit in zip(time.strftime('%I%M'), DIGITS):
# set time number sign
for i in range(8):
if NUMBERS[timeStr][i] == 0:
SI.high()
else:
SI.low()
# flash shift clock
SCK.flash()
# flash latch clock
RCK.flash()
# flash 7segLED digit
digit.flash(interval_time)
finally:
# GPIO pins reset and cleanup
reset()
GPIO.cleanup()
###実際に配線はさっぱりしたか?
これにて今回の内容はおしまいになりますが、タイトルにした「配線さっぱり」は達成できたでしょうか?
ラズパイのGPIOピンの使用数の結果はこんな感じで言うほど削減されるわけじゃ無かった。。
シフトレジスタ未使用 | シフトレジスタ使用 | |
---|---|---|
合計 | 12 | 10 |
内訳 | 8: 7セグLEDの数字表現用 4: 7セグLEDの桁位置指定用 |
1: 7セグLEDの数字表現用 4: 7セグLEDの桁位置指定用 1: Vcc(電源) 1: グラウンド 1: マスターリセット 1: シフトレジスタクロック 1: ラッチレジスタクロック |
で、でも限りあるGPIOなんだし、少しでも配線が省略できて空きのピンが増える事はすごく大事になるはず!