M5StackとDYNAMIXELサーボをつなぎたい！

**本稿は[ACCESS Advent Calendar 2023](https://qiita.com/advent-calendar/2023/access) 25日目の記事としてお送りします！**

## 緒言

こんにちは．12/13に記事を投稿予定でしたが大遅刻をキメたB-SKY-Labです． @Yam3939 さん，代打ありがとうございました...関係者各位にこの場を借りてお詫びと御礼申し上げます．

さて本題ですが，株式会社ACCESSのQiita説明欄には，次のような記載があります．

> SDNからセンサ、家電、電子書籍まで。ACCESSはあらゆるレイヤのデバイス、サービスを「繋げて」いきます。

というわけでラスト記事は，黒塗りの高級サーボことDYNAMIXEL XLシリーズと，M5Stackを「繋ぐ」IF基板について調べた際の記録をお送りします．

この作業のモチベーションは「DYNAMIXELの公式IF基板であるOpenRBを買ってみたはいいが，思ったより大きいから必要な回路だけを取り出して自作の小型IF基板を作りたい！」というのが発端です．それではどうぞ！

## 免責事項
本稿の内容を用いて行う実験等について，全て自己責任でお願いいたします．また，この記事の一切の責任は @B-SKY-Labにのみ帰属します．

## 使用機器
- Servo Motor: DYNAMIXEL XL330
- IDE: Arduino IDE on Windows11
- MCU: M5Stack Core2

## 調査

### とりあえず公式ページ

まずはDYNAMIXEL公式のIF基板である[OpenRB-150のemanual](https://emanual.robotis.com/docs/en/parts/controller/openrb-150/ "https://emanual.robotis.com/docs/en/parts/controller/openrb-150/")をちぇっく．

[7節のDownloads](https://emanual.robotis.com/docs/en/parts/controller/openrb-150/#downloads "https://emanual.robotis.com/docs/en/parts/controller/openrb-150/#downloads")にSchematicのPDFがありました．神？

[https://www.robotis.com/service/download.php?no=2117](https://www.robotis.com/service/download.php?no=2117)  

今回使いたいのはシリアルサーボのシリアル通信のインターフェースになっている回路なので， `TTL with Auto TX Enable` の箇所を眺めてみます．


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490597/3bf94962-2a5d-890d-e2af-883670f9ec51.png)

今回扱うDYNAMIXEL XLシリーズは，UARTの信号を半二重通信の形式に（強引に）変換して通信しています．そのため，このようなワンクッションが必要になるわけです．
  

  

## 部品調達

回路図を眺めると，コアとなる部品は次の3つです．

- 74LVC1G125 (GW)
- 74LVC1G126 (GW)
- 74HC2G14

GWがカッコ書きなのは，この部分がチップ固有の特性に対するグレードを表しているためです．つまり，ここが変わっても基本的な機能は同じで，耐久性が変わったりするだけなので，一旦無視してよいものとしました．

それぞれの部品のデータシートと論理記号は以下の通りです．

74LVC1G125: [https://assets.nexperia.com/documents/data-sheet/74LVC1G125.pdf](https://assets.nexperia.com/documents/data-sheet/74LVC1G125.pdf)  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490597/de1e6e95-2e68-4ed2-c69c-87b9820f79ec.png)

74LVC1G126: [https://assets.nexperia.com/documents/data-sheet/74LVC1G126.pdf](https://assets.nexperia.com/documents/data-sheet/74LVC1G126.pdf)   

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490597/34665682-8403-0777-bdde-a76cdea11d41.png)


74HC2G14: [https://assets.nexperia.com/documents/data-sheet/74HC\_HCT2G14.pdf](https://assets.nexperia.com/documents/data-sheet/74HC_HCT2G14.pdf)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1490597/ed7d09ce-df2e-fdf6-5876-a4b6042b69c7.png)

この3つの機能（を持つ部品）を揃えれば，IF基板を再現できそうです．

### 代替部品等

おたくは道が見えたらすぐに試したくなる生き物です．悠長にKiCADで図面を引いて発注して...と1週間も待っていられません．秋葉原で調達可能な店舗縛りで，代替部品を探しました．

以下で全部揃いそう．日本もまだまだ捨てたものではありません．

- 74LVC1G125→[東芝(TOSHIBA)　TC74HC125AP CMOSロジックIC](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=5Z2T-3DG3 "https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=5Z2T-3DG3")（千石）

- 74LVC1G126→[東芝(TOSHIBA)　TC74HC126AP CMOSロジックIC](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=8Z2U-2DG2 "https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=8Z2U-2DG2")（千石）
- 74HC2G14→[東芝(TOSHIBA)　TC74HC14AP CMOSロジックIC](https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=758P-A6EU "https://www.sengoku.co.jp/mod/sgk_cart/detail.php?code=758P-A6EU")（千石）
- BAS16L→[汎用小信号高速スイッチング・ダイオード 1N4148 100V200mA (50本入)](https://akizukidenshi.com/catalog/g/gI-00941/ "https://akizukidenshi.com/catalog/g/gI-00941/")（秋月）  



### 配線
基本的に `TTL with Auto TX Enable` の回路図をそのまま使えばOKです．今回はまずブレッドボード上で動作確認まで行いました．

ここで注意したいのが， **M5StackのGPIOは3.3Vレベル駆動**という点です．
DYNAMIXEL XLシリーズのGPIOも実は3.3V駆動で，OpenRB-150上のマイコンだけが5V駆動であるため，公開されている図面はこれに対応した回路になっています．今回は5V系が間に挟まらないため，**ICの電源電圧も全て3.3Vで統一**して配線していきましょう．ここさえ間違えなければ問題なく動くはずです．


**2024年3月16日修正**
書き込むテストコードを修正したので，以下の変更は不要になりました．

### ~~ライブラリの書き換え~~
~~DYNAMIXEL公式ライブラリである `dynamixel2arduino`はM5Stackをサポートしていないため，今回は暫定的にライブラリを直接書き換えてポート番号の指定を行います．後ほど差分パッチを公開予定ですのでご容赦ください！！~~

~~`dynamixel2arduino\src\utility\port_handler`で定義されている`void SerialPortHandler::begin(unsigned long baud){`の中の55行目...~~

~~port_.begin(baud_);~~

~~これを~~

~~port_.begin(baud_, SERIAL_8N1, 32, 33);~~

~~こうしてベタ書きでポート指定します．繰り返しますが，後ほど差分パッチは公開するので今はこれでご容赦ください...ちなみにですが，この32, 33はM5Stack Core2のPORT Aのピン番号です．他のM5Stackシリーズを使いたい場合には適宜変更してください．~~




## 動作チェック

配線したあとの写真はスパゲッティすぎるので省略します．さっそく動作チェックです．今回はdynamixel2arduinoのサンプルコードから速度指令モードを使ってみました．一定時間ごとにサーボの角速度が反転するだけのコードです．

~~前節のライブラリ魔改造をした状態で，~~ 修正したの魔改造は不要です．

以下のコードを用いました．
と言っても，`velocity_mode`のサンプルほとんどそのままですが...

```cpp
#include <Dynamixel2Arduino.h>
#include <M5Unified.h>

#define DEBUG_SERIAL Serial
HardwareSerial& DXL_SERIAL = Serial1;
Dynamixel2Arduino dxl;

// M5Stack Core2 PORT A
const uint8_t RX_SERVO = 32;
const uint8_t TX_SERVO = 33;

const uint8_t DXL_ID = 1;
const float DXL_PROTOCOL_VERSION = 2.0;

using namespace ControlTableItem;

void setup() {

  DXL_SERIAL.begin(57600, SERIAL_8N1, RX_SERVO, TX_SERVO);
  dxl = Dynamixel2Arduino(DXL_SERIAL);

  M5.begin();
  M5.Lcd.setTextSize(2);
  M5.Display.println("DYNAMIXEL TTL");
  M5.Display.println("");
  M5.Display.println("Velocity Mode Example");
  DEBUG_SERIAL.begin(115200);

  dxl.begin(57600);
  dxl.setPortProtocolVersion(DXL_PROTOCOL_VERSION);
  dxl.ping(DXL_ID);

  dxl.torqueOff(DXL_ID);
  dxl.setOperatingMode(DXL_ID, OP_VELOCITY);
  dxl.torqueOn(DXL_ID);
}


void loop() {

  // Set Goal Velocity using RPM
  dxl.setGoalVelocity(DXL_ID, 60, UNIT_RPM);
  delay(1000);
  DEBUG_SERIAL.print("Present Velocity(rpm) : ");
  DEBUG_SERIAL.println(dxl.getPresentVelocity(DXL_ID, UNIT_RPM));
  delay(1000);

  dxl.setGoalVelocity(DXL_ID, -60, UNIT_RPM);
  delay(1000);
  DEBUG_SERIAL.print("Present Velocity(rpm) : ");
  DEBUG_SERIAL.println(dxl.getPresentVelocity(DXL_ID, UNIT_RPM));
  delay(1000);
}

```

### 動いた！！！

無事に自作の回路でDYNAMIXELが動いた様子を御覧ください．ツイートツリーを遡ると回路のデバッグの様子も見られます．気になる方はぜひ．

  <blockquote class="twitter-tweet" data-media-max-width="560"><p lang="ja" dir="ltr">あぁぁぁぁぁぁ動いたぁぁぁぁああああああ(*&gt;△&lt;)！！！！！！！！！！！！ <a href="https://t.co/cH73T7ynTp">pic.twitter.com/cH73T7ynTp</a></p>&mdash; 孔明@B-SKY Lab (@eternalfriend17) <a href="https://twitter.com/eternalfriend17/status/1725222945222770774?ref_src=twsrc%5Etfw">November 16, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## 結言
本稿ではDYNAMIXEL XLシリーズの半二重シリアル通信のIF回路を公式回路図から起こして，実際に動作するまでの様子をお送りしました．これで **「あらゆるレイヤのデバイス、サービスを「繋げて」いきます」** の謳い文句に相応しい(?)記事で今年のアドカレを終えることができたのではないでしょうか．

それでは皆様，良いお年を！！


## 免責事項（再）
本稿の内容を用いて行う実験等について，全て自己責任でお願いいたします．また，この記事の一切の責任は @B-SKY-Labにのみ帰属します．