はじめに
WR-XX制御基板は、合計で20個のサーボモータを同時にコントロールできますが、シリアル通信でコントロールデータを送信します。通信の仕組みそのものは単純ですので、サーボモータを一つだけ操作するモジュールを作ってみました。
この基板は、PICを2個使って制御をしていますが、PIC側のソースコードまでは公開されていません。したがって、制御コマンドの仕様は「WR-XX 通信プロトコル ガイド(第2版)」からの情報に限られます。
サーボ制御出力コマンド(コマンド 6)
WR-XX基板に接続されたサーボモータの動作を制御するコマンドです。
各サーボごとの回転位置の指定、移動速度(全て同一となります)、コマンドを受信してからの動作開始までの時間などを指定することができます。
(中略)
モータの指定は連続の番号でしか行えません。M0~M4,M10,M15の分だけといった飛び飛びの指定はできません。
WR-XX基板はこのコマンドを受け取ってもPCへの返信は何も行いません。
使い方の概要
今回制作したプログラムでは、サーボモータの動作はコマンドライン引数で指定します。
[ファイル名] [目標値 M0] [移動速度] [待機時間]
目標値 :約160°を220分割して指定します。
移動速度:15段階。MG90Sは、0.1秒/60° 1.8kgf・cm(4.8V)で動作するようです。
待機時間:15ms~3.3秒(220段階)
(例)サーボモータ M0 のみを 110 の位置へ速度10、待機時間15msで移動します。
$ gcc WR-XX_motion-script.c
$ ./a.out 110 10 1
ソースコード
/***********************************************************************************************************
* WR-XX Motion Script for Linux ver. 0.1.2
* Author : Lian Ivvakanni (12-19-2020)
* License: Dual BSD/GPL (with absolutely no warranty.)
* Purpose: send return message to Wonder Roid Motion Maker V3.1.1
***********************************************************************************************************/
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/ioctl.h>
# include <fcntl.h>
# include <termios.h>
# include <unistd.h>
# include <string.h>
# include <stdio.h>
# include <stdlib.h>
/* change this definition for the correct port */
# define MODEM_DEVICE "/dev/ttyS8"
# define BAUD_RATE B38400
/* command item number */
# define M 32
/* buffer size */
# define N 32
int main(int argc, char *argv[]) {
int fd, i;
struct termios tio;
char s[N], buf[N], ret[M][N];
/* Command 5: A/D status dummy data */
char com_6[M] = {0xFD,0x07,0x06,0x01,0x0F,0x6E,0xFE};
/* target position: approx 160° */
if(atoi(argv[1]) > 0 && atoi(argv[1]) <= 220)
com_6[5] = atoi(argv[1]);
else
com_6[5] = 0x00;
/* velocity */
if(atoi(argv[2]) > 0 && atoi(argv[2]) <= 15)
com_6[4] = atoi(argv[2]);
else
com_6[4] = 0x0A;
/* wait time 15ms/1 */
if(atoi(argv[3]) > 0 && atoi(argv[3]) <= 220)
com_6[3] = atoi(argv[3]);
else
com_6[3] = 0x01;
/* set return data */
for(i = 0; i <= 7; i++)
ret[i][2] = i + 0x10;
/* clear structure for port settings */
memset(&tio, 0, sizeof(tio));
/*
BAUDRATE: 38400 bps
CS8 : 8bit,no parity,1 stopbit (8n1)
CLOCAL : local connection, no modem contol
CREAD : enable receiving characters
*/
tio.c_cflag = BAUD_RATE | CS8 | CLOCAL | CREAD;
/* Open modem device for reading and writing */
fd = open(MODEM_DEVICE, O_RDWR);
if (fd < 0) {perror(MODEM_DEVICE); exit(-1);}
/* clean the modem line and activate the settings for the port */
tcflush(fd, TCIFLUSH);
ioctl(fd, TCSETS, &tio);
write(fd, com_6, M);
close(fd);
return 0;
}
おわりに
コマンドラインで使うなら、デバイスの指定もできるようにしたいところですが、関数として使用するにはちょうどいいかな、という感じでの仕上がりになっています。本当のところ、やっと、ここまで来たな・・・と感無量です。
次は、サーボモータ二つを使ったプログラムに挑戦します。
あとは、サーボモータの「トルク」という数値が現実の世界でどのような役割を担って働くのかよくわかりませんので、今後、ちゃんと調べておこうと思います。