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

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

  • 1.
    OpenCM IDE、OpenCM 485EXP を用いての 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. OpenCMIDE    インストール、ドライバの設定が完了していること。 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
  • 4.
  • 5.
  • 6.
  • 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のGoalPositionへ設定する。   ・シリアルモニタに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 toMASTER/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. 値の定義について ​サンプルコードで使用している定義に関しての説明を記載する。 /* DynamixelID 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 ControlTable 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 485EXP アドレス配置 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 toMASTER/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. 値の定義について ​サンプルコードで使用している定義に関しての説明を記載する。 /* DynamixelID 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
  • 23.
  • 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を押すと、​Goalposition​を-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. 値の定義について サンプルコードで使用している定義に関しての説明を記載する。 /* DynamixelID 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
  • 32.
  • 33.