RPU-10講座/第七章 とにかくサーボ動作
すいません m(_ _)m、本記事はブログ引越時に書式が崩れました。順次修正中です。
いよいよサーボを動作させます。やっとかい!って感じですが、なかなか全機能を紹介するのは大変でして…。RS301(他のRSシリーズも同様だと思いますが)、コマンド式サーボなので、PWMを送るのではなく、RS485によってデータを送信します。
仕様書はFUTABAのホームページからダウンロードすることができます。読んでいただければわかるのですが、なにやらおまじないみたいなデータを使ってRS301内のデータを書き換えるようなことをすればいいようですね。
■サーボを動作させる手順
GDLのライブラリでは、単にサーボを動かすだけならば簡単な関数が用意されています。これを使いますが、それなりのお作法というのがあります。まず、RS301、電源を入れた時点では、無力状態です。最初にトルクオンコマンドを送り、それから角度と動作時間を指示することで動作します。
余談ですが、SIPHA SYSTEM内では、動作時間、事実上、ほとんど使っていません。章が進んできたら、詳細に説明します。
RS301のトルク状態は3種類あります。指定値は「0:オフ、1:オン、2:ブレーキ」となっています。
オン、オフはわかるとして、ブレーキってのはなんだろう?という方もいらっしゃるかと思いますが、簡単に言えば「ほどよく動作抵抗があるけど自分からは動かない状態」という感じです。教示をする時に使えるモードです。これでトルクをオンにしておいて角度と時間を与えれば、すいーっとサーボが目標角度まで指定時間で動作します。
GDLのライブラリでは、以下の関数が用意されています。
short SV_TorqueOnOff( unsigned char *tbuf, unsigned char id, unsigned char mode );
short SV_Angle( unsigned char *tbuf, unsigned char id, short angle, short time );
この「tbuf」というのがよくわからなかったんですが、まあ、そういうものらしいので、適当に、RS485に載せるときに一番大きい状態になりそうなデータがまかなえるぐらいの大きさにしておくことにします。どっかで読んだ記憶だと256バイトが最大だそうですが、なんとなく255バイトが最大な気がします。
この2つの関数を使用すると、RS485でどのような通信を行う必要があるのか、考えずに指示を出すことができます。まずはサーボを動かしてみる、ということで、これらの関数を使用することにします。
■サーボとの通信について
先の「tbuf」はどれくらいのサイズを取るべきか?というところと関係するのですが、RS301にコマンドを送る場合、身のデータ以外に前後にデータがくっつきますので、プラス8バイトを見込まないといけません。で、後々、ロングパケットで角度と時間を一緒に送信しようとすると、それぞれのデータは2バイト、これにサーボIDが1バイトつきますから、全部で5バイトになります(小細工しても4バイト)。これをサーボ24個分送ったとすると、データサイズの総計は128バイトとなり、まあ、マイコン的に切りのいいところで256バイトもデータを取っておけば大丈夫、ということになります。
■サンプルプログラム
キー入力により、サーボID「1」のサーボの角度を変更します。SIMPLE TERMで接続しておき、「a」を入力すると数値の大きい方へ、「z」を入力すると数値の小さいほうへ10度ずつ動作します。このプログラムでは、最初、いきなり指示値を「0度」にしていますので、動作させるときは注意してください。RS301のサーボ出力軸にはポッチがついていますが、これが縦方向の上側(なんと表現したらいいんでしょう?)に向いているときが0度になりますので、事前に、その位置にしておくとスムーズにテストできると思います。
この起動時にいきなり動くという問題ですが、問題解決方法については、単に最初の動作だけ動作時間をゆっくりにしておく方法(RS301自身は、自分の角度を知っているので、ゆっくりとした時間で目標値を与えておけば、そこまでまったり動作します)と、指示前にRS301から角度情報を取り込むことでそこをプログラムの起点とするなどの方法がありますのが、取り込みについては「サーボ角度の取得」までお待ちください。
1: //—————————————————————————————-
2: // キーボード入力によってサーボを動作
3: // パソコン(シリアル端末)からの入力にて、サーボを動作させます。
4: //
5: // 環境 RPU-10、GDL V2.00
6: // 説明 ビルドされた本プログラムをRPU-10へ転送後、パソコン側で「SIMPLE TERM」(GDLに
7: // 同梱)などを使って通信速度115200bpsで通信ポートを開いてください。その後RPU-10
8: // を再起動するとプログラムがスタートし、キーボードから「a」、「z」を入力すること
9: // で、+10度、-10度ずつサーボを動作させます。
10: //
11: // AUTHORED BY SISO JUNK STDUIO
12: //—————————————————————————————-
13: #include <avr/pgmspace.h>
14: #include <avr/io.h>
15: #include <avr/interrupt.h>
16: #include <avr/eeprom.h>
17: #include <stdio.h>
18: #include <avr/boot.h>
19: #include <avr/wdt.h>
20:
21: #include <sv.h>
22: #include <rs.h>
23:
24: #include <../ATmega128/rs0_printf_P.c> // URART0用フォーマット(ROM用)
25:
26:
27:
28: int main( void )
29: {
30: short sAngle; // サーボ角度
31: unsigned char aucTBuff[256]; // RS485通信用バッファ
32:
33: RPU_InitConsole( br115200 ); // RPU-10ライブラリの初期化
34: SV_Init( br115200 ); // サーボ制御ライブラリの初期化
35: sei(); // 割り込み処理開始
36:
37: sAngle = 0; // 指示角度変数初期化
38:
39: // 起動メッセージの表示
40: rs0_puts_P( PSTR( “MOVE SERVO” ));
41:
42: // 1秒待つ(よく知らないけど必要らしい)
43: RPU_ResetTimerCounter();
44: while( RPU_GetTimerCounter10() < 100 );
45:
46: // サーボ(1)トルクオン
47: SV_TorqueOnOff( aucTBuff, 1, 1 );
48:
49: while( 1 ){
50: // 角度指示(100ms)後、100ms待つ
51: SV_Angle( aucTBuff, 1, sAngle, 10 );
52: RPU_ResetTimerCounter();
53: while( RPU_GetTimerCounter10() < 10 );
54:
55: // 値の表示
56: rs0_printf_P( PSTR( “SERVO DEGREE %d\n” ), sAngle );
57:
58: // RS232Cより入力を受け付け、角度指示変数を設定する。
59: switch( rs0_getc()){
60: case ‘a’:
61: if( sAngle < 1500 ) sAngle += 100;
62: break;
63: case ‘z’:
64: if( sAngle > -1500 ) sAngle -= 100;
65: break;
66: default:;
67: }
68: }
69:
70: return 1;
71: }
L47
この関数の実行により、ID=1のサーボのトルクをオンします。2番目の引数は「サーボID=1」を表し、3番目の引数はモードを表します。もしモードを「0」にすればトルクオフ、「2」にすればブレーキモードになります。
L50~L53
この関数の実行によりサーボに動作指示を与えます。この行は、「指定角度(sAngle)まで100msecで動作しなさい」という意味になります。初めてこの行が実行されるときは、sAngleは0ですから、プログラム起動直後、サーボ角度は0度になります。また、100msecで動作するよう指示していますので、プログラムの方も、同じように100msec待ちます。
実際のところ、この待ちを入れなくても、サーボは問題なく動作します。キーボードからの入力間隔が100msec以上空いていれば、待ち処理はあっても無くても同じことですし、もし、100msec以内に次の指示を出した場合、サーボはそれにしたがって、その時点から目標値まで100msecで動作するだけです。試しに待ち処理をはずしてみても問題はありません。
L68~L67
キーボード(RS232C)からの入力を受け付け「a」ならばsAngleを+100、「z」ならば-100します。RS301は、0.1度単位での指示が可能ですが、指示する場合、10倍した値で指示する必要があります。よって、「10.0度」動作させたい場合は、「100」を指示します。
■今回使用した関数
- short SV_TorqueOnOff( unsigned char *tbuf, unsigned char id, unsigned char mode )
サーボのトルクオン/オフを指示します。第1引数は通信用バッファ(まあ、256バイトも取っておけば十分でしょう)、第2引数はサーボID、第3引数はモードを指定します。モードは、0:トルクオフ、1:トルクオン、2:ブレーキモードとなっています。通常、ロボットを動作させる場合は、トルクオンとします。戻り値は調査していません。 - short SV_Angle( unsigned char *tbuf, unsigned char id, short angle, short time )
サーボの角度を指示します。第1引数は通信用バッファ、第2引数はサーボID、第3引数は角度を10倍した値で指定します。RS301の場合、±150度動作が可能ですので、指示できる値は「-1500~+1500」ということになります。戻り値は調査していません。
■サーボIDについて
RS301を購入すると、デフォルトでサーボIDは「1」になっています。そのため、うちで使っているマシーンでは、サーボID「1」は使わないようにしています。これは、サーボが故障した時に要らぬトラブルを避けるためです。もし「1」のサーボが2つ接続してしまったら、RPU-10やサーボが混乱してしまいます。そんなわけで、「1」は使わず、新しいサーボを取り付けたら「1」から必要なIDに書き換えるようにしています。
※注意:本BLOGにてRPU-10での再プログラミングについての情報を公開していますが、これらはSISOが個人的に再プログラミングを行った時の技術情報を整理して紹介しています。GDLへのRPU-10ライブラリ同梱については、Best Technologyさんのご好意で、趣味人への1つのチャンスとして同梱してくださっていると理解しています。そのため、RPU-10の再プログラミングについては、くれぐれもご自身の責任で、また、Best TechnologyさんやFUTABAさんに問い合わせたりすることの無いようにお願いいたします。
[…] RPU-10講座/第七章 とにかくサーボ動作 […]