作成日時:2015年06月03日 09時50分01秒
更新日時:2020年05月19日 08時46分33秒
この記事は10年ほど前に投稿されました。内容が古くなっている可能性がありますので更新日時にご注意ください。
前回、Raspberry Pi 2にて7セグLEDの制御をしましたが。
今回は2桁以上の7セグLEDに数字を表示してみたいと思います。
7セグLEDを使用する場合は2桁以上で使う方が多いと思いますので、基本的にこの制御方法を行う事になると思います。
必要な物
- 2桁以上の7セグLED(カソードコモン 今回は3桁を使用)
- NPNトランジスタ(桁数分 2SC1815を使用※)
- 適当な抵抗(7セグLEDの仕様に合うもの)
- 適当なケーブル
- WiringPi
ケーブルとWiringPiは今後書きません。
※2SC1815は生産終了予定なので新規設計は推奨されないのですが、生産終了が通達されて早4年になりますが、ホビーユースで使う分にはまだ潤沢に在庫があるようですのでこれを使います。まぁ、基本的にNPNトランジスタなら何でも良いです。本当は仕様とにらめっこするべきですが、ホビーユースのLED点灯程度なら問題ないでしょう。最近はセカンドソース品が潤沢に出回っているので本家本元、東芝製が絶対必要なほどの高信頼性が要求されるような場所でなければセカンドソース品を使い続けて問題無いでしょう。よってホビーユースであれば気にする必要はないでしょう。(2015年12月18日追記)
表示方式のお話
7セグLEDを複数桁表示する表示方法は大体以下の2つです。
- スタティック点灯方式
LEDを常に点灯しておく点灯方式。前回行った7セグLEDの点灯方式がこれ。
この方式で複数桁の7セグLEDを駆動させようとすると、ラズパイだと2桁までしか表示できないし配線もめんどくさいのでオススメしない。 - ダイナミック点灯方式
LEDを高速でオンオフさせる点灯方式。7セグLEDの各桁のA~Gに繋がっている配線を各セグメント毎に1つにまとめ、各桁のコモン端子を別々に配線してこのコモン端子にスイッチを付けてそれぞれオンオフを切り替える事で各桁に別々の数字を表示しようという考え。このオンオフの切り替えを高速に行う事で、全ての桁があたかも同時に違う数値を表示しているように見せるというもの。
例えばトップ画像の396を表示しようと思ったら、
左から1桁目のLEDのコモンのスイッチをオンにして、他の桁のスイッチをオフにする ↓ LED A~Gの各ポートに3の形になるように信号を送る ↓ 1ms待つ 2桁目のLEDのコモンのスイッチをオンにして他の桁のスイッチをオフにする ↓ LED A~Gの各ポートに9の形になるように信号を送る ↓ 1ms待つ 3桁目のLEDのコモンのスイッチをオンにして他の桁のスイッチをオフにする ↓ LED A~Gの各ポートに6の形になるように信号を送る ↓ 1ms待つ 最初に戻る
と言う動作を繰り替えす事であたかも3桁に別の数字を表示しているかの如く見せる事が出来ます。そしてこのスイッチの役割をしているのがトランジスタと言う事になります。今回はカソードコモンなのでNPNトランジスタを使用しましたが、アノードコモンならPNPです。
配線
今回は前回の続きなので諸々省略しますが、前回のLEDの配線の他に、GPIO.1~3に各桁のコモン制御用の配線をしました。トランジスタのベースに抵抗を挟んでGPIOピンを接続、コレクタに7セグLEDのコモンを、エミッタはGNDに接続します。
なお、回路図では省略されていますが、各セグメントとIOポートの間に抵抗を挟むのが普通らしいので。各自適当に付けてください。
配線の確認
接続が終わったら、接続確認をします。シェルでGPIO.1~3を1に(gpio write n 1 (n=1~3))して、前回で作ったプログラムを走らせ、各桁同じ数字が表示される事を確認してください。
(試しに2を表示させてみた。)
次に一旦全ての桁を非表示(GPIO.1~3を0にする)にして、GPIO.1を1にして1桁目を点灯させ、左から1桁目に「2」が表示されている事を確認してください。
次のそのポートを0にして、GPIO.2を1にして2桁目を点灯させます。
最後に同じ要領で3桁目を点灯させます。
これで動作確認は終了しました。次は3桁違う数字を表示してみましょう。
制御ソフトウェア制作
今回のプログラムは前回の7セグLED制御用プログラムと殆どおなじで、単純に桁切り替えのプログラムを追加するだけです。
プログラム冒頭、LEDポート設定の前後に以下の行を追加します。
// 桁制御ポートの設定 #define LED_1 1 // 1桁目 #define LED_2 2 // 2桁目 #define LED_3 3 // 3桁目
LEDの数字を表示する関数を変更します。
int LED_SET(int num,int dot){ ↓ 変更 int LED_SET(int num,int dot,int keta){
表示関数のdigitalWrite…の塊の前に以下のコードを追加します。
digitalWrite(LED_1,0); digitalWrite(LED_2,0); digitalWrite(LED_3,0); if(keta==1){digitalWrite(LED_1,1);} if(keta==2){digitalWrite(LED_2,1);} if(keta==3){digitalWrite(LED_3,1);}
これで3桁制御化は完了です。
LEDの表示
LED表示のコマンドはこうなります。
LED_SET(表示したい数字,小数点の有無,表示する桁);
例えば、左から1桁目に「2」を表示したい場合は以下のようになります。
LED_SET(2,0,1);
【表示例】
(使い回しなんて言わない。)
この表示関数をdelayコマンドを挟んで3桁分用意する事で、3桁に別の数字を表示する事が出来ます。
for(;;){ // 無限ループ LED_SET(1,0,1); // 一桁目 delay(1); LED_SET(1,0,2); delay(1); LED_SET(1,1,3); delay(1); }
例えば、「123」を表示するようにプログラムしてみました。
【表示例】
高速で各桁を切り替える事でそれぞれの桁に別の数字を表示する事に成功しました。
終わりに
これで2桁以上の7セグLEDに別々の数字を表示する事が出来ました。
方法を簡単にまとめると、
- 全ての桁のLEDに繋がるピンを各セグでひとまとめにする
(最初から2桁以上ある7セグLEDは最初からこの接続になっている。) - コモン端子を別々にしてコモン端子の開閉で切り替えられるようにする
- プログラムで各桁を高速で切り替えて肉眼では3桁が同時に表示されているように見せる
と言う事になります。
制御が意外と手間ですが、実際にやっている事はそう難しい事では無いと思います。
以上の条件で動作可能なソースを置いておきますね。
#include <stdio.h> #include <wiringPi.h> // LEDポート設定(GPIO.x) #define LED_A 29 #define LED_B 28 #define LED_C 27 #define LED_D 26 #define LED_E 25 #define LED_F 24 #define LED_G 23 #define LED_P 22 // 桁制御ポートの設定 #define LED_1 1 // 1桁目 #define LED_2 2 // 2桁目 #define LED_3 3 // 3桁目 // LED切り替え間隔の設定(ミリ秒) #define LED_DEL 1 // 各桁に表示する数字の設定(左から) #define N1 1 // 1桁目 #define N2 2 // 2桁目 #define N3 3 // 3桁目 int main(void){ wiringPiSetup(); pinMode(LED_A,OUTPUT); pinMode(LED_B,OUTPUT); pinMode(LED_C,OUTPUT); pinMode(LED_D,OUTPUT); pinMode(LED_E,OUTPUT); pinMode(LED_F,OUTPUT); pinMode(LED_G,OUTPUT); pinMode(LED_P,OUTPUT); pinMode(LED_1,OUTPUT); pinMode(LED_2,OUTPUT); pinMode(LED_3,OUTPUT); // 数字を表示する for(;;){ LED_SET(N1,0,1); delay(LED_DEL); LED_SET(N2,0,2); delay(LED_DEL); LED_SET(N3,1,3); delay(LED_DEL); } } int LED_SET(int num,int dot,int keta){ // セグメント定義 int seg[18][7] ={{1,1,1,1,1,1,0}, // 0 {0,1,1,0,0,0,0}, // 1 {1,1,0,1,1,0,1}, // 2 {1,1,1,1,0,0,1}, // 3 {0,1,1,0,0,1,1}, // 4 {1,0,1,1,0,1,1}, // 5 {1,0,1,1,1,1,1}, // 6 {1,1,1,0,0,0,0}, // 7 {1,1,1,1,1,1,1}, // 8 {1,1,1,1,0,1,1}, // 9 {1,1,1,0,1,1,1}, // A {0,0,1,1,1,1,1}, // B(b) {0,0,0,1,1,0,1}, // C(c) {0,1,1,1,1,0,1}, // D(d) {1,0,0,1,1,1,1}, // E {1,0,0,0,1,1,1}, // F {0,0,0,0,0,0,1}, // - {0,0,0,0,0,0,0}};// Blank digitalWrite(LED_1,0); digitalWrite(LED_2,0); digitalWrite(LED_3,0); if(keta==1){digitalWrite(LED_1,1);} if(keta==2){digitalWrite(LED_2,1);} if(keta==3){digitalWrite(LED_3,1);} digitalWrite(LED_A,seg[num][0]); digitalWrite(LED_B,seg[num][1]); digitalWrite(LED_C,seg[num][2]); digitalWrite(LED_D,seg[num][3]); digitalWrite(LED_E,seg[num][4]); digitalWrite(LED_F,seg[num][5]); digitalWrite(LED_G,seg[num][6]); digitalWrite(LED_P,dot); }
総閲覧数:607 PV
[…] 原理としては、以前複数桁の7セグLEDを表示したときに使用したものと同じです。 […]
[…] 以前、Raspberry Pi 2 で複数桁の7セグLED制御 を実行しましたが、この処理はメイン処理系でLED表示を無限ループさせていました。しかし、これでは7セグLEDを表示している場合に他の処理ができなかったり、逆に他の処理をしている際にLEDの表示が止まるという感じで少々不便でしたね。 […]