[再掲]PICで電飾はじめの一歩 その5 点滅パターンの作成 その1
ソフトとハード
前回までの作業でLED点滅回路が完成しました。点灯消灯のパターンを変えるにはどうするか、また複数のLEDを制御するにはどうするか、が今回のテーマです。
今回小見出しの字を青と緑に分けています。青はPIC固有の機能にかかわる内容で、緑は一般的なC言語にかかわる内容です。
PICを学ぶ初心者にとって辛いのが、ソフトの知識とハードの知識を平行して学ばないといけないということです。
ソフトとしてここで使うのはC言語ですが、PIC固有の機能を設定したり、動かしたりするための独自の用語用法があって、C言語だけ勉強してもPICを使えるようにはなりません。
PICの機能の一覧はマクロチップ社のHPから見られるデータシートに全て載っているのですが、これだけ見ても何のことやらさっぱりです。
PICを学ぶのに一番効率的なのが人の作ったものを真似しながら、手を動かして少しずつものにすることです。
問題は人のプログラム例を見てわからないところがあった時、初心者にはそれがC言語の本をあたるべきなのか、PICの資料をあたるべきなのかすらわからないということがあることです。
そうした問題を少しでも低減するために色を分けてみました。
GP* :足の番号
開始する前に、手元の回路のPICの上に紙テープか何かを貼って、写真のように番号をつけてください。右下2番めから時計回りに0,1,2,3,4,5です。
この番号がPICでLEDを制御するときの足の番号です。12F683の制御プログラムの中では「GP+番号」と書きます。違うPICだと番号や名前が違ってきますのでその都度確認してください。
手元の回路では0番の足にLEDが繋がっているはずです。つまりGP0の足です。
では前回のプログラムを見返してみましょう。前の方はPICのどの機能をどう使うかの設定ですが説明は省略します。LEDの点滅に関係するのは最後のこの部分だけです。
プログラム上でGP0=1;と書くと、0番の足にPICへの入力電圧と同じ電圧がかかります。PICに5Vをかけているなら同じ5Vです。この電力でLEDが点灯します。
次の行の__delay_ms(500); は、500ミリ秒待て、という意味です。msはミリセカンドです。500ミリ秒ですから0.5秒ですね。
LEDの消灯はGP0=0; と書いてやります。これで0番の足にかかる電圧が無くなります。消灯後、また__delay_ms(500);で0.5秒待ちます。
( )の中の数字を変えてやれば、点灯時間と消灯時間を自由に変えることが出来るわけですね。試してみてください。
while文
点灯、消灯をコントロールするブログラムの前後に
while(1)
{
}
というフレーズがありますがこれはwhile文と呼ばれます。
while(条件文) {実行内容}
という形式を持っていて
( )内の条件を満たしている間は{ }内の作業を繰り返しなさい
という意味を持っています。
特に条件はなくいつでもずっと点滅を繰り返して欲しい、というときは括弧の中に1を入れます。
したがって上のプログラムは、GP0に電圧をかけて0.5秒待ち、電圧カットして0.5秒待ち、を無条件で繰り返しなさい、というプログラムになっているわけです。
これでプログラムの基本的な構造は分かりました。するともうかなりのことができてしまいます。例えば2つのLEDを交互に点滅させたいなら、1番の足にもLEDをつけてやります。ブレッドボード上ならば17列目のa行のところに抵抗入りLEDのプラスを挿します。
抵抗が入っていないLEDをお使いの場合、LEDがひとつの時と同様に、列をまたいで抵抗を付け、その先にLEDを付けてください。
その上でプログラムに
while(1)
{
GP0=1;
GP1=0;
__delay_ms(500);
GP0=0;
GP1=1;
__delay_ms(500);
}
赤字の行を足してください。0番に電圧をかけている間は1番は休み、0番が休んでいる間は1番に電圧をかける、を繰り返すことで2つのLEDが交互に点滅します。
書き足すときは、行の最後にセミコロン「;」を書くのを忘れないで下さい。これがないとどこが区切りなのかコンピュータは理解できません。
逆に言えば、セミコロンを入れれば改行やスペースを入れなくても大丈夫です。{}の中を
GP0=1;GP1=0;__delay_ms(500);
GP0=0;GP1=1;__delay_ms(500);
こんなふうに書いても、動作は同じです。
GPIO
0番、1番と同じ調子で2番、4番、5番の足も使うことができます。それぞれGP2、GP4、GP5ですね。ただしGP3だけは使えません。3番の足はリセットもしくは信号入力専用だからです。
LEDを5個もつけると、GP何番、GP何番といちいち点灯消灯の指示を個別に出すのが面倒になってきます。そんな時はGPの親玉、GPIOという制御方法を使います。例えば5番と0番のLEDだけ点灯、後は消灯させたい時、こう書きます。
GPIO=0b00010001;
最初の2文字、0bは「今から2進法で説明するよ」という宣言です。C言語では他に8進法、10進法、16進法で書く事ができますが、PICの制御という点では2進法でやるのが一番初心者向きだと思います。
残りの8桁を使って足のコントロールをするのですが、PIC12F683には入出力に使える足は6本しかないので、0bに続く2桁の00は無視されます。(足がもっと多いPICではこの上位2桁も使用されます)
残りの6桁がそれぞれの足に対応します。今は1桁目と5桁目に1を入れました。この文はつまりGP0とGP5に出力をしろという意味になります。
ナイトライダー
これを使って、LEDを5個並べて、ナイトライダーのボンネットのランプのように、左右に点灯を動かす回路とプログラムを作ってみましょう。
まずはブレッドボードにLEDを5個並べましょう。GP2はさっきの2個のLEDの隣に挿せますが、GP4、GP5の足は反対側なのでそうは行きませんね。もちろんブレッドボード上での作業は試運転みたいなものなので本当に模型に組み込む時と同じ順番に並べる必要はありませんが、試運転もなるべく本番に近い感じで眺められたほうが動作の感じがつかみやすいのではないでしょうか。
ここでは写真のようなジャンパ線を使って、GP4、GP5からの電圧を反対側に回すことにします。
こんな感じです。GP4からの電圧をオレンジの線で10列のbに持って行き、10列のaにからLEDにつなぐ、GP5からの電圧を緑の線で9列のbに持って行って9列のaからLEDにつなぐ、という形でやっています。
気を付けて欲しいのがPICへの書き込み用のグレーの線が接続されている12列目や13列目に繋がないで欲しいということです。
グレーの線はPICへのプログラム書き込みの時以外は仕事をしていませんが、電気は通ります。
下の写真のようにオレンジの線を12列目に繋いでしまうと、グレーの線を通じてGP0とGP4が繋がってしまいます。当然、期待したように動いてくれなくなります。
ブレッドボードの準備ができたので今度はプログラムです。まず全部消灯させて少し待つ行を作ります。
GPIO=0b00000000; __delay_ms(500);
これをコピペして8行作り、点灯する桁に1を入れてゆきます。
GPIO=0b00000001; __delay_ms(500);
GPIO=0b00000010; __delay_ms(500);
GPIO=0b00000100; __delay_ms(500);
GPIO=0b00010000; __delay_ms(500);
GPIO=0b00100000; __delay_ms(500);
GPIO=0b00010000; __delay_ms(500);
GPIO=0b00000100; __delay_ms(500);
GPIO=0b00000010; __delay_ms(500);
上のプログラムにはGP3を点灯させるGPIO=0b00001000;がありませんね。先程述べたとおり、GP3は入力専用なので出力するように書いても無視されます。そもそもLEDを繋いでませんし、出力を指示してもしょうがないので飛ばすわけです。
上記の8行をwhile(1)以降 の{ }の中に入れてください。金槌ボタンでビルドして矢印ボタンでPICに書き込むと左、右、左と点灯が行ったり来たりするはずです。
というわけで、LEDの発光パターンの作成は実は、
1) PICの足にLEDをつなぐ。
2)GPIO=0b00xxxxxx;の点灯させたいLEDにつないだ足番号のxには1、消灯させたいxには0を入れる。
3)何秒光らせたいかはその直後の__delay_ms( )の括弧の中の数字で決める。
この3ステップだけで、どんなのでも作れるのです!
同時に発光させるLEDはいくつでも構いません。実はPICから供給される電流に上限があるので、必要電流が大きいLEDを何個も同時発光させようとすると無理が出てくるのですが、最近のLEDは数ミリアンペアで十分光るので、12F683につないだ分だけならほとんど問題は起きないでしょう。
というわけで発光パターンの作成はこつこつ
GPIO=0b00xxxxxx;__delay_ms();
を書き連ねていけばいいだけ、ではあるのですが、やっているうちにコピペで済むとはいえ同じような文を何度も書くのは面倒だと感じてくると思います。なにかもっとスマートな方法はないでしょうか。
また、複数の発光パターンを作って切り替えながら発光させるようなことはできないでしょうか。
プログラミング言語をもう少し詳しく知るとそうしたさらなる欲求に応えることができます。次回、いくつかLED発光パターンの制御に有用な構文について説明します。