SlideShare uma empresa Scribd logo
1 de 33
Baixar para ler offline
OpenCM IDE、OpenCM 485 EXP
を用いての Dynamixel Xシリーズ の制御
1
1. 前提条件 3
2. XL430-W250の設定について 4
3. Master/Slaveサンプルコードの説明 8
4. 同期制御サンプルコードの説明 17
5. TeraTermについて 23
6. シリアル通信サンプルコードの説明 25
2
1. 前提条件
環境が設定済みであれば、実施する必要はない。
未設定の場合は、下記の項目のリンクに従って設定を行う。
1.1. OpenCM IDE
   インストール、ドライバの設定が完了していること。
URL:​OpenCM IDE - ROBOTIS e-MANUAL
1.2. OpenCM9.04
初期設定が完了していること。
URL:​OpenCM9.04 - ROBOTIS e-MANUAL
URL:​Testing the Controller Control Table
1.3. OpenCM 485 EXPの接続
OpenCM9.04と、上記のボートと接続済みであること。
URL:​OpenCM 485 EXP - ROBOTIS e-MANUAL
1.4. Dnamixel
XL430-W250シリーズを使用していること。
URL:​XL430-W250 - ROBOTIS e-MANUAL
3
2. XL430-W250の設定について
サンプルコードを動作させるための設定を確認する。
2.1 確認手順
​以下のように​U2D2​、PC、Dynamixelを接続し設定が所望な値となっているかを確認す
る。
​R+ Maneger 2.0を起動し、 画面に従い設定を確認する。
DYNAMIXEL X​を選択する。
4
Update & Test​を選択する
Next​を選択する。
5
Next​を選択する。
Next​を選択する。
6
Next​を選択する。
3つの​XL430-W250​の以下の項目の設定を確認する。
1. 7 - ID → 1~3がそれぞれ割あたっていること。
2. 8 - Baud Rate(Bus) → 3(1Mbps)に設定されていること。
3. 11 - Operating Mode → 3(Position Control)に設定されていること。
4. 13 - ProtocolVersion → 2(Protocol 2.0)に設定されていること。
7
3. Master/Slaveサンプルコードの説明
Master/Slaveを用いてDynamixelの制御を行う。
  <動作概要>
・Button1が押されたらMaster/Slaveを入れ替える。
・MasterはLEDが点灯し、SlaveはLEDが消灯する。
  ・MasterのGoal PositionをSlaveのGoal Positionへ設定する。
  ・シリアルモニタにID 1、ID 2のGoal Positionを表示する。
以下、サンプルコード。
/* Dynamixel ID defines */
#define ID_NUM_1 1
#define ID_NUM_2 2
#define GLOBAL_ID 254
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_LED 65
#define DXL_GOAL_POS 116
/* OpenCM 485 EXP Defines */
#define BUTTON_1 16
/* Defines for parameter */
#define OFF 0
#define ON 1
#define PUSH_CNT 100
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
8
/* Global Variables */
Dynamixel Dxl(DXL_BUS_SERIAL3);
bool​masterMode = true;
/* setup */
void​​setup​() {
​delay​(​5000​); ​// Wait DXL boot
Dxl.​begin​(DXL_BAUD_RATE); ​// Set Baud Rate 56700
pinMode(BUTTON_1, INPUT_PULLDOWN); ​// Button1 enable
}
/* main loop */
void​​loop​() {
​unsigned​​long​goalPos[​2​];
​unsigned​​long​pushCnt = ​0​;
​// Get Button State
​while​(​digitalRead​(BUTTON_1)) {
pushCnt++;
}
​// Chattering control
​if​( pushCnt > PUSH_CNT ){
masterMode = !masterMode;
}
​// Get GoalPos
goalPos[​0​] = Dxl.readDword(ID_NUM_1,DXL_GOAL_POS);
goalPos[​1​] = Dxl.readDword(ID_NUM_2,DXL_GOAL_POS);
​//Output SerialUSB
SerialUSB.​print​(​"GOAL_POS ID1: "​);
SerialUSB.​println​(goalPos[​0​]);
SerialUSB.​print​(​"GOAL_POS ID2: "​);
SerialUSB.​println​(goalPos[​1​]);
9
​// Switch to MASTER/SLAVE
​if​(masterMode) {
Dxl.writeByte(ID_NUM_1, DXL_LED, ON); ​// ID1 LED ON
Dxl.writeByte(ID_NUM_2, DXL_LED, OFF); ​// ID2 LED OFF
Dxl.writeByte(ID_NUM_1, DXL_TRQ, OFF); ​// ID1 Trq OFF
Dxl.writeByte(ID_NUM_2, DXL_TRQ, ON); ​// ID2 Trq ON
Dxl.writeDword(ID_NUM_2,DXL_GOAL_POS, goalPos[​0​] ); ​// Set ID1
GoalPos
}
​else​{
Dxl.writeByte(ID_NUM_1, DXL_LED, OFF); ​// ID1 LED OFF
Dxl.writeByte(ID_NUM_2, DXL_LED, ON); ​// ID2 LED ON
Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON); ​// ID1 Trq ON
Dxl.writeByte(ID_NUM_2, DXL_TRQ, OFF); ​// ID2 Trq OFF
Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] ); ​// Set ID2
GoalPos
}
​delay​(​10​); ​// 10[ms]
}
10
3.1. 値の定義について
​サンプルコードで使用している定義に関しての説明を記載する。
/* Dynamixel ID defines */
#define ID_NUM_1 1
#define ID_NUM_2 2
#define GLOBAL_ID 254
ID_NUM_1 1​、​ID_NUM_2​は、各XL430-W250に割り当てられているID。
IDの重複が起きないように設定する。
GLOBAL_ID​は、全てのXL430-W250にアクセスできるID。
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
XL430-W250とOpenCM9.04間で使用するシリアルの設定。
本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_LED 65
#define DXL_GOAL_POS 116
Dynamixelには、ROM/RAMの領域が用意されており、各アドレスにアクセスして制御を行
う。ROM領域は、トルクが無効(‘0’)の場合に書き換えが可能で、トルクが有効(‘1’)の場合
は、書き込みがロックされる。
ここでは、今回使用するアドレスをピックアップして定義しておく。
アドレスの詳細は、以下の表を参照。
※Control Tableの値や位置は、機種ごとに異なるため確認が必要。
11
表1 XL430-W250 Control Table
Area Address Size
[byte]
Data Name Description Access initial
Value
RAM 64 1 Torque Enable Motor Torque
On/Off
RW 0
65 1 LED Status LED On/Off RW 0
... ... ... ... ... ...
112 4 Profile Velocity Velocity Value of
Profile
RW 0
116 4 Goal Position Target Position
Value
RW -
/* OpenCM 485 EXP Defines */
#define BUTTON_1 16
BUTTON_1​は、OpenCM 485 EXP のタクトスイッチ(Button1)のアドレス。
その他にも、以下のスイッチやLEDが使用可能。
図1 OpenCM 485 EXP LED、Button配置
12
表2 OpenCM 485 EXP アドレス配置
Name OpenCM9.04 I/O
Button1 16
Button2 17
LED1 18
LED2 19
LED3 20
/* Defines for parameter */
#define OFF 0
#define ON 1
#define PUSH_CNT 100
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
コード上で使用する数値を理解しやすいように、予め定義しておく。
DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。
本ケースでは、1Mbpsの3を設定する。
13
3.2. コードの動作について
サンプルコードの動作について記載する。
/* setup */
void​​setup​() {
delay(​5000​); ​// Wait DXL boot
Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps
pinMode(BUTTON_1, INPUT_PULLDOWN); ​// Button1 enable
}
setup​()​では、Dynamixelがブートするまでの待機時間、BaudRateの設定、OpenCM 485
EXPのButton1を有効にするための設定をそれぞれ行っている。
​// Get Button State
​while​(digitalRead(BUTTON_1)) {
pushCnt++;
}
​// Chattering control
​if​( pushCnt > PUSH_CNT ){
masterMode = !masterMode;
}
タクトスイッチでMaster/Slaveを切り替える。
チャタリングでの誤動作を防止するために、ある程度ボタンが押されたらMaster/Slaveを入
れ替える。
​// Get GoalPos
goalPos[​0​] = Dxl.readDword(ID_NUM_1,DXL_GOAL_POS);
goalPos[​1​] = Dxl.readDword(ID_NUM_2,DXL_GOAL_POS);
​//Output SerialUSB
SerialUSB.print(​"GOAL_POS ID1: "​);
SerialUSB.print(goalPos[​0​]);
SerialUSB.print(​" GOAL_POS ID2: "​);
SerialUSB.println(goalPos[​1​]);
14
ID 1とID 2 のXL430-W250から現在の​Goal Positionを取得し、
USBで接続経由で、PCへシリアル通信で値を送信する。
OpenCM IDEで Ctrl+Shift+Mを押すとシリアルモニターが起動し、
XL430-W250から取得した値が表示される。
図2 シリアルモニタ画面
15
​// Switch to MASTER/SLAVE
​if​(masterMode) {
Dxl.writeByte(ID_NUM_1, DXL_LED, ON); ​// ID1 LED ON
Dxl.writeByte(ID_NUM_2, DXL_LED, OFF); ​// ID2 LED OFF
Dxl.writeByte(ID_NUM_1, DXL_TRQ, OFF); ​// ID1 Trq OFF
Dxl.writeByte(ID_NUM_2, DXL_TRQ, ON); ​// ID2 Trq ON
Dxl.writeDword(ID_NUM_2,DXL_GOAL_POS, goalPos[​0​] ); ​// Set ID1
GoalPos
}
​else​{
Dxl.writeByte(ID_NUM_1, DXL_LED, OFF); ​// ID1 LED OFF
Dxl.writeByte(ID_NUM_2, DXL_LED, ON); ​// ID2 LED ON
Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON); ​// ID1 Trq ON
Dxl.writeByte(ID_NUM_2, DXL_TRQ, OFF); ​// ID2 Trq OFF
Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] ); ​// Set ID2
GoalPos
}
タクトスイッチが押されると、​masterMode​が切り替わる。
Dxl.writeByte(ID_NUM_1, DXL_LED, ON)​では、ID 1のLEDを点灯に設定している。
Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON)​では、ID 1のMotor TorqueをONに設定してい
る。
※TorqueをONに設定すると、ROM領域の書き込みがロックされる。
Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] )​では、ID 1のGoal Positionに
ID 2のGoal Positionを設定している。
また、​writeByte​は1Byteの書き込みで、​writeDwordは​4Byteの書き込みである。
使用する関数は、前記してある”表1 XL430-W250 Control Table“のsize[byte]に応じて使い分
ける必要がある。
※sizeが2Byteの場合は、​writeWord​を使用する。
16
4. 同期制御サンプルコードの説明
SyncWriteメソッドを用いてDynamixelの同期制御を行う。
  <動作概要>
・ID1~3のXL430-W250を同期させて動作させる。
・ID1,3は同じ向きに動作。ID 2は逆側に動作する。
以下、サンプルコード。
/* Dynamixel ID defines */
#define DXL_ID_1 1
#define DXL_ID_2 2
#define DXL_ID_3 3
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_LED 65
#define DXL_PROFILE_VELOCITY 112
#define DXL_GOAL_POS 116
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
/* Parameter Defines */
#define OFF 0
#define ON 1
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
#define PACKET_LEN 9
#define NUM_OF_DATA 2
#define DXL_NUM 3
/* Global Variables */
Dynamixel ​Dxl​(DXL_BUS_SERIAL3);
byte dxlId[DXL_NUM] = {
DXL_ID_1,
DXL_ID_2,
DXL_ID_3
17
};
word SyncVelocity1[PACKET_LEN] =
{
​//ID ,Profile Velocity
DXL_ID_1, ​100​, ​0​,
DXL_ID_2, ​100​, ​0​,
DXL_ID_3, ​100​, ​0
};
word SyncVelocity2[PACKET_LEN] =
{
​//ID ,Profile Velocity
DXL_ID_1, ​200​, ​0​,
DXL_ID_2, ​200​, ​0​,
DXL_ID_3, ​200​, ​0
};
word SyncGoalPos1[PACKET_LEN] =
{
​//ID ,Goal Position
DXL_ID_1, ​1024​, ​0​,
DXL_ID_2, ​1024​, ​0​,
DXL_ID_3, ​1024​, ​0
};
word SyncGoalPos2[PACKET_LEN] =
{
​//ID ,Goal Position
DXL_ID_1, ​0​, ​0​,
DXL_ID_2, ​2048​, ​0​,
DXL_ID_3, ​2048​, ​0
};
/* setup */
void​​setup​() {
delay(​5000​); ​// Wait DXL boot
Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps
​for​(​int​cnt = ​0​; cnt < DXL_NUM; cnt++) {
Dxl.jointMode(dxlId[cnt]); ​// Set Dynamixel ID
Dxl.writeByte(dxlId[cnt], DXL_TRQ, ON); ​// Set Trq on
18
}
}
/* main loop */
void​​loop​() {
​// Sync write
Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity1,
PACKET_LEN);
Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos1, PACKET_LEN);
delay(​1000​); ​// 1000[ms]
​// Sync write
Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity2,
PACKET_LEN);
Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos2, PACKET_LEN);
delay(​1000​); ​// 1000[ms]
}
19
4.1. 値の定義について
​サンプルコードで使用している定義に関しての説明を記載する。
/* Dynamixel ID defines */
#define DXL_ID_1 1
#define DXL_ID_2 2
#define DXL_ID_3 3
DXL_ID_1 ​、​DXL_ID_2​、​DXL_ID_3​は、各XL430-W250に割り当てられているID。
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_LED 65
#define DXL_PROFILE_VELOCITY 112
#define DXL_GOAL_POS 116
使用するアドレスを予め定義しておく。
アドレスの詳細は、”表1 XL430-W250 Control Table”を参照。
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
XL430-W250とOpenCM9.04間で使用するシリアルの設定。
本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。
20
/* Parameter Defines */
#define OFF 0
#define ON 1
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
#define PACKET_LEN 9
#define NUM_OF_DATA 2
#define DXL_NUM 3
コード上で使用する数値を理解しやすいように、予め定義しておく。
DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。
本ケースでは、1Mbpsの3を設定する。
PACKET_LEN ​では、送信する全てのデータ数を設定する。
本ケースでは、ID1~3と​Profile Velocity​or​Goal Position​の合わせた9になる。
NUM_OF_DATA ​では、1つのIDに対して送信するデータ数を設定する。
本ケースでは、​DXL_ID​と​Profile Velocity​or​Goal Position​の2となる。
DXL_NUM​では、使用するDynamixelの数を設定する。
21
4.2. コードの動作について
サンプルコードの動作について記載する。
/* setup */
void​​setup​() {
delay(​5000​); ​// Wait DXL boot
Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps
​for​(​int​cnt = ​0​; cnt < DXL_NUM; cnt++) {
Dxl.jointMode(dxlId[cnt]); ​// Set Dynamixel ID
Dxl.writeByte(dxlId[cnt], DXL_TRQ, ON); ​// Set Trq on
}
}
setup​()​では、Baudrateの設定、Jointモードの設定、トルクを有効にするための設定をそれ
ぞれ行っている。
/* main loop */
void​​loop​() {
​// Sync write
Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity1,
PACKET_LEN);
Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos1, PACKET_LEN);
delay(​1000​); ​// 1000[ms]
​// Sync write
Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity2,
PACKET_LEN);
Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos2, PACKET_LEN);
delay(​1000​); ​// 1000[ms]
}
メインの処理では、先にVelocityを設定し、Goal Positionを設定した契機で動作する。
Dynamixelでは、目標角度と速度を設定し簡単にモータの制御を行う事ができる。
22
5. TeraTermについて
OpenCM9.04とPCを用いてシリアル通信を行うために使用するツール。
5.1 のインストール&セットアップ
以下のURLからダウンロードし、インストールする。
​https://ja.osdn.net/projects/ttssh2/releases/
TeraTermを起動し、シリアル(E) を選択して使用する ポート(R): を選択する。
ポート名は、 ROBOTIS Virtual COM Port を選択する。
※Port番号は、使用する環境によって変わる。
23
OpenCM9.04と接続された後に、シリアルポートの設定を行う。
タブの 設定(s) → シリアルポート(E).... を選択すると以下の画面が開くので、
スピードを​9600​→​57600​へ変更する。
24
6. シリアル通信サンプルコードの説明
  ​​OpneCM9.04のUARTを使用して、PCとシリアル通信を行いDynamixelを制御する。
PC上では、TeraTermを用いしてコマンドのやり取りを行う。
※今回は、LN-101ではなく​U2D2​を使用して接続する。
<動作概要>
・wを押すと、​Goal position​を+100する。
・sを押すと、​Goal position​を-100する。
・Enterを押すと、設定した値でGoal Positionへ移動する。
以下、サンプルコード。
/* Dynamixel ID defines */
#define DXL_ID_1 1
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_PROFILE_VELOCITY 112
#define DXL_GOAL_POS 116
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
#define DXL_UART_BAUD_RATE 57600
25
/* Parameter Defines */
#define DXL_POS_MIN 0
#define DXL_POS_MAX 4095
#define DXL_POS_DEFAULT 0
#define DXL_VELOCITY_SPEED 200
#define POS_PARAM 100
#define ON 1
#define OFF 0
/* Global Variables */
Dynamixel ​Dxl​(DXL_BUS_SERIAL3);
int​pos = DXL_POS_DEFAULT;
void​​setup​(){
​// セットアップ待ち
delay(​1000​);
​// UARTの初期化
Serial2.begin(DXL_UART_BAUD_RATE);
​// UARTの割り込み設定
Serial2.attachInterrupt(serialInterrupt);
​// Dynamixelの設定
Dxl.begin(DXL_BAUD_RATE);
Dxl.jointMode(DXL_ID_1);
Dxl.writeByte(DXL_ID_1, DXL_TRQ, ON);
Dxl.writeDword(DXL_ID_1, DXL_PROFILE_VELOCITY, DXL_VELOCITY_SPEED);
​// コマンドの説明
Serial2.println(​"----push key----"​);
Serial2.print(​"w : +"​); Serial2.println(POS_PARAM);
Serial2.print(​"s : -"​); Serial2.println(POS_PARAM);
Serial2.println(​"Enter : execute"​);
Serial2.println(​"----------------"​);
}
26
// UARTの割り込み時の処理
void​​serialInterrupt​(byte buffer){
​switch​(buffer) {
​case​​'w'​: ​// wが押されたとき
pos += POS_PARAM;
​// 最大値でリミット
​if​(pos >= DXL_POS_MAX) {
pos = DXL_POS_MAX;
}
Serial2.print(​"Goal Position : "​);
Serial2.println(pos);
​break​;
​case​​'s'​: ​// sが押されたとき
pos -= POS_PARAM;
​// 最小値でリミット
​if​(pos <= DXL_POS_MIN) {
pos = DXL_POS_MIN;
}
Serial2.print(​"Goal Position : "​);
Serial2.println(pos);
​break​;
​case​​'r'​: ​// enterが押されたとき
​case​​'n'​:
​// Gaol positionを設定する
Dxl.writeDword(DXL_ID_1, DXL_GOAL_POS, pos);
​break​;
​default​:
​break​;
}
}
// メイン処理
void​​loop​(){
delay(​10​);
}
27
6.1. 値の定義について
サンプルコードで使用している定義に関しての説明を記載する。
/* Dynamixel ID defines */
#define DXL_ID_1 1
DXL_ID_1 ​は、XL430-W250に割り当てられているID。
/* Dynamixel Address Defines */
#define DXL_TRQ 64
#define DXL_PROFILE_VELOCITY 112
#define DXL_GOAL_POS 116
使用するアドレスを予め定義しておく。
アドレスの詳細は、”表1 XL430-W250 Control Table”を参照。
/* Serial Device Defines for Dynamixel bus */
#define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04
#define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210
#define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM
485EXP
XL430-W250とOpenCM9.04間で使用するシリアルの設定。
本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。
/* Parameter Defines */
#define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1:
57600, 2: 115200, 3: 1Mbps
#define DXL_POS_DEFAULT 0
#define DXL_POS_MAX 4095
#define DXL_POS_MIN 0
#define DXL_UART_BAUD_RATE 57600
#define DXL_VELOCITY_SPEED 200
#define ON 1
#define OFF 0
#define POS_PARAM 100
28
コード上で使用する数値を理解しやすいように、予め定義しておく。
DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。
本ケースでは、1Mbpsの3を設定する。
DXL_POS_DEFAULT​では、DyanamixelのデフォルトのGoal Positionを設定する。
DXL_POS_MAX​​、​DXL_POS_MIN​では、Goal Positionの最大/最小値を設定する。
最大/最小値は、​1.4. Dnamixelのリンク先の​Goal Position (116)​を参照。
DXL_UART_BAUD_RATE ​では、TeraTermと通信するUARTのbaudRateを設定する。
DXL_VELOCITY_SPEED ​では、Dyanamixelの動作スピードを設定する。
動作スピードは、​1.4. Dnamixelのリンク先の​Profile Velocity (112)​を参照。
本ケースでは、0.229[RPM] × 200 = 45.8となる。実際には、44でリミットされ最大速度で動作す
る。
POS_PARAM ​では、w/sが一度押されたときのGoal Positionの増減値を設定する。
29
6.2. コードの動作について
サンプルコードの動作について記載する。
void​​setup​(){
​// セットアップ待ち
delay(​1000​);
​// UARTの初期化
Serial2.begin(DXL_UART_BAUD_RATE);
​// UARTの割り込み設定
Serial2.attachInterrupt(serialInterrupt);
​// Dynamixelの設定
Dxl.begin(DXL_BAUD_RATE);
Dxl.jointMode(DXL_ID_1);
Dxl.writeByte(DXL_ID_1, DXL_TRQ, ON);
Dxl.writeDword(DXL_ID_1, DXL_PROFILE_VELOCITY, DXL_VELOCITY_SPEED);
​// コマンドの説明
Serial2.println(​"----push key----"​);
Serial2.print(​"w : +"​); Serial2.println(POS_PARAM);
Serial2.print(​"s : -"​); Serial2.println(POS_PARAM);
Serial2.println(​"Enter : execute"​);
Serial2.println(​"----------------"​);
}
UARTを使用するために、​Serial2​の設定を行う。
Serial2.begin(DXL_UART_BAUD_RATE)​では、BaudRateの設定を行っている。
Serial2.attachInterrupt(serialInterrupt)​では、UARTで外部割り込みを使用する設定を行って
いる。
// Dynamixelの設定​では、Baudrateの設定、Jointモードの設定、トルクを有効にするための
設定、動作スピードの設定をそれぞれ行っている。
// コマンドの説明​では、UART経由で、TeraTerm上にキーの説明を表示する。
30
// UARTの割り込み時の処理
void​​serialInterrupt​(byte buffer){
​switch​(buffer) {
​case​​'w'​: ​// wが押されたとき
pos += POS_PARAM;
​// 最大値でリミット
​if​(pos >= DXL_POS_MAX) {
pos = DXL_POS_MAX;
}
Serial2.print(​"Goal Position : "​);
Serial2.println(pos);
​break​;
​case​​'s'​: ​// sが押されたとき
pos -= POS_PARAM;
​// 最小値でリミット
​if​(pos <= DXL_POS_MIN) {
pos = DXL_POS_MIN;
}
Serial2.print(​"Goal Position : "​);
Serial2.println(pos);
​break​;
​case​​'r'​: ​// enterが押されたとき
​case​​'n'​:
​// Goal positionを設定する
Dxl.writeDword(DXL_ID_1, DXL_GOAL_POS, pos);
​break​;
​default​:
​break​;
}
}
void​​serialInterrupt​(byte buffer)​では、TeraTermからの入力があった際の動作を記述する。
buffer​には、TeraTermから送信した文字が一文字格納される。
TeraTermから送信された文字が、​'w'​の場合は、現在のGoal positionに​POS_PARAM​の値を
加算する。加算後に最大値を以上の場合は、​DXL_POS_MAX​で値をリミットする。
TeraTermから送信された文字が、​'s'​の場合は、現在のGoal positionに​POS_PARAM​の値を
減算する。減算後に最小値を以下の場合は、​DXL_POS_MAX​で値をリミットする。
TeraTermから送信された文字が、​'r'​または​'n'​の場合(Enterが押されたとき)は、現在のGoal
PositionをDynamixelに書き込む​。
31
TeraTermを起動し、USB Serial Port(COM6)を選択する。
設定→シリアルポートの設定→スピードを57600に設定する。
以下のような画面が表示されれば通信成功。
※Port番号は、環境によって変わるため注意する。
32
問い合わせ先:
株式会社ロボティズ日本支店
tel:03-6869-8804
e-mail : jp.support@robotis.com
33

Mais conteúdo relacionado

Mais procurados

プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
Takuya Akiba
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
Miki Shimogai
 
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Preferred Networks
 

Mais procurados (20)

NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造プログラミングコンテストでのデータ構造
プログラミングコンテストでのデータ構造
 
キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達キャッシュコヒーレントに囚われない並列カウンタ達
キャッシュコヒーレントに囚われない並列カウンタ達
 
SSII2019企画: 点群深層学習の研究動向
SSII2019企画: 点群深層学習の研究動向SSII2019企画: 点群深層学習の研究動向
SSII2019企画: 点群深層学習の研究動向
 
データサイエンティストのつくり方
データサイエンティストのつくり方データサイエンティストのつくり方
データサイエンティストのつくり方
 
SAT/SMTソルバの仕組み
SAT/SMTソルバの仕組みSAT/SMTソルバの仕組み
SAT/SMTソルバの仕組み
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみるいまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
いまどきの組込みOSの​ ZephyrRTOSと​ OpenThreadを​ Arduino環境で遊んでみる
 
π計算
π計算π計算
π計算
 
DockerコンテナでGitを使う
DockerコンテナでGitを使うDockerコンテナでGitを使う
DockerコンテナでGitを使う
 
SQLチューニング入門 入門編
SQLチューニング入門 入門編SQLチューニング入門 入門編
SQLチューニング入門 入門編
 
高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装高速な倍精度指数関数expの実装
高速な倍精度指数関数expの実装
 
ゆるバグ
ゆるバグゆるバグ
ゆるバグ
 
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
[GTCJ2018]CuPy -NumPy互換GPUライブラリによるPythonでの高速計算- PFN奥田遼介
 
AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解AVX-512(フォーマット)詳解
AVX-512(フォーマット)詳解
 
いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門いまさら聞けない!CUDA高速化入門
いまさら聞けない!CUDA高速化入門
 
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
プログラミングコンテストでのデータ構造 2 ~平衡二分探索木編~
 
pg_dbms_statsの紹介
pg_dbms_statsの紹介pg_dbms_statsの紹介
pg_dbms_statsの紹介
 
Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)Ansible 入門 #01 (初心者向け)
Ansible 入門 #01 (初心者向け)
 
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
Pythonの理解を試みる 〜バイトコードインタプリタを作成する〜
 

Semelhante a OpenCM IDE、OpenCM 485 EXPを用いてのDynamixel Xシリーズの制御

HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
akirahiguchi
 
PF部2011年12月勉強会.androidsola
PF部2011年12月勉強会.androidsolaPF部2011年12月勉強会.androidsola
PF部2011年12月勉強会.androidsola
android sola
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another side
Kiwamu Okabe
 
C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml
ssuser3a4b8c
 
Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etc
kasaharatt
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみる
ftnk
 
整数列圧縮
整数列圧縮整数列圧縮
整数列圧縮
JAVA DM
 
COMSTARでiSCSI - OpenSolaris勉強会 2011.08
COMSTARでiSCSI - OpenSolaris勉強会 2011.08COMSTARでiSCSI - OpenSolaris勉強会 2011.08
COMSTARでiSCSI - OpenSolaris勉強会 2011.08
tokuhy
 

Semelhante a OpenCM IDE、OpenCM 485 EXPを用いてのDynamixel Xシリーズの制御 (20)

平成26年度熊本高専Arduino講座 第3週 DCモータの制御
平成26年度熊本高専Arduino講座 第3週 DCモータの制御平成26年度熊本高専Arduino講座 第3週 DCモータの制御
平成26年度熊本高専Arduino講座 第3週 DCモータの制御
 
RouterBOARD with OpenFlow
RouterBOARD with OpenFlowRouterBOARD with OpenFlow
RouterBOARD with OpenFlow
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
about dakota6.7 gui
about dakota6.7 guiabout dakota6.7 gui
about dakota6.7 gui
 
PF部2011年12月勉強会.androidsola
PF部2011年12月勉強会.androidsolaPF部2011年12月勉強会.androidsola
PF部2011年12月勉強会.androidsola
 
Bluetooth通信の 仕組みと活用法紹介
Bluetooth通信の仕組みと活用法紹介Bluetooth通信の仕組みと活用法紹介
Bluetooth通信の 仕組みと活用法紹介
 
Dive into RTS - another side
Dive into RTS - another sideDive into RTS - another side
Dive into RTS - another side
 
C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml C base design methodology with s dx and xilinx ml
C base design methodology with s dx and xilinx ml
 
さわってみようTOPPERS/SSP
さわってみようTOPPERS/SSPさわってみようTOPPERS/SSP
さわってみようTOPPERS/SSP
 
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
コンテナセキュリティにおける権限制御(OCHaCafe5 #3 Kubernetes のセキュリティ 発表資料)
 
Slide
SlideSlide
Slide
 
Stellaris を使った組み込みアプリ開発ガイド
Stellaris を使った組み込みアプリ開発ガイドStellaris を使った組み込みアプリ開発ガイド
Stellaris を使った組み込みアプリ開発ガイド
 
Postgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etcPostgre sql9.3 newlockmode_and_etc
Postgre sql9.3 newlockmode_and_etc
 
PBL1-v1-008j.pptx
PBL1-v1-008j.pptxPBL1-v1-008j.pptx
PBL1-v1-008j.pptx
 
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
Db2 v11.5.4 高可用性構成 & HADR 構成パターンご紹介
 
Python で munin plugin を書いてみる
Python で munin plugin を書いてみるPython で munin plugin を書いてみる
Python で munin plugin を書いてみる
 
about DakotagUI
about DakotagUIabout DakotagUI
about DakotagUI
 
整数列圧縮
整数列圧縮整数列圧縮
整数列圧縮
 
PF部第19回資料 poor man's JTAG
PF部第19回資料 poor man's JTAGPF部第19回資料 poor man's JTAG
PF部第19回資料 poor man's JTAG
 
COMSTARでiSCSI - OpenSolaris勉強会 2011.08
COMSTARでiSCSI - OpenSolaris勉強会 2011.08COMSTARでiSCSI - OpenSolaris勉強会 2011.08
COMSTARでiSCSI - OpenSolaris勉強会 2011.08
 

Mais de ROBOTIS Japan

Mais de ROBOTIS Japan (9)

Brochure TurtleBot3(A4)
Brochure TurtleBot3(A4)Brochure TurtleBot3(A4)
Brochure TurtleBot3(A4)
 
Brochure HN12-I101 set
Brochure HN12-I101 setBrochure HN12-I101 set
Brochure HN12-I101 set
 
Brochure HN13-101 set
Brochure HN13-101 setBrochure HN13-101 set
Brochure HN13-101 set
 
Open manipulator x-assembly_guide_ver1913
Open manipulator x-assembly_guide_ver1913Open manipulator x-assembly_guide_ver1913
Open manipulator x-assembly_guide_ver1913
 
TurtleBot3でROSを始めよう
TurtleBot3でROSを始めようTurtleBot3でROSを始めよう
TurtleBot3でROSを始めよう
 
DYNAMIXEL XWシリーズ パンフレット
DYNAMIXEL XWシリーズ パンフレットDYNAMIXEL XWシリーズ パンフレット
DYNAMIXEL XWシリーズ パンフレット
 
Turtlebot3 friends:tank_setup
Turtlebot3 friends:tank_setupTurtlebot3 friends:tank_setup
Turtlebot3 friends:tank_setup
 
「Turtlebot3の紹介」 ROS Japan UG #10 勉強会
「Turtlebot3の紹介」 ROS Japan UG #10 勉強会「Turtlebot3の紹介」 ROS Japan UG #10 勉強会
「Turtlebot3の紹介」 ROS Japan UG #10 勉強会
 
Manipulator X 4DOF パンフレット
Manipulator X 4DOF パンフレットManipulator X 4DOF パンフレット
Manipulator X 4DOF パンフレット
 

Último

Último (11)

Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 

OpenCM IDE、OpenCM 485 EXPを用いてのDynamixel Xシリーズの制御

  • 1. OpenCM IDE、OpenCM 485 EXP を用いての Dynamixel Xシリーズ の制御 1
  • 2. 1. 前提条件 3 2. XL430-W250の設定について 4 3. Master/Slaveサンプルコードの説明 8 4. 同期制御サンプルコードの説明 17 5. TeraTermについて 23 6. シリアル通信サンプルコードの説明 25 2
  • 3. 1. 前提条件 環境が設定済みであれば、実施する必要はない。 未設定の場合は、下記の項目のリンクに従って設定を行う。 1.1. OpenCM IDE    インストール、ドライバの設定が完了していること。 URL:​OpenCM IDE - ROBOTIS e-MANUAL 1.2. OpenCM9.04 初期設定が完了していること。 URL:​OpenCM9.04 - ROBOTIS e-MANUAL URL:​Testing the Controller Control Table 1.3. OpenCM 485 EXPの接続 OpenCM9.04と、上記のボートと接続済みであること。 URL:​OpenCM 485 EXP - ROBOTIS e-MANUAL 1.4. Dnamixel XL430-W250シリーズを使用していること。 URL:​XL430-W250 - ROBOTIS e-MANUAL 3
  • 7. Next​を選択する。 3つの​XL430-W250​の以下の項目の設定を確認する。 1. 7 - ID → 1~3がそれぞれ割あたっていること。 2. 8 - Baud Rate(Bus) → 3(1Mbps)に設定されていること。 3. 11 - Operating Mode → 3(Position Control)に設定されていること。 4. 13 - ProtocolVersion → 2(Protocol 2.0)に設定されていること。 7
  • 8. 3. Master/Slaveサンプルコードの説明 Master/Slaveを用いてDynamixelの制御を行う。   <動作概要> ・Button1が押されたらMaster/Slaveを入れ替える。 ・MasterはLEDが点灯し、SlaveはLEDが消灯する。   ・MasterのGoal PositionをSlaveのGoal Positionへ設定する。   ・シリアルモニタにID 1、ID 2のGoal Positionを表示する。 以下、サンプルコード。 /* Dynamixel ID defines */ #define ID_NUM_1 1 #define ID_NUM_2 2 #define GLOBAL_ID 254 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_LED 65 #define DXL_GOAL_POS 116 /* OpenCM 485 EXP Defines */ #define BUTTON_1 16 /* Defines for parameter */ #define OFF 0 #define ON 1 #define PUSH_CNT 100 #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps 8
  • 9. /* Global Variables */ Dynamixel Dxl(DXL_BUS_SERIAL3); bool​masterMode = true; /* setup */ void​​setup​() { ​delay​(​5000​); ​// Wait DXL boot Dxl.​begin​(DXL_BAUD_RATE); ​// Set Baud Rate 56700 pinMode(BUTTON_1, INPUT_PULLDOWN); ​// Button1 enable } /* main loop */ void​​loop​() { ​unsigned​​long​goalPos[​2​]; ​unsigned​​long​pushCnt = ​0​; ​// Get Button State ​while​(​digitalRead​(BUTTON_1)) { pushCnt++; } ​// Chattering control ​if​( pushCnt > PUSH_CNT ){ masterMode = !masterMode; } ​// Get GoalPos goalPos[​0​] = Dxl.readDword(ID_NUM_1,DXL_GOAL_POS); goalPos[​1​] = Dxl.readDword(ID_NUM_2,DXL_GOAL_POS); ​//Output SerialUSB SerialUSB.​print​(​"GOAL_POS ID1: "​); SerialUSB.​println​(goalPos[​0​]); SerialUSB.​print​(​"GOAL_POS ID2: "​); SerialUSB.​println​(goalPos[​1​]); 9
  • 10. ​// Switch to MASTER/SLAVE ​if​(masterMode) { Dxl.writeByte(ID_NUM_1, DXL_LED, ON); ​// ID1 LED ON Dxl.writeByte(ID_NUM_2, DXL_LED, OFF); ​// ID2 LED OFF Dxl.writeByte(ID_NUM_1, DXL_TRQ, OFF); ​// ID1 Trq OFF Dxl.writeByte(ID_NUM_2, DXL_TRQ, ON); ​// ID2 Trq ON Dxl.writeDword(ID_NUM_2,DXL_GOAL_POS, goalPos[​0​] ); ​// Set ID1 GoalPos } ​else​{ Dxl.writeByte(ID_NUM_1, DXL_LED, OFF); ​// ID1 LED OFF Dxl.writeByte(ID_NUM_2, DXL_LED, ON); ​// ID2 LED ON Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON); ​// ID1 Trq ON Dxl.writeByte(ID_NUM_2, DXL_TRQ, OFF); ​// ID2 Trq OFF Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] ); ​// Set ID2 GoalPos } ​delay​(​10​); ​// 10[ms] } 10
  • 11. 3.1. 値の定義について ​サンプルコードで使用している定義に関しての説明を記載する。 /* Dynamixel ID defines */ #define ID_NUM_1 1 #define ID_NUM_2 2 #define GLOBAL_ID 254 ID_NUM_1 1​、​ID_NUM_2​は、各XL430-W250に割り当てられているID。 IDの重複が起きないように設定する。 GLOBAL_ID​は、全てのXL430-W250にアクセスできるID。 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP XL430-W250とOpenCM9.04間で使用するシリアルの設定。 本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。 /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_LED 65 #define DXL_GOAL_POS 116 Dynamixelには、ROM/RAMの領域が用意されており、各アドレスにアクセスして制御を行 う。ROM領域は、トルクが無効(‘0’)の場合に書き換えが可能で、トルクが有効(‘1’)の場合 は、書き込みがロックされる。 ここでは、今回使用するアドレスをピックアップして定義しておく。 アドレスの詳細は、以下の表を参照。 ※Control Tableの値や位置は、機種ごとに異なるため確認が必要。 11
  • 12. 表1 XL430-W250 Control Table Area Address Size [byte] Data Name Description Access initial Value RAM 64 1 Torque Enable Motor Torque On/Off RW 0 65 1 LED Status LED On/Off RW 0 ... ... ... ... ... ... 112 4 Profile Velocity Velocity Value of Profile RW 0 116 4 Goal Position Target Position Value RW - /* OpenCM 485 EXP Defines */ #define BUTTON_1 16 BUTTON_1​は、OpenCM 485 EXP のタクトスイッチ(Button1)のアドレス。 その他にも、以下のスイッチやLEDが使用可能。 図1 OpenCM 485 EXP LED、Button配置 12
  • 13. 表2 OpenCM 485 EXP アドレス配置 Name OpenCM9.04 I/O Button1 16 Button2 17 LED1 18 LED2 19 LED3 20 /* Defines for parameter */ #define OFF 0 #define ON 1 #define PUSH_CNT 100 #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps コード上で使用する数値を理解しやすいように、予め定義しておく。 DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。 本ケースでは、1Mbpsの3を設定する。 13
  • 14. 3.2. コードの動作について サンプルコードの動作について記載する。 /* setup */ void​​setup​() { delay(​5000​); ​// Wait DXL boot Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps pinMode(BUTTON_1, INPUT_PULLDOWN); ​// Button1 enable } setup​()​では、Dynamixelがブートするまでの待機時間、BaudRateの設定、OpenCM 485 EXPのButton1を有効にするための設定をそれぞれ行っている。 ​// Get Button State ​while​(digitalRead(BUTTON_1)) { pushCnt++; } ​// Chattering control ​if​( pushCnt > PUSH_CNT ){ masterMode = !masterMode; } タクトスイッチでMaster/Slaveを切り替える。 チャタリングでの誤動作を防止するために、ある程度ボタンが押されたらMaster/Slaveを入 れ替える。 ​// Get GoalPos goalPos[​0​] = Dxl.readDword(ID_NUM_1,DXL_GOAL_POS); goalPos[​1​] = Dxl.readDword(ID_NUM_2,DXL_GOAL_POS); ​//Output SerialUSB SerialUSB.print(​"GOAL_POS ID1: "​); SerialUSB.print(goalPos[​0​]); SerialUSB.print(​" GOAL_POS ID2: "​); SerialUSB.println(goalPos[​1​]); 14
  • 15. ID 1とID 2 のXL430-W250から現在の​Goal Positionを取得し、 USBで接続経由で、PCへシリアル通信で値を送信する。 OpenCM IDEで Ctrl+Shift+Mを押すとシリアルモニターが起動し、 XL430-W250から取得した値が表示される。 図2 シリアルモニタ画面 15
  • 16. ​// Switch to MASTER/SLAVE ​if​(masterMode) { Dxl.writeByte(ID_NUM_1, DXL_LED, ON); ​// ID1 LED ON Dxl.writeByte(ID_NUM_2, DXL_LED, OFF); ​// ID2 LED OFF Dxl.writeByte(ID_NUM_1, DXL_TRQ, OFF); ​// ID1 Trq OFF Dxl.writeByte(ID_NUM_2, DXL_TRQ, ON); ​// ID2 Trq ON Dxl.writeDword(ID_NUM_2,DXL_GOAL_POS, goalPos[​0​] ); ​// Set ID1 GoalPos } ​else​{ Dxl.writeByte(ID_NUM_1, DXL_LED, OFF); ​// ID1 LED OFF Dxl.writeByte(ID_NUM_2, DXL_LED, ON); ​// ID2 LED ON Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON); ​// ID1 Trq ON Dxl.writeByte(ID_NUM_2, DXL_TRQ, OFF); ​// ID2 Trq OFF Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] ); ​// Set ID2 GoalPos } タクトスイッチが押されると、​masterMode​が切り替わる。 Dxl.writeByte(ID_NUM_1, DXL_LED, ON)​では、ID 1のLEDを点灯に設定している。 Dxl.writeByte(ID_NUM_1, DXL_TRQ, ON)​では、ID 1のMotor TorqueをONに設定してい る。 ※TorqueをONに設定すると、ROM領域の書き込みがロックされる。 Dxl.writeDword(ID_NUM_1,DXL_GOAL_POS, goalPos[​1​] )​では、ID 1のGoal Positionに ID 2のGoal Positionを設定している。 また、​writeByte​は1Byteの書き込みで、​writeDwordは​4Byteの書き込みである。 使用する関数は、前記してある”表1 XL430-W250 Control Table“のsize[byte]に応じて使い分 ける必要がある。 ※sizeが2Byteの場合は、​writeWord​を使用する。 16
  • 17. 4. 同期制御サンプルコードの説明 SyncWriteメソッドを用いてDynamixelの同期制御を行う。   <動作概要> ・ID1~3のXL430-W250を同期させて動作させる。 ・ID1,3は同じ向きに動作。ID 2は逆側に動作する。 以下、サンプルコード。 /* Dynamixel ID defines */ #define DXL_ID_1 1 #define DXL_ID_2 2 #define DXL_ID_3 3 /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_LED 65 #define DXL_PROFILE_VELOCITY 112 #define DXL_GOAL_POS 116 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP /* Parameter Defines */ #define OFF 0 #define ON 1 #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps #define PACKET_LEN 9 #define NUM_OF_DATA 2 #define DXL_NUM 3 /* Global Variables */ Dynamixel ​Dxl​(DXL_BUS_SERIAL3); byte dxlId[DXL_NUM] = { DXL_ID_1, DXL_ID_2, DXL_ID_3 17
  • 18. }; word SyncVelocity1[PACKET_LEN] = { ​//ID ,Profile Velocity DXL_ID_1, ​100​, ​0​, DXL_ID_2, ​100​, ​0​, DXL_ID_3, ​100​, ​0 }; word SyncVelocity2[PACKET_LEN] = { ​//ID ,Profile Velocity DXL_ID_1, ​200​, ​0​, DXL_ID_2, ​200​, ​0​, DXL_ID_3, ​200​, ​0 }; word SyncGoalPos1[PACKET_LEN] = { ​//ID ,Goal Position DXL_ID_1, ​1024​, ​0​, DXL_ID_2, ​1024​, ​0​, DXL_ID_3, ​1024​, ​0 }; word SyncGoalPos2[PACKET_LEN] = { ​//ID ,Goal Position DXL_ID_1, ​0​, ​0​, DXL_ID_2, ​2048​, ​0​, DXL_ID_3, ​2048​, ​0 }; /* setup */ void​​setup​() { delay(​5000​); ​// Wait DXL boot Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps ​for​(​int​cnt = ​0​; cnt < DXL_NUM; cnt++) { Dxl.jointMode(dxlId[cnt]); ​// Set Dynamixel ID Dxl.writeByte(dxlId[cnt], DXL_TRQ, ON); ​// Set Trq on 18
  • 19. } } /* main loop */ void​​loop​() { ​// Sync write Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity1, PACKET_LEN); Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos1, PACKET_LEN); delay(​1000​); ​// 1000[ms] ​// Sync write Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity2, PACKET_LEN); Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos2, PACKET_LEN); delay(​1000​); ​// 1000[ms] } 19
  • 20. 4.1. 値の定義について ​サンプルコードで使用している定義に関しての説明を記載する。 /* Dynamixel ID defines */ #define DXL_ID_1 1 #define DXL_ID_2 2 #define DXL_ID_3 3 DXL_ID_1 ​、​DXL_ID_2​、​DXL_ID_3​は、各XL430-W250に割り当てられているID。 /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_LED 65 #define DXL_PROFILE_VELOCITY 112 #define DXL_GOAL_POS 116 使用するアドレスを予め定義しておく。 アドレスの詳細は、”表1 XL430-W250 Control Table”を参照。 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP XL430-W250とOpenCM9.04間で使用するシリアルの設定。 本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。 20
  • 21. /* Parameter Defines */ #define OFF 0 #define ON 1 #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps #define PACKET_LEN 9 #define NUM_OF_DATA 2 #define DXL_NUM 3 コード上で使用する数値を理解しやすいように、予め定義しておく。 DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。 本ケースでは、1Mbpsの3を設定する。 PACKET_LEN ​では、送信する全てのデータ数を設定する。 本ケースでは、ID1~3と​Profile Velocity​or​Goal Position​の合わせた9になる。 NUM_OF_DATA ​では、1つのIDに対して送信するデータ数を設定する。 本ケースでは、​DXL_ID​と​Profile Velocity​or​Goal Position​の2となる。 DXL_NUM​では、使用するDynamixelの数を設定する。 21
  • 22. 4.2. コードの動作について サンプルコードの動作について記載する。 /* setup */ void​​setup​() { delay(​5000​); ​// Wait DXL boot Dxl.begin(DXL_BAUD_RATE); ​// Set Baud Rate 1Mbps ​for​(​int​cnt = ​0​; cnt < DXL_NUM; cnt++) { Dxl.jointMode(dxlId[cnt]); ​// Set Dynamixel ID Dxl.writeByte(dxlId[cnt], DXL_TRQ, ON); ​// Set Trq on } } setup​()​では、Baudrateの設定、Jointモードの設定、トルクを有効にするための設定をそれ ぞれ行っている。 /* main loop */ void​​loop​() { ​// Sync write Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity1, PACKET_LEN); Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos1, PACKET_LEN); delay(​1000​); ​// 1000[ms] ​// Sync write Dxl.syncWrite(DXL_PROFILE_VELOCITY, NUM_OF_DATA, SyncVelocity2, PACKET_LEN); Dxl.syncWrite(DXL_GOAL_POS, NUM_OF_DATA, SyncGoalPos2, PACKET_LEN); delay(​1000​); ​// 1000[ms] } メインの処理では、先にVelocityを設定し、Goal Positionを設定した契機で動作する。 Dynamixelでは、目標角度と速度を設定し簡単にモータの制御を行う事ができる。 22
  • 24. OpenCM9.04と接続された後に、シリアルポートの設定を行う。 タブの 設定(s) → シリアルポート(E).... を選択すると以下の画面が開くので、 スピードを​9600​→​57600​へ変更する。 24
  • 25. 6. シリアル通信サンプルコードの説明   ​​OpneCM9.04のUARTを使用して、PCとシリアル通信を行いDynamixelを制御する。 PC上では、TeraTermを用いしてコマンドのやり取りを行う。 ※今回は、LN-101ではなく​U2D2​を使用して接続する。 <動作概要> ・wを押すと、​Goal position​を+100する。 ・sを押すと、​Goal position​を-100する。 ・Enterを押すと、設定した値でGoal Positionへ移動する。 以下、サンプルコード。 /* Dynamixel ID defines */ #define DXL_ID_1 1 /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_PROFILE_VELOCITY 112 #define DXL_GOAL_POS 116 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps #define DXL_UART_BAUD_RATE 57600 25
  • 26. /* Parameter Defines */ #define DXL_POS_MIN 0 #define DXL_POS_MAX 4095 #define DXL_POS_DEFAULT 0 #define DXL_VELOCITY_SPEED 200 #define POS_PARAM 100 #define ON 1 #define OFF 0 /* Global Variables */ Dynamixel ​Dxl​(DXL_BUS_SERIAL3); int​pos = DXL_POS_DEFAULT; void​​setup​(){ ​// セットアップ待ち delay(​1000​); ​// UARTの初期化 Serial2.begin(DXL_UART_BAUD_RATE); ​// UARTの割り込み設定 Serial2.attachInterrupt(serialInterrupt); ​// Dynamixelの設定 Dxl.begin(DXL_BAUD_RATE); Dxl.jointMode(DXL_ID_1); Dxl.writeByte(DXL_ID_1, DXL_TRQ, ON); Dxl.writeDword(DXL_ID_1, DXL_PROFILE_VELOCITY, DXL_VELOCITY_SPEED); ​// コマンドの説明 Serial2.println(​"----push key----"​); Serial2.print(​"w : +"​); Serial2.println(POS_PARAM); Serial2.print(​"s : -"​); Serial2.println(POS_PARAM); Serial2.println(​"Enter : execute"​); Serial2.println(​"----------------"​); } 26
  • 27. // UARTの割り込み時の処理 void​​serialInterrupt​(byte buffer){ ​switch​(buffer) { ​case​​'w'​: ​// wが押されたとき pos += POS_PARAM; ​// 最大値でリミット ​if​(pos >= DXL_POS_MAX) { pos = DXL_POS_MAX; } Serial2.print(​"Goal Position : "​); Serial2.println(pos); ​break​; ​case​​'s'​: ​// sが押されたとき pos -= POS_PARAM; ​// 最小値でリミット ​if​(pos <= DXL_POS_MIN) { pos = DXL_POS_MIN; } Serial2.print(​"Goal Position : "​); Serial2.println(pos); ​break​; ​case​​'r'​: ​// enterが押されたとき ​case​​'n'​: ​// Gaol positionを設定する Dxl.writeDword(DXL_ID_1, DXL_GOAL_POS, pos); ​break​; ​default​: ​break​; } } // メイン処理 void​​loop​(){ delay(​10​); } 27
  • 28. 6.1. 値の定義について サンプルコードで使用している定義に関しての説明を記載する。 /* Dynamixel ID defines */ #define DXL_ID_1 1 DXL_ID_1 ​は、XL430-W250に割り当てられているID。 /* Dynamixel Address Defines */ #define DXL_TRQ 64 #define DXL_PROFILE_VELOCITY 112 #define DXL_GOAL_POS 116 使用するアドレスを予め定義しておく。 アドレスの詳細は、”表1 XL430-W250 Control Table”を参照。 /* Serial Device Defines for Dynamixel bus */ #define DXL_BUS_SERIAL1 1 ​//Dynamixel on Serial1(USART1) <-OpenCM9.04 #define DXL_BUS_SERIAL2 2 ​//Dynamixel on Serial2(USART2) <-LN101,BT210 #define DXL_BUS_SERIAL3 3 ​//Dynamixel on Serial3(USART3) <-OpenCM 485EXP XL430-W250とOpenCM9.04間で使用するシリアルの設定。 本ケースでは、OpenCM 485 EXPを使用するので、​DXL_BUS_SERIAL3​を使用する。 /* Parameter Defines */ #define DXL_BAUD_RATE 3 ​// Dynamixel 2.0 Baudrate -> 0: 9600, 1: 57600, 2: 115200, 3: 1Mbps #define DXL_POS_DEFAULT 0 #define DXL_POS_MAX 4095 #define DXL_POS_MIN 0 #define DXL_UART_BAUD_RATE 57600 #define DXL_VELOCITY_SPEED 200 #define ON 1 #define OFF 0 #define POS_PARAM 100 28
  • 29. コード上で使用する数値を理解しやすいように、予め定義しておく。 DXL_BAUD_RATE​では、DyanamixelのBaudrateを設定する。 本ケースでは、1Mbpsの3を設定する。 DXL_POS_DEFAULT​では、DyanamixelのデフォルトのGoal Positionを設定する。 DXL_POS_MAX​​、​DXL_POS_MIN​では、Goal Positionの最大/最小値を設定する。 最大/最小値は、​1.4. Dnamixelのリンク先の​Goal Position (116)​を参照。 DXL_UART_BAUD_RATE ​では、TeraTermと通信するUARTのbaudRateを設定する。 DXL_VELOCITY_SPEED ​では、Dyanamixelの動作スピードを設定する。 動作スピードは、​1.4. Dnamixelのリンク先の​Profile Velocity (112)​を参照。 本ケースでは、0.229[RPM] × 200 = 45.8となる。実際には、44でリミットされ最大速度で動作す る。 POS_PARAM ​では、w/sが一度押されたときのGoal Positionの増減値を設定する。 29
  • 30. 6.2. コードの動作について サンプルコードの動作について記載する。 void​​setup​(){ ​// セットアップ待ち delay(​1000​); ​// UARTの初期化 Serial2.begin(DXL_UART_BAUD_RATE); ​// UARTの割り込み設定 Serial2.attachInterrupt(serialInterrupt); ​// Dynamixelの設定 Dxl.begin(DXL_BAUD_RATE); Dxl.jointMode(DXL_ID_1); Dxl.writeByte(DXL_ID_1, DXL_TRQ, ON); Dxl.writeDword(DXL_ID_1, DXL_PROFILE_VELOCITY, DXL_VELOCITY_SPEED); ​// コマンドの説明 Serial2.println(​"----push key----"​); Serial2.print(​"w : +"​); Serial2.println(POS_PARAM); Serial2.print(​"s : -"​); Serial2.println(POS_PARAM); Serial2.println(​"Enter : execute"​); Serial2.println(​"----------------"​); } UARTを使用するために、​Serial2​の設定を行う。 Serial2.begin(DXL_UART_BAUD_RATE)​では、BaudRateの設定を行っている。 Serial2.attachInterrupt(serialInterrupt)​では、UARTで外部割り込みを使用する設定を行って いる。 // Dynamixelの設定​では、Baudrateの設定、Jointモードの設定、トルクを有効にするための 設定、動作スピードの設定をそれぞれ行っている。 // コマンドの説明​では、UART経由で、TeraTerm上にキーの説明を表示する。 30
  • 31. // UARTの割り込み時の処理 void​​serialInterrupt​(byte buffer){ ​switch​(buffer) { ​case​​'w'​: ​// wが押されたとき pos += POS_PARAM; ​// 最大値でリミット ​if​(pos >= DXL_POS_MAX) { pos = DXL_POS_MAX; } Serial2.print(​"Goal Position : "​); Serial2.println(pos); ​break​; ​case​​'s'​: ​// sが押されたとき pos -= POS_PARAM; ​// 最小値でリミット ​if​(pos <= DXL_POS_MIN) { pos = DXL_POS_MIN; } Serial2.print(​"Goal Position : "​); Serial2.println(pos); ​break​; ​case​​'r'​: ​// enterが押されたとき ​case​​'n'​: ​// Goal positionを設定する Dxl.writeDword(DXL_ID_1, DXL_GOAL_POS, pos); ​break​; ​default​: ​break​; } } void​​serialInterrupt​(byte buffer)​では、TeraTermからの入力があった際の動作を記述する。 buffer​には、TeraTermから送信した文字が一文字格納される。 TeraTermから送信された文字が、​'w'​の場合は、現在のGoal positionに​POS_PARAM​の値を 加算する。加算後に最大値を以上の場合は、​DXL_POS_MAX​で値をリミットする。 TeraTermから送信された文字が、​'s'​の場合は、現在のGoal positionに​POS_PARAM​の値を 減算する。減算後に最小値を以下の場合は、​DXL_POS_MAX​で値をリミットする。 TeraTermから送信された文字が、​'r'​または​'n'​の場合(Enterが押されたとき)は、現在のGoal PositionをDynamixelに書き込む​。 31