電子工作

PICピカピカ

PICを使ったLEDを光らせます。このページで作ったのは下のとおりです。

よくあるピカピカを改造PIC16F84A12個のLED。輝度変調/振ると字の出る
MIDIでピカピカPIC16F648AMIDIで12個のLEDを制御
イルミネーション・ライン--LEDドライバ回路
74LS47をPICに接続する7セグ8桁表示PIC16F648A74LS47を使って
PICで7セグ8桁表示PIC16F648A74LS47を使わずにPICで表示
PICでMIDIチャンネル表示(その1)PIC16F648AMIDIチャンネル表示器
PICでMIDIチャンネル表示(その2)PIC16F648AMIDIチャンネル表示器。回路を節約版。
PICでMIDIチャンネル指定&表示PIC16F648AMIDIチャンネル表示器にチャンネル切り替え機能を追加。
8クイーン - 8x8ドットLEDを使って -PIC16F648A8x8ドット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 pin25 mA
Maximum output current sourced by any I/O pin25 mA
Maximum current sunk by PORTA80 mA
Maximum current sourced by PORTA50 mA
Maximum current sunk by PORTB150 mA
Maximum current sourced by PORTB100 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をそのまま流用します。

  1. PWMで輝度変調をしてみた。(新しいHexファイルです)

    ずらりと並んだLEDをPWMで輝度変調(明るさのコントロール)をしてみました。消灯状態から始まり、ゆっくりと明るくなり、段々と暗くなってから消灯。これを繰り返します。部屋の電気を消して眺めると、それなりに、雰囲気があります。

    実験をしてみると、明るさはPWMに対してリニアではなく、明るいほうはクリップ状態。LED時間的な応答性(なかなか消えない)の問題かと思います。

    プログラムでは、タイマー0をフリーランで走らせ、地面でタイマー0のカウントが現在の輝度情報よりも小さければポートに「1」、小さければ「0」を書く処理をしています。輝度情報の更新はタイマー0の割り込みの中。

    多少重くなるのですが、原理的には、この方法で全ビット独立の輝度調整ができるはず。

  2. 振ると字の出る。。。(Hexファイルです)

    PORTBに繋がっているLED8つを使って、基板を振ると文字列が見えるプログラムです。

    LEDが縦になるように基盤を持ち、ガイダンス用にPORTAの2ビットのLEDが交互に点滅するので、それに合わせて基板を左右に振ります(電源コードが切れないようにご注意!)。

    部屋を暗くして、うまく、同期するとかなりはっきりと文字列が見えます。ガイドLEDを見ていると文字列は見えません(ガイド専用のハードが無いので、仕方が無いですね)。

    表示する文字列はEEPROMに格納してあるので。プログラムをPICに焼きこむときに編集可能です。このとき、文字列の最後には0を付けて下さい。長さは最大64文字まで可能ですが、振ることを考えると、5〜10文字くらいが妥当でしょう。

    フォントは、0x20から0x5fまで、つまり、英数大文字+大体の記号が用意されています。

    予想していたよりも面白かったので、専用のハードを作るかも。となると、左右の振り方向を検出するセンサーが必要そう。加速度センサーをつけるとチープではなくなるので身の回りのものなどで何とか工夫してみたいです。


MIDIでピカピカ

しょうもないと思いつつ、MIDIでLEDを制御すれば、よくあるMIDIのシーケンサでイルミネーションパターンが組めます。暫定で作るものは一つのラインでLEDを一つつけるだけ。でも、ちゃんとドライバーをつければクリスマスツリー風のイルミネーションがちょっとは豪華になるはず。

とりあえずは、オクターブ内の11音に対応してノートオン・ノートオフで点滅させるという陳腐なものでスタートさせましょう。

まず、使うPICは、PIC16F648Aを考えてみました。これは、PIC-PSGでも、PIC-MIDICVでも使ったもの。面倒なMIDIのプログラムはそのまま流用できるのでというは、安易な考えです。。

つぎにピンの割り当てを考えなければなりません。どうも、一つ足りません。シリアルを使っている間でも、TXをGPとして使えればいいのですが…マニュアルを読んだ限りでは、SPEN(シリアルポート・イネーブル)にした時点で回路がシリアル出力に切り替わるようなのです。また、TRISB[1:2]は1にして入力モードにせよとあります。

16F648Aで試行錯誤中のピン割り当て
信号i/o用途備考
RA0oLEDC#
RA1oLEDC
RA2oLEDA#
RA3oLEDA
RA4oLEDG#プルアップ必要
RA5i(SW)入力用ポート1ビット。コンフィグで指定が必要。
RA6-xtalセラロック20MHz
RA7-xtal同上
RB0oLEDG
RB1-RXMIDI入力
RB2-TXMIDI出力(?)。USARTを使用しているときは、出力ポートにできない?。
RB3oLEDF#
RB4oLEDF
RB5oLEDE
RB6oLEDD#
RB7oLEDD

LEDの数を12にこだわっているのは、1オクターブが12音だから。同一の複数個のものを揃えれば、最大で120LED(10個の回路)をパラ接続で処理できます。シーケンサ側では異なるCPUを選ぶときには、オクターブを変えればいいわけです。

もちろん、外部に回路を設けてラッチすれば、一つのCPUで多くのLEDを使用できますが、コストや基板面積を考えると、CPUを増設した方が作りやすく、値段も安そうです。というわけで12個は守りたい線。

何か無いかと知恵を絞ると、

いっそのこと、シリアル入力をソフトウェアで処理することにすれば、ピンが一つ空きます。すると、648Aを使わなくてもいいじゃないかということにもなりそう。

余っている16F84Aにするかなぁ。もし、追試製作する方がいると、16F84Aは割高(秋月で380円)。

  1. シリアル入力をソフト処理にする。

    入力をRA5にすれば、ポートが二つ空きます。これならば、USARTがいらないので、PIC16F648Aを使う理由が無かったりしますが、いろいろ、考えあわせるとやはり、16F648Aになりそう。

    価格(秋月)秋月ライターの対応
    PIC16F648A200結局これ?
    PIC16F84A380値段が高い
    PIC16F628A200645Aよりプログラム容量が小さい
    PIC16F819A250値段が高い
    PIC16F57120×28P。安いけれど秋月のライターで書けない
  2. PIC16F648Aを内蔵クロック(4MHz)で使う。

    セラロックを繋いでいる端子を出力に振り返られるのでポートが二つ増えます。問題は、内蔵クロックの精度が悪いこと(1%誤差)と遅いこと(20Mの1/5)。速度的に間に合わなければ、MIDIの処理を地べたに放り出します。

  3. 上位のCPUを使う。

    USARTがついていて、28ピンの物などが良いのですが、いずれも、値段が高いです。16F873Aが秋月で400円。いっそのこと40ピンのPIC16F877Aにして大幅にLEDの数を増やしてしまう手もあります。

最初は、PIC16F648Aを内蔵クロックで使う。速度的にきつくなった場合には、他の手段もということにしました。ピンの割り当てを検討しなおします。

16F648Aで内部発信器を使った場合のピン割り当て
信号i/o用途備考
RA0oLEDC# (1:点灯 0:消灯 以下同)
RA1oLEDC
RA2oLEDB
RA3oLEDA#
RA4-LEDエラー表示。0:点灯 1:消灯
RA5iMCLR_Nリセット端子。
RA6oLEDD
RA7oLED#
RB0oLEDA
RB1-RXMIDI入力
RB2-TXMIDI出力
今回は使用しないがTXに割り当ててある。
RB3oLEDG#
RB4oLEDG
RB5oLEDF#
RB6oLEDF
RB7oLEDE

上の割り当てで、出力条件が違う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. チャンネルの指定:EEPROM 0 番地。

    チャンネル1ならば、0、チャンネル2ならば1といった具合で書き込みます。

    MIDI Channel12345678910111213141516
    EEPROM 0000102030405060708090A0B0C0D0E0F
  2. オクターブ指定:EEPROM 1 番地。

    表示するオクターブの一番下の音のノート番号を書き込みます。Cからはじめるためには12の倍数で書く必要があります。デフォルトは C3(60)で始まるオクターブなので、C3のノート番号60、16進で0x3Cが書き込まれています。

    ここに、0x80以上の値を書き込むと、どのオクターブの音が来ても該当する音が対象となります。この場合、重複の検査は行っていません。

    オクターブC-2C-1C0C1C2C3C4C5C6C7オクターブ無視
    EEPROM 1 000C1824303C4854606C80 - 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Ω)。

LEDのVf(V)
1.8301.8331.8341.8301.826
1.9571.9331.9071.9751.950
2.0732.0782.0772.0852.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)
47010.88.64
40010.810.05
33011.510.28
25012.210.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の数があると、輝度変調などは要らない感じです。クリスマス・イルミネーションのつもりならば、ソフトはこのままで良いようです。

ハードの方は、最終的にはコンパクトな方が良さそう。トランジスタの列をやめて、トランジスタ・アレイ(入力抵抗つき)を使って小さくしたものを最終的に作る予定です。


7セグLEDを使ったMIDIチャンネル表示器

アナログシンセの掲示板でPIC-MIDICVにチャンネル表示が欲しいという話題が出ていました。

色々検討したのですが、まずは、PIC-MIDICVへ与える4本のチャンネルセレクトから単純に表示する方法を考えてみます。

  1. セグメントドライバーのICを使う方法。

    BCD(10進)のセグメント表示用IC74LS47、あるいは、4511Bなどを使う方法です。takedaさんのインプリメントのようにチャンネルが8チャンネルまでならば、一桁で十分なので、この方法でも十分です。使用する7セグLEDが、アノードコモンならば、74LS47(シンクドライブ)。カソードコモンならば4511B(ソースドライブ)を使います。問題は、二点。

    1. PIC-MIDICVのチャンネルセレクトは負論理。74LS47/4511Bは正論理なので、このままならば、インバータが必要。あるいは、PIC-MIDICVにチャンネルを正論理で解釈するモードを加えるなどの工夫が必要。
    2. 内部の値をそのまま出力することになるので、表示の数値が1小さくなる。
      MIDIチャンネルが1の場合には、表示は0ということになります。
  2. PICをセグメントドライバーとして使用する。

    18ピンのPICを使うとすると、色々考えたけれど、結局、値段が一番安い16F648A。内蔵発振器を使うと使用できるIOは15本。チャンネルセレクトの読み取りに4本。セグメントのドライブに8本。二桁表示にするならば、桁のセレクト用に2本。都合14本でうまく収まります。

PICを使う案は、もう一ひねりすると、チャンネルセレクトのハードウェアの面倒を見るものも考えられます。

チャンネルセレクトに使う部品で色々な方法が考えられることになります。

  1. DIPSW

    当初は、動作時のチャンネル切り替えを考えていなかったので、普通のDIPSWを想定していました。この場合は、原案のまま。

  2. ロータリー式DIPSW

    回転式で値を選べるロータリー式のDIPSWがあるので、それを使えば、回すのがちょっと不便ですが、そのまま、使えます。お値段は100円から150円ぐらい。

  3. ロータリー・スイッチ

    回転式のセレクタを使って切り替える方法。takedaさんはこの方法で8チャンネル切り替えをなさってます。16チャンネルを直接切り替えるとなると、ロータリー・スイッチが高すぎ。上位(1-8)と下位(9-16)の切り替えスイッチを別に設ける方が良さそうです。ロータリスイッチからエンコードする機能と表示機能を合わせて実現したい。

  4. ヴォリューム(可変抵抗器)

    PICをADのあるものに変えれば、ボリュームの値を読むことで、チャンネルを指定できます。候補は、16F819とか、16F88。チャンネルセレクトの信号はPICから出力します。

    PIC-MIDICVの16F88版を作成すれば、済む話かもしれません。

  5. プッシュスイッチ

    チャンネルをプッシュスイッチで切り替える。ピンの数が足りないので、スイッチを一つだけにするか、LEDを一桁にするか。あるいは、外付けの回路を少し工夫するか…というところ。あるいは、ドット(小数点)を省くとかですね。

とりあえずは、7セグの表示方法に付いて、簡単なところから実験を進めてようと考えています。手持ちの7セグは、なぜか、すべてアノードコモン。そこで、アノードコモンの7セグ用の回路が対象となります。といことで、以降、7セグの表示実験をしてみました。


CPUを使わない7セグ表示

PICを使用しない回路の実験はこちらで行いました。74LS47の使い方実験です。74LS47のちょっとした使い方も書いてあります。


74LS47をPICに接続する7セグ8桁表示

ついでだから、74LS47をPICで使う実験をしてみようかと思います。74LS47を一つにして数桁表示する回路実験です。ダイナミック点灯なので、余り桁が多いと、ちらついたり、暗くなったりしそうです。

手持ちの7セグ二桁のLED(アノードコモン)が4つ、都合8桁分あるので、これを前提に回路を考えます。各セグメントの端子はすべて電流制限抵抗を介して74LS47に並列接続。各桁のコモン(アノード)に、PNPトランジスタ(ここでは2SA1015)を通して電流を流す。このトランジスタを順番に切り替えることで桁表示の切り替えを行います。トランジスタをトランジスタアレイに置き換えられれば良いのですが、残念ながら手持ちがありません。

トランジスタのベースは、同時に一つだけをLOWにします。正直にPICに繋ぐと桁数だけ必要になりますが、外部にデマルチプレクサを接続すれば、本数を減らせます。ここでは、八桁ですから、デマルチプレクサを使えば、3本で十分。もちろん、デマルチプレクサを使わなくても出来るので、状況に応じて判断。今回は、使ってみたい。

デマルチプレクサを決めます。機能的には3-8デマルチプレクサで出力論理がLのもの。74HC138になりそうです。こういう実験のときにはHCよりLSの方が空き端子の処理など気を使わなくて楽なのですが、手持ちがないので仕方がありません。

ハードウェア

PIC16F648Aは内蔵発振モードで扱うことにします。表示の実験なので、表示回路だけをドライブすることにして、表示データは適当にプログラムで作って試します。

16F648Aのピン割り当て
信号i/o用途備考
RA0oアドレス b0デマルチプレクサ(74HC138)へ接続
RA1oアドレス b1同上
RA2oアドレス b2同上
RA3o未使用
RA4o未使用(od)
RA5iMCLR_Nリセット端子。
RA6o未使用(xtal)
RA7o未使用(xtal)
RB0i(デモ切替スイッチ)
RB1o未使用(rx)
RB2o未使用(tx)
RB3o未使用(ccp)
RB4oデータ b0セグメントドライバー74LS47へ接続
RB5oデータ b1同上
RB6oデータ b2同上
RB7oデータ b3同上

PIC16F648Aを使っても、端子が8つ余ります。アプリケーションで、これらの端子を使ってクロックを外部にするなり、入力ポートを付けるなりする余裕があります。ここではデモ切り替え用に端子を一つだけ使っています。

PIC16F648ARB0は、内部でプルアップしてある端子で、ここをオープンにするか、ショートにするかでデモの動作を切り替えられるようにしてあります。

デマルチプレクサ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)。

回路図中には書いてありませんが、PIC16F648A74LS4774HC138の電源とグランドの間には、0.1μFのパスコンを付けてください。また、電源は5VのACアダプタで十分ですが、これも、コネクタから受けたところに、10〜47μFの電解コンデンサを付けます。

実は、ここに書いた回路、とりあえず、実験するだけの回路です。きちんと考えると、結構面倒で、部品点数も増えてしまいます。トランジスタのエミッタ-ベース間に抵抗を入れたり、PICがなかなか起きないので、リセットを引き回したり…。特に桁指定の方は、74HC138の出力が同時にLになると、よろしくないので、きちんとイネーブルを入れなければいけないはず。自前の工作ならば、この辺は、実用的に問題なければOKなんですが、製品となると、その辺の考慮がしてあるはずです。

ソフトウェア

表示プログラムは、8バイトの「VRAM」領域を用意して、その下位ニブル(4ビット)にBCDデータがあるものとして表示します。具体的には、タイマー0を約2mSの周期で回し割り込みをかけて、「VRAM」一桁ずつ取り出し、表示をしています。上位桁から下位桁の順に表示し、このとき、ゼロサプレス処理も同時に行っています。8桁表示するのに都合16mSかかるわけです。

表示プログラムにデータを渡す、つまり、「VRAM」に書き込むときに、表示が乱れないように、表示禁止フラグの操作と桁カウンタの初期化を行うようにしています。

初めは固定データで試していたのですが、面白くないので、次の二つのデモプログラムを動かすことにしました。電源投入時に、PIC16F648ARB0をオープンにすると最初のデモ、グランドに落としておくと二番目のデモを実行します。

  1. 0-9の数字の並びを右から左へとシフトする動作の繰り返し。
  2. カウントアップ動作

プログラム中に、二つのサブルーチンvramDisp1vramDisp2があります。vramDisp1はゼロサプレス処理をしないプログラムですが、使用していません。vramDisp2はゼロサプレスをするプログラムです。ゼロサプレスをやめる場合には、タイマー割り込みのvramDisp2呼び出し先をvramDisp1に変更してください。

資料

プログラム(asm/hex)と回路図です。

ソースプログラム(07/10/20)7seg01.asm
プログラムのHEX(07/10/20)7seg01.hex
回路図(07/10/20)7seg01.pdf

PICで7セグ8桁表示

せっかく、ブレッドボードに8桁回路を配線したので、74LS47を使わない回路を実験したいと思います。桁アドレス用の74HC138も省くとすると、18ピンのPICだとピンの数が本当にギリギリ。他方、多ピンのPICはというと、手持ち在庫では28ピンではPIC16F873A、40ピンではPIC16F877A。アプリケーションで機能ピンを残したいなどと考えると、これらを使っても、やはり荷が重そうです。

結局、74HC138は使用することにするとなれば、実験用なので、PIC16F648Aで作っておけば、多ピンのPICにも流用できると判断しました。

74LS47を使った回路との大きな相違点は、74LS47が入力から「数字フォント」を作っていたので、これをPICの内部で代替することです。

ハードウェア

16F648Aのピン割り当て
信号i/o用途備考
RA0oアドレス b0デマルチプレクサ(74HC138)へ接続
RA1oアドレス b1同上
RA2oアドレス b2同上
RA3iSW1アプリケーション(モードスイッチ)
RA4iSW2アプリケーション(モードスイッチ)
RA5iMCLR_Nリセット端子。
RA6oアプリケーション(未使用)
RA7oアプリケーション(未使用)
RB0oセグメントALEDに接続
RB1oセグメントB同上
RB2oセグメントC同上
RB3oセグメントD同上
RB4oセグメントE同上
RB5oセグメントF同上
RB6oセグメントG同上
RB7oセグメントdot同上

ピンの割り当ては左の通りにします。

セグメントの割り当ては実装に合わせるのが本当でしょうが、今回は実験用ということで順番に並べています。RB7はドットセグメント用に保留しておきます。

多ピンのPICに置き換えたとき、RBはそのまま移行できるので、この割り当てでいいかなと思っています。

アプリケーション用に残るピンは、四つ。ここではデモ用ソフトのモード切替にそのうち二つを使うことにしました。

ソフトウェア

74LS47を使用したときと同様に、8バイトのVRAMを用意して、それを表示するようになっています。デモは、スイッチの状態で動作が4通り選べます。

表示フォントは、一応、スクリプトで作りました。

SW端子電圧機能
SW1 OnLoゼロサプレスなし
OffHiゼロサプレスあり
SW2 OnLo数字のシフトデモ
OffHiカウントアップ

フォントは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でMIDIチャンネル表示(その1)

ようやく、本題に戻って、PIC-MIDICV用のチャンネル表示器。4ビットを読み込んで二桁で表示。チャンネル指定はは0から始まるのすが、表示自体は1から始まるようにします。ICの使用はPICのみに抑えたい。サイズやお値段を考えて、やはり、PIC16F648Aを使用します。

ハードウェア

16F648Aのピン割り当て
信号i/o用途備考
RA0iデータ b1チャンネル指定スイッチ
RA1iデータ b0チャンネル指定スイッチ
RA2o桁指定 1一桁目トランジスタ
RA3o桁指定 2二桁目トランジスタ
RA4iSWモードスイッチ
RA5iMCLR_Nリセット端子。
RA6iデータ b3チャンネル指定スイッチ
RA7iデータ b2チャンネル指定スイッチ
RB0oセグメントALEDに接続
RB1oセグメントB同上
RB2oセグメントC同上
RB3oセグメントD同上
RB4oセグメントE同上
RB5oセグメントF同上
RB6oセグメントG同上
RB7oセグメントdot同上

ピンの配置を考えてみました。

桁指定は直接出して、トランジスタ経由でLEDのアノードコモンに接続します。データ入力用の端子が変則的なのは一応、実装を考慮して近接したピンに順番に配置したからです。PIC-MIDICVに接続した場合には、ラインの引き回しが長くなるとプルアップが必要かもしれませんが、これは、実装してから確認します。

セグメント出力は、順番は、まぁ、いいかということで、そのまま配置。抵抗を経由して、LEDの各セグメント端子に繋ぎます。

モードスイッチは、正論理/負論理の切り替えに使用。PIC-MIDICVは負論理ですから、通常はスイッチを省略してグランドに落としておきます。

いずれにしても、回路図が入らないほど単純になりますが、心配事がひとつ。電源容量の問題です。この回路だけで、100mA近く消費しそう。LEDが一つに10mA流しているので、これだけで、80mA。PIC-MIDICVでの5V電源のレギュレータの容量次第では大幅に不足しそうです。この点は、姑息にソフトウェアで対策することにしました。

PIC-MIDICVに接続する際には、RA0RA1RA6RA7をチャンネル指定の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

PICでMIDIチャンネル表示(その2)

最初のバージョンで省電流プログラムを書いたのですが、よく考えてみると、通常流す電流は最大でも常に10mA。つまり、アノードコモンをドライブするためのトランジスタがなくても十分にドライブできるはずです。

この方法の欠点は、プログラムを間違えると(あるいは暴走すると)PICが破壊される恐れがあることです。つまり、その1は安全な版、その2はちょっと冒険している版ということになりますね。
 早速、勇気を持って、回路とプログラムに手を入れてみました。

ピンの割り当てや、プログラムの仕様は、PICでMIDIチャンネル表示(その1)と同じです。

プログラムと回路図のみを掲載します。

ソースプログラム(07/10/29)7seg04.asm
プログラムのHEX(07/10/29)7seg04.hex
回路図(07/11/01)7seg04b.pdf

PICでMIDIチャンネル指定&表示

16F648Aのピン割り当て
信号i/o用途備考
RA0oデータ b0チャンネル出力
RA1oデータ b1チャンネル出力
RA2oデータ b2チャンネル出力
RA3oデータ b3チャンネル出力
RA4iSWチャンネル切り替え
RA5iMCLR_Nリセット端子。
RA6o桁指定 1一桁目LEDコモンへ
RA7o桁指定 2二桁目LEDコモンへ
RB0i/oロータリースイッチ/セグメントAロータリースイッチ/LEDに接続
RB1i/oロータリースイッチ/セグメントB同上
RB2i/oロータリースイッチ/セグメントC同上
RB3i/oロータリースイッチ/セグメントD同上
RB4i/oロータリースイッチ/セグメントE同上
RB5i/oロータリースイッチ/セグメントF同上
RB6i/oロータリースイッチ/セグメントG同上
RB7i/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
プログラムのHEX7seg05.hex
回路図7seg05.pdf

8クイーン - 8x8ドットLEDを使って -

昔、マイコンの時代にソフトを作るときに、練習用として必ず書いたのが、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で少々高いが、ストレートに組めます。

騎士巡回のプログラムもデモンストレーションで作成しようとしていたのですが、実行時間や、見せ方の問題があって、公開は見送ることにしました。

8Queenを表示テストをしてみた

表示テスト版の16F648のピン割り当て
信号i/o用途備考
RA0Oアドレス 0HC238へ接続
RA1oアドレス 1同上
RA2oアドレス 2同上
RA3o
RA4o(OD)
RA5iMCLR_Nリセット端子。
RA6o(xtal)
RA7o(xtal)
RB0oCOLUMN 0LEDのコラム端子に接続
RB1oCOLUMN 1同上
RB2oCOLUMN 2同上
RB3oCOLUMN 3同上
RB4oCOLUMN 4同上
RB5oCOLUMN 5同上
RB6oCOLUMN 6同上
RB7oCOLUMN 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と順にスキャン、そのとき、PICRBnで該当する行のデータを出力すれば表示できます。

回路図には描いてありませんが、各ICのグランドと電源の近くには、0.1μF程度の積層セラミックコンデンサを入れておきます。

プログラムは、とりあえず、8Queenの盤面上のQueenを表示しながら、解を求めていくもの。解が見つかるとちょっとの間停止します。暫定版なので、凝った処理はしていません。素直に実行するとあまりに速いので、30mSの待ち時間を挟んでいます。

Queen(ドット)のスキャンは左上隅から行っています。

8x8LED基本回路
回路図(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回で八つのスイッチすべてが確定します。チャッタリング対策として、確定した結果が二回続けて同じ場合、これをキーの状態として保存しています。

8x8LEDキー入力付き
回路図(07/11/16)88dot01b.pdf
プログラムのソース(07/11/16)88dot01b.asm
プログラムのHEX(07/11/16)88dot01b.hex

音を出す

キー&ブザー付き版の16F648のピン割り当て
信号i/o用途備考
RA0Oアドレス 0HC238へ接続
RA1oアドレス 1同上
RA2oアドレス 2同上
RA3iキー入力キー入力
RA4oブザー(OD)プルアップしてブザーへ
RA5iMCLR_Nリセット端子。
RA6o(xtal)予約
RA7o(xtal)予約
RB0oCOLUMN 0LEDのコラム端子に接続
RB1oCOLUMN 1同上
RB2oCOLUMN 2同上
RB3oCOLUMN 3同上
RB4oCOLUMN 4同上
RB5oCOLUMN 5同上
RB6oCOLUMN 6同上
RB7oCOLUMN 7同上

キー入力の反応音を出したり、8Queenの解を表示するときに音を出すなど、ブザーがついていると便利。一番簡単なのは自励式のブザーを付けること。この場合はポートをオンにするだけで固定周波数の音が出ます。ところが、手持ちの発音体は、他励式のセラミック振動子。これを使うとなると、発振音を自前で用意する必要があります。PICの内部で作ってポートを周期的に揺すればいいのですが、PICは意外なことにこれが苦手。

良くあるのは、タイマーが周期を任意に設定できて、これが自動的に外に出るようになっている構成なのですが、PICの場合は、タイマーの割り込みなどで意図的にポートに書き込むのが普通の方法。あるいは、CCPのPWMを使うぐらいです。CCPはRB3に割り当てられているので、ちょっと、今回は見送りたい。

そこで、安易に、RA4にセラミック振動板を接続し、LED表示の割り込みのタイミングでオンオフすることにしました。これだと、500Hzぐらいになるので、セラミックの共振周波数を大きく下回っているので音量が心配なのですが、試して音が出れば良しとします。

出力ポートのRA4はオープンドレインのポートなので、プルアップ抵抗が必要、その代わり、今回は使いませんが、ちょっと高い電圧で動作させることが出来ます。RA6RA7ならば普通のポートなので、抵抗が一つ省略できるけれど、ここは、セラロックのクロック入力と兼用。ひょっとして、将来、外付けのセラロックで20MHz動作をさせるかもしれません。そこで、最後まで空けておきたい。で、やむなく、RA4を使うことになりました。

ということで、早速、プログラムを変更し、発音体を繋いだところ、無事に発音しました。

発音体によって、音量が相当違います。プラスチックの筐体に入っているものは、そのままでも、そこそこ音量が出ますが、振動板のみのものは、しっかりと固定しないと音量が足りません。振動板を使う場合は、ケースなどに固定すれば使えそうです。今回は、安易に筐体入りのものを使いました。

発音体と平行に繋いでいるダイオードは、安心のための、逆起電流対策で、本来ならば、ショットキー・ダイオードを使うところ。また、セラミック振動体のドライブ回路は、セラミック振動体によって異なるのでご使用になる振動体のデータシートをご参照下さい。

周波数に関しては、手持ちのものをいくつか調べたところ、小さい振動体では、やはり、音量が足らず、この場合には周波数を数倍にする必要がありそうです。

なお、秋月で販売されている「圧電スピーカー」SPT08(@50)を試したところ、現在の回路のままで動作しました。

プログラムは、前回と同様。電源投入後、SW0(HC238のY0に接続)をオンにすると8Queenを実行します。解が見つかるたびに、ちょっと停止して、ブザーを鳴らします。

8x8LED(Key & Buzzer)
回路図(07/11/22)88dot01c.pdf
プログラムのソース(07/11/22)88dot01c.asm
プログラムのHEX(07/11/22)88dot01c.hex

実装

一応、この段階で基板に組んでみようと思います。

基板は2枚にして、一枚はパネルボード。LEDとスイッチ、ブザーを載せます。もう一枚は回路部分。これを背中合わせに接続してケースに入れル予定です。セラロック用の端子は空いているので、この際だから、20MHz版への変更も検討予定。実装に合わせて回路図を作らなければいけません。


もっと8x8LED(予定)

せっかく作った8x8LED。もう少し、遊んでみる予定です。

手始めに考えているのは、アニメーション。わずか、8x8なので、どこまでできるか楽しみです。

階調表示ができれば、それなりに、表現力が加わると思うのでこれを試すことが一点目。

アニメーションデータの製作と書き込み環境構築が二点目。

順次、暇を見ながら、試して行きたいと思います。最終的には、ハードウェアを作り直すことになるかも。


三色LED(予定)

三色で1チップのLEDが手元にいくつかあるのですが、結構、使い道がない。つまり、面白そうと思って手に入れただけで、終わっています。

寝せていても、仕方がないので、簡単な実験キットを作って遊んでみようと思いました。

3ヴォリュームで、RGBのそれぞれの輝度を決定し、PWMで三色それぞれをコントロール。色の変化を試してみようということです。何の役にも立たないし、面白くないかもしれないんだけど…

時間的な変化は、秒当たり30フレーム確保できれば良いとすれば、30mS程度の周期で十分だし、精度もそれほど要求しない。となれば、PWMはソフトで処理することにして、汎用のポート出力でOK。一方、ヴォリュームはADで読み込めばよい。

となると、汎用出力ポートが三つ。AD変換入力が三つ。数だけで言えば、8ピンのPICで足りそうだけれど、リセット端子が入力にしかならないので、8ピンでは難しそうです。18ピンから選ぶとするなら、PIC16F716がADも四つ付いていて、お値段も秋月で@110とお手軽なので、これを使おうと考えています。

メニューへ戻る
アルゴ算法堂へ戻る