前の記事では74HC595を使って1桁の7セグメントLEDを点灯させました。ここでは同じように74HC595を使って4桁の7セグメントLEDをダイナミック点灯させます。
使用する4桁7セグメントLEDは5461AS-1です。

ダイナミック点灯
74HC595を使用してダイナミック点灯をする回路図とタイムチャートを示します。
回路図の波線に囲まれた部分が4桁7セグメントLEDモジュールの5461-ASです。5461-ASは4つの7セグメントLEDのセグメントA-G、DPおよび各7セグメントLEDの共通化されたカソード(digi1-4)が端子に接続されています。そして74HC595のパラレル出力(Q0-Q7)は7セグメントLEDモジュールのセグメントA-G、DPに接続します。

4桁7セグメントLEDモジュールの左からLED1、LED2、LED3そしてLED4とすると、LED1に数字の1を、LED2に数字の2を、LED3に数字の3を、LED4に数字の4を点灯させるタイムチャートです。例えば、LED1は制御信号digi1がロー・レベルでアクティブとなり、この期間に74HC595の出力(今回の場合は数字の1に対応したデータ0x06)に応じたセグメントを点灯させる事になります。このように、4つの7セグメントLEDは同時にアクティブになることはなく、常に1つの7セグメントLEDのみがアクティブとなり点灯する事になります。つまり、ある瞬間では1つの7セグメントLEDのみ点灯しますが、繰返し表示する事により残像現象により全ての7セグメントLEDが点灯しているように見えます。
なお、1つの7セグメントLEDが点灯する周期は1ミリ秒から10ミリ秒程度が良いとされます。この周期が長いとちらついて見えるようになります。

4桁7セグメントLEDを単に”1234″と点灯させるソースが以下になります。ファイル名はtest12.pyとしています。
#!/usr/bin/python
import RPi.GPIO
import spidev # spidevライブラリの読み込み
import time # timeライブラリの読み込み
seven_seg = [
0x3f, # 0
0x06, # 1
0x5b, # 2
0x4f, # 3
0x66, # 4
0x6d, # 5
0x7d, # 6
0x07, # 7
0x7f, # 8
0x6f # 9
]
digit1 = 22 # Digit 1の制御ピン
digit2 = 23 # Digit 2の制御ピン
digit3 = 24 # Digit 3の制御ピン
digit4 = 25 # Digit 4の制御ピン
delay = 0.0015 # 7seg LEDのアクティブ時間
spi = spidev.SpiDev() # spidevのインスタンス化
gpio = RPi.GPIO # RPi.GPIOのインスタンス化
spi.open(0,0) # CE0を指定
spi.max_speed_hz = 500000 # 転送速度を500kHzに設定
spi.mode = 0b00 # SPIモード0
gpio.setmode(gpio.BCM)
gpio.setup(digit1, gpio.OUT)
gpio.setup(digit2, gpio.OUT)
gpio.setup(digit3, gpio.OUT)
gpio.setup(digit4, gpio.OUT)
try:
while True:
gpio.output(digit1, 0) # digit1をLOW
spi.xfer2([0x06]) # 数字の1に対応するデータの送出
time.sleep(delay) # digit1のアクティブ時間の生成
spi.xfer2([0x00]) # 7セグLEDの全消灯
gpio.output(digit1, 1) # digit1をHIGH
gpio.output(digit2, 0) # digit2をLOW
spi.xfer([0x5b]) # 数字の2に対応するデータの送出
time.sleep(delay) # digit2のアクティブ期間の生成
spi.xfer2([0x00]) # 7セグLEDの全消灯
gpio.output(digit2, 1) # digit2をHIGH
gpio.output(digit3, 0) # digit3をLOW
spi.xfer([0x4f]) # 数字の3に対応するデータの送出
time.sleep(delay) # digit3のアクティブ時間の生成
spi.xfer2([0x00]) # 7セグLEDの全消灯
gpio.output(digit3, 1) # digit3をHIGH
gpio.output(digit4, 0) # digit4をLOW
spi.xfer([0x66]) # 数字の4に対応するデータの送出
time.sleep(delay) # digit4のアクティブ時間の生成
spi.xfer2([0x00]) # 7セグLEDの全消灯
gpio.output(digit4, 1) # digit4をHIGH
except KeyboardInterrupt:
spi.close() # SPI通信を終了
gpio.cleanup()
ソース中の
time.sleep(delay)
は、digit1-4のアクティブ期間を生成しています。delay時間は1.5ミリ秒としていますが、2回のSPIのデータ転送も含めLOW期間は約2.2ミリ秒となり、周期はその4倍の約8.8ミリ秒となっています。
また、
spi.xfer2([0x00])
で7セグメントLEDを全消灯させていますがこれは、ある瞬間に表示させている桁の前に表示された数字が僅かに点灯するのを防ぐためのものです。例えばLED2には数字の2を表示させますが、LED1で表示されている数字の1(セグメントのC)が点灯してしまっています。この不要な点灯を防止します。

少し詳しく見てみます。
7セグメントLED1のdigit1と74HC595のラッチクロックRCLKをオシロスコープで確認します。
ソースではLEDを点灯させるタイミングはdigit1信号をロー・レベルにしてその直後にシリアルデータの転送をします。データを74HC595でラッチするタイミングはRCLKの立ち上がりですが、これには約130マイクロ秒かかっています。74HC595はdigit1信号をロー・レベルにしてから新たにデータをラッチするまでのこの時間は直前のデータを出力しているので、digit4のデータを表示する事になります。これが表示に現れています。LED1ではその前のデータ、つまりLED4のデータであるセグメントFとGがこの期間表示されています。

このことを踏まえて、一旦74HC595に0x00を設定することによりdigit1-4の立ち下がりエッジからデータをラッチするまではセグメントを消灯させることになり、直前のデータを表示することが無くなります。

Raspberry Pi Zero Wとの接続
Raspberry Pi Zero Wとの接続は下表のようになります。
| Raspberry Pi Zero W | 74HC595 | 5461AS-1 | ||||
| 信号名 | GPIO番号 | 物理ピン番号 | 信号名 | ピン番号 | 信号名 | 端子番号 |
| MOSI | GPIO10 | 19 | SER | 14 | ||
| SPICLK | GPIO11 | 23 | SRCLK | 11 | ||
| CE0 | GPIO8 | 24 | RCLK | 12 | ||
| Digit1 | GPIO22 | 15 | digit1 | 12 | ||
| Digit2 | GPIO23 | 16 | digit2 | 9 | ||
| Digit3 | GPIO24 | 18 | digit3 | 8 | ||
| Digit4 | GPIO25 | 22 | digit4 | 6 | ||
| 3.3V | 17 | VDD | 16 | |||
| GND | 20 | GND | 8 | |||
ブレッドボードに74HC595と4桁7セグメントLEDモジュールを実装し配線した状態です。
プログラムは以下のコマンドで実行します。
$ python test12.py

