armadillo300のシリアルデバイス経由でプログラムによりサーボを動作させる.ここで,armadillo300のシリアルデバイスに接続する機器として以下のものがある.
- armadillo300のシリアルデバイス
- RS-232Cレベルの信号を扱うシリアルデバイスである.具体的には,-15V~15Vの範囲を扱い,論理0が+3V~+15V,論理1が-15V~-3Vである.
- AGB65-RSC
- シリアルポート経由で受けた指令を元にサーボを制御する機器である.この機器が扱うシリアルデバイスはTTLレベル信号であり,論理0が0V,論理1が5Vである.
- AGB65-232C
- RS-232Cレベルの信号とTTLレベルの信号には電圧互換がないため,変換処理が必要となる.AGB65-232CはRS-232Cレベルの信号とTTLレベルの信号の変換処理を行う機器である.
- サーボモータ
- 物体の位置などを制御量として目標値に追従するように自動で作動するモータ.
各デバイスの接続は図1のようになる
- 演習後は消すこと
- 演習用ディレクトリにて,プログラムファイルを作成し,コンパイル,実行を行うこと.
- コンパイル例:プログラムファイル:sample.c, 実行ファイル:sample
- gcc sample.c -o sample
- 実行
- ./sample
以下のように配列を定義して値を代入する.
unsigned char output[7] = {255,3,4,2,0,127,20};
各配列の値の意味は以下のようになる.
シンクロバイト(255) | RSCにデータの通信開始を知らせるデータで,常に「255」で始まる. |
ID(3) | RSCに設定された固有のID(AGB65シリーズを複数接続したときの判別用.RSCの場合,出荷時のIDは「3」.) |
送信バイト数(4) | 送信される命令の(バイト)数.シンクロバイト,ID,送信バイト数は数えない. |
命令1(2) | 個別サーボ駆動設定 |
命令2(0) | サーボ番号.0はRSC基板上のP0に対応 |
命令3(127) | 角度(min:0,max:255で,絶対位置を指定) |
命令4(2) | 指定した角度まで移動する速度(x15ms) |
この配列をシリアル送信する.
下記のプログラムを作成,実行してサーボの制御について学ぶ.
入力 in: 出力 out
- 0 ≦ in ≦ 255 : inに応じたサーボの角度
- 上記以外 : プログラム終了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | #include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SERIAL_PORT "/dev/ttyAM1"
int main(){
int fd;
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
if(fd < 0){
printf("%s doesn't open it\n",SERIAL_PORT);
return -1;
}
struct termios oldtio, newtio;
tcgetattr(fd, &oldtio);
newtio = oldtio;
/* 通信方式の設定・非カノニカル入力処理選択 */
newtio.c_iflag = IGNPAR;
newtio.c_lflag = 0;
/* read関数での文字待ちうけの設定 */
newtio.c_cc[VTIME] = 0; /* 値x0.1秒待つ */
newtio.c_cc[VMIN] = 1; /* 値の文字分だけ入力されるまで待つ*/
/* 通信速度の設定 */
cfsetspeed(&newtio, B9600);
/* シリアルデバイス初期化処理 */
tcflush(fd, TCIFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
/* サーボ指令の雛形 */
/* 個別サーボ駆動モード, サーボコントローラID:3, サーボ番号:0 */
unsigned char output[7] = {255,3,4,2,0,127,20};
/* input(入力):サーボへの角度指令:有効範囲0(0°)-255(180°) */
/* 入力が有効範囲内の間,サーボをコントロール */
int input;
while(1){
printf("input value from 0 to 255[-1:end]:");
scanf("%d", &input);
if(input < 0 || input > 255){ /* サーボコントロール終了 */
break;
}
/* output[5]がサーボへの角度指令 */
output[5] = (unsigned char)input;
write(fd, output, sizeof(output));
}
/* シリアルデバイス終了処理 */
tcsetattr(fd, TCSANOW, &oldtio);
close(fd);
return 0;
}
|
データの基本形は次の通り.[ ]内は1バイトを表す.()内は送りえる数値の範囲.
[シンクロバイト(255)] [ID(0-3)] [送信バイト数(1-14)] [命令1] [命令2] [命令3] ..
この時の各意味は以下の表となる.
シンクロバイト | RSCにデータの通信開始を知らせるデータで,常に「255」で始まる. |
ID | RSCに設定された固有のID(AGB65シリーズを複数接続したときの判別用.RSCの場合,出荷時のIDは「3」.) |
送信バイト数 | 送信される命令の(バイト)数.シンクロバイト,ID,送信バイト数は数えない. |
命令 | RSCに動作させたい命令.詳細は以下の表. |
命令の種類は以下のものがある.
命令値 | 動作 | 方向 | フォーマット |
---|---|---|---|
1 | 全サーボ駆動 | 送信 | [255][ID][長(14)][命令(1)][P0][P1]...[P10][P11][Speed] |
2 | 個別サーボ駆動 | 送信 | [255][ID][長(4)][命令(2)][サーボ番号][サーボ位置][Speed] |
3 | 全サーボパルス停止 | 送信 | [255][ID][長(1)][命令(3)] |
4 | 指定サーボパルス停止 | 送信 | [255][ID][長(2)][命令(4)][サーボ番号] |
5 | 180°モード | 送信 | [255][ID][長(1)][命令(5)] |
6 | 255解像度モード(default) | 送信 | [255][ID][長(1)][命令(6)] |
(*)[Speed]は指定したサーボ位置までにかかる時間.[Speed]×15ms.