XBUSServoをシリアルで動かす（簡易テスト）

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) まずは１個だけでも...

## やること
JR PROPOブランドのXBUSServoをシリアルコマンドで動かします。
今回は7.4V用で銀色の小型サーボ「S3911」を使ってみました。
（※メーカー推奨とは言えないテスト方法ですので、実施は自己責任にてお願いします。）

## 作業環境
* Arduino UNO
* Arduino IDE
* S3911(JR PROPO/RC DEPOT XBUSServo)

## ライブラリの導入
[RC DEPOTの公式サイトの左側下にある「JR製品取扱説明書」](https://rcdepot-jp.sakura.ne.jp/)からXBUSServo関連の資料やライブラリをDLすることができます。

今回は**Arduino等に導入しやすいように階層構造を調整したバージョン**をテスト用としてGithubにアップしておきましたので、それを使います。（※転載許諾いただきました。）

#### STEP 1:
XBUSServo用のライブラリをDLします。
https://github.com/Ninagawa123/XBusServo
緑の「CODE」ボタンからDownload ZIPを選択します。

#### STEP 2:
ライブラリをインストールします。
Arduino IDE のメニューから「スケッチ」→「ライブラリをインクルード」→「.ZIP形式のライブラリをインストール」を選択し、先ほどDLしたZIPファイル（XBusServo-main.zip）を選択します。
![SS 1277.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/79fd45fa-98d5-fc55-17da-bd0bce8731b3.png)

#### STEP 3:
メニューの「スケッチ」→「ライブラリをインクルード」に「XBusServoLib」が追加されたことを確認します。表示されていれば導入完了です。

## サーボとArduinoの動作テスト用簡易接続
今回は動作テストとして、以下の仕様や特性を利用して簡易的に動かします。

#### テスト接続のポイント
- サーボは5V給電でもギリギリ動く。
- サーボへの送信信号は3.3Vだが5Vでも一応動く。（ただし受信信号は3.3V）
- サーボのラインは、中央の黒線がVcc、外側の黒線がGND、白線が信号線。
- ハードウェアシリアルを使うので、書き込み時はサーボ信号線を外す。

#### Arduinoとの接続

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/7f5d5655-6a1e-38a4-00a1-d5a0ffeb0ec7.png" width=500>

|サーボ線|機能|Arduino|
|-|:-:|-|
|外側の黒線|GND|GNDピン|
|中央の黒線|Vcc|5Vピン|
|外側の白線|信号線|1番ピン（※今はつながない）|
 
ハードウェアシリアルはPCとArduinoの通信や書き込みに使うので、サーボの信号線はここでは外したままにします。

# サンプルコード
下記のコードをコピペしてArduino UNOに書き込みます。

```c++:xbus_test.ino
#include <XBusServo.h>

#define  kMaxServoNum    1       // XBusサーボの接続数 : 1 - 50
#define  kDirPinNum      -1      // 送受信切り替えピンの番号. -1 で送信のみ.

XBusServo      myXBusServo(kDirPinNum, kMaxServoNum); // ライブラリのインスタンス化
unsigned int   servoValue = 32767;// サーボ位置の値. 0x7FFF がXBusServoのサーボ位置の中央値
float radiansval = 0.0; // サインカーブ算出用のラジアン値
float radiansIncrement = 0.03; // ループ毎のラジアン値の増加量

void setup()
{
  myXBusServo.begin();
  myXBusServo.addServo(0x01, kXbusServoNeutral);    // 最初のサーボID. 今回は1番(0x01)のみ. 
}

void sendPacket()
{
  myXBusServo.sendChannelDataPacket();
}


void loop()
{
  // サインカーブ用の値を算出
  radiansval += radiansIncrement;  //ラジアン値を増加
  radiansval = (radiansval > 2 * PI) ? 0 : radiansval; //ラジアン値が2πを超えたら0にリセット

  // サーボの値をセットする
  servoValue = 32767 + int(sin(radiansval) * 30426); // サーボ位置の上限下限の許容範囲でサイン揺動させる
  myXBusServo.setServo(1, servoValue); //サーボ値をセットする
  myXBusServo.sendChannelDataPacket(); //データを送信する
  delay(10); //10ミリ秒ディレイ. 14ミリ秒以下の必要がある.
}
```

# 起動と動作結果
書き込みが終わったら、Arduinoの1番ピンにサーボの信号線を挿します。
1秒間隔ぐらいでサーボが左右に加減速しながら左右に回転すれば実験成功です。


# 少しだけ細かい話

XBusServoはデフォルト状態では**無信号状態が1.5秒続くと脱力**する仕様だそうです。今回のスクリプトでは10msごとに信号を送っています。標準的なインターバルは14msとのことです。 

信号線は送受信１線式です。受信を行う場合には別途、**半二重回路**が必要になります。

**信号速度は ~~220,000bps~~250kbps**です。よく見る115,200bpsの約2倍ですが、ゆえに旧来のArduinoではハードウェアシリアルのみの対応となっています。250kbpsは最近よく使われている通信速度らしいです。

角度の指定については約220度を16ビットで分解しているそうです。開き度合いは別途設定できるようです。

その他、仕様については[JR製品取扱説明書](https://rcdepot-jp.sakura.ne.jp/)のXBusServoLibrary.pdf、XbusServoSpec.pdfなどに詳しく書かれています。

今回のライブラリは内部的にArduino標準のハードウェアシリアルの使用を指定しています。ハードウェアシリアルが2つ以上あるArduinoやESP32、Teensyなどの場合はライブラリを修正しSerial1、Serial2などを使えるようにすればPCとのUSB接続と共存できると思います。（あとで対応バージョンのライブラリを作るかもしれません。）

# さいごに

また、冒頭にも書きましたが今回はあくまで簡易的な動作テストであり、**サーボの本体電源、信号ともに推奨の電圧ではありません。** なるべく早くテストを終了し、推奨の正しい電圧にて運用してください。

よき電子工作ライフを！

# つづき

ESP32のSerial2などでも動くようにライブラリを改造しました↓

https://qiita.com/Ninagawa123/items/1a9fe640d47f30b855ab