PICを使ったLEDを光らせます。このページで作ったのは下のとおりです。
よくあるピカピカを改造 | PIC16F84A | 12個のLED。輝度変調/振ると字の出る |
MIDIでピカピカ | PIC16F648A | MIDIで12個のLEDを制御 |
イルミネーション・ライン | -- | LEDドライバ回路 |
74LS47をPICに接続する7セグ8桁表示 | PIC16F648A | 74LS47を使って |
PICで7セグ8桁表示 | PIC16F648A | 74LS47を使わずにPICで表示 |
PICでMIDIチャンネル表示(その1) | PIC16F648A | MIDIチャンネル表示器 |
PICでMIDIチャンネル表示(その2) | PIC16F648A | MIDIチャンネル表示器。回路を節約版。 |
PICでMIDIチャンネル指定&表示 | PIC16F648A | MIDIチャンネル表示器にチャンネル切り替え機能を追加。 |
8クイーン - 8x8ドットLEDを使って - | PIC16F648A | 8x8ドットLEDに8QUEENの解を表示 |
秋月のPICライターを組み立てたときに、テスト用に組み立てたものです。回路はPICライターのドキュメントにあったテスト回路で、PIC16F84Aのポートから電流制限の抵抗を介してLEDにつながっているというシンプルなもの。付属のテストプログラムをPICに焼きこみ、ライターが動作したことを確認するためのものです。PICをセットして電源を入れると、右から左、左から右へと一つの光が移動します。クロックは10MHz。
回路は、PICのRB0-RB7,RA0-RA3から抵抗を介し、LEDへ、LEDはグランドに繋がっているもの。抵抗の値は、手持ちの都合で330オームとしました。点灯時に抵抗の両端の電圧を測ると、2.7V強。電流は、8.2mA流れていることになります。
PIC16F84Aの場合の出力電流の制限は、次の通りです。
Maximum output current sunk by any I/O pin | 25 mA |
Maximum output current sourced by any I/O pin | 25 mA |
Maximum current sunk by PORTA | 80 mA |
Maximum current sourced by PORTA | 50 mA |
Maximum current sunk by PORTB | 150 mA |
Maximum current sourced by PORTB | 100 mA |
このボードの回路では、ポートの+側から電流が流れるので、sourced。上の表から、各ポートは最大25mA。PORTAの合計で50mA。PORTBの合計で100mAとなります。
実測値から大目に見て9mVとすると、全部点灯したとき、PORTAは4*9=36mA。PORTBは72mA。それぞれの条件を満たしています。
しかし、そのほかの条件で、電源ピンの電流制限が150mA。グランドピンの電流制限が100mA。消費電力の上限が800mW。こちらのほうは、簡単に確認できません。この回路はPORTA+PORTBで110mA。CPU自身が5.5V20MHzで最悪20mA。とすると、130mAの電源が必要かも。他に内部動作での分が加算されることになりそう。
結局、12個のLEDを同時点灯させるのは、現実には動くけれど、スペック的には疑問が残るところでしょうか。
せっかく組み立てたハードウェアなので、ソフトウェアを乗せ替えて遊ぼうかと思います。もちろんCPUはPIC16F84Aをそのまま流用します。
ずらりと並んだLEDをPWMで輝度変調(明るさのコントロール)をしてみました。消灯状態から始まり、ゆっくりと明るくなり、段々と暗くなってから消灯。これを繰り返します。部屋の電気を消して眺めると、それなりに、雰囲気があります。
実験をしてみると、明るさはPWMに対してリニアではなく、明るいほうはクリップ状態。LED時間的な応答性(なかなか消えない)の問題かと思います。
プログラムでは、タイマー0をフリーランで走らせ、地面でタイマー0のカウントが現在の輝度情報よりも小さければポートに「1」、小さければ「0」を書く処理をしています。輝度情報の更新はタイマー0の割り込みの中。
多少重くなるのですが、原理的には、この方法で全ビット独立の輝度調整ができるはず。
PORTBに繋がっているLED8つを使って、基板を振ると文字列が見えるプログラムです。
LEDが縦になるように基盤を持ち、ガイダンス用にPORTAの2ビットのLEDが交互に点滅するので、それに合わせて基板を左右に振ります(電源コードが切れないようにご注意!)。
部屋を暗くして、うまく、同期するとかなりはっきりと文字列が見えます。ガイドLEDを見ていると文字列は見えません(ガイド専用のハードが無いので、仕方が無いですね)。
表示する文字列はEEPROMに格納してあるので。プログラムをPICに焼きこむときに編集可能です。このとき、文字列の最後には0を付けて下さい。長さは最大64文字まで可能ですが、振ることを考えると、5〜10文字くらいが妥当でしょう。
フォントは、0x20から0x5fまで、つまり、英数大文字+大体の記号が用意されています。
予想していたよりも面白かったので、専用のハードを作るかも。となると、左右の振り方向を検出するセンサーが必要そう。加速度センサーをつけるとチープではなくなるので身の回りのものなどで何とか工夫してみたいです。
しょうもないと思いつつ、MIDIでLEDを制御すれば、よくあるMIDIのシーケンサでイルミネーションパターンが組めます。暫定で作るものは一つのラインでLEDを一つつけるだけ。でも、ちゃんとドライバーをつければクリスマスツリー風のイルミネーションがちょっとは豪華になるはず。
とりあえずは、オクターブ内の11音に対応してノートオン・ノートオフで点滅させるという陳腐なものでスタートさせましょう。
まず、使うPICは、PIC16F648Aを考えてみました。これは、PIC-PSGでも、PIC-MIDICVでも使ったもの。面倒なMIDIのプログラムはそのまま流用できるのでというは、安易な考えです。。
つぎにピンの割り当てを考えなければなりません。どうも、一つ足りません。シリアルを使っている間でも、TXをGPとして使えればいいのですが…マニュアルを読んだ限りでは、SPEN(シリアルポート・イネーブル)にした時点で回路がシリアル出力に切り替わるようなのです。また、TRISB[1:2]は1にして入力モードにせよとあります。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | o | LED | C# |
RA1 | o | LED | C |
RA2 | o | LED | A# |
RA3 | o | LED | A |
RA4 | o | LED | G#プルアップ必要 |
RA5 | i | (SW) | 入力用ポート1ビット。コンフィグで指定が必要。 |
RA6 | - | xtal | セラロック20MHz |
RA7 | - | xtal | 同上 |
RB0 | o | LED | G |
RB1 | - | RX | MIDI入力 |
RB2 | - | TX | MIDI出力(?)。USARTを使用しているときは、出力ポートにできない?。 |
RB3 | o | LED | F# |
RB4 | o | LED | F |
RB5 | o | LED | E |
RB6 | o | LED | D# |
RB7 | o | LED | D |
LEDの数を12にこだわっているのは、1オクターブが12音だから。同一の複数個のものを揃えれば、最大で120LED(10個の回路)をパラ接続で処理できます。シーケンサ側では異なるCPUを選ぶときには、オクターブを変えればいいわけです。
もちろん、外部に回路を設けてラッチすれば、一つのCPUで多くのLEDを使用できますが、コストや基板面積を考えると、CPUを増設した方が作りやすく、値段も安そうです。というわけで12個は守りたい線。
何か無いかと知恵を絞ると、
いっそのこと、シリアル入力をソフトウェアで処理することにすれば、ピンが一つ空きます。すると、648Aを使わなくてもいいじゃないかということにもなりそう。
余っている16F84Aにするかなぁ。もし、追試製作する方がいると、16F84Aは割高(秋月で380円)。
入力をRA5にすれば、ポートが二つ空きます。これならば、USARTがいらないので、PIC16F648Aを使う理由が無かったりしますが、いろいろ、考えあわせるとやはり、16F648Aになりそう。
価格(秋月) | 秋月ライターの対応 | ||
---|---|---|---|
PIC16F648A | 200 | ○ | 結局これ? |
PIC16F84A | 380 | ○ | 値段が高い |
PIC16F628A | 200 | ○ | 645Aよりプログラム容量が小さい |
PIC16F819A | 250 | ○ | 値段が高い |
PIC16F57 | 120 | × | 28P。安いけれど秋月のライターで書けない |
セラロックを繋いでいる端子を出力に振り返られるのでポートが二つ増えます。問題は、内蔵クロックの精度が悪いこと(1%誤差)と遅いこと(20Mの1/5)。速度的に間に合わなければ、MIDIの処理を地べたに放り出します。
USARTがついていて、28ピンの物などが良いのですが、いずれも、値段が高いです。16F873Aが秋月で400円。いっそのこと40ピンのPIC16F877Aにして大幅にLEDの数を増やしてしまう手もあります。
最初は、PIC16F648Aを内蔵クロックで使う。速度的にきつくなった場合には、他の手段もということにしました。ピンの割り当てを検討しなおします。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | o | LED | C# (1:点灯 0:消灯 以下同) |
RA1 | o | LED | C |
RA2 | o | LED | B |
RA3 | o | LED | A# |
RA4 | - | LED | エラー表示。0:点灯 1:消灯 |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | LED | D |
RA7 | o | LE | D# |
RB0 | o | LED | A |
RB1 | - | RX | MIDI入力 |
RB2 | - | TX | MIDI出力 今回は使用しないがTXに割り当ててある。 |
RB3 | o | LED | G# |
RB4 | o | LED | G |
RB5 | o | LED | F# |
RB6 | o | LED | F |
RB7 | o | LED | E |
上の割り当てで、出力条件が違うRA4を避けることが出来ました。MIDIのクロック生成は、以前PIC-PSGの時に検討した結果から、4MHzでは、Mode:Lo でValue 1 にするか、Mode:HiでValue 7 にするか、どちらかでいいようです。
LEDは出力ポートに抵抗を介してグランドに落とせばいいように、正極性の出力とします。電流はアバウトに8mA程度。どのみち実験なのでこんなものでいいでしょう。
内蔵発振器を使ってわかったことは、内蔵発振器を使う場合には、MCLRにGPIOを割り付けてはいけないらしいこと。リセット回路を作るのは面倒なので、抵抗を介してHIに吊っておきます。
受信エラー用のLEDをRA4につけることにしましたが、これがオープンドレインなので他の端子と回路を変えなければなりません。LEDは抵抗を介して電源に繋ぐことにして、負ロジックにしておきます。LED消灯時に電流を流さないためです。
組み上げた基板は二枚です。MIDI入力(フォトカプラ)とPIC16F648Aが載っている主基板と、LEDが載っているデモ基板の二つに分けて作りました。デモ基板にドライブ回路を載せれば、将来のクリスマスツリー・イルミネーションも試せるように分けたわけです。
右が主基板の拡大写真。基板の右辺にあるコネクタは、5V電源とMIDI入力。下にある長いコネクタがデモ基板に繋がるコネクタで、13ピン(LED12ラインとグランド)。基板の中、やや右寄りにRXと示したコネクタは、フォトカプラの出力(MIDI入力)と電源とグランドを後から使えるようにしてあります。ここに増設CPUをつければフォトカプラが節約できるはず。エラー表示のLEDは一応、念のためで、実際には必要ないでしょう。
それから、デモ基板。要するに表示パネルです。単にLEDが12個と、電流制限抵抗(今回はなぜか370Ωで、8mA弱)。LEDは鈴商で前に買っておいた、おそらく、レベルメータ用の連装LED。緑と赤できれいな発色です。いつも、裸のLEDを並べているだけでつまらなかったので、今回は、ちょっと、変わったものを使ってみたというのが登場の理由です。電流はもっと流せば輝度が得られますが、一応、安全を見てこんなところにしました。
プログラムの概略は次の通りです。現在の第二版では、EEPROMオプションでオクターブに関わらず、該当する音を点灯する処理を組み込みました。
プログラムは、単純で、指定したチャンネルの指定した1オクターブの12音をノートオン、ノートオフで切り替えるというもの。
チャンネル指定、オクターブの指定は例によって、秋月のライターで手でEEPROMに書き込みます。
チャンネル1ならば、0、チャンネル2ならば1といった具合で書き込みます。
MIDI Channel | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
EEPROM 0 | 00 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 0A | 0B | 0C | 0D | 0E | 0F |
表示するオクターブの一番下の音のノート番号を書き込みます。Cからはじめるためには12の倍数で書く必要があります。デフォルトは C3(60)で始まるオクターブなので、C3のノート番号60、16進で0x3Cが書き込まれています。
ここに、0x80以上の値を書き込むと、どのオクターブの音が来ても該当する音が対象となります。この場合、重複の検査は行っていません。
オクターブ | C-2 | C-1 | C0 | C1 | C2 | C3 | C4 | C5 | C6 | C7 | オクターブ無視 |
---|---|---|---|---|---|---|---|---|---|---|---|
EEPROM 1 | 00 | 0C | 18 | 24 | 30 | 3C | 48 | 54 | 60 | 6C | 80 - FF |
あまりに単純なので、回路図は不要かもしれませんが、一応、載せておきます。フォトカプラの出力を吊っている抵抗は、複数CPUを載せるならば、1k程度にした方が良いでしょう。
受信エラーLEDが不要の方は10kぐらいで電源に吊ってください。
ソースプログラム | picmidiled00.asm |
プログラムのHEX(07/07/04) | picmidiled00.hex |
暫定の回路図(07/07/03) | picmidiled00.pdf |
PIC-MIDILEDでのデモボードをイルミネーション・ラインに置き換えたい。
電源は15V、LEDをライン当たり、6個程度使用とします。問題になるのはLEDの順方向電圧Vfのバラつき。これが大きいと、抵抗で電流制限とはいかず、定電流ダイオードなどを使わうことになります。
とりあえず、どんなものか、秋月でいつも使っている100個500円前後のLEDで簡単に調べてみます。LEDの型番は、緑:OSNG3133A、黄:OSYL3133A、赤:OSDR3133A。ばらつきを見るだけなので、抵抗を固定してLEDの両端の電圧を測ってみました(5Vで220Ω)。
赤 | 1.830 | 1.833 | 1.834 | 1.830 | 1.826 |
黄 | 1.957 | 1.933 | 1.907 | 1.975 | 1.950 |
緑 | 2.073 | 2.078 | 2.077 | 2.085 | 2.088 |
本来なら電流量を固定して測らなければならないのですが、とりあえず、バラつきを見ると、予想外に少ない。これならば、同じ百個袋の中で使えば、ある程度の範囲で抑えられそうです。色別に制限抵抗を変えなければいけませんが、電流制限抵抗で十分いけそうです。
赤LEDで概算してみます。 Vf=1.83V として、6本で10.98V。抵抗にかかる電圧は、15-10.8=4.02V。電流を10mAに制限するので、R=V/I から、4.02/0.01→402Ω。抵抗を組み合わせて、180+220。あるいは、390,430,470のいずれか一本。
黄LEDの場合。Vf=1.95V として、6本で、11.7V。抵抗にかかる電圧は、3.3V。抵抗は、3.3/0.01=330Ω。
緑LEDでは、Vf=2.08Vとして、6本で、12.48V。抵抗にかかる電圧は、2.52V。抵抗は、2.52/0.01=252Ω。手持ちの抵抗ならば、150+100。一本ならば、220、240、270のいずれか一本。
抵抗のバラつきもあるので、電流が8mAから12mAの範囲に入ればよいぐらいのつもりで実測してみます。
色 | 抵抗(Ω) | Vf(V) | 電流(mA) |
---|---|---|---|
赤 | 470 | 10.8 | 8.64 |
400 | 10.8 | 10.05 | |
黄 | 330 | 11.5 | 10.28 |
緑 | 250 | 12.2 | 10.49 |
右の写真がドライバ基板(デモボード2号)です。
ドライブ回路の方ですが、電流容量はPICのピンで間に合うはずなのですが、LEDをオフするときにPICの端子をオンにします(5V)。電源が15Vなので、この状態でも電流が流れてしまう。PICの端子がオープンコレクタではないので仕方がありません。
ということで、トランジスタでドライブすることになりました。トランジスタアレイを使う手もあったのですが、ここはディスクリートのトランジスタをずらっと12個ならべることにしました。コスト的にはトランジスタアレイの方が安そうなのですが、こういう巨艦式のものを作ってみたかっただけです。(回路図、要るのかな。後でアップします。)
使うトランジスタは、手持ちの2SC1815。ベース抵抗は4.7k。エミッタはグランドに落とし、コレクタに付ける電流制限抵抗は、シリアルに繋いだLEDのケーブルの中に入れます。これは、色別に抵抗値が違うので(それにバラつきがあったときはここで吸収するつもり)その対策です。一つのトランジスタで、数本のラインぐらいまでは余裕でつなげられます。
電源(15v)は、このボードに繋ぐことにして、ここに三端子レギュレータを載せて5vを作り、CPUボードに供給。
LEDラインを2ラインずつつなげられるように一応24ピン(グランド込みで48ピン)コネクタを載せました。
イルミネーションラインは、LED六個を直列につなぎ、電流制限抵抗を付けるだけ。抵抗値は色別に違うのでちょっと注意。ケーブルは1.5φの緑の縒り線を使いました。暗い緑の線がなかなか無くて、秋葉のガードしたのタイガー無線で購入。3mで100円。
LEDの間は15cmの線で結び、さらに30cm離して抵抗を入れ、さらに、5cmほど線を繋いでコネクタへ。
仕事の合間というか、気分転換にイルミネーションラインを12本作ったのですが、なかなか、面倒でした。全部繋いで、MIDIシーケンサのピアノロールを利用して点滅パターンを書き、ループ再生すると、なかなか壮観です。
PIC-MIDILEDの受信チャンネルを16chなど適当なものに設定しておけば、音楽のタイミングに合わせた点滅をできるので、結構、楽しいんじゃないかと思いました。
作ってみた反省点は、イルミネーションラインのケーブル、根元をもっと長くするべきだったこと。自由にレイアウトするためには、元のリード部分が長い方が使いやすい。これは、本番のクリスマスまでに改造しなきゃならない点です。
また、これだけLEDの数があると、輝度変調などは要らない感じです。クリスマス・イルミネーションのつもりならば、ソフトはこのままで良いようです。
ハードの方は、最終的にはコンパクトな方が良さそう。トランジスタの列をやめて、トランジスタ・アレイ(入力抵抗つき)を使って小さくしたものを最終的に作る予定です。
アナログシンセの掲示板でPIC-MIDICVにチャンネル表示が欲しいという話題が出ていました。
色々検討したのですが、まずは、PIC-MIDICVへ与える4本のチャンネルセレクトから単純に表示する方法を考えてみます。
BCD(10進)のセグメント表示用IC74LS47、あるいは、4511Bなどを使う方法です。takedaさんのインプリメントのようにチャンネルが8チャンネルまでならば、一桁で十分なので、この方法でも十分です。使用する7セグLEDが、アノードコモンならば、74LS47(シンクドライブ)。カソードコモンならば4511B(ソースドライブ)を使います。問題は、二点。
18ピンのPICを使うとすると、色々考えたけれど、結局、値段が一番安い16F648A。内蔵発振器を使うと使用できるIOは15本。チャンネルセレクトの読み取りに4本。セグメントのドライブに8本。二桁表示にするならば、桁のセレクト用に2本。都合14本でうまく収まります。
PICを使う案は、もう一ひねりすると、チャンネルセレクトのハードウェアの面倒を見るものも考えられます。
チャンネルセレクトに使う部品で色々な方法が考えられることになります。
当初は、動作時のチャンネル切り替えを考えていなかったので、普通のDIPSWを想定していました。この場合は、原案のまま。
回転式で値を選べるロータリー式のDIPSWがあるので、それを使えば、回すのがちょっと不便ですが、そのまま、使えます。お値段は100円から150円ぐらい。
回転式のセレクタを使って切り替える方法。takedaさんはこの方法で8チャンネル切り替えをなさってます。16チャンネルを直接切り替えるとなると、ロータリー・スイッチが高すぎ。上位(1-8)と下位(9-16)の切り替えスイッチを別に設ける方が良さそうです。ロータリスイッチからエンコードする機能と表示機能を合わせて実現したい。
PICをADのあるものに変えれば、ボリュームの値を読むことで、チャンネルを指定できます。候補は、16F819とか、16F88。チャンネルセレクトの信号はPICから出力します。
PIC-MIDICVの16F88版を作成すれば、済む話かもしれません。
チャンネルをプッシュスイッチで切り替える。ピンの数が足りないので、スイッチを一つだけにするか、LEDを一桁にするか。あるいは、外付けの回路を少し工夫するか…というところ。あるいは、ドット(小数点)を省くとかですね。
とりあえずは、7セグの表示方法に付いて、簡単なところから実験を進めてようと考えています。手持ちの7セグは、なぜか、すべてアノードコモン。そこで、アノードコモンの7セグ用の回路が対象となります。といことで、以降、7セグの表示実験をしてみました。
PICを使用しない回路の実験はこちらで行いました。74LS47の使い方実験です。74LS47のちょっとした使い方も書いてあります。
ついでだから、74LS47をPICで使う実験をしてみようかと思います。74LS47を一つにして数桁表示する回路実験です。ダイナミック点灯なので、余り桁が多いと、ちらついたり、暗くなったりしそうです。
手持ちの7セグ二桁のLED(アノードコモン)が4つ、都合8桁分あるので、これを前提に回路を考えます。各セグメントの端子はすべて電流制限抵抗を介して74LS47に並列接続。各桁のコモン(アノード)に、PNPトランジスタ(ここでは2SA1015)を通して電流を流す。このトランジスタを順番に切り替えることで桁表示の切り替えを行います。トランジスタをトランジスタアレイに置き換えられれば良いのですが、残念ながら手持ちがありません。
トランジスタのベースは、同時に一つだけをLOWにします。正直にPICに繋ぐと桁数だけ必要になりますが、外部にデマルチプレクサを接続すれば、本数を減らせます。ここでは、八桁ですから、デマルチプレクサを使えば、3本で十分。もちろん、デマルチプレクサを使わなくても出来るので、状況に応じて判断。今回は、使ってみたい。
デマルチプレクサを決めます。機能的には3-8デマルチプレクサで出力論理がLのもの。74HC138になりそうです。こういう実験のときにはHCよりLSの方が空き端子の処理など気を使わなくて楽なのですが、手持ちがないので仕方がありません。
PIC16F648Aは内蔵発振モードで扱うことにします。表示の実験なので、表示回路だけをドライブすることにして、表示データは適当にプログラムで作って試します。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | o | アドレス b0 | デマルチプレクサ(74HC138)へ接続 |
RA1 | o | アドレス b1 | 同上 |
RA2 | o | アドレス b2 | 同上 |
RA3 | o | 未使用 | |
RA4 | o | 未使用(od) | |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | 未使用(xtal) | |
RA7 | o | 未使用(xtal) | |
RB0 | i | (デモ切替スイッチ) | |
RB1 | o | 未使用(rx) | |
RB2 | o | 未使用(tx) | |
RB3 | o | 未使用(ccp) | |
RB4 | o | データ b0 | セグメントドライバー74LS47へ接続 |
RB5 | o | データ b1 | 同上 |
RB6 | o | データ b2 | 同上 |
RB7 | o | データ b3 | 同上 |
PIC16F648Aを使っても、端子が8つ余ります。アプリケーションで、これらの端子を使ってクロックを外部にするなり、入力ポートを付けるなりする余裕があります。ここではデモ切り替え用に端子を一つだけ使っています。
PIC16F648AのRB0は、内部でプルアップしてある端子で、ここをオープンにするか、ショートにするかでデモの動作を切り替えられるようにしてあります。
デマルチプレクサ74HC138の入力端子は開放に出来ないので、必要に応じてレベルを確定します。一応、G1をプルアップしましたが、直接、5vに接続してもかまいません。
また、74HC138の入力端子A B Cをプルダウンしています。PICが起動するまでの短い時間はポートが読み込みモードであるため、これらの端子の電圧が確定しません。CMOSの74HC138に不確定な入力は好ましくないということで、起動時の電圧をLに決めているわけです。短い時間なので、気にしなければ省略も可能と思います。TTLの74LS138ならば、プルダウン抵抗は不要なのですが…。
74HC138のアドレスとLEDの桁の対応は、アドレス:0が最下位桁になるようにしました。
74LS47の方は、Hに固定する端子はすべて開放のままにしてあります。より安定させる場合には、適当な抵抗(4.7kぐらい)でプルアップしてください。PICの起動時には、こちらもポートが入力モードなので、ハイインピーダンス状態(出力がない状態)となりますが、74LS47にとっては、入力がHということになります。都合の良いことにデータ入力がすべてH、つまり、16進のFの場合には、全消灯となるので、起動時に特定の桁が光ることはありません。(よく考えられてありますね、、74LS47)。
回路図中には書いてありませんが、PIC16F648A、74LS47、74HC138の電源とグランドの間には、0.1μFのパスコンを付けてください。また、電源は5VのACアダプタで十分ですが、これも、コネクタから受けたところに、10〜47μFの電解コンデンサを付けます。
実は、ここに書いた回路、とりあえず、実験するだけの回路です。きちんと考えると、結構面倒で、部品点数も増えてしまいます。トランジスタのエミッタ-ベース間に抵抗を入れたり、PICがなかなか起きないので、リセットを引き回したり…。特に桁指定の方は、74HC138の出力が同時にLになると、よろしくないので、きちんとイネーブルを入れなければいけないはず。自前の工作ならば、この辺は、実用的に問題なければOKなんですが、製品となると、その辺の考慮がしてあるはずです。
表示プログラムは、8バイトの「VRAM」領域を用意して、その下位ニブル(4ビット)にBCDデータがあるものとして表示します。具体的には、タイマー0を約2mSの周期で回し割り込みをかけて、「VRAM」一桁ずつ取り出し、表示をしています。上位桁から下位桁の順に表示し、このとき、ゼロサプレス処理も同時に行っています。8桁表示するのに都合16mSかかるわけです。
表示プログラムにデータを渡す、つまり、「VRAM」に書き込むときに、表示が乱れないように、表示禁止フラグの操作と桁カウンタの初期化を行うようにしています。
初めは固定データで試していたのですが、面白くないので、次の二つのデモプログラムを動かすことにしました。電源投入時に、PIC16F648AのRB0をオープンにすると最初のデモ、グランドに落としておくと二番目のデモを実行します。
プログラム中に、二つのサブルーチンvramDisp1、vramDisp2があります。vramDisp1はゼロサプレス処理をしないプログラムですが、使用していません。vramDisp2はゼロサプレスをするプログラムです。ゼロサプレスをやめる場合には、タイマー割り込みのvramDisp2呼び出し先をvramDisp1に変更してください。
プログラム(asm/hex)と回路図です。
ソースプログラム(07/10/20) | 7seg01.asm |
プログラムのHEX(07/10/20) | 7seg01.hex |
回路図(07/10/20) | 7seg01.pdf |
せっかく、ブレッドボードに8桁回路を配線したので、74LS47を使わない回路を実験したいと思います。桁アドレス用の74HC138も省くとすると、18ピンのPICだとピンの数が本当にギリギリ。他方、多ピンのPICはというと、手持ち在庫では28ピンではPIC16F873A、40ピンではPIC16F877A。アプリケーションで機能ピンを残したいなどと考えると、これらを使っても、やはり荷が重そうです。
結局、74HC138は使用することにするとなれば、実験用なので、PIC16F648Aで作っておけば、多ピンのPICにも流用できると判断しました。
74LS47を使った回路との大きな相違点は、74LS47が入力から「数字フォント」を作っていたので、これをPICの内部で代替することです。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | o | アドレス b0 | デマルチプレクサ(74HC138)へ接続 |
RA1 | o | アドレス b1 | 同上 |
RA2 | o | アドレス b2 | 同上 |
RA3 | i | SW1 | アプリケーション(モードスイッチ) |
RA4 | i | SW2 | アプリケーション(モードスイッチ) |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | アプリケーション(未使用) | |
RA7 | o | アプリケーション(未使用) | |
RB0 | o | セグメントA | LEDに接続 |
RB1 | o | セグメントB | 同上 |
RB2 | o | セグメントC | 同上 |
RB3 | o | セグメントD | 同上 |
RB4 | o | セグメントE | 同上 |
RB5 | o | セグメントF | 同上 |
RB6 | o | セグメントG | 同上 |
RB7 | o | セグメントdot | 同上 |
ピンの割り当ては左の通りにします。
セグメントの割り当ては実装に合わせるのが本当でしょうが、今回は実験用ということで順番に並べています。RB7はドットセグメント用に保留しておきます。
多ピンのPICに置き換えたとき、RBはそのまま移行できるので、この割り当てでいいかなと思っています。
アプリケーション用に残るピンは、四つ。ここではデモ用ソフトのモード切替にそのうち二つを使うことにしました。
74LS47を使用したときと同様に、8バイトのVRAMを用意して、それを表示するようになっています。デモは、スイッチの状態で動作が4通り選べます。
表示フォントは、一応、スクリプトで作りました。
SW | 端子電圧 | 機能 | |
---|---|---|---|
SW1 | On | Lo | ゼロサプレスなし |
Off | Hi | ゼロサプレスあり | |
SW2 | On | Lo | 数字のシフトデモ |
Off | Hi | カウントアップ |
フォントはEEPROMの先頭から格納してあります。標準でLS247と同じフォント。実際には、0x0a-0x0fまでの16進表記分だけ追加してあるので、都合16バイト。その後ろの10バイトにLS47と同じフォントも格納しました。EEPROM内で、この10バイトを先頭の10バイトに複写すれば、LS47と同じ表示になります。
表示のドライバー処理は二つ。
vramDisp1はゼロサプレスしないので、VRAMからインデックスされたフォントを表示するだけなので、EEPROMから任意のフォントを格納しておけば、最大256種類(当たり前ですね)表示できるようになっています。
vramDisp2はゼロサプレスするので、0-9のみをVRAMに格納して下さい。
今回の処理では、ドットセグメントもフォントと同様に扱っているので、ドット位置を制御するような小数点処理では多少の変更が必要です(リクエストがあれば、作成しますが…)。小数点が固定の場合は、該当する桁のドット端子を抵抗を介してグランドに落としておけば十分です。
実用的な応用でしたら、もう少し、大きなチップにすれば、ほとんど、このプログラムの修正で作成できると思います。また、桁が少なければ、HC138を省略して直接PICから桁選択を出してもよいでしょう。
PIC16F648Aでこの桁数で出来そうなのは、シリアル入力を使った表示器とかが考えられます。このときは、ピンの割り当てに応じてポートを動かす必要があるので、多少の変更が必要です。
プログラム(asm/hex)と回路図です。
ソースプログラム(07/10/27) | 7seg02.asm |
プログラムのHEX(07/10/27) | 7seg02.hex |
回路図(07/10/21) | 7seg02.pdf |
ようやく、本題に戻って、PIC-MIDICV用のチャンネル表示器。4ビットを読み込んで二桁で表示。チャンネル指定はは0から始まるのすが、表示自体は1から始まるようにします。ICの使用はPICのみに抑えたい。サイズやお値段を考えて、やはり、PIC16F648Aを使用します。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | i | データ b1 | チャンネル指定スイッチ |
RA1 | i | データ b0 | チャンネル指定スイッチ |
RA2 | o | 桁指定 1 | 一桁目トランジスタ |
RA3 | o | 桁指定 2 | 二桁目トランジスタ |
RA4 | i | SW | モードスイッチ |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | i | データ b3 | チャンネル指定スイッチ |
RA7 | i | データ b2 | チャンネル指定スイッチ |
RB0 | o | セグメントA | LEDに接続 |
RB1 | o | セグメントB | 同上 |
RB2 | o | セグメントC | 同上 |
RB3 | o | セグメントD | 同上 |
RB4 | o | セグメントE | 同上 |
RB5 | o | セグメントF | 同上 |
RB6 | o | セグメントG | 同上 |
RB7 | o | セグメントdot | 同上 |
ピンの配置を考えてみました。
桁指定は直接出して、トランジスタ経由でLEDのアノードコモンに接続します。データ入力用の端子が変則的なのは一応、実装を考慮して近接したピンに順番に配置したからです。PIC-MIDICVに接続した場合には、ラインの引き回しが長くなるとプルアップが必要かもしれませんが、これは、実装してから確認します。
セグメント出力は、順番は、まぁ、いいかということで、そのまま配置。抵抗を経由して、LEDの各セグメント端子に繋ぎます。
モードスイッチは、正論理/負論理の切り替えに使用。PIC-MIDICVは負論理ですから、通常はスイッチを省略してグランドに落としておきます。
いずれにしても、回路図が入らないほど単純になりますが、心配事がひとつ。電源容量の問題です。この回路だけで、100mA近く消費しそう。LEDが一つに10mA流しているので、これだけで、80mA。PIC-MIDICVでの5V電源のレギュレータの容量次第では大幅に不足しそうです。この点は、姑息にソフトウェアで対策することにしました。
PIC-MIDICVに接続する際には、RA0、RA1、RA6、RA7をチャンネル指定のDIPSWに接続。RA4をグランドに落とします。takedaさんのインプリメントのようにチャンネル切り替えが0-7ならば、7セグLEDは一桁で十分。このときはアノードコモン側のトランジスタの回路も一つでよいことになります。
プログラムは8桁表示で作った処理を元に修正の予定です。
問題になるのは入力データのサンプリングタイミングですが、レベル入力なので、適当でいいかなと思っています。チャッタリングの処理とか、遅れの対策、表示乱れ対策はなしで考えます。
当然、桁は、ダイナミック表示。省電力のために、ちょっと、工夫をしようと思います。実験してきた8桁表示では、桁切り替えで十分な輝度が出ていました。ということは、10mAでデューティ 1/8 で十分という。ならば、セグメントを分割して、別のタイミングで表示するようにすれば、いいわけです。二桁分で、16セグメントあるので、単純には1周期で2セグメントずつ点灯すればよく、この場合は。トータルで20mA程度。1/16で試して十分明るければ、10mA。
とりあえず、一度に1セグメントずつ点灯(デューティ 1/16)する版を作成しました。輝度も十分、ちらつきもありませんでした。消費電流をきちんと測っていないのですが、こんなものでしょう。
RA4は、入力データの論理を決めるもの。Lで負論理。Hで正論理。PIC-MIDICVでは負論理ですから、スイッチを繋がずにグランドに落としておけば充分です。
フォントは例によってEEPROMの先頭から格納してあるので、別のフォントが必要な場合は、ここを書き換えてください。「スクリプトのオモチャ」-「7segment LED Editor」で作成できます。
プログラムと回路図です。
ソースプログラム(07/10/28) | 7seg03.asm |
プログラムのHEX(07/10/28) | 7seg03.hex |
回路図(07/10/28) | 7seg03.pdf |
最初のバージョンで省電流プログラムを書いたのですが、よく考えてみると、通常流す電流は最大でも常に10mA。つまり、アノードコモンをドライブするためのトランジスタがなくても十分にドライブできるはずです。
この方法の欠点は、プログラムを間違えると(あるいは暴走すると)PICが破壊される恐れがあることです。つまり、その1は安全な版、その2はちょっと冒険している版ということになりますね。
早速、勇気を持って、回路とプログラムに手を入れてみました。
ピンの割り当てや、プログラムの仕様は、PICでMIDIチャンネル表示(その1)と同じです。
プログラムと回路図のみを掲載します。
ソースプログラム(07/10/29) | 7seg04.asm |
プログラムのHEX(07/10/29) | 7seg04.hex |
回路図(07/11/01) | 7seg04b.pdf |
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | o | データ b0 | チャンネル出力 |
RA1 | o | データ b1 | チャンネル出力 |
RA2 | o | データ b2 | チャンネル出力 |
RA3 | o | データ b3 | チャンネル出力 |
RA4 | i | SW | チャンネル切り替え |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | 桁指定 1 | 一桁目LEDコモンへ |
RA7 | o | 桁指定 2 | 二桁目LEDコモンへ |
RB0 | i/o | ロータリースイッチ/セグメントA | ロータリースイッチ/LEDに接続 |
RB1 | i/o | ロータリースイッチ/セグメントB | 同上 |
RB2 | i/o | ロータリースイッチ/セグメントC | 同上 |
RB3 | i/o | ロータリースイッチ/セグメントD | 同上 |
RB4 | i/o | ロータリースイッチ/セグメントE | 同上 |
RB5 | i/o | ロータリースイッチ/セグメントF | 同上 |
RB6 | i/o | ロータリースイッチ/セグメントG | 同上 |
RB7 | i/o | ロータリースイッチ(セグメントdot) | ロータリースイッチ |
これがとりあえずの目標。ボリュームを使った例を考えていたのですが、8チャンネルだけならロータリー・スイッチで実現できそう。ICもPICだけで何とかなりそうです。
ロータリー・スイッチは、切り替え数が多くなると、意外に高額。その意味でも8チャンネルは、コストを考えると限界です。
回路のベースは、上の、「PICでMIDIチャンネル表示(その2)」。1−8チャンネルと9−16チャンネルをスライドスイッチなどで選択できるようにして、これは、RAのどれかに接続。いままでのチャンネル指定読み込みの分が今回は出力。セグメントの桁指定と合わせてRAポートの割り当てをプログラムを組みやすいように考え直したい。
ロータリースイッチの入力は、LEDのセグメント出力用のRBポートを入出力兼用にして使います。LEDの桁指定を切った状態でポートを読み込めば、LEDのちらつきも無く扱えるので出来そう。ただ、ロータリー・スイッチにあまり電流を流せそうに無いのが一抹の不安ですが、これは、実際に試してから。
ロータリー・スイッチは秋月の1回路12段(@150)。これは、軸のカバーを外してストッパーを差し込むと2段から11段まで回転範囲を限定できるものです。
要になるのは(といっても大したものではないのですが)、セグメントLEDへの出力とロータリスイッチ入力の兼用回路。詳しくは、掲載予定の回路図を見ていただくとして、ポートのピンから一つは、電流制限用の抵抗を介してLEDのカソードに接続。ポートのピンからはもう一本。抵抗二本を直列にして電源に繋ぎます。この二本の抵抗の中間をロータリスイッチの端子に接続します。
ロータリースイッチは、セレクトした端子がグランドに落ちるようにして置きます。
出力の場合、ロータリースイッチがオンの時は、二本の抵抗の真ん中がグランドに落ちて、ポートのプルダウン抵抗のように見え、オフの時には二本まとめて電源に繋がるのでプルアップのように見えます。
入力の時には、LEDのアノードをLowにしておけば、よくあるダイオードによる保護回路のように見え、ただのスイッチ入力となります。
PICでは普段はLEDへの出力を行い、スイッチをセンスする場合にだけ、ポートを入力に切り替えて値を読み込みます。
PIC16F648Aを内蔵クロックで動かしているのは、前傾の表示回路と同じ。タイマー0の割り込みは、およそ、1mSの周期に設定しました。この割り込み毎に二桁あるセグメント、16個を順番に表示します。丁度、小数点に当たるときに、RBポートを入力切り替えて、スイッチのスキャンをしています。このため、スイッチ・スキャンの周期は、およそ、8mS。
スイッチ・スキャンでは、チャタリング対策で、連続して同じ値を読んだ場合のみ、値を有効にしています。また、ロータリー・スイッチを回している途中に、全部のスイッチがオフになる場合がありますが、このときは、値を無効にしています。
電源投入してから、初めて値が確定するまで、およそ、16mSかかるので、本来ならば、値の有効をホスト(PIC-MIDICV)側に知らせる必要があるのですが、「電源を入れてからちょっと待て」でよいかと思い省略しています(というか、ピンの余裕がない)。同様にホスト側とのリセットタイミングの同期なども取っていません。
掲載したのは、単独でブレッドボードの上で動作確認した段階のものです。
回路図上では、電源のコンデンサや、パスコンは省略してあります。
ホスト(PIC-MIDICV)からの引き回しによっては、ボードに電源を引き込んだところに10-47μFの電解コンデンサを付けた方がいいかもしれません。
また、PIC16F648Aの電源端子とグランド端子に近接したところに0.1μFの積層セラミックコンデンサを必ず付けてください。
ソースプログラム | 7seg05.asm |
プログラムのHEX | 7seg05.hex |
回路図 | 7seg05.pdf |
昔、マイコンの時代にソフトを作るときに、練習用として必ず書いたのが、8クイーンのプログラム。丁度表示に8*8の盤面が必要なので、8*8ドット・マトリックスLEDを使って、見ながら実行できないかと考えました。
問題になるのは、8*8ドットLEDの点灯に必要な端子の数。ダイナミック点灯を前提に行、列それぞれ8本ずつ、都合16本必要になります。また、列か行のいずれかは、一度に沢山のLEDが繋がるので、PICのピンの電流量がちょっと心配。ドライブ用にトランジスタを用意することになりそうです。
ドライブ側は一度に全部オンさせず、順番に1本ずつオンさせることになるので、ドライバ内臓のデマルチプレクサがあればよいのですが、ちょっと、入手しにくいしのが難点。ドライバ+デマルチプレクサ+PICでは、チップが三つになってしまう。もう少しピンの多いPICにすれば、デマルチプレクサは省略できるのですが…。ちょっと思案のしどころです(AVRが呼んでいる?)。結局お値段で決めるのかなぁ。
とりあえず、手持ちのICで、考えると、ドライバーはTD62083(秋月@50円)。反転入力のシンクドライバー。つまり、論理Hでオンになって電流引き込み。入力の制限抵抗も入っているのでお得。
となるとデマルチプレクサは、3-8デコーダーで、出力論理がHのもの。手持ちから選ぶと、74HC238(鈴商@50円)が相当します。
単色のドットLED(BU5004-R。秋月@90円)を使うので、LEDのアノード側に電流制限抵抗(抵抗アレイ2個。千石@20円)を介して接続するのが8本。ピックの3本の出力(安全のためにもう1本いるかな?)をデマルチプレクサ→ドライバーでLEDのカソード側に接続。都合11本で足りるので、18ピンのPIC(PIC16F648A。秋月@200円)でも動作可能。余ったピンは、操作用の入力などに使える予定。
LEDのVFは2Vぐらいで、10mAぐらい流せそう(実測していませんが…)。電源を5Vとすれば、電流制限抵抗は、300オームで丁度 10mA( (5-2)V / 300Ω = 0.01A )。手持ちの抵抗アレイからこれに近い値を選びます。
ピン数の大きなPIC、例えば40ピンのものを使った場合、ICの数を減らせそうなのですが、結局、ドライバーのICは減らせそうにありません。RAW側の出力は、デマルチプレクサ74HC238を使用せず、直接PICで出力するのですが、ポート当たりの電流の制限が25mA。これで同時に8個のLEDが点灯する可能性があるので、LED一つに割り当てる電流は3mAとなってしまいます。これで十分な輝度がちょっと期待できません。
コスト的には、PIC16F648A+74HC238と、多ピンPICのお値段の関係。前者が、およそ、250円程度。作り始めたときには、これに匹敵するものが無かったのですが、最近の秋月のラインナップだと、いくつか候補がありそうです。
20ピンの16F690は@210。ただし、ポートが生き別れになる。
40ピンの16F914は@300で少々高いが、ストレートに組めます。
騎士巡回のプログラムもデモンストレーションで作成しようとしていたのですが、実行時間や、見せ方の問題があって、公開は見送ることにしました。
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | O | アドレス 0 | HC238へ接続 |
RA1 | o | アドレス 1 | 同上 |
RA2 | o | アドレス 2 | 同上 |
RA3 | o | ||
RA4 | o | (OD) | |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | (xtal) | |
RA7 | o | (xtal) | |
RB0 | o | COLUMN 0 | LEDのコラム端子に接続 |
RB1 | o | COLUMN 1 | 同上 |
RB2 | o | COLUMN 2 | 同上 |
RB3 | o | COLUMN 3 | 同上 |
RB4 | o | COLUMN 4 | 同上 |
RB5 | o | COLUMN 5 | 同上 |
RB6 | o | COLUMN 6 | 同上 |
RB7 | o | COLUMN 7 | 同上 |
このアバウトな状態で簡単な手書き回路図を見ながらブレッドボードに組んだところ、表示テストはあっさりと動いてしまいました。この状態で、8クイーンのプログラムを組み込みました。せっかくだから、あとで遊べるようにキー入力などを付けようかと迷っています。
ポートは余っていないのですが、出力ポートを切り替えて、せこく入力と兼用にすると、結構な数のスイッチ入力を付けられるます。また、内蔵クロック(4MHz)で試したのですが、セラロックで20MHzにして速度も稼ぎたい気もするし、と、ハードウェアはちょっとフィックスできない状態です。
下に掲載したのは、入力機能無しの場合の、言わば基本回路です。
今回使った88ドットのLEDは、秋月で購入した赤単色のBU5004-R。ROW(行)とCOLUMN(列)8本ずつの入力があり、内部では格子状に線が走り、列と行の交点にドット一つ分のLEDがあります。今回のものでは、アノードがCOLUMN、カソードがROWに接続されているタイプ。例えば、COLUMN3からROW4へ電流を流すと、座標(3,4)が点灯します。
ROWの信号は、PICから3本のアドレスとして、HC238へ送られ、そこで8本の単線に分解。この中の1本だけがHIになります。これが、NPNトランジスタアレイのTD62083を経由してLEDのROWのどれか一つがほぼグランドレベルとなります。TD62083はトランジスタが8個とベース用の電流制限抵抗などがついていて、ちょっと、お得。サージ保護の端子がありますが、今回は電源に吊っておけば十分です。
COLUMNの信号は、PICから電流制限抵抗を介して与えられます。ROWで選択された行の、ここがHIになったLEDが点灯します。
プログラムは、定期的にROWのアドレスを0-7と順にスキャン、そのとき、PICのRBnで該当する行のデータを出力すれば表示できます。
回路図には描いてありませんが、各ICのグランドと電源の近くには、0.1μF程度の積層セラミックコンデンサを入れておきます。
プログラムは、とりあえず、8Queenの盤面上のQueenを表示しながら、解を求めていくもの。解が見つかるとちょっとの間停止します。暫定版なので、凝った処理はしていません。素直に実行するとあまりに速いので、30mSの待ち時間を挟んでいます。
Queen(ドット)のスキャンは左上隅から行っています。
回路図(07/11/02) | 88dot01.pdf |
プログラムのソース(07/11/15) | 88dot01.asm |
プログラムのHEX(07/11/15) | 88dot01.hex |
現状の回路をベースにキー入力用の回路を追加しました。HC238でデコードした単線信号をスイッチ経由で一本にまとめ、PICに入力するというもの。まじめに組めばマルチプレクサ、あるいは、ラインセレクタのICを使うところですが、楽をしてダイオードで済ませました。心配なのは電流を余り流せないことと、容量性負荷での遅れですが、試作したところ大丈夫なようです。
配線量は、ICでもダイオードでも同じくらい。ダイオードは、小信号用のものなら何でも良いでしょう。ここでは秋月で売っている1N4148を使っていますが、これは、まとめて買うと1本1円、都合8円。ICならば100円程度。コストの違いがダイオードを使う理由です。
このダイオードを使った回路(回路図参照)は、入力が一つでもHIならば、出力がHIになるというもの。スイッチがオフならばその入力は無効。スイッチがすべてオフならば出力はLOです。結果的にHC238の出力がHIになっているラインのスイッチのオン・オフを出力に反映してPICのポートに入力します。
プログラムは、ドットLEDのための各ROWのタイミングで、入力がHIならば、該当スイッチがオンであると判定します。デコードした信号は8本あるので、入力ポート一つ当たり8個まで設置できます。
入力ポートはRA3を使用しました。
プログラムは、電源オンでキースキャンしながら待機。ここで、SW0(HC238のY0に接続)をオンにすると8Queenを実行します。
キーを検出する動作は割り込みの中。割り込み1回でスイッチ一つ読み込み、8回で八つのスイッチすべてが確定します。チャッタリング対策として、確定した結果が二回続けて同じ場合、これをキーの状態として保存しています。
回路図(07/11/16) | 88dot01b.pdf |
プログラムのソース(07/11/16) | 88dot01b.asm |
プログラムのHEX(07/11/16) | 88dot01b.hex |
信号 | i/o | 用途 | 備考 |
---|---|---|---|
RA0 | O | アドレス 0 | HC238へ接続 |
RA1 | o | アドレス 1 | 同上 |
RA2 | o | アドレス 2 | 同上 |
RA3 | i | キー入力 | キー入力 |
RA4 | o | ブザー | (OD)プルアップしてブザーへ |
RA5 | i | MCLR_N | リセット端子。 |
RA6 | o | (xtal)予約 | |
RA7 | o | (xtal)予約 | |
RB0 | o | COLUMN 0 | LEDのコラム端子に接続 |
RB1 | o | COLUMN 1 | 同上 |
RB2 | o | COLUMN 2 | 同上 |
RB3 | o | COLUMN 3 | 同上 |
RB4 | o | COLUMN 4 | 同上 |
RB5 | o | COLUMN 5 | 同上 |
RB6 | o | COLUMN 6 | 同上 |
RB7 | o | COLUMN 7 | 同上 |
キー入力の反応音を出したり、8Queenの解を表示するときに音を出すなど、ブザーがついていると便利。一番簡単なのは自励式のブザーを付けること。この場合はポートをオンにするだけで固定周波数の音が出ます。ところが、手持ちの発音体は、他励式のセラミック振動子。これを使うとなると、発振音を自前で用意する必要があります。PICの内部で作ってポートを周期的に揺すればいいのですが、PICは意外なことにこれが苦手。
良くあるのは、タイマーが周期を任意に設定できて、これが自動的に外に出るようになっている構成なのですが、PICの場合は、タイマーの割り込みなどで意図的にポートに書き込むのが普通の方法。あるいは、CCPのPWMを使うぐらいです。CCPはRB3に割り当てられているので、ちょっと、今回は見送りたい。
そこで、安易に、RA4にセラミック振動板を接続し、LED表示の割り込みのタイミングでオンオフすることにしました。これだと、500Hzぐらいになるので、セラミックの共振周波数を大きく下回っているので音量が心配なのですが、試して音が出れば良しとします。
出力ポートのRA4はオープンドレインのポートなので、プルアップ抵抗が必要、その代わり、今回は使いませんが、ちょっと高い電圧で動作させることが出来ます。RA6、RA7ならば普通のポートなので、抵抗が一つ省略できるけれど、ここは、セラロックのクロック入力と兼用。ひょっとして、将来、外付けのセラロックで20MHz動作をさせるかもしれません。そこで、最後まで空けておきたい。で、やむなく、RA4を使うことになりました。
ということで、早速、プログラムを変更し、発音体を繋いだところ、無事に発音しました。
発音体によって、音量が相当違います。プラスチックの筐体に入っているものは、そのままでも、そこそこ音量が出ますが、振動板のみのものは、しっかりと固定しないと音量が足りません。振動板を使う場合は、ケースなどに固定すれば使えそうです。今回は、安易に筐体入りのものを使いました。
発音体と平行に繋いでいるダイオードは、安心のための、逆起電流対策で、本来ならば、ショットキー・ダイオードを使うところ。また、セラミック振動体のドライブ回路は、セラミック振動体によって異なるのでご使用になる振動体のデータシートをご参照下さい。
周波数に関しては、手持ちのものをいくつか調べたところ、小さい振動体では、やはり、音量が足らず、この場合には周波数を数倍にする必要がありそうです。
なお、秋月で販売されている「圧電スピーカー」SPT08(@50)を試したところ、現在の回路のままで動作しました。
プログラムは、前回と同様。電源投入後、SW0(HC238のY0に接続)をオンにすると8Queenを実行します。解が見つかるたびに、ちょっと停止して、ブザーを鳴らします。
回路図(07/11/22) | 88dot01c.pdf |
プログラムのソース(07/11/22) | 88dot01c.asm |
プログラムのHEX(07/11/22) | 88dot01c.hex |
一応、この段階で基板に組んでみようと思います。
基板は2枚にして、一枚はパネルボード。LEDとスイッチ、ブザーを載せます。もう一枚は回路部分。これを背中合わせに接続してケースに入れル予定です。セラロック用の端子は空いているので、この際だから、20MHz版への変更も検討予定。実装に合わせて回路図を作らなければいけません。
せっかく作った8x8LED。もう少し、遊んでみる予定です。
手始めに考えているのは、アニメーション。わずか、8x8なので、どこまでできるか楽しみです。
階調表示ができれば、それなりに、表現力が加わると思うのでこれを試すことが一点目。
アニメーションデータの製作と書き込み環境構築が二点目。
順次、暇を見ながら、試して行きたいと思います。最終的には、ハードウェアを作り直すことになるかも。
三色で1チップのLEDが手元にいくつかあるのですが、結構、使い道がない。つまり、面白そうと思って手に入れただけで、終わっています。
寝せていても、仕方がないので、簡単な実験キットを作って遊んでみようと思いました。
3ヴォリュームで、RGBのそれぞれの輝度を決定し、PWMで三色それぞれをコントロール。色の変化を試してみようということです。何の役にも立たないし、面白くないかもしれないんだけど…
時間的な変化は、秒当たり30フレーム確保できれば良いとすれば、30mS程度の周期で十分だし、精度もそれほど要求しない。となれば、PWMはソフトで処理することにして、汎用のポート出力でOK。一方、ヴォリュームはADで読み込めばよい。
となると、汎用出力ポートが三つ。AD変換入力が三つ。数だけで言えば、8ピンのPICで足りそうだけれど、リセット端子が入力にしかならないので、8ピンでは難しそうです。18ピンから選ぶとするなら、PIC16F716がADも四つ付いていて、お値段も秋月で@110とお手軽なので、これを使おうと考えています。