ではインドアエアプレーンのスピードコントローラを実現するための基本的なプログラムを組んで ATtiny15L で実際にテストしてみよう。前回の PWM テストプログラムを参考にして、実際に使われる送信機からのスロットルパルス幅の変化を PWM 出力に変換する。
テストには Futaba の送信機を使い、スロットルは一般のスピードコントローラでの設定と同じリバース設定にする。スロットルスティックを一番下げた状態でパルス幅が狭く、一番上げた状態で最大幅となる。スロットルトリムを中央にセットした状態でパルス幅は約 950usec から 1750usec の範囲で変化する。変化幅は 800usec ということになる。この 800usec の変化幅を PWM 出力のデューティ比 0 から 100% に割り当てるプログラムを組むことになる。
スロットルのパルス幅は時々刻々変化するので、それに合わせて PWM 出力制御をしなければならない。取得したパルス幅を加工して PWM 制御レジスタに渡せばあとは更新するまで PWM 出力が継続する。従ってスロットルパルス幅を取得するためのプログラムがメインとなる。プログラムループステップ数も分解能を決める重要な要素となる。
スロットルパルス幅のカウントプログラムは以下のようになる。
loop: in temp, PINB ;ポートBから入力 sbrs temp, 2 ;入力が1なら次をスキップ rjmp loop lp0: in temp, PINB ;ポートBから入力 inc thr_cnt ;スロットルカウンターインクリメント nop nop nop nop nop nop nop sbrc temp, 2 ;入力がゼロなら次をスキップ rjmp lp0 ;このループ16ステップ(10usec)ATtiny15L の内蔵発振回路は 1.6MHz なので 1 ステップは 0.625usec(1/1.6usec) となる。一方スロットル幅のカウンターに使用するレジスタは 8 ビットなので、最大パルス幅カウント時でも 8 ビットに収まるようにしたい。フルスロットル時のパルス幅は 1750usec なので 10 分の 1 にすると都合がいい。ということでパルスカウントループは 10usec に設定した。つまり 16 ステップのループになるようにする。ということでステップ数を合わせるために nop を挿入。
これで 10usec 刻みで PWM 制御ができることになる。パルスの変化幅が 800usec になるので 80 ステップの分解能を持ったスピードコントローラが作れることになる。この分解能はいままでの PIC (内蔵発振回路使用)では実現できなかったほどきめ細かい。
.equ thr_l = 97 cpi thr_cnt, thr_l ;スロットルカウンター値とスロットルロー値を比較 brlo lp1 ;スロットルカウンター値がスロットルロー値以下ならlp1へ subi thr_cnt, thr_l ;スロットルカウンター値からスロットルロー値を減算 rjmp lp2 lp1: clr thr_cnt ;スロットルカウンターをクリア lp2: out OCR1A, thr_cnt ;PWM出力を更新さて、実際に計算通り動くかどうか ATtiny15L にプログラムを書き込んで受信機と接続し、その動作を確かめてみた。スロットル最スローからフルハイまできちんと PWM 出力動作をしていることが確認できた。横軸一目盛りが 50usec なので、 20KHz もの高速な PWM 動作をしていることがオシロの画像から確認できる。画像はスロットルを中にしたときの PWM 出力波形でデューティ比がほぼ 50% になっている。
こんなにも簡単に PWM 出力ができるなんて夢のようだ。ここまで勉強してきて初めて PIC を上回る機能を確認することができた。
このままでも FET をつなぐだけで即スピードコントローラとして使えそうだ。しかし今回のプログラムは送信機からの信号が途絶えてもそのまま出力し続ける。安全性を考えて一定時間入力が途絶えたら PWM 出力を停止する機能をウォッチドッグタイマなどを使って追加すればなおいい。
今回はアウトドア用受信機につないで動作テストを行った。このところ SM タイプの AVR でいろいろな実験を繰り返している関係で、変換アダプタをもう一つ作った。なかなか使い勝手がいいと自己満足している。