OpenRB, Dynamixel, OpenRCFの連携方法

本稿では，OpenRBというマイコン（OpenCMの後継機）を経由してOpenRCFからDynamixelを動かす方法について説明します．

## OpenRB側の設定

まず，Arduino IDEのボード設定で OpenRB を選択できるようにします．
Arduino IDEを起動し，「ファイル」の中の「基本設定」を開きます．
「追加のボードマネージャーのURL」という欄に以下のURLを入力し，OKを押します．
https://raw.githubusercontent.com/ROBOTIS-GIT/OpenRB-150/master/package_openrb_index.json
ボードマネージャーで「OpenRB-150」を選択できるようになっているので，インストールします．

次にOpenRBにプログラムを書き込みます．「ファイル」→「スケッチの例」→「OpenRB-150」→「usb_to_dynamixel」を開き，そのプログラムをそのまま書き込みます．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310597/5617069f-e6d8-b717-ab70-cd9de4837848.png)

*「ボードの選択」の所で「OpenRB-150」が選択されていないと，「スケッチの例」の中に「OpenRB-150」が出ないので，ご注意ください．

以上でOpenRB側の設定は完了です．

## OpenRCF側の設定

説明書の「Dynamixelとの通信」に記載されているサンプルコードをそのまま使用することができます．例えば，Dynamixelが３つあり，全てのボーレートが57600bps，IDが1, 2, 3，OpenRBのCOMポートが「COM3」，であった場合は以下のように記述します．

```ruby:MainWindow.xaml.cs
SerialDevice.Dynamixel Dynamixel = new SerialDevice.Dynamixel(57600);

void Button1_Click(object sender, RoutedEventArgs e)
{
    Dynamixel.PortOpen("COM3");
}

void Button2_Click(object sender, RoutedEventArgs e)
{
    Dynamixel.TorqueEnable(0, 1, 2);
}
```
ボタン１を押すとCOMポートが開き，ボタン２を押すとID1, 2, 3のサーボがトルクオンになります．上記のコマンドに限らず，OpenRCFに搭載されている全ての機能がそのまま使えます（角度や電流の読み書きをするコマンドについては，OpenRCFの説明書をご覧ください）．

ただし，サーボを動かすにはPCからの電源（USBケーブルから供給される5V電源）だけでは足りないので，OpenRBには外部電源（11～12V程度）も供給する必要があります．初期設定ではOpenRBがUSBケーブルのみから電源を取得するモードになっているので，これを外部電源から取得するモードに変更する必要があります．外部電源を使うためには，OpenRBのキャップ（下図の赤丸）を１列分だけ隣にズラします（ピンは３本なので移動先は一意に定まります）．

![IMG_2029.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310597/2b6788fc-376f-e181-0777-5d6d0a33bb02.jpeg)





## BLEモジュールを使って遠隔操作する方法

これまではPCとOpenRBをUSBケーブルで接続していましたが，この接続を下図のBLEモジュール（Robotisで売ってるやつ）で無線化する方法を書いておきます．

![IMG_2030.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310597/0d8cb53c-3bc9-6201-a4b4-90d312ecff3f.jpeg)

左をOpenRB，右をPCに接続します．OpenRBにはBLEモジュールを刺す場所が無いので，下図の場所にコネクタ（JST PH型端子）をハンダ付けします．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310597/72ac4fa0-1b5a-0162-b6f6-2e973085ce67.png)

次に，OpenRBにBLE用のプログラムを書き込みます．
本稿で最初に書き込みをした「usb_to_dynamixel」を以下のように修正します．

``` ruby:OpenRB
#include <Dynamixel2Arduino.h>

#define DXL_BUS Serial1
#define USB Serial2
#define DXL_PACKET_BUFFER_LENGTH 1024

uint8_t packet_buffer[DXL_PACKET_BUFFER_LENGTH];
unsigned long led_update_time = 0;

Dynamixel2Arduino dxl(DXL_BUS);

void setup() {
  pinMode(LED_BUILTIN, OUTPUT);
  USB.begin(57600); // BLE Baudrate
  dxl.begin(57600); // DYNAMIXEL Baudrate
}

void loop() {
  dataTransceiver();
}

uint8_t readData[512];
int idx = 0;

void dataTransceiver() {

  while (0 < USB.available()) {
    readData[idx] = USB.read();
    idx++;
  }

  if (5 < idx) {
    int LEN = readData[5] + 7;
    if (idx >= LEN) {
      DXL_BUS.write(readData, LEN);
      ledStatus();
      idx -= LEN;
    } 
  }
  
  int length = 0;
  int i = 0;

  // DXL -> USB
  length = DXL_BUS.available();
  if (length > 0) {
    if (length > DXL_PACKET_BUFFER_LENGTH) {
      length = DXL_PACKET_BUFFER_LENGTH;
    }
    for (i = 0; i < length; i++) {
      packet_buffer[i] = DXL_BUS.read();
    }
    USB.write(packet_buffer, length);
    ledStatus();
  }
  
}

void ledStatus() {
  if ((millis() - led_update_time) > 200) {
    digitalWrite(LED_BUILTIN, 1);
    led_update_time = millis();
  } else {
    digitalWrite(LED_BUILTIN, 0);
  }
}
```
変更したことは以下の通りです．
- 「#define USB Serial」を「#define USB Serial2」に変更
- 「USB.begin(57600);」の引数（57600）をBLEモジュールに設定されているボーレートと同じにする
- 「USB.baud()」をDynamixelに設定されているボーレート（具体的な数値）に置き換える
- 「USB -> DXL」に関する処理の書き方を変更（元々の書き方だと4つ以上のサーボと同時に通信ができない問題を確認済）

以上の修正をしたら，それを書き込みます．これでPC（OpenRCF）からOpenRBに無線で信号を送ることができるようになります．