HOME > 技術談話 > PIC® microcontroller > マトリクスLED制御

はじめに マトリクスLED テーマ 回路 配置図 サンプルプログラム 
ポート割り付け 同時点灯手法 ダイナミック制御手法 データの取り扱い サンプルデータ 
データ制御 フローチャート 


■はじめに

 ダイナミック制御を利用してマトリクスLEDを制御するサンプルプログラムについて解説します。

 今回のサンプルでは8*8のマトリクスLEDを制御しますが、制御内容の理解を補足する意味で、
LEDのPWM制御  … 点灯周期と点灯比率について解説しています。
複数LED制御  … スタティック制御とダイナミック制御について解説しています。
1つのスイッチ  … 1つのスイッチで複数の事象を認識する方法について解説しています。
セグメントLED制御 … 2桁の7セグメントLEDの制御について解説しています。
を予めチェックすることをお勧めします(リンク先は新しいウィンドウで開きます)。

 今回のテーマを「試食」でと思いましたが、技術としては枯れた(?)内容なので中級編の位置付けにしました。

 注意事項

■マトリクスLED

 マトリクスLEDを目にすることは…室内では少ないですが屋外では多く見られます。
 ガソリンスタンドの看板や工事現場での注意看板。ドット絵で自由に「絵」を表現することができます。時にはカラーLEDが利用されていてカラフルな表示を行う場合があります。町中にある大きな広告モニター。あれもマトリクスLEDの集合体と思っても良いと思います(値段は滅茶苦茶高いと思いますよ)。

 一番シンプルな実物としては…以下の様な感じです。広告モニターから比べるとチープです(汗


 写真は8*8のLEDが内蔵されたマトリクスLEDです。

 各LEDのアノードとカソードが連結され、任意のLEDを点灯あるいは縦方向任意(横方向任意)のLEDを同時点灯することができます。

 同時点灯数が左の写真のタイプでは縦、もしくは横方向の8個になり、総てのLEDが同時点灯しているように見せるためにはダイナミック制御が必要になります。

 写真では発光していない部分が灰色に浮き上がって見えますが、製品に組み込む際は表面に濃い色のフィルターを被せて発光している部分だけを強調します。

 マトリクスLEDの中身は以下の様なイメージです。パッケージの中にLEDと配線が封印されています。

 マトリクスLEDは縦方向の並びをCOL、横方向の並びをROWと称します。
 このCOL/ROWの並びの順にピン配置が決まっていればよいのですが、たいていはバラバラです。

 任意のLEDを点灯する場合はCOL/ROWの
一方を単数選択、他方を0個以上の複数選択とします。どちらを単数選択すべきかはマトリクスLEDに接続する電流制限抵抗の位置により異なりますが、通常は電流制限抵抗を接続していない側が単数選択です(下図中央)。

 上図右側の指定はCOL/ROWの双方を複数選択しているので誤りです。

 マトリクスLEDでは7セグメントLEDと異なり、コモン端子という考え方はあまりしません。ただしこれは単色の場合。
 複数色の場合はコモン端子が存在するので注意してください。

 今回のサンプルプログラムで利用したマトリクスLEDは単色タイプ8*8マトリクスです。たまたま手元にあったのですが、ピン間が0.1inchの倍数なのでユニバーサル基板やブレッドボードに刺すことができます。

 注意:デバイスによっては2mmピッチや2列のピン間距離に端数が出る種類があります。

■テーマ

(1)利用するマイコン

 今回は制御する出力ポート数が多いので
PIC16F886 を利用します。このPICマイコンは28pinタイプです。

 小ピン数のPICマイコンでもシフトレジスタを組み合わせることでマトリクスLEDを制御することができますが、部品の入手が容易であること、外部ドライバ回路を組まなくて済むこと、低価格であることから PIC16F886 を選択しました。

 コンパイラは…問題ありません。HI-TECH Cでは PIC16F886 に対応しています。

 書き込み機は…Micropchip社製のPickit2は対応していますが、秋月電子通商様の PIC Programer V4 を利用する場合はソフトウェアのバージョンアップが必要になる場合があります。

(2)動作

 8*8のマトリクスLEDに図形と文字を表示しますが、同時点灯風に見せるためにダイナミック制御は必須です。

 今回はスイッチを1個だけ用意します。このスイッチを押下するたびに表示パターンを切り替えます。
 表示パターンは以下の通りです。

・基本図形表示 … 接続の誤りを検出します。
・大きな文字の16進数表示 … 7*7のデザインで16種を順番に表示します。
・程よい文字の16進数表示 … 5*7のデザインで16種を順番に表示します。
・小さな文字の16進数表示 … 3*7のデザインです。7セグメント表示もどきで2桁表示します。
・撮影用固定表示 … デジカメ撮影用です。
・スクロール表示 … 文字データを横スクロールで表示します。

 スイッチは1個だけなのでスイッチライブラリにミニ関数を利用しています。
 押下エッジだけを検出するだけですが、ライブラリを利用したほうが簡単なので(汗

■回路

(1)回路図

 今回は
PIC16F886 を利用します。源発振は内蔵クロック4MHz、電源電圧は 3.0V を利用しています。

 図をクリックすると大きな画像を見ることができます(新しいウィンドウで開きます)。
 大きな画像の解像度が荒い場合は画像の上にマウスカーソルをかざすと画像右下に拡大ボタンが表示されます。

 今回の装置では部品点数を減らし、容易に実験できるようトランジスタ等による電流増幅手段を採っていません。
 (その分、輝度が暗いともいえる…汗)

 3.0V電源、510オームの電流制限抵抗の組み合わせで PIC16F886 の
出力ポート許容範囲内で動作させています。この許容範囲についてはデータシートに詳細が記載されていますので御確認下さい。

 今回使用した PIC16F886 では1端子当たりの出力ポート許容電流は Max25mA です。マトリクスLEDに 3.0V 電源、510オームを接続した場合は約 2.73mA 流れます。ダイナミック制御上の同時点灯数は8個なので最大約 21.84mA が1つの出力ポートに集中しますが許容範囲内です。

 仮に
3.3V 電源を利用するならば、電流制限抵抗は750オーム(この場合は約2.27mA)を利用してください。510オームのまま電源電圧を上げるとPICマイコンの許容電流をオーバーします。

 そうそう、RE3/_MCLR端子。今回はMCLRとして機能します。この場合は内部プルアップが有効(自動)なので端子に対して外付けプルアップ抵抗は付けていません。

(2)用意した部品

 ブレドボードに関する部材については「7セグメントLEDの制御」参照ください。
 直接制御にかかわる部材は以下の通りです。

名称 通販コード 金額 備考
赤色LEDドットマトリクス(8*8) I-00963 100 TOM-1588BH、38mm×38mm
PICマイコン 16F886-I/SP I-02240 190 DIP形状です
カーボン抵抗 1/4W 510Ω R-25511 100 100本入っていて、内8本使用
カーボン抵抗 1/4W 10KΩ R-25103 100 100本入っていて、内1本使用
積層セラミックコンデンサー 0.1uF 50V P-00090 100 10本入っています、内1個使用
タクトスイッチ(黄) P-03650 10 色は何でも構いません

 電源装置については記載しませんでしたが、目標電圧 3.0V を出力することのできる電源を用意してください。
 乾電池でも大丈夫ですが、3.0V を上回らないように注意します。

 紹介した部材は総て秋月電子通商様で調達することができます。(リンク先は新しいウィンドウで開きます)。
 通販コードを検索すると詳細を見ることができます。上記の価格は、2010/05/24現在の価格です。

 紹介した部材は一例です。新規に購入せず手持ちの部材を利用しても問題ありません。ただ、回路図とプログラムの修正が必要になるので、このあたりは…各自で検討してください。

 再検討の際は
出力ポートに対する電流値に注意してください。

■配置図

(1)ブレッドボード配置例

 今回も実験用としてブレッドボードを利用します。以下に配置例を載せます。

 図をクリックすると大きな画像を見ることができます(新しいウィンドウで開きます)。
 大きな画像の解像度が荒い場合は画像の上にマウスカーソルをかざすと画像右下に拡大ボタンが表示されます。

 7セグメントLEDの時と同様、マトリクスLEDを配置する部分(右端)が大変なことになっています。
 マトリクスLEDのピン配置がばらばらで…そのあたりは空中配線で吸収しています。

 妙な配線がありますが気にしないでください。ワイヤー1本の長さが足りず、複数本で中継をしています。

(2)実装例

 部品とジャンパ線を組み付けると以下の様な感じに出来上がります(電源入ってます ^ ^ v)。

 スイッチは左端に1つあります。
 7セグメントLEDの時と異なり、今回は下部にある「+/-」のラインは電源、GNDに接続されています。

 ポートの割り付け、マトリクスLEDのピン配置の並びの補正をジャンパ線で行っています。


 左に配置された PIC16F886 のアップ。

 ピン数は28です。ピン数の割にシュリンクタイプなのでスッキリしています。


 右に配置されたマトリクスLEDの下…

 7セグメントLEDの時に比べるとスッキリしてます。
 その分、空中のジャンパ線が苦労して (ry

 それにしてもマトリクスLEDが大きい。
 サイズは38mm×38mmです。
 実装の際は部品名称印刷面を手前にします。

■サンプルプログラム

 サンプルプログラムを公開します → TestMatrix010x.zip 
 開発環境は MPLAB IDE V8.40 と HI-TECH C V9.70 を利用しています(開発環境の準備)。

 
HI-TECH C v9.70 で作成されたプログラムを v9.81 以降のコンパイラで再コンパイルする際の注意点
  → 開発環境による修正 2011/03/09

 今回のサンプルプログラムでは解説済みのスイッチ汎用ライブラリを使用しています。
・main.c … 制御プログラム本体です。割り込み処理も含めて記述されています。
・DrvSw.c … スイッチ汎用ライブラリです。詳細については「1つのスイッチ」を参照願います。

 スイッチ汎用ライブラリはユーザ環境(DrvSw.u)のみ変更しています。今回はスイッチ押下のみで連続押下を認識する必要はありませんが、コーディングを省略できるので利用しています。また、スイッチが1個なのでミニ関数形式を利用してプログラム容量の削減を図っています。詳しくはユーザ環境ファイルを参照願います。

 HEXファイルを秋月電子通商様の PIC Programer V4 で書き込む場合はソフトウェアのバージョンアップが必要な場合があります。詳細は秋月電子通商様の 製品ページ を御確認下さい。
 今回、私の場合はソフトウェアのセットアップができなくて悩みましたが ここ に対策方法が記載されていました。

 秋月電子通商様ネタで恐縮ですが、デバイス PIC16F886 を選択すると以下のメッセージが表示されます。

今回は「VPP-FIRST(推奨)」側を選択してください。

■ポート割り付け

 今回使用するPICマイコン PIC16F886 のポート割り付けを以下にまとめます

ポート In/Out 制御対象 備考
RA0 In SW0 スイッチ押下でL。
RA1 Out (未使用) 常時L出力。
RA2 Out (未使用) 常時L出力。
RA3 Out (未使用) 常時L出力。
RA4 Out (未使用) 常時L出力。
RA5 Out (未使用) 常時L出力。
RA6 Out (未使用) 常時L出力。
RA7 Out (未使用) 常時L出力。
RB0 Out COL0 マトリクスLED、COL(カソード)
RB1 Out COL1  (同上)
RB2 Out COL2  (同上)
RB3 Out COL3  (同上)
RB4 Out COL4  (同上)
RB5 Out COL5  (同上)
RB6 Out COL6  (同上)
RB7 Out COL7  (同上)
RC0 Out ROW0 マトリクスLED、ROW(アノード)
RC1 Out ROW1  (同上)
RC2 Out ROW2  (同上)
RC3 Out ROW3  (同上)
RC4 Out ROW4  (同上)
RC5 Out ROW5  (同上)
RC6 Out ROW6  (同上)
RC7 Out ROW7  (同上)
RE3 --- _MCLR リセット時は L 印加。

 今回も7セグメントLEDの時と同様、空中ジャンパ線の助けを借りて端子の並びをそろえました。

 それにしてもマトリクスLEDのピン配置はバラバラで閉口します。今回はブレッドボードなので回避できましたが、ユニバーサル基板でジャンパ線無しで組み付ける場合は悩みそうです。

■同時点灯手法

 マトリクスLEDを制御する場合はダイナミック制御と同時点灯制御が必要です。
 この時、同時点灯制御については電流制限抵抗の接続位置により制御の仕方が変わるので注意が必要です。

 以下に回路の例を載せます(今回は左側の回路構成です)。

 単に1個のLEDを点灯するだけであれば双方の回路共に問題ありません。
 出力ポートXnの1つをLow、他をHigh。出力ポートYnの1つをHigh、他をLowにするだけです。
 例として「LED A」だけを点灯するのであれば、X1=Low、X2=High、Y1=High、Y2=Lowです。

 マトリクスLEDを制御するに当たり1個のLEDだけを注目するのは方法論としては間違いではありませんが、複数個のLEDで構成されたマトリクスLEDをダイナミック制御すると巡回周期が非常に長くなり、結果、輝度の低下を招きます。上記の回路であれば4巡しないと総てのLEDを制御できません。
 そこで、
巡回周期を短くするために同時点灯制御を行います。COL、ROWの一方に注目し、LEDを同時点灯することで巡回周期を短くし、輝度を確保します。上記の回路であれば2巡で総てのLEDを制御するイメージです。

 さて、ここで1つの問題が生じます。同時点灯する側はCOLなのかROWなのかです。一見どちらでも良い様に思えますが、
電流制限抵抗の位置で決まります。
 上図左の「アノード側に抵抗を接続した場合」を例とし、制御の組み合わせをまとめてみました。

X1 X2 Y1 Y2 LED A LED B LED C LED D NOTE
- - L L × × × ×
L L L H × × 輝度低下
L L H L × × 輝度低下
L L H H 輝度低下
L H L H × × × 輝度標準
L H H L × × × 輝度標準
L H H H × × 輝度標準、X1へ電流2倍
H L L H × × ×
H L H L × × × 輝度標準
H L H H × × 輝度標準、X2へ電流2倍
H H - - × × × ×

 輝度標準は1つのLEDを点灯した場合の輝度を基準とした状態です。

 組み合わせでピンとくると思いますが「アノード側に抵抗を接続した場合」、輝度を保つためにはアノード側は1個以上の選択、かつカソード側は1つの選択になります。この方法は7セグメントLEDの場合と同じです。

 上図右「カソード側に抵抗を接続した場合」を例にした場合は真逆の選択方法になります(組み合わせ表は各自で作成のこと)が、
基本は電流制限抵抗を付けた側が複数選択可能、反対側は単数選択になります。

 なお、輝度云々にかかわらず、複数個のLEDを点灯した場合に他方は電流が合流することになります。マイコン、ドライバデバイスの
許容電流未満で運用しなければならないことは基本条件です。

■ダイナミック制御手法

 既に7セグメントLEDの制御をマスターしていればマトリクスLEDのダイナミック制御は簡単です。
 今回のサンプルプログラムでは「アノード側に抵抗を接続した場合」に基づくので、
カソード側(COL)の選択を繰り返すダイナミック制御でマトリクスLEDを制御します。

 プログラムは「カソードデータを1つ選択、アノードデータを複数個選択する構成」になります。

 運用開始後、2ms(厳密には2048us)周期でカソード側(COL)を順番に1つだけ選択することでCOL位置基準でマトリクスLEDを制御します。任意のある瞬間ではマトリクスLEDの縦1列だけが表示されていますが、高速に巡回することで見かけ上は総てのLEDが同時点灯しているように見えます。

 マトリクスLEDの制御周期は7セグメントLEDの制御周期に比べると長いです。
 マトリクスLEDが8×8。これで数字1文字を表現。7セグメントLEDで数字1文字を表現。この場合は7セグメントLEDの方が輝度を稼ぐ面では有利です。見た目の認識も7セグメントLEDの方がハッキリしています(慣れ?)。

 ですが、複雑な形状、たとえば英字、図形といった表現を行う場合はマトリクスLEDが遥かに有利です。マトリクスLEDを採用した場合はハードウェア、プログラム共に複雑な構造になりますが、このあたりは「何を目的にするか」で使い分けるのが良いでしょう。

■データの取り扱い

 データの取り扱いはプログラムとハードウェア、そしてデザイナー(実データを作る人という意味で)の間で非常に悩ましい問題を投げかけます。まぁ「決め」の問題なんですけどね(汗

 ・基準点は何処か?
 ・データの並びはどちらか?
 ・ビットの並びはどちらか?
 ・定義した値が明るいのか、暗いのか?

 連携が上手く取れていないと表示された内容が上下反転、左右反転、輝度反転…なんてことになりかねません。
 プログラムの各所で変換を繰り返し、非常に重いプログラムになりかねないので、
設計初期の段階で「データの取り扱い」を決めておいた方が良いでしょう

 この「決め」に基づいて表示データを作成するとプログラムからのアクセスが非常に楽になります。

(1)基準点

 角を基準にする方法が一般的ですが、時にはマトリクスの中央を基準にする場合があります。

 パソコン等で扱われる画像を表示するような場合は画像ファイルの形式を参考にするのも良いと思います。


(2)データの並び

 今回のサンプルプログラムで使用したマトリクスLEDは8×8なので問題ありませんが、16×16や32×32の様な多バイトにわたる構成の場合、続くバイトデータが左右に位置するのか上下に位置するのかも決めましょう。

 マトリクスの構成でバイト端数が生じた場合に端数を切り捨てるのか、次の場所に回り込ませるのかも忘れずに検討します。

 そういえばファイルシステムのFAT12。メモリ効率は良いのですが制御に手間が増えます。

(3)ビットの並び

 プログラム仕様書でよく見かけるのは上図左、LSBが右側にあるパターンです。が、基準点の採り方によってはLSBを左に配置しなければなりません。縦方向の並びもしかりです。

 一概にベストな方法は決められませんが、縦、もしくは横方向が多バイトになる場合は注意した方が良いでしょう。
 シフト演算した際に下位バイトのLSBを右シフトして上位バイトのMSBに入るなんて避けたいです。

(4)ビットの並び(ハードウェア都合)

 基板を新規に作成する場合はビットの並びと配線の並びは一致すると思います。ですが、手作りの場合は配線の並びがバラバラになる場合が多々あります。
 7セグメントLEDの場合は表示種が少なく、ハードウェアの配線の都合に合わせてデータの並びを置き換えます。数字であれば10種のデータだけなので苦はありません。
 一方、マトリクスLEDの場合は自由度があり過ぎて表示種を特定できず、図形デザインレベルでハードウェア配線に合わせるのは困難です。また、画像シフト操作(絵を動かす)を考えるとデザインは通常、表示するタイミングで並びを変えるプログラム構成の方が無難かと思います。

(5)明るさの定義

 データの「1」が点灯するのか、消灯するのか。些細なことですが重要な要素です。間違えた場合は単に反転すれば済む話ですが、できる事ならば初めから決めておいた方がプログラムの手間は減ります。

 そういえば、学生時代の黒板とチョークの関係。生徒からみるとノートと鉛筆。輝度が逆転しています。
 WindowsOSの画像形式であるBMPファイル。2値で保存した場合の白と黒の情報はそのまま利用すると反転表示になったりしますので注意してください(経験済み)。概して「動かしてから判明した事実」というのもあります。

(6)今回採用したデータの構成

 今回のサンプルプログラムで採用したデータの構成です。。
 ひねりがなくてすみません orz

 ジャンパ線の活躍でビットの並びと配線の並びは一致しています。

 1つのCOLを選択しROWデータを1バイト分、無加工でセットすることで縦列を1つ表示します。ビットの意味づけは1で点灯、0で消灯です。COLを高速で切り替えて任意の図形、文字を表示します。

■サンプルデータ

 今回のサンプルプログラムで利用したサンプルデータ(フォント、図形データ)は画像編集ソフト(私の場合はペイント)を使ってデザインし、変換ツールを使って一括変換しています。必要とあらば1文字、1図形毎に手でデータを作ることもできますが、数が多い場合、修正を繰り返す場合は変換ツールがあると便利です。

 このサンプルデータの構成は前述の「データの取り扱い」に準じています。

 サンプルデータは文字だけでも良いのですが、べた黒、べた白、数字の0、英字のA…左右対称、上下対称のデータは診断データには不向きです。
 ハードウェアの診断も兼ねて
上下左右、反転状況を確認するデータを用意しておくと便利です。

■データ制御

 更新タイミング遅れてしまいましたが解説を再開します。

(1)役割分担の考え方

 データ制御はバッファを境界線とし編集側のメイン処理、表示側のタイマ割り込み処理と分けて考えます。
 今回のサンプルプログラムでは以下の様に役割分担を行っています。

 フォントデータをタイマ割り込み処理で直接参照してダイナミック制御する方法もあるのですが、これは特殊です。
 この特殊な手法はRAMメモリ容量が確保できない場合に採用することがありますが、割り込み処理時間を多く必要とし、何よりも「割り込み処理ありき」という構造になってしまうので初心者にはお勧めできません。

 比較的軽い処理、例えばシリアル通信で受信したコードに対するフォントを未編集で表示する位ならばこの方法も有りかと思います。

 無難な方法は、バッファ、いわゆるVRAMに相当する緩衝領域を設け、メイン処理側で編集、タイマ割り込み処理側で参照する方式を採用した方が何かと好都合です。特に
表示内容をアクティブに切り替える場合に有利です。

(2)バッファ

 今回のサンプルプログラムでは緩衝領域であるバッファを2種類を用意しました。
 どちらも同じ構成、同じ容量になっています(少なくとも「表示イメージ≦制御イメージ」なメモリ配分が必要)。

・表示イメージ … メイン処理での編集用途
・制御イメージ … タイマ割り込み処理での参照用途

 表示イメージの編集が完了した段階で表示イメージを制御イメージに一括コピーしています。
 コピー作業中の割り込み禁止操作は任意です。サンプルプログラムでは割り込み禁止操作をしていません。
 
割り込み禁止にしたとしてもダイナミック制御故、表示済みの過去データによる残像は回避できないからです。

 ダイナミック制御巡回の先頭のタイミングで一括コピー。これも悪くは無いのですが、残像は残ります。

 良くある残像回避の手法として、表示を変化させる前にスペース表示(マトリクスLED総てオフ)の期間をダイナミック制御の一巡時間以上確保する方法もあります。ただし、表示オフによる「ちらつき」は覚悟しなくてはなりません。

 が、システム仕様として定義してしまえば「ちらつき」も正義(?)です。

 例えば、天気予報マークを表示する場合。「晴れマーク」から「雨マーク」に切り替わる際に0.5秒程度の表示オフ期間を設ける事は問題にはなりません。むしろ切り替わりを明示的に表現できるという面では歓迎されるかもしれません。

(3)バッファの数

 システムによっては表示イメージと制御イメージを一本化しても大丈夫です。メモリ容量の面から非常に有利なのですが、今回のサンプルプログラムではバッファを2つ持ちました。その大きな理由としては、

・各プログラムから見て編集対象、参照対象を1つに絞りたい。 … 混乱防止。
・編集の作業過程を表示させたくない。 … 結構目立ちます。
・割り込み処理時間を短く、割り込み処理に考えさせたくない。 … これ重要。

 前回、セグメントLED制御について解説しました。同サンプルプログラムでは1つのバッファだけ(制御イメージ)が確保されていましたが、セグメントLEDは情報量が格段に少ないのでバッファを1つだけで対応しました。

 この辺りは表示情報量、ハードウェア構成に依存してしまうかと思います。

(4)バッファ盤面による高速化の案

 今回のサンプルプログラムでは
 ・表示イメージ
 ・制御イメージ
という2つの用途別バッファを定義しました。メモリサイズから見ると「表示イメージ≦制御イメージ」です。

 定義上は編集用、参照用と別れているのですが、これを汎用的に定義する方法もあります。それが盤面です。
 (盤面という言い方はローカルルールかもしれないのでご注意を)

 2つの同一構成のバッファを用意し、編集用、参照用で相反するバッファを利用します。そして、編集用のバッファに対する編集が完了した段階で作業対象のバッファを入れ替えます。

 この方法はインデックスの操作だけで切り替えるのでメモリコピー操作が不要になり処理性能のアップを期待できます。特にマトリクスLEDの制御数が増加(表示情報量の増加)する場合に効果があります。

 反面、必要メモリサイズが確実に「倍」になることに注意が必要です。
 また、
編集過程が見えてもかまわない。という場合はこの限りではありません

■フローチャート

 サンプルプログラムをフローチャートを交えて簡単に解説します。.

 サンプルプログラムは大きく分けてメイン処理と割り込み処理に分かれます。
処理 概要
メイン処理 スイッチの認識とスイッチ事象に応じた表示イメージ、制御イメージの更新。
割り込み処理 制御イメージに基づいたダイナミック制御。時間管理。 

 今回のサンプルプログラムではタイマ割り込みを約2ms周期に設定しています。

 前述の「データ制御」の項でも触れていますが、タイマ割り込みをトリガとして列を単位に表示を行い、都合8列で表示が一巡します。2msという時間が短い様にも思えますがマトリクスLEDを表示する場合は表示を一巡する時間を考えなければなりません。特に
アクティブに表示が切り替わる場合、表示画素数が多い場合ほど短時間で一巡しないと表示バランスが悪くなります。マトリクスLEDの制御って表示内容の変化頻度以上に忙しいです。

 マトリクスLEDを静止した状態で利用する分には問題にならない表示の一巡周期。マトリクスLEDが物理的に移動する場合はどうなるでしょうか?例えば電車の側面についている行き先表示。停車している場合は問題ありませんが、時速80kmとかで移動している最中も表示を行っていた場合、表示が伸びてしまうと思います。

 さて、前置きはこれくらいにして各処理の流れを概略フローにしてみました。

 ちょっと縦長で見づらいです(汗。

 基本的な流れはセグメントLED制御の時と同じです。メイン処理で表示イメージを編集し、編集完了により制御イメージにコピーを行います。一方タイマ割り込みは定期的に制御イメージを参照してLEDに出力します。

 メイン処理ではスイッチの状態を監視し、スイッチ押下で機能番号の切り替えを行い、表示内容を変更します。

 前述の「データ制御」で表示バッファと制御バッファの2つを解説しましたが、いくつかの機能処理はフォントデータを無編集で制御バッファに転送しています。この辺りは実現する機能に依ります(編集過程が見えても良いか否か)。


 タイマ割り込み処理が二段階で処理していることに気が付きましたか?
 今回のサンプルでは情報量が少ないので一段階でも問題ないと思いますが、例として2段階制御を行っています。

 マトリクスLEDに表示すべきデータを制御イメージから取得した後、直ちに出力しないで次のタイマ割り込みのタイミングで出力しています。割り込み処理の作業を分割すると「出力」、そして「取得」の順番になります。

 二段階制御している理由はマトリクスLEDへの出力更新周期を安定させるためです。
 タイマ割り込みの発生後、処理時間のばらつきなく出力を行います。その後の取得は後処理的な扱いで、処理時間がばらついても表示に影響しません。

 処理時間のばらつきが目に見えるか?と言われると…恐らく見えないと思いますが、提示された仕様に対するプログラム設計者の意地(笑)になるかもしれません。この辺りは「見えないおしゃれ」ということで。

 けど、意外な場所でこの考え方が役に立つ場合がありそうです(ちょっと意味深)。


Copyright 2010,2011 PaletteSoft LLC. All rights reserved. 利用条件 | HOME | サイトマップ | お問合せ