XBUS Library for Arduino のページ(2025/09/09更新)

元々東大阪時代からヲイラが全部一人で書いてた奴なんやけど、正式に引き取るコトにしたので、今後はココで公開していきます。

●概要

ArduinoマイコンボードにてXBUSサーボをシリアル駆動するためのライブラリ

●リンク

XBusServoLib.zip

●対応ボード(検証済みボード)

  • Arduino UNO R3
  • Arduino M0
  • (工事中)

●注意事項

  • 本ページは、XBUSサーボをArduinoにシリアル接続して使うためのライブラリに関する仕様概略です。このページに掲載されていない部分については、別ドキュメントの「XBUSサーボ仕様概略」をご参照ください。
  • 本ページはArduinoに対応するものではありますが、全てのArduinoでの動作を保障するものではありません。現時点においては、Arduino UNO R3での動作を前提に記述されています。互換機等、他の環境での動作についてはあまり確認しておりませんので、ご注意ください。
  • 本ページや本ライブラリは、ライブラリ改良等及びドキュメント改良等のため予告なく変更されることがあります。
  • 本ページや本ライブラリは、状況に応じて非公開になる場合があります。
  • 本ページや本ライブラリの無断転載は、最新情報更新の妨げになる場合が多いですのでお控えください。但し、本ページを基にした解説等の公開や、その際に必要な正しい引用については無論問題ございません。むしろ、歓迎します。もしよろしければ、その際は参照用として当本ページへのリンク等を掲示していただければ幸いです。
  • 本ページや本ライブラリに関連するトラブル等については、ZakLabは一切の責任を負わないものとします。
  • 本ページに関するお問い合わせは、ZakLabの連絡先ページからお願いします。

●ハードウエアについて

・通常仕様

XBUSサーボをArduinoに接続する場合、Arduinoのシリアル信号線は基本的に5Vであり、なおかつ通常の2線双方向信号ですので、これを3.3Vの1線双方向シリアル信号に変換する必要があります。XBUSサーボ自体は5Vトレラントですので5Vのままでも構わないと言えば構わないのですが、一応本筋は3.3Vですね。

以下の回路はその概略です。


やっていることとしては、

  • TXに3ステートバッファを入れ、受信時にTXのラインをカットする。
  • 3.3V駆動のバッファ(上の例では74125と表記)を使い、レベル変換を行う。
  • 保護抵抗を入れ、回路を保護する。

といった辺りです。回路図中の74125は、実際には最近販売されているタイプで構いませんが、信号レベルがTTLであること、電源電圧が3.3Vであること、入出力ともに5Vトレラントであることが条件です。

出力側が5Vトレラントでない場合、Arduino基板のRxのプルアップがRxバッファの出力側から回り込み、3.3V電源を上昇させてしまいますのでご注意ください。その場合は、Rxバッファのみ5V電源にすれば解決する場合がありますが、入力レベルに注意が必要です。

Pin2が回路図上指定されていますが、これは固定ではなく任意のデジタルピン、アナログピンを設定できます。ライブラリの初期化時に、何番のピンを使うのかを指定しています。

10KΩでプルアップしていますが、これは受信に切り替えた時になんらかの理由で一時的にバスのレベルが下がるのを防止するために入れています。XBUSサーボからの情報を受信する際、一時的に双方が受信する状態になる場合があり、このときバスのレベルが下がってしまうと、信号が開始されたと勘違いをする場合があるためです。

なお、このプルアップの値は100KΩまでの間で調整するのが望ましいです。特に複数のXBUSサーボを設置する場合は、もう少し大きな値にしておくことをお勧めします。

・TXOnly仕様

XBUSサーボからの情報を一切受け取らない場合、TXのみの接続で動かすことができます。使用部品は通常仕様とあまり変わりませんが、RX側の回路や切り替え信号が不要になります。

ただし、この場合以下の制限があります。

  • 一切XBUSサーボの情報を受け取れない。
  • ID設定を含む各種設定は、その都度個別に当該XBUSサーボのみを接続して行う。

気軽にXBUSサーボを使う場合は、こちらの方が便利かもしれません。

通常仕様に合わせて10KΩでプルアップしていますが、こちらはあってもなくても特に大きな問題はありません。

なお、このプルアップを設置する場合は100KΩまでの間で調整するのが望ましいです。特に複数のXBUSサーボを設置する場合は、もう少し大きな値にしておくことをお勧めします。

・3.3V仕様のArduinoについて

一部のArduino(及び互換機)には、もともと信号が3.3Vで出力されているものがあります。この場合、レベル変換は不要かと思いますが、通常仕様の場合はTXを遮断するバッファが必要になります。また、マイコンボード自体の出力が弱い(出力インピーダンスが高い)場合、最悪は信号が鈍る可能性もありますので、安全のためにも5V仕様と同様、バッファを入れておくことをお勧めします。

●ソフトウエアについて

・基本コンセプト

本ライブラリの主目的は、Arduino環境においてXBUSサーボのパケットプロトコルを内包し抽象化するコトです。それと同時に、ライブラリのソースを読むコトでパケットプロトコルを理解し、他環境でのコーディングの参考にするコトも含まれます。

本ライブラリは、APIを呼ぶだけで細かい初期設定やパケット構築抜きにXBUSサーボ相手にパケットを送受信できるようになっています。内部的にはCRC計算等の面倒な処理もありますが、本ライブラリを使えばそういったことに煩わされる心配はありません。

なお、XBUSサーボの仕様そのものに関しては、XBUSサーボプロトコル仕様概略をご覧ください。

・XBUSパケットプロトコルについての簡単な解説

XBUSプロトコルのパケットは大きく分けて2種類あります。XBUSサーボの各種設定を行うコマンドデータパケットと、いわゆるRCサーボにPWM信号(=角度情報)を与えるのと同等の意味を持つチャンネルデータパケットです。

各XBUSサーボにはID(メインID)が割り当てられており、これは任意に書き換え可能です。IDの範囲は1〜50までです。各ID毎にサブIDとして0〜3を割り当てるコトができます。この二つはこんな感じで1バイト内に並んでいます。この全体でチャンネルIDと呼んでいます。

Bit7Bit6Bit5Bit4Bit3Bit2Bit1Bit0
サブIDサブIDメインIDメインIDメインIDメインIDメインIDメインID

コマンドデータパケットにおいては、この8bit分全部でXBUSサーボの特定を行います。しかし、チャンネルデータパケットにおいては、メインIDだけでXBUSサーボの特定を行います。その結果、例えばXBUSサーボを複数個連動させたいような場合に、サブIDも使って個別にニュートラル調整を行い、角度指示としては一つのメインIDで指示するコトで、角度情報送信時のパケットサイズを減らすコトができます。

・ライブラリの初期化に関して

コマンドデータパケットはせいぜい10バイト以下のデータですので大きな問題はないのですが、チャンネルデータパケットは最大50個分のXBUSサーボに対して一気に角度情報を送れるため、最大パケットサイズは単体で200バイトを超えます。ただでさえメモリが少ないArduinoで常時200バイトもメモリを占有するのはヨロシくないため、ライブラリの起動時に「最大何個分の角度情報を同時に発するのか」を指定し、メモリの節約を図っています。

ハードウエアの解説にあった通り、本ライブラリ初期化時にTXを制御する信号線を割り当てます。前述の回路図ではPin2に割り当てていますが、デジタル信号が出る端子であれば、どこでも構いません。また、この割り当て引数にマイナス1を与えると、TXOnly仕様として動作します。

XBUSサーボへ角度情報を送る時は、先に指定した個数分の枠があるバッファに対し、まずはそれぞれのXBUSサーボのメインIDを登録していきます。同時に、当該XBUSサーボの初期状態での角度情報もセットするコトで、初期位置を設定できます。

登録するメインIDは一連でなくても構いません。ですので、たとえば「0x05, 0x02, 0x07」の三つを使うといった設定も可能です。使用途中での追加登録、削除も問題ありませんが、その際は位置情報の送信メソッド呼び出しとタイミングが被らないようにだけ注意してください。被ってもトラブルにはなりませんが、登録、削除中はデータが送信されません。

なお、登録する必要があるのは位置の指示を行う場合だけです。ですので、たとえばチャンネルID設定機を製作する等設定を行うだけの場合は、登録を行う必要はありません。その場合、XBUSサーボの最大数にも0を指定して構いません。

・角度操作について

通常、XBUSサーボは角度情報を受け続けないと脱力するように設定されています。そのため、Arduinoでどんな操作が行われていても位置を維持するために、タイマ等を用いて角度情報送信のメソッドを一定時間間隔で常に呼ぶようにしてください。サンプルコードでは、そのやり方も解説しています。

XBUSサーボのストップモードをオンにすると、最後に受け付けた角度情報の位置で維持されます。脱力させることが不要で、特定のタイミングでのみ動作させたい場合は、事前に各XBUSサーボのストップモードをオンにしてください。必要なタイミングで角度情報送信のメソッドを呼べば、送信したタイミングでその通りに動作します。初心者には、こちらの方が使いやすいかもしれません。

角度の指示は16bitで行います。この値は、従来のPWM信号の概念を踏襲しており、以下のような値で指示します。XBUSサーボは概ね850-2150uSecの範囲で動作するようになっています。それ以外の範囲での角度指示を行うと、即時脱力します。

16bit数値相当パルス幅備考
0x0000800uSec
0x1249900uSec(-60度、または-90度)
0x7FFF1500uSec(0度)
0xEDB62100uSec(+60度、または+90度)
0xFFFF2200uSec

ただし、後述のリミット値が設定されている場合、その値よりも外側の指示についてはリミット値でクリップされるため、設定によってはリミット位置で停止します。現時点では、リミット値が工場出荷時に800-2200で設定されているため、リミット値は無効になっています。

XBUSサーボの最大角は通常120度ですが、設定により180度まで広げることができます。用途に応じ、設定のコマンドを送信して切り替えて使うのがお勧めです。この場合、位置の指示は同じく900-2100で180度動作するようになっています。

・コンストラクタ

XBusServo      myXBusServo(kDirPinNum, kMaxServoNum);
kDirPinNum 通常仕様で接続する場合の、TX切り替え端子を指し示します。前述の回路図では、2になります。この値にマイナス1を指定すると、TXOnlyモードとして動作します。シールドの回路に合わせて選択してください。
kMaxServoNum接続するXBUSサーボの最大数を指示します。

XBUSサーボを使用する場合、最初に必ずこの宣言が必要になります。もちろん、名称はmyXBusServoでなくても構いません。

注意:サブIDを使う場合、同一メインID分は単一のXBUSサーボとしてカウントしてください。ココで登録するのはあくまでチャンネルデータパケットのサイズを規定するためです。

・使用開始・終了関係のメソッド

void	begin(void);
パラメータなし
戻り値なし

XBUSサーボを使用する場合、最初に必ずこのメソッドを呼んでください。これ以降、シリアルポートは本ライブラリが占有します。通常はsetupメソッドの内部で呼びます。

void	end(void);
パラメータなし
戻り値なし

XBUSサーボの使用を終了する場合、最後に必ずこのメソッドを呼んでください。これ以降、シリアルポートは開放されます。

・XBUSサーボ登録・角度情報関係のメソッド

XBusError	addServo(char channelID, unsigned int initValue);
channelID登録するXBUSサーボのチャンネルID(メインID)
initValue登録するXBUSサーボの初期角度情報
戻り値エラーコード

XBUSサーボを登録します。kMaxServoNumの個数分登録することができます。

XBusError	removeServo(char channelID);
channelID削除するXBUSサーボのチャンネルID(メインID)
戻り値エラーコード

登録されたXBUSサーボを削除します。

XBusError	setServo(char channelID, unsigned int value);
channelID角度指示するXBUSサーボのチャンネルID(メインID)
value角度指示値
戻り値エラーコード

XBUSサーボへ角度指示をします。ただし、この段階ではまだXBUSサーボには送信されていません。本ライブラリ内部のバッファに蓄積されただけです。

void	sendChannelDataPacket(void);
パラメータなし
戻り値なし

XBUSサーボへ位置指示のためのデータを送信します。この時点で、登録されている全てのXBUSサーボへの角度指示が一括して行われます。

・通常仕様時のコマンド関係のメソッド

XBusError setChannelID (char oldChannelID, char newChannelID);
oldChannelIDチャンネルIDを変更したいXBUSサーボのチャンネルID
newChannelID新しいチャンネルID
戻り値エラーコード

XBUSサーボのチャンネルIDを変更します。oldChannelIDが設定されているXBUSサーボのチャンネルIDをnewChannelIDに変更します。

注意:oldChannelIDにゼロを指定した場合、接続されている全てのXBUSサーボがnewChannelIDで指示される同一のチャンネルIDに設定されますのでご注意ください。

XBusError setCommand(char channelID, char order, int* value);
channelID設定するXBUSサーボのチャンネルID
order設定項目
value指示内容(指示後は設定値が戻ります)
戻り値エラーコード

XBUSサーボの設定を変更します。設定項目や設定値の解説は、別表ををご覧ください。

なお、設定した値がそのサーボにとってレンジオーバーだった場合、エラーは返らず設定後の値としてレンジ限界値が返ります。

XBusError getCommand(char channelID, char order, int* value);
channelID取得するXBUSサーボのチャンネルID
order設定項目
value設定値
戻り値エラーコード

XBUSサーボの設定値を取得します。設定項目や取得値の解説は別表ををご覧ください。

・TXOnly仕様時のコマンド関係のメソッド

XBusError setChannelID (char newChannelID);
newChannelID新しいチャンネルID
戻り値エラーコード

現在接続されている全てのXBUSサーボのチャンネルIDを、newChannelIDに変更します。

XBusError setCommand(char order, int* value);
order設定項目
value指示内容(指示後は設定値が戻ります)
戻り値エラーコード

現在接続されている全てのXBUSサーボの設定を変更します。設定項目や設定値の解説は、別表をご覧ください。

・設定項目、設定値解説

Order意味初期値備考
kXBusOrder_Versionファームウエアバージョン機種毎get only
kXBusOrder_Product機種番号(別表2参照)機種毎get only
kXBusOrder_Reset別表1のIndexで指定したパラメータを初期値に戻す。——set only
kXBusOrder_ParamWrite別表1のIndexで指定したパラメータをROM領域へ書き込む。——set only
kXBusOrder_Reverse・0x00 通常動作
・0x01 左右反転動作
0x00
kXBusOrder_Neutralニュートラル位置に対するオフセットを指定する。±600の範囲で指定できる。主に複数XBUSサーボの同期連動時補正に使用する。0
kXBusOrder_H_Travelニュートラル位置よりも上の領域において、角度指示を拡大する。通常128、最大192まで指定できる。主に複数XBUSサーボの同期連動時補正に使用する。128
kXBusOrder_L_Travelニュートラル位置よりも下の領域において、角度指示を拡大する。通常128、最大192まで指定できる。主に複数XBUSサーボの同期連動時補正に使用する。128
kXBusOrder_H_Limit角度指示できる最大値。Limit Low未満には設定できない。無理に設定しても、自動的にLimit Lowに修正される。0xFFFF
kXBusOrder_L_Limit角度指示できる最小値。Limit Highより大きくは設定できない。無理に設定しても、自動的にLimit Highに修正される。0x0000
kXBusOrder_P_GainXBUSサーボが持つPゲインに対する増減値。±50の範囲で指定できる。0
kXBusOrder_I_GainXBUSサーボが持つIゲインに対する増減値。±50の範囲で指定できる。0大半の機種で未実装
kXBusOrder_D_GainXBUSサーボが持つDゲインに対する増減値。±50の範囲で指定できる。0
kXBusOrder_DeadBandXBUSサーボが持つデッドバンドに対する増減値。±10の範囲で指定できる。0
kXBusOrder_PowerOffsetXBUSサーボが持つブースト値に対する増減値。±999の範囲で指定できる。0
kXBusOrder_AlarmLevelXBUSサーボからアラームが発せられるパワー閾値。0-100%で指定できる。アラームが発せられると、モータ音が変化する。機種毎大半の機種で未実装
kXBusOrder_AlarmDelayXBUSサーボからアラームが発せられるまでの遅延時間を指定できる。この時間が経過しない範囲で閾値から下がれば、警告されない。0-5000mSecまで指定できる。機種毎大半の機種で未実装
kXBusOrder_AngleMode・0x00 通常動作(最大角120度)
・0x01 最大角180度(一部の機種では、180度に到達しない場合がある)
・0x02 最大角150度
機種毎
kXBusOrder_SlowStart・0x00 起動後、すぐに通常動作する。
・0x01 起動時、最初に取り込んだ角度指示までゆっくり移動する。ただし、移動中に角度指示が変化した場合、その時点から通常動作に移行する。
機種毎
kXBusOrder_StopMode・0x00 通常動作(角度指示が途絶えると1秒前後で脱力する)
・0x01 ホールド動作(角度指示が途絶えると直前の角度を維持する)
機種毎
kXBusOrder_CurrentPos現在の出力軸の角度情報を返す。静止していても、角度指示情報と一致しているとは限らないので注意すること。——get only
kXBusOrder_CurrentPow現在モータへ掛けているパワーを返す。0-100%の値を示す。——get only
kXBusOrder_SpeedLimit0 通常動作 1-30 速度制限モード(1が最も遅い)機種毎大半の機種で未実装
kXBusOrder_MaxIntegerIゲインの積分値リミッタに対する増減値。±999の範囲で指定できる。0大半の機種で未実装
kXBusOrder_PWMModePWM信号を受け取った時の挙動を決める
・0x00 通常動作(900 – 2100uSec)
・0x01 F Mode(880 – 2160uSec)
・0x02 FN Mode(440 – 1080uSec)
・0x03 SN Mode(44 – 556uSec)
機種毎
kXBusOrder_InterpolateMode・0x00 通常動作(角度指示されたら即座に動く)
・0x01 角度指示時、前回の角度情報から補間して滑らかな動作を行う。
機種毎一定時間間隔で角度指示をしていないと効果がない

別表1 Parameter Reset、Parameter WriteにおけるIndex

Index適用備考
kParamIdx_AllData_wIDreset onlyCH-IDを0x00にする必要がある。ROM領域へ自動で記録される。リセットに成功すると、チャンネルIDは0x01になる。
kParamIdx_AllData_woIDreset only 
kParamIdx_ServoIDreset onlyCH-IDを0x00にする必要がある。ROM領域へ自動で記録される。リセットに成功すると、チャンネルIDは0x01になる。
kParamIdx_Reversedboth  
kParamIdx_NeutralOffsetboth  
kParamIdx_TravelHighboth  
kParamIdx_TravelLowboth  
kParamIdx_LimitHighboth  
kParamIdx_LimitLowboth  
kParamIdx_PGainDiffboth  
kParamIdx_IGainDiffboth  
kParamIdx_DGainDiffboth  
kParamIdx_DeadBandDiffboth  
kParamIdx_PWOffsetDiffboth  
kParamIdx_AlarmLevelboth  
kParamIdx_AlarmDelayboth  
kParamIdx_AngleModeboth  
kParamIdx_SlowStartboth  
kParamIdx_StopModeboth  
kParamIdx_SpeedLimitboth  
kParamIdx_MaxIntegerDiffboth  
kParamIdx_PWMModeboth
kParamIdx_InterpolateModeboth

別表2 Productにおける応答値/機種名(一例)

応答値機種名
0x0200NX8921
0x0201NX3421
0x0202NX588
0x0203NX8925
0x0204NX3425
0x0205NX6421
0x0206NXR89
0x0207NXR34
0x0208NXB8921
0x0209NXB8925
0x020ANXB89G
0x020BNX8931
0x020CNX8935

・エラーコード解説

エラーコード意味
kXBusError_NoError エラーはありません。
kXBusError_CRCErrorCRCに問題があります。多くの場合、これは受信エラーです。
kXBusError_ServoNumOverflowこれ以上、XBUSサーボを登録できません。
kXBusError_ServoNumIsZeroこれ以上、XBUSサーボを削除できません。
kXBusError_AddWithSameID新たに登録しようとしたのと同じチャンネルIDのXBUSサーボが既に登録されています。
kXBusError_IDNotFoundそのチャンネルIDは見つかりません。
kXBusError_Unsupportedその指示はサポートされていません。
kXBusError_OnlyForTxOnlyModeそのコマンドはTxOnlyモードでしか使えません。
kXBusError_OnlyForNormalModeそのコマンドは通常仕様でしか使えません。
kXBusError_MemoryFullメモリが不足しています。
kXBusError_TimeOutデータ読み出し中にタイムアウトしました。

●スペシャルサンプルコード“XBusServoChecker”について

・概略

本サンプルコードは、XBUSサーボのパラメータを変更できる設定器をArduinoを用いて実装する場合のサンプルです。なお、このコードは実際に業務で使用しているものをそのまま添付しておりますが、作業用ですので、あまり細かい部分までは配慮がなされていない事をご了承ください。

・ハードウエア構成

ざっとした回路図を後に記載しました。基本的に以下の部品を実装しています。コードに合わせて実装するか、自身の思う配置で実装してコードを修正するかはお任せします。なお、全ての部品が秋葉原の電子部品店等で購入可能なものになっていますので、入手は容易かと思います。参考までに、秋月電子通商さんでの番号も付記します。回路図中には描いていませんが、もちろん双方向用のバッファの電源はどちらも3.3Vにしてください。

  • 前述のXBUS双方向通信用バッファ回路(I-06481、P-04800等)
  • バッファ回路用3.3V電源回路(I-00538、P-06165、P-05002等)
  • タクトスイッチ4つ(P-03646、P-03649、P-03651、P-03650等)
  • ロータリーエンコーダ1つ(P-06357、P-07240、P-00997等)
  • I2C接続小型LCD1つ(P-06669、P-06794、K-06795等)
  • 基板、配線関係(P-07555、C-00167、C-04397等)

・ソフトウエア構成

基本的な使い方としては、上下左右のボタンでカーソルの位置を移動させ、その項目に対してロータリーエンコーダーを回して変化させるという形になっています。

なお、同時にリンクするLCDのライブラリによっては、カーソル移動の指示を出してもカーソルが表示されない場合がありますので、適宜ライブラリの変更をお願いします。

・注意

Arduino側の3.3V電源は容量が小さいのか、バッファ回路を接続するとうまく動作しないことがありましたので、別途電源を確保しています。

サーボ用の電源を一旦シールド基板へ接続し、ArduinoのVinへ供給することでArduino基板を動作させる方式で実装しています。本来はイリーガルだったかと思いますが、現状UNOでは問題は発生していません。気になる方は、別途電源を直接Arduino側へ供給すればよろしいかと思います。なお、Arduino側電源からサーボへの電源を確保すると、最悪の場合基板が焼き切れるかもしれませんので、ご注意ください。

なお、このコードに対応した基板も設計してあります。どこかでZakLabが出店を出していたら、購入可能かも…

●更新履歴

  • 2025/09/08:暫定アップ/解説PDFをweb化
  • 2025/09/09:ソフトウエア関係を中心に加筆/それに伴い、ライブラリコードも若干追記