RobotRobotのページ書籍も多く、入門用のマイコンとしてよく使用される秋月のH8/3052において、多足歩行ロボット用のサーボーモーターを24軸(最大40軸)まで制御するためのプログラムについて、説明します。ハードウェアではなくソフトウェアに依存した手法です。C言語なんで、そこそこジッターもあって微妙ですが、利点としては「とにかく簡単!」それだけが取り柄です!ポート1〜3にサーボモータの信号が出るんで適当に取り回しすればすぐ使えます。仕様は1.50と変わってません。ループを展開して少し高速化。公開開始24軸制御のしくみ一般的なPWMを利用したサーボモーターは20msに一度600μ〜2300μsの信号で制御されます。いうことは、余裕を持ってひとつのサーボの制御信号が2500μsとしても、20msで8回、8個分のサーボの信号を作り出すことが出来ます。いうわけで、ここではコンペアマッチ割り込みを利用したソフトウェア制御のPWM発生方法について考えます。24軸ということで、使用するタイマの数は24÷8=3で、3つです。図では1つのタイマのみを取り上げているので、実際はこの図が3つあるものと考えてください。ギザギザのイメージはカウンタを時間軸に合わせてカウントアップしているところを表します。Modulation)の項目で見かける図なんですが、馴染みのない人はそういうもんだと思って、ちょっと本等を覗いてみてください。ここでは、PWMが何なのかということは言及しませんので、知りたい人は詳しくはTekuRobo工作室さんの「PWMでモーター制御」(http://homepage1.nifty.com/rikiya/software/106pwm1.htm)あたりを参考にしてください。次のビットを上げ(0→1)、コンペアマッチでまた倒す。その繰り返しの無限ループでサーボに必要なPWMパルスを汎用I/Oポートから発生させます。パルスの長さを決めるGRBレジスタの値についてはカウンタクリアの瞬間に次のサーボの値に更新します。どのビットを上げるか、またどのサーボの値をGRBに代入するかの判断は、カウンタ変数をインクリメント(1増やすこと)して数えましょう。8個のサーボに信号を送ったら次は1番目のサーボに戻ります。1/1,000,000秒)という単位を聞くとものすごく早い気がして、「本当に扱えるの?」という気分になりますが、マイコンにしてみると、人間が「いーち、にー、さーん・・・」と数えるようなもんなので、理論を順番に考えていけば、絶対に理解できますので、あきらめずにとにかくソースを読んでみてください。サーボの信号線を接続するだけです。ポートとサーボの間に100Ωくらいの抵抗を入れるといいかもしれません。補足ですが、割り込みを使用して汎用ポートから信号を出していますが、PortAからは8個の信号を合成した信号が出力されています。このプログラムにおいてPortAは、I/Oとして使用できないということだけ覚えておいてください。応用で40軸まで対応させる現在、ITU(インテグレーティッドタイマユニット)を0〜2まで使用していますが、残りの3,4を使用することで、最大8×5=40個のサーボを制御することが出来ます。ソースに関しては、基本的にコピペで対応するITUを増やせばOKです。操作するビットは適宜空いているビットを使用してください。当然ですが、この場合ジャイロやロータリーエンコーダーなど、入力系に使えるITUがなくなります。ITU3,4を使用した場合、PortBも使用できなくなります。基本的な使い方メイン関数のなかでinitPWM関数を呼び、startPWM関数を呼べばサーボに信号が流れます。pulse3[x]を書き換えることで、サーボの角度が変化します。基本のソースを載せますと・・・。0;}これを実行するとPort1のBit0に接続したサーボが動きます。ポジションに関してはサーボにより個体差がありますが、KONDOのサーボ、GWSのサーボ、JRのサーボに関しては2000〜7000の範囲で稼働域の最小から最大まで動きます。具体的な数字はサーボに合わせて調整してみてください。強調している13,14,15行目の部分を自由にプログラミングすることで、サーボの制御が自由自在に行えます。脱力したいときにon_off_pwm(0)、再びトルクオンしたいときにon_off_pwm(1)を実行することで、遠隔操作による緊急時の脱力等に対応します。割り込みを使用してシビアな時間管理をしていますので、この他に割り込み(シリアル受信割り込み・AD変換割り込みetc)を使うとジッター(ゆらぎ)が発生しサーボがプルプルしてしまいますが、これは仕様です。ソフトではなくハードでカバーすれば問題ないでしょう。割り込みをいっぱい使いたい人はこちらをお勧めします。ロボットを制御することは、PWM波を出すことが目的ではないので、その部分で悩むようなら、シリアル制御のサーボに移行することをオススメします。initPWM(void);PWMの初期化関数プログラムの一番初めに呼び出します。