2016-01-15 22:40 | カテゴリ:1/8モデル
ちょっと横道になりますが、、、
CPU内蔵のLEDの制御のテストを行いました。

このLEDは、フライデーの胸の上部にある口にあたる所に内蔵させて、TVと同じように、喋るタイミングで点滅させようと思います。
TVでは、赤色(?)のランプが内蔵されて、点滅するようですが、私は、ここをフルカラーLEDで表現しようとの目論見です。
その為には、このCPU内蔵のLEDの色制御をマスターしなければなりません。

LED_Pic.jpg


このLEDは、いつもの秋月電子さんで購入したもので、電源端子とシリアルの入出力端子を備え、複数のLEDの出力と入力をイモズル式に接続して、PICなどで発光色をシリアル制御できる優れものです。
大型の屋外のLEDネオンサインに、派手な映像が高速で表示されている物を見かけますが、恐らくはこの様な制御方式のインテリジェントLEDが使用されていると、想像します。

さて、制御方法のポイントは、

1)シリアル方式で、1ビットをHとLのデューティー比であらわして、一つのLED当たり、RGBの8x3=24ビットを送信します。
具体的には、
0を送信=0.35マイクロ秒のHと1.36マイクロ秒のLを送出
1を送信=1.36マイクロ秒のHと0.35マイクロ秒のLを送出となります。
複数のLEDをイモズルで接続している場合は、手前のLEDのデータから、最後のLEDのデータまでを、連続して送信します。

CPULEDSpec.jpg



2)一連のデータの先頭をあらわす為に、50マイクロ秒の間、出力をLにします。

最初のLEDが一連のデータを受信すると、最初のLED用のRGBデータを自身の処理に使用し、後に続く他のLED用のデータは、そのままスルーして、後ろのLEDに転送します。
こうすることで、多数のLEDの点滅を制御できます。
ただし、多くのLEDを制御する場合は、最初のLEDと最後のLEDの表示には時間差が生じます。
この時間差は、シリアル転送のタイムラグですので、少なくする為には、転送スピードを高速にする必要があります。
実際、本LEDでは、1ビットあたり、1.7マイクロ秒かかります。
1LED当たりでは、1.7X24=40.8マイクロ秒
100個のLEDを接続した場合は、4m秒かかることになります。
趣味で使用する範囲なら、遅れはほとんど気にならないでしょう。

それでは、具体的な制御方法を考えて見ます。

上記の通り、制御にはスピードが要求されます。
PICを20MHzのクロックで動作させることを前提に考えると、PICのクロック周期は、0.05マイクロ秒。
基本命令の実行に要するクロックは、4クロックですので、0.05X4=0.2マイクロ秒。

えーー!!
送信1ビットのデータの長さが、1.7マイクロ秒なのに。
これではたった8命令しかなく、8命令でデータのシリアル制御をしなければなりません。
アセンブラ(機械語)の8命令です。
第一の関門は、この部分はかなりシンプルなアセンブラで工夫した処理にしなければなりません。

次に、データを用意する為の処理は、C言語の方が簡単なので、C言語の中に、アセンブラのシリアル送信処理を組み込まねばなりません。
これが第二の関門。

さらに、1ビットデータ処理のアセンブラ処理を24ビット分(あるいはそれ以上)繰り返すとなると、結構なアセンブラの記述量となり、大変です。

うー、気が重くなってきました。

ひょっとしたら、NETで先人の方々がきっと良いプログラムを開発されているのではと、ちょっとググッてみました。
アンドロイド系では、専用の関数が用意されていて、C言語から簡単に使えるようです。
PIC系では、特定のPIC16F1509などでConfigurable Logic Cell (CLC)をサポートしています。
しかし、手持ちのPIC16F877ではサポートされていません。

もう少し調べてみると、ノーマルのPICでアセンブラとC言語で制御関数を組み上げた方のWEBがありました。

「かしまのボヤキ天国」
というサイトになんとそのものずばりのプログラムがありました。

リンク

PICのXC8の関数の形で、所定のシリアル送信の処理が記述されています。
変更しなければならないのは、クロックが8MHzなので、それを20MHzに合うように修正すればよいだけです。
早速、これを参考にさせていただき、プログラムの修正を進めました。

処理を少し遅くすれば良いので、適当なところにNOP命令を挿入し、オシロで、目的のデューティー比になる様に試行錯誤します。
0.2マイクロ秒単位でしか調整できないので、もっともLEDの通信規格に近いところにします。
20MHzなら、私のソフトの通りでOKですが、違う周波数のPICで調整するにはオシロがないと面倒かもしれません。

結果、私の製作したプログラム(デモ表示)は、こんな感じです。

Prog1.jpg

この部分はXC8言語の決まった作法の様な部分ですので、さらっと。

Prog2.jpg

disp_rgbの関数を定義する最初の部分です。
このあたりはC言語で。


Prog3.jpg

C言語内に記述するアセンブラ部分です。
先の説明の通り、指示されたビットが0か1によって、送出するシリアル信号のHとLのデューティー比を制御する重要な部分です。
また、putbitというマクロ命令を定義しています。
このマクロ命令は、後で、繰り返し呼び出されて、実際にはPICメモリー上に展開されます。(サブルーチンとマクロは異なります)

Prog4.jpg

ここで、先に定義されたマクロを24回(8ビットx3色)呼び出しています。
結果、マクロ定義されたルーチンが24回繰り返してメモリーに展開されます。

Prog5.jpg

C言語のメインプログラムの定義です。
PICのポートCを出力用に設定します。
また、モニター用に付けたLEDを点滅させてPICの起動を確認できるようにしました。
フルカラーLEDは、初期設定で電源をつなぐと、薄い青色に光ります。
それを消灯させる為に、ゼロリセット信号を送っています。


Prog6.jpg

RGBそれぞれの8ビットデータを40飛びに変化させて、色を変えています。
8ビットの変数はCHAR型になっていますので、0-255まで扱えますが、きりの良いところで止めています。

早速、ブレッドボードにPICとLEDをセットしたテスト回路を作成しました。

DSC01710.jpg


LEDは、4本足。
電源の+とGND、シリアル入力と出力です。

DSC01711.jpg


この抵抗は、150Ωで、LEDの電源ラインに直列で入れました。(電流制限用で指定されていましたので)

DSC01712.jpg


で、動作中の動画を撮影しました。




まずは、LEDのテスト制御はなんとか成功しました。

管理者のみに表示する