Raspberry Pi – シフトレジスタ―~4桁7セグメントLED

概要

  • Raspberry Piでシフトレジスターを介して4桁7セグメントLEDをコントロール
  • 各桁を短時間で明滅させて、視覚的に全桁が同時発光しているように見せる
  • おまけでカウントダウンタイマーにしてみた

4桁7セグメントLEDのピン配置と回路

キットに同梱されていたLEDのピン配置は下図の通り。

D1~D4のピンは左から順に各桁の7セグメントLEDに対応している。これらのピンがHIGHのLEDにa~dpのピンへの入力が反映されて表示される。LOWの時にはLEDは消灯する。

a~dpは7セグメントLEDのピン配置に対応している。

内部の回路は以下の通りで、カソードコモンとなっている。たとえば左から2桁目のLEDを点灯させたいときは、D2をHIGHにしてa~dpのうち点灯させたいセグメントのピンをLOWに、消灯させたいセグメントのピンをHIGHにする。

4桁の同時発光

セグメントの明滅を制御するa~dpのピンが1組しかないので、ある桁を特定のパターンで点灯させたいときは、他の桁は消灯させる(でなければ、DnがHIGHになっている桁の全てが同じパターンで点灯する)。

そこで、ある桁を短い時間点灯させたあと消灯するという動作を各桁入れ替えながら実行していく。点灯・入れ替えの時間が十分短いと、残像減少によって人の目には全桁が同時発光しているように見える。

Raspberry Piによる制御回路

全体の考え方は以下の通り。

  • D1~D4の桁選択ピンは4つのGPIOピンでコントロールする
  • a~dpのセグメント選択ピンはシフトレジスター74HC595を介してコントロールする
  • 7セグメントLEDの保護抵抗はD1~D4に1つずつ繋ぎ、1つの7セグメントあたり1つとする

試験点灯

ソフトウェアによる制御の考え方は以下の通り。

  1. 初期設定ではD1~D4をLOWにする
  2. DnをD1~D4と順番に入れ替えて以下を繰り返す
    1. DnをHIGHにして選択する
    2. 選択したLEDに対してシフトレジスターを介して表示パターンを送る
      • 表示パターンはa→dpの順の8ビットで定義して、LSBから順にシフトレジスターに送り込む
    3. 一定時間sleepさせる
    4. HIGHにしたDnをLOWにする
  3. CTRL-Cが押されたらD1~D4をLOWにして終了処理を行う。

以下のPythonコードでは、いくつかの関数を定義している。

initialize
LEDとシフトレジスターの初期化を行う。
destroy
終了処理を行う。
display_a_digit
指定した桁のLEDを指定したパターンで一定時間点灯させる。桁の指定は左から0~3、パターンは0~9の数字に対応したビットパターン、点灯時間はミリ秒で与える。
display_digits
表示させる4桁の数値を文字列で与えて、一定時間点灯させる。ミリ秒で与えた点灯時間はdisplay_a_digit関数にそのまま渡される。

カウントダウンタイマー

time.perf_counter

4桁7セグメントLEDでカウントダウンタイマーを作ってみた。

  • 左2桁が分、右2桁が秒に対応する
  • 動作中は秒数でコントロールし、LED表示のために分と秒を分解する
  • 点灯時間をtime.perf_count関数で計り、約1秒ごとにカウントダウンする
  • カウントダウンを終えたら’0000’を表示して割り込みを待つ

なお、整数値の分・秒を2桁表示の文字列にする関数get_two_digits関数を定義している。

69-72行で分と秒をセットし、それを総秒数に計算。

77-93行がカウントダウン部分。

  • tartとendをtime.perf_counterで取得して経過秒数を計算
  • 表示秒数が1秒たつとカウントダウン
  • カウントダウン後と残りゼロ秒になったときに内側のループを抜ける

95-98行目では、残りゼロ秒になったときにオールゼロを表示して待機。

スレッド

実行部分をシンプルにするためにスレッドを使ってみた。

66-83行目で、4桁の内容を表示し続けるスレッドクラスを準備。

95-108行目で、1秒ごとにスレッドを発生させて現在の残り時間を表示。

回路の写真

74HC595の向きを逆にしてしまったのでコードがごちゃごちゃ。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です