マイコンにロジックICを添えて
この記事は UEC koken Advent Calendarの記事です
自己紹介とか
初めまして、SEGAサタンと申します。2018年度の工学研究部の部長を務めております
今回、Advent Calendarの記事を書くべく初めてブログとやらに手を伸ばしました。
プロローグ
近年、ArduinoやRaspberry Piなどの普及により電子工作の世界へ誘われる方が多数見られます。大変喜ばしいことです。
しかし、7セグメントLEDやマトリクスLEDなどのピンが(比較的)多数生えている素子を使おうとして、I/Oピンが足りなくなって困っているケースが見られます。
それを打開するため、複数のArduinoを用いたり、Arduino MEGAなどのI/Oピンが潤沢なハードを使用すると言った策が取られています。
マイコンの通信の練習やI/Oピンの潤沢なハードを得られると言った点ではとてもメリットがありますが
正直Arduino高くない???
Amazonで検索してヒットするUno純正品だと3,240円(2018/12/14現在)します。
始めたばかりの初心者にこれはさすがにお高い買い物になるのではないかと思われます
かといってAVRやPICと言ったマイコンそのものは比較的安く(400円ほど)手に入りますが、書き込みなどの環境を建てるために紆余曲折してしまいます。
そのため今回は
- 安くて
- 速くて
- I/Oピン数を削減
を目標に、8桁の7セグLEDを制御するモジュールを作成します。
7セグLED
たぶんこのブログを見てくださっている方は多少電子工作に興味を持たれている方だろうと思われます。Lチカくらいをしたことがあれば大丈夫です。したことなければさっそく足を踏み入れてみてください!
7セグLEDは、LEDが数字の8の字に並んでいるように作られた素子です。体育とかで見る電光掲示板を思い出してもらえれば分かりやすいかと
それぞれのLEDにはa~gまでのアルファベットがふられており、LEDを点ける場所によって数値を表現できます。例えばb,cを点けると「1」になります。
また、dpは小数点として扱えたりできます。
計8つのLEDが入っているため、LEDのアノードとカソードで16本の足が生えていると考える方がいると思います。しかし足は9~10本(型番による)です。なぜなら
このように、アノードまたはカソードが1つにまとまっているからですね。
今回はアノードが1つにまとまった「アノードコモン」の7セグを用います。
単純に考えれば、これを8桁分用意すれば良いだけなので、回路図は
(回路図作成ソフトは水魚堂のBSch3vを使いました)
ですね、簡単!!!!!
いやアホかと、こんな配線量やりたくないし、ArduinoUnoのI/Oがアナログピン含めて25ピンしかないので最低3台必要になりますね()
(初心者の方へ:記号の説明は省きましたがVccは電源の+だと思ってください)
さて、これが何ピンまで減らせると思いますか?マイコンで7セグを扱った事がある人は、ぱっと16本くらいかなぁと思いつけると思います。しかし今回は
64ピン→3ピン
(※GND含めると4ピン)
です。驚異の圧縮率95%
経験者向けになりますが、やろうと思えば1Wire(GND含め2ピン)も可能です。安定性やマイコンの負担を考えると、同期した通信が好ましいのと、SPI準拠の通信にしたかったということから、3ピンで押さえました
まず、簡単な64ピン→16ピンの圧縮を考えます
ダイナミック点灯
これに関しては有名なのでご存知の方が多いと思われます。
ダイナミック点灯とは、高速で表示を切り替えることで残像が残り、それで全桁を表示させているように見せる方式です。
例えば、「123」を表示させたければ、消灯をBと書いて
「BB3」
「B2B」
「1BB」
を高速で入れ替えます、消灯は人間には見えない(日本語が不自由)ので残像として
「123」が見えます。
ちなみに先ほど紹介した64本の配線で7セグ全てを独立させて点灯する制御は「スタティック点灯」と呼ばれます。配線量だったり消費電力の観点からあまり使われません。
ダイナミック点灯を用いる事で、64本の配線は
8本の桁選択線+8本の数字パターン線=16本
と、かなり削減できます。配線が減って楽ができる上、こうなればArduino1台でも8桁を制御できて、さらに数本ですがI/Oの空きが出来ますね。回路図は
上の8ピンで表示する7セグを選択、下のコネクタで数字のパターンを表示します。ちなみに同時に点くわけでないので、抵抗も1セットの8本へ削減できています。
これでも十分そうですが、まだまだ行きます。
デコーダーIC
ダイナミック点灯をする時に桁選択の8本を伸ばすことは先ほど説明しました。
しかし、制御の性質上、2つ以上のピンが同時に点灯状態にはなりません。
2つ以上のピンが同時に点灯をしてしまったら、同じ数字しかだせませんからね。
そのため、8ピンのうちどれかを選択し、それだけ点灯状態にする機能を付けることでさらにピンの削減に繋がります。今回はデコーダーIC「74HC138」を用います。
ここで、余談ですが74ICについて簡単な説明をします。
74シリーズは、大部分がロジックICと呼ばれるものです。ANDだったりNOTだったりの入出力が「High」か「Low」かで演算をしていく素子のことですね。
今回の用途ではLEDを「点ける」か「点けない」かなので、ロジックICが適しています。
74HC138は「3to8 Line Decoder」と呼ばれるICで、3本の入力で8本の出力いずれかを出力状態に出来ます。ICは以下のようなピンを持っています。
一気に本数が増えて大変そうに見えますが、意味さえ知ってしまえばそこまで大変ではありません。
- VccとGND
先ほど説明したとおり、Vccは電源の+へ、GNDは電源の-(正確には接地)へ繋ぎます。
動作電圧は2~6Vですが、今後紹介するICの動作電圧が5Vなので、今回は5Vにします。
- G1,~G2A,~G2B
これらは、イネーブルピンと呼ばれます。イネーブルピンが全て有効設定であれば、
ICは動作を行います。しかし一つでも無効設定があるとICは動作しません。
全消灯などに用いる事が出来ますが、今回は使わないので全て有効設定にします。
G1を有効にするためには、「High」にすればいいため、5VであるVccに繋げます。
~G2について、図を見るとGの上に線が入っているのがわかります。
これは負論理であることを示します。つまり「Low」にすると有効なので、0VであるGNDへ繋ぎます。2つありますが両方ともGNDに落とせばOKです。
なお上に線を引く機能が見つからなかったのと、簡略化のために負論理は記号の前に「~」をつけることにします。
- A,B,C
入力ピンです。出力ピンと合わせて紹介します
- ~Y0~7
出力ピンです。これに関しては表を見てもらった方が分かりやすいので、それで解説します。
何だか読むのが億劫になりそうですが、読み方があります。
左にある「Inputs」を選んで、右の「Outouts」を読むだけです。たとえば最上段は
G1がL(Low)になっています。さっきのイネーブルピンの説明から分かるように
出力全てがH(High)になっています。Highだと全部のLEDが選ばれるから選べてないじゃん!と思われがちですが、出力は「~Y」のため、「~」がついていますね。つまり
出力は負論理で、選ばれるとLow、選ばれないとHigh
になります、なんやそのくそややこしい機能は
これに関しても、正論理のICが有りますがちょっとした理由から負論理を選択しています。後で紹介します。
イネーブルピンが1つ無効なので、機能が許可(Enable)されません。全ピン無選択です。
2段目、3段目もどれかのイネーブルピンが無効だとピン選ばれないよ~っていう意味ですね。
では全許可されているとどういう挙動になるかと言うと
入力(CBA)を2進数で読んだ番号のYだけLowになります
例えば、入力(CBA)が(HLH)だったとします。(101)2=5なので、~Y5だけがLowになります。真理値表で確認してみてください。
入力は3bitなので、全状態は2^3=8です。出力は~Y0~7なので8本有りますね。
これを用いる事で、たった3ピンで8つの全桁を選べることができます。
出力負論理の理由
なぜわざわざ選ばれるとLowを出すめんどくさいものを使ったのかという事について説明します。
74HCシリーズが出力できる電流は、データシートを見ると20mAがメーカー最大値です
これを越えると正しい動作が出来なくなったり、最悪ICが破損します。
なので20mAを越えないように出力を調整する必要があります。
特に今回は7セグのため、8つ全点灯する事があります。20mAを均等に分けると
2.5mAとなり、まぁLEDなら十分ではと思います。しかしダイナミック点灯のため、実際に点いている明るさはこの1/8の0.31mAくらいになります。ちょっと無理があります
なので、電流を流すためのサポーターが必要になります。それがトランジスタです。
トランジスタについては様々なところで紹介されていると思うので割愛しますが、今回は電源から7セグへ電流を流すため、PNPトランジスタを使います。
PNPトランジスタは、C→Bへ小電流が流れると、C→Eへ電流を流せます。
CよりBの電圧を下げれば良いので、選ばれたベースをLowにする負論理が適切でした。
毎回8桁分書くの大変だったので、バス線などでまとめました。
これで16ピン→11ピンです。
7セグメントドライバ
桁選択は上手く出来たので、次に数字を出すパターンを考えます。
ここについては若干妥協した感じはあるのですが、出せる値は0~9の数字のみに限定しました。頑張れば一部のアルファベットは表示できますが、基本的に使わないので無しです。
0~9までに減らせたと言うことは、4bit(=16)で全数値を表現できます。
当たり前ですが、マイコンに7セグのパターンは入っていません。つまりフォント手打ちになります。何が起きるかというと…
「0ならabcdefが点灯するからHigh...いやアノードコモンだからLowになってうーーーーーーーーん0000001かな、あれ桁あってる?うん?…」
いやダルすぎない?数字入れるだけで勝手に数値出して欲しいですよね。
そんな都合の良いICが居るのかと思われますが、居ます。
7セグデコーダーと呼ばれるICです。今回は手持ちだった74LS247を用います
74シリーズのICですが、先ほどの74「HC」138に対して、今回は74「LS」247です。
詳しく書くと長くなるのですが、簡単に言うと内部で使っているトランジスタの種類が異なっています。LSは電流で制御する「バイポーラトランジスタ」がメインです。NPNとかPNPの奴らですね。そのため内部の電流が設計から崩れると機能しなくなります。つまり内部電流を決める動作電圧が推奨値を外れていると動作しません。
しかもその電圧が4.75V~5.25Vと狭いです。なので全体の電圧を5Vに固定しました。
ちなみに、HCとLSではHighとLowのレベルが異なっていることがあります。今回の電圧(5V)ではHC出力→LS入力は大丈夫なので、問題ありません。逆に繋ぐときは注意しましょう。
話を戻します。74LS247は「BCD to 7 SEGMENT Decoder」です。入力の2進数に対して、出力のピンを7セグパターンへ変換することができます。論理回路の授業で見た!
ピンの説明をします。
- A,B,C,D
入力ピンです、74HC138と同じように、2進数で(DCBA)に当たる7セグのパターンを出力ピンへ出力してくれます。
ちなみに10を越えた場合内部設定上不思議なフォントが出力されます。頑張れば何かに使えるかも…
15を入力すると消灯になるので、わざわざ消灯ピンを作らなくて良いのもGoodですね
2桁以上の制御するときにそれぞれの247を接続するピンです。使わないので入力の
~RBIをVccへ繋げて禁止にします。~BI/~RBOは入出力ピンという特殊なものなので、どこにも繋げずに浮かせてOKです。
- ~LT
TESTピンです。Lowにすると7セグを全点灯(8)にします。使わないのでVccへ繋げます
- a,b,c,d,e,f,g
出力ピンです。それぞれのアルファベットに対応する7セグのピンへ繋げます。
これらのピンは「オープンコレクタ」と呼ばれる出力になっています。どういうことかというと、今までの出力が「H」なら5V、「L」なら0Vを出していましたが
オープンコレクタは、GNDに繋げるか繋げないかを意味します。
GNDに繋がれば電流が流れるのでLEDが点きます。繋がっていないと光りません。
オープンコレクタは、電流を吸い込むことに特化しているため、15mAまで吸い込めます。つまり出力は直に7セグに繋げて大丈夫です。
まとめると、回路は
これで、11本あった配線は
桁選択3本+数字指定4本+小数点指定1本=8本
まで減りました。最初から考えると1/8になっています。
シフトレジスタ
先ほどの回路でも十分ピン数を減らせています。しかし7セグ表示器がダイナミック点灯しているとは言え、そこまで高速な動作は要求されていません。
たとえば、人間がチラツキを感じなくなる速度として60fpsが知られています。
60fpsで8桁を表示させるには、60×8=480Hzの速度でLEDをダイナミック点灯させれば良いわけですね。速そうに見えますが、マイコンのI/Oが最速1MHz以上の速度で動けると考えるとちょっとオーバースペックかなと、数百Hzの動作のために1MHz級のI/Oが8本取られるのはいかがなものかと思うので、更に圧縮します。
それを用いるために、シリアル-パラレル変換という手法を用います。
今回の回路は8本の入力を直接繋いでいます。これはパラレル(並列)接続と言い、配線量が膨大な反面、速度重視の動作に向きます。PC内のバス線とかがこれですね。
それに対してシリアル(直列)接続では、配線量が少ない反面、高速な動作に不向きです。今回は3本の線で8つのデータを送信するシリアルを作ります。
今回は、74HC595を用います。
74HC595は「8bit shift registers with 3state output registers」というICです。
動作を説明するために図を使います。
入力ピンはSDAT,SCLK,LCLKの3本です、出力はA~HおよびH'になります。
まず、SDATに1を入れて、SCLKを立ち上げます。
すると1が内部の左下の箱に入ります。
ちなみにこの箱はD-FFと呼ばれ、8つのセットでレジスタと呼ぶことにします。
続いて、0を入れた状態でSCLKを立ち上げます。すると左下の箱に入っていた1は、隣の箱へ移動しつつ、0を左下の箱へ入れます。
このように、数値がシフトしていくレジスタのことを「シフトレジスタ」と呼びます。
これを繰り返すことで、例えば01010101というデータが2本の線で入力できます。
ちなみに、ここで0を入れると右下の桁はどこへ行くかというと
外へはみ出します。これを他の595のSDATへ繋げることでシフトレジスタの増設が出来ます。
しかし、これはシフトレジスタ内のデータであるため、まだ出力されていません。
そこで、LCLKを立ち上げます。
これにより、出力レジスタへデータがコピーされ、めでたく出力が出来ます。
このコピーを「ラッチ」と呼びます。
ちなみに、ラッチ後にデータを送っても、それはシフトレジスタのほうのデータが変更されるだけなので出力に影響しません。安全にデータを送り、完了した時点でデータをラッチして保存すれば良いと言うことです。
長くなりましたが、結論として3ピンで8つのデータを個別に用意できます。
通信の方法がややこしいですが、実はこれSPIという通信とほぼ同一規格です。
それぞれSDAT→MOSI,SCLK→SCK,LCLK→~SSとするだけです。
むしろ、SPI通信自体がただのシフトレジスタなので、それを逆手にとりました。
SPI通信は普及しているため、ArduinoやAVR、PICにRaspberry Piなど幅広いマイコンで容易に扱えます。
一応、ICのピン配置と使っているピンの紹介をします
- QA~H,Q'H
出力です。先ほど述べたまんまです
- SER,RCLK,SRCLK
入力です。名前が違いますがSER→SDAT,RCLK→LCLK,SRCLK→SCLKと読んでください。
- ~OE,~SRCLR
制御用ピンです。~OEはアウトプットイネーブルで、負論理なのでLowで出力許可です。ちなみにHighにすると出力はハイインピーダンスという特殊な状態になります。簡単に言うとHighでもLowでもなく、ピンは切り離されて浮いている状態になります。
使わないのでLowへ落としておきます。
~SRCLRはクリアーピンです、Lowにすると全データが初期化(0)されます。Highにしましょう。
完成品と動作確認
長かったですが、これにて8ピンの制御が3ピン、つまり
64ピン→3ピン
が達成されました!!!!!
最後に回路図と回路定数を決めて、組み立てと動作確認を行います
まず、7セグの抵抗を考えます(R10~17)
1LEDあたり、15mAほど流したいため、LEDのVfがだいたい2.2Vとして
(5-2.2)/0.015=186Ωです、余裕を持って200Ωにしました。電流はだいたい14mAです。次に電流を供給するPNPトランジスタです。今回は7セグフル点灯で14×8=112mAなので、余裕をもってコレクタ電流Ic>200mAほどのものを選びます。見つかったものでは
2SA952がIc=700mAだったので十分として使いました。たぶん1015でもIc=150mAでカツカツですがギリギリ大丈夫かなと。たぶんトランジスタアレイが一番おすすめです
ベース電流を決めるR2~9を考えます。2SA952のhfe(直流増幅率)が200くらいなので
ベース電流IbはIc/200=112/200=0.56mA以上とします。VBEが-0.7Vとすれば、
抵抗には5-0.7=4.3Vほどかかるため、4.3/0.56=7.7kΩ以下であれば0.56mA以上流せます。余裕を持って5.6kΩとしました。
最後に、小数点のDPは74HC595直づけでも良かったのですが、それだけ負論理だと気持ち悪いので、2SC1815で簡単にNOTを組み、正論理にしました。595にも負荷がかからず良いと思います。
電源は5Vレギュレータで作りました。7805とかで十分ですが手持ちのやつを使いました。
PasSで配線図を作りました。
ガッと作って動作させたものが以下です。
SPI8桁7セグメントモジュール pic.twitter.com/8lDwJTxXyj
— SEGAサタン (@seg_514) 2018年12月8日
見て分かるとおり、右上の4ピン(SPIの3ピン+GND)で8桁のLEDが制御されています。
最後に
で、目標は達成されたかと言うことですが、
- 安くて→たぶん全部含めて材料費800円くらい
- 速くて→60fps出るから人の目では判断不可能なレベル
- I/Oピン数を削減→61ピン削減しました
と、満足できる結果です。
ここまでピンが減ると簡単に接続できるため、マイコンのデバッグで簡易モニターにしたり、センサーの値を出力したりと、いろいろな活用が出来ます。
たくさんのモジュールを作って、マイコンを軸に組み合わせる工作も楽しそうですね。
かなり長くなってしまいましたが、ここまで読んでいただきありがとうございました。