7セグメントディスプレイは単純に7個のLEDが1つにまとまっているというようなものです。配線や変数も多くなりますが、そのあたりをPythonのプログラムで工夫していきます。7セグメントディスプレイの基礎を学びます。
1ケタの表示版ですので、0から9までの数字とAからFまでのアルファベットを表示させるプログラムを作ってみます。
プログラムを作りにあたり、16進数や2進数も学びます。
使用する部品
- Raspberry Pi 3 Model B × 1
- 電源アダプター5V 2.5A × 1
- ブレットボード × 1
- 7セグメントディスプレイ × 1
- 抵抗 220Ω × 1
- ジャンプワイヤー(オス/オス) × 9
※これらの部品はFabshopがふるさと納税で提供している「ふるさと納税Raspberry Piスターターキット」もしくは当サイトで購入可能な「Raspberry Pi スターターキット」の電子工作キットに同梱されています。
実体配線図
7つのLEDが1つに収まった表示板ですので、それぞれLEDをON、OFFすることで表示板に数字を表示させていきます。
7セグメントLEDの端子は10本あります。このうち表示につかうのはa~gまでの7端子と、数字右下のドットで1端子。Groundで2端子用意されています。
プログラムのコピーと保存
ラズベリーパイメニューをクリックして「プログラミング」-「Geany」をクリックして、Pythonコードの入力の準備をしておきます。
メニューバーから「ファイル」→「新規」をクリックします。
【Lessoon1】のときと同じように、この下にある「7-Segment Displayのプログラム」の枠右上に並んだアイコンの内、右から2番目のアイコンをクリックします。(マウスをアイコンに近づけると”Copy”の表示が現れます)
すると、プログラムの文字列が全て選択されるので、「Ctrl」と「C」キーを同時に押してコピーします。
import RPi.GPIO as GPIO import time pins = [11,12,13,15,16,18,22,7] dats = [0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x80] def setup(): GPIO.setmode(GPIO.BOARD) for pin in pins: GPIO.setup(pin, GPIO.OUT) GPIO.output(pin, GPIO.LOW) def writeOneByte(val): GPIO.output(11, val & (0x01 << 0)) GPIO.output(12, val & (0x01 << 1)) GPIO.output(13, val & (0x01 << 2)) GPIO.output(15, val & (0x01 << 3)) GPIO.output(16, val & (0x01 << 4)) GPIO.output(18, val & (0x01 << 5)) GPIO.output(22, val & (0x01 << 6)) GPIO.output(7, val & (0x01 << 7)) def loop(): while True: for dat in dats: writeOneByte(dat) time.sleep(0.5) def destroy(): for pin in pins: GPIO.output(pin, GPIO.LOW) GPIO.cleanup() if __name__ == '__main__': setup() try: loop() except KeyboardInterrupt: destroy()
プログラム解説
今回は使うピンの数も多く、また数字を表現するために7つのLEDを組み合わせて数字を作っていくため、どこを光らせるかという設定を行う関数が必要です。
pins にはピン番号をリスト形式で格納しておき、datsには16進数で表現したLEDを点灯する際の0~9の表示データとA~Gを表示させるデータをリスト形式で入れておきます。このあたりは経験や知識がないと作れないプログラムですので、順を追って仕組みを見ていきましょう。
そもそも0x3fってなんなんだ?
ここでは2進数(バイナリ)や16進数の知識が必要となってきます。まず、dats という変数に格納している0x3f , 0x06 などの見慣れない数字とアルファベットの組み合わせはなんだろうか?
配線図では7セグメントの端子に対して aは11番PIN、bは12番PINと以下のように割り当てられています。
a: 11 、b:12、c:13、d:15、e:16、f:18、g:22
たとえば「0」を7セグメントで表示したいときには以下の表のようにA~Fまでを全て点灯させて、Gだけを点灯させないという状況を作ります。
0x3f というのは2進数に直すと0b00111111と表現します。この2進数表示の先頭2つ「0b」はバイナリ表記を意味しているので、実際に使うのは右側8つの数値です。「0x」は16進数を表しています。一番最下位は「1」でこれとaが対応し、最下位から2番目がb という順にgまでが対応します。bのとなりが8個目になりますが、これはPIN番号でいう7番目で7セグメントディスプレイのドットの部分とします。つまりbitsに入っている16進数を2進数に直して、それをLEDが光る位置を表している事になります。
0x3f = 0b00111111 数字の0
0x06 = ob00000110 数字の1
0X5b = ob01011011 数字の2
上の表の下にある実際の点灯ヶ所と比べると丁度あっています。
setup()関数は、以前のLessonでも解説してきましたので、もう大丈夫でしょう。for文で一気にすべてのGPIOポートのセットアップを完了させています。
次にwriteOneByte(val) 関数の定義部分です。この関数でどのLEDを光らせるかを決めます。valに入ってくる値を見てそれをそれぞれのPIN出力に割り振っていきます。関数の中では直接11,12のようにピン番号をふってしまっていますが、ここもpins = のリストから持ってくることも可能です。
GPIO.output(11, val & (0x01 <<0)) これを全てのピンに対して行っていますが、何をしているのでしょうか?
「<<」記号はシフト演算子で例えば 0x01 << 1となっているならば、0b00000001 を1ビットシフトさせるという事になるので、0b00000010 と1が左側に1つずれるという処理をするという事になります。
今回のGPIO.output(11, val & (0x01 <<0)) は、valには最初datsから0x3fが入ってきますので、2進数で表記すると
GPIO.output(11, ob00111111 & (0b00000001 <<0))となります。<<0となっているので、最初は0ビット左にシフトする、つまり何もしないという事になるため、11番PINには ob00111111 AND 0b00000001 という計算をすればよいという事になります。ANDの計算はかけ算になりますから、各ビットを合わせてそれぞれかけ算をすると、ob00000001 が答えで出てきます。つまり、「1」という意味ですから、11番PINはHIGHにするという事です。という具合に0x01を1ケタずつずらして掛けていく事で、1があるケタではPINから信号を出して、0のビットのところではすべてがゼロになるため、0「LOW」を出力するという事になります。
これでどこをONにして、どこをOFFにするかを決めて、それぞれのピンに割り振っているわけです。
あとはLoop()関数でこれを繰り返して、表示させます。
新たに開いたタブ「untitled×」の1行目にマウスカーソルを置いて右クリックして出てくるメニューから「貼り付け」を選択します。
Geanyのメニューバーから「ファイル」→「別名で保存」をクリックします。
新たに「ファイルを保存」画面が現れるので、左ペインの「デスクトップ」をクリックします。
「ファイルを保存」画面の1番上の項目「名前:」の入力欄に拡張子”.py”でプログラム名を入力し、「保存」ボタンをクリックします。
プログラムの実行
Geanyの画面に戻って、ツールバーの紙飛行機のようなアイコンをクリックします。
新たに「ターミナル」画面が開き、7セグメントディスプレイの表示が0から9まで変化して、これを繰り返します。「Ctrl」と「C」キーを同時に押すとプログラムが停止します。