ページへ戻る

− Links

 印刷 

Dynamixel Protocol 2 Library のソース :: Besttechnology

knowledge:Dynamixel Protocol 2 Libraryのソース

« Prev[3]  
TITLE:Dynamixel Protocol 2 Library
**概要 [#va21cbfb]
Dynamixel Protocol 2 Libraryは[[DYNAMIXEL Communiation Protocol 2.0]]に対応した製品をWindows等のOSから操作するためのライブラリ集です。~
シリアル通信に関するAPI、タイミングやエラー処理、プロトコルの整合性チェック等をライブラリ内で行うため、シリアル通信である事をほとんど意識する事無くアプリケーションの作りこみに専念できます。

なお、PCと[[BTE061D]]・[[BTE061E]]・[[BTE068]]・[[BTE068B]]・[[BTE068C]]・[[BTE082]]・[[BTE083]]・[[BTE074]]・[[BTE074B]]・[[BTE079]]・[[BTE080]]・[[BTE079B]]・[[BTE080B]]・[[BTE079C]]・[[BTE080C]]・[[BTE096]]・[[BTE101]]・[[BTE110]]・[[BTX229>http://emanual.robotis.com/docs/en/parts/interface/u2d2/]]のいずれかがUSBポートに接続され、PCのOSに仮想COMポートが増設された状態で使用するものとします。[[BTE100]]の場合はRaspberry Piに依存します。

|CENTER:BGCOLOR(red): :idea:|[[DYNAMIXEL Communiation Protocol 1.0]]と[[DYNAMIXEL Communiation Protocol 2.0]]を装備した装置を同一ネットワーク上で同時に運用する事は推奨できない。|

**ライブラリおよびサンプルプログラムのダウンロード [#j8bd290f]
以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。
-''2023/11/6 Ver.3.0''~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V3.0.zip)
更新内容
--最新GCC Developer Liteの更新に伴うコンパイル環境の調整
--python向けのサンプルを拡充
-2022/3/1 Ver.2.9~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.9.zip)
更新内容
--最新GCC Developer Liteの更新に伴うコンパイル環境の調整
--新しく追加されたDynamixelの定義を追加
--コンパイル用バッチファイルの名称を変更
--バッチファイル中のパスの指定はジャンクションを使用する事で空白を含むファイル名によるコンパイル時の問題を回避
-2021/10/8 Ver.2.8
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.8.zip)
更新内容
--タイムアウトのデフォルトオフセット時間を30msに変更
--全プラットホームにおけるコンパイル時のウォーニング抑止
--Linux上における非標準ボーレート指定を許容
--makedll.batとbuild_dxlib.shの内容を一部変更
--新しく追加されたDynamixelの定義を追加
--Dynamixelの最新ファームに備わったTime-based profileに対応したAPI(DXL_SetDriveMode, DXL_SetDriveModesEquival, DXL_SetGoalAngleAndTime2, DXL_SetGoalAnglesAndTime2)を追加
--暫定的にmacOSへ対応
--C言語のサンプルコードをプラットホーム共通に
--放置していたRubyのサンプルを修正
-2021/07/20 Ver.2.7~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.7.zip)
更新内容
--追加APIの各デバイス毎の速度リミッタ見直し
--DXL_GetPresentCurrent内のPシリーズ用アドレス幅指定バグ修正
--新しく追加されたDynamixelの定義を追加
--Linux環境における受信処理の見直し
--makedll.batとbuild_dx2lib.shの内容を一部変更
--dx2lib.py内のDXL_ScanDevicesの誤記修正
--Linux用のサンプルを追加
--C言語のサンプルソースをUTF-8のBOM付きに統一
-2020/01/22 Ver.2.6~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.6.zip)
更新内容
--新しく追加されたDynamixelの定義を追加
--makedll.batとbuild_dx2lib.shの内容を一部変更
-2020/08/04 Ver.2.5~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.5.zip)
更新内容
--新しく追加されたDynamixelの定義を追加
--WriteBlockDataの変数定義を変更
-2019/11/16 Ver.2.4~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.4.zip)
更新内容
--Visual Studio上での動作検証を行いヘッダを一部修正
--ライブラリソースのエンコードをUTF-8のBOM付きに統一
--新しく追加されたDynamixelの定義を追加
-2019/04/04 Ver.2.3~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.3.zip)
更新内容
--拡張APIにおけるDynamixel PRO plus及びDynamixel PRO (A)ファーム正式対応~
-2019/03/26 Ver.2.2~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.2.zip)
更新内容
--拡張API追加~
--その他修正
-2016/12/05 Ver.1.3beta~
#ref(https://www.besttechnology.co.jp/download/DX2LIB_V1.3beta.zip)
内容
--ベータリリース~

最新版のアーカイブファイルには以下のファイルが同梱されます。必要に応じて解凍してください。
|DX2LIB|dx2lib_x32.dll|<|ライブラリ本体 |
|~|dx2lib_x64.dll|<|~|
|~|libdx2lib_x32.a|<|MINGW用ライブラリ(定義のみ) |
|~|libdx2lib_x64.a|<|~|
|~|dx2lib_x32.llb|<|MSVC用ライブラリ(定義のみ) |
|~|dx2lib_x64.lib|<|~|
|~|dx2lib.cpp|<|ライブラリソース |
|~|dx2lib_intuitive.cpp|<|~|
|~|dx2lib.h|<|ライブラリヘッダ |
|~|dx2memmap.h|<|DXLアイテムアドレス定義ヘッダ |
|~|dx2lib_matlab.h|<|matlab用ヘッダ |
|~|dx2lib.py|<|python用モジュール |
|~|makelib.cmd|<|Windows向けライブラリ再構築用バッチ |
|~|build_dx2lib.sh|<|Linux向けライブラリ再構築用スクリプト |
|SampleCode|C|smpl??.c |サンプル |
|~|~|dxmisc.h |サンプル共通設定 |
|~|~|kbhit.h |kbhitエミュレーション |
|~|~|makefile |サンプルコンパイル用makefile |
|~|~|makeexe.cmd|Windows向け再構築用バッチ |
|~|~|dx2lib.h |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2memmap.h |~|
|~|~|dx2lib_x32.dll |~|
|~|~|dx2lib_x64.dll |~|
|~|DELPHI|Project1.dpr |サンプル |
|~|~|Unit1.dfm |~|
|~|~|Unit1.pas |~|
|~|~|DX2LIB.pas |~|
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x64.dll |~|
|~|Python|smpl??.py |サンプル |
|~|~|kbhit.py |kbhitエミュレーション |
|~|~|dx2lib.py |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x32.dll |~|
|~|~|dx2lib_x64.dll |~|
|~|LabVIEW2011|sample??.vi |サンプル |
|~|~|DX2LIB.llb |DX2LIBラッパーライブラリ |
|~|~|DX2LIB_DXL.llb |DX2LIBラッパーライブラリ |
|~|~|DX2LIB_Wrapper.llb |~|
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|EXCEL|text.xls |サンプルシート |
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x64.dll |~|
|~|Ruby|smpl??.rb |サンプル |
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x64.dll |~|

**開発環境毎の設定 [#u3ff03d9]
ここでは3つのツールで使用する場合の設定方法を説明します。ここで紹介しないツールでも必要とされる操作は概ね同様ですが、全てに対応できるとまでは明言しません。

***GCC Developer Lite [#e1d4017c]
GCC Developer Liteの詳細については[[こちら>GCC Developer Lite]]。~
「基本パック」と「WINパック」を[[ダウンロード>GCC Developer Lite#DOWNLOAD]]してインストールしてください。

'SampleCode\C'フォルダにはAPIの基本的な使い方を紹介したサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。

****DLLの静的リンク [#la562acf]
静的にDLLを使用する場合は以下の手順でDLLをリンクする指定を行った上でコンパイルします。なお32bit環境を前提とします。
+ファイルの準備~
~ダウンロードファイルを解凍後、コンパイルするソースファイルと同一フォルダに以下のファイルをコピー~
|=ファイル |=ファイル名 |=備考 |
|<ヘッダ |<dx2lib.h |<必要な宣言を集約 |
|<DLL |<dx2lib_x32.dll |<DLL本体(実行時およびリンク時に必要) |
+コンパイルオプションの選択
~ツールメニュー→コンパイラオプションをクリックし、表示されるダイアログボックスの設定リストから'x86 (Console)'を選択~
#ref(GCC_CompileOption_sel.png)~
+ライブラリの追加
~etc...タブ内の追加ボタンを押し、新規に行を追加~
#ref(GCC_CompileOption_AddEtc.png)~
~新規に追加された空の行をクリックし'dx2lib_x32.dll'と入力~
#ref(GCC_CompileOption_AddDx2lib.png)~

~OKを押して設定を反映

****DLLの動的リンク [#y15bf22f]
動的にDLLを使用する場合はDLL自体をコンパイラオプションへ追記する必要はありません。その代わりソース中でdx2lib.hをインクルードする前に_DYNAMICLOADマクロを定義しておきます。
#html{{
<style type="text/css">
	.syntaxhighlighter {
		overflow-y: auto !important;
		overflow-x: auto !important;
		max-height: 900px;
		-webkit-text-size-adjust: 100%;
	}
</style>
<pre class="brush: c;">
#define _DYNAMICLOAD
#include "dx2lib.h"
</pre>
}}
これによりヘッダファイル内の諸定義が切り替わり、LoadDLLとUnloadDLLで動的なDLL読み込みと破棄ができます。
#html{{
<pre class="brush: c;">
  TDeviceID   dev;
  // DLLを読み込み
  if (LoadDLL ()) {
    if ((dev = DX2_OpenPort (COMPORT, BAUDRATE))) {
      ...
      DX2_ClosePort (dev);
    }
    // DLLを破棄
    UnloadDLL ();
  }
</pre>
}}
LoadDLLが成功していない状態で各APIを呼び出してはいけません。またDLL自体は実行プログラムと同じフォルダかOSがDLLを検索できる場所に配置しておく必要があります。

****サンプルフォルダ内のmakefileを使用 [#a00c8b73]
サンプルをコンパイルするだけならばGCC Developer Liteを起動する必要は無く、サンプルフォルダ内に同梱される「makeexe.cmd」を実行すればmakefileを読み込んでGCC Developer Liteに同梱されるmakeを使用してコンパイルします。~
引数にソース名をしていするとそのソースだけコンパイル、何も付けなければフォルダ内の拡張子がCのソースファイル全てがコンパイル対象となります。
#html{{
<pre class="brush: bash;">
makeexe sample2_ping2 (特定のソースのみコンパイル)
makeexe (カレントの全ソースをコンパイル)
</pre>
}}
なおI/Fのポート名やボーレート等はサンプル共通として「dxmisc.h」に記述してありますので、環境に応じて修正した上でコンパイルして下さい。
#html{{
<pre class="brush: c;">
// マクロ定義
#if _WIN32  // Wiindows時
#define _COMPORT    "\\\\.\\COM3"   // ポート名
#define _COMPORT2   "\\\\.\\COM4"
#else       // LinuxやmacOS時
#define _COMPORT    "/dev/ttyUSB0"  // ポート名
#define _COMPORT2   "/dev/ttyUSB1"
#endif
#define _BAUDRATE   (57600)         // ボーレート[bps]
#define _TARGETID   (1)             // 対象ID
#define _TARGETID2  (2)             // 対象ID
</pre>
}}

またバッチファイル内においてコンパイラなどのツール類へのパスを通す際に64bit環境を優先しています。

***Microsoft Visual C++ [#j5a74d33]
[[Visual C++ 2010 Express:http://www.microsoft.com/japan/msdn/vstudio/express/]]でDLLの静的なリンク方法のみ紹介します。
+ファイルの準備~
~ダウンロードファイルを解凍後、コンパイルするソースファイルと同一フォルダに以下のファイルをコピー~
|=ファイル |=ファイル名 |=備考 |
|<ヘッダ |<dx2lib.h |<必要な宣言を集約 |
|<DLL |<dx2lib_x32.dll |<実行時に必要 |
|<ライブラリ |<dx2lib_x32.lib |<リンク時に必要 |
+プロジェクトのプロパティを変更~
~構成プロパティ→C/C++→全般→追加のインクルードディレクトリの項目にヘッダファイルの格納フォルダを指定~
#ref(VCC_property_include.png)~
~構成プロパティ→リンカー→全般→追加のライブラリディレクトリの項目にLIBファイルの格納フォルダを指定~
#ref(VCC_property_lib_path.png)~
~構成プロパティ→リンカー→入力→追加の依存ファイルの項目にLIBファイル名を指定~
#ref(VCC_property_lib_file.png)~
~構成プロパティ→C/C++→プリコンパイル済ヘッダーの項目にプリコンパイル済ヘッダーを使用しないを指定~
#ref(VCC_property_precompile.png)

***National Instruments LabVIEW [#mdd5d507]
'SampleCode\LabVIEW2011'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~
[[LabVIEW:http://www.ni.com/labview/ja/]]には外部のDLLへアクセスする手段が提供されています。しかしながらDX2LIBそのままの定義ではLabVIEWからは使いづらいため、サンプルプログラムではサブviでラッピングしてDX2LIB.llbにまとめて提供しています。
#ref(vi_frontpanel.png)
#ref(vi_diagram.png)

***DELPHI [#bdd8ef87]
'SampleCode\DELPHI'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~
[[DELPHI:http://www.embarcadero.com/jp/products/delphi]]はPASCAL言語によるPC向け開発ツールであり、外部のDLLへ容易にアクセスする事ができます。サンプルに含まれるDX2LIB.pas内にdx2lib_x32.dllないしdx2lib_x64.dllを動的にロードする関数を用意しましたので、ユーザソースのuses節にdx2libを追記すればDynamixel Libraryの各APIへ簡便にアクセスできます。

***VB [#p8d7963b]
'SampleCode\EXCEL'フォルダにサンプルが同梱されます。~
ここではVBと似たMicrosoft OfficeのVBAを使用し、マクロの標準モジュールにDX2LIBHEADという名称でDLLに含まれるいくつかのAPIが定義してあります。~
Module1にPingTestとMotorTestというマクロが記述されていますので、ワークシートから適宜マクロを呼び出して実行してください。結果がシート上に反映されます。

***Ruby [#r63b1e3e]
'SampleCode\Ruby'フォルダにサンプルが同梱されます。ライブラリ名・ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~
[[Ruby:http://www.ruby-lang.org/ja]]はオープンソースの動的なプログラミング言語で、外部のライブラリはfiddleを使用してアクセスします。
#html{{
<pre class="brush: ruby;">
require "fiddle/import"

module DX2LIB		
  extend Fiddle::Importer
  dlload './dx2lib_x32.dll'
  extern 'void * DX2_OpenPort( const char *, long )'
  extern 'char DX2_Active( void * )'
  extern 'char DX2_Ping( void *, unsigned char, unsigned short * )'
  extern 'char DX2_ClosePort( void * )'
end

devid = dx2lib.DX2_OpenPort( 'ポート名', ボーレート )
</pre>
}}

LinuxやmacOSの場合は予め[[ライブラリを再構築>#w5c096b8]]しておいて下さい。

***Python [#mc6a5a49]
'SampleCode\Python'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~
[[Python:http://www.python.jp]]はオープンソースの動的なプログラミング言語で、外部のDLLへ簡易にアクセスできます。~
各APIのPython用の宣言を定義したdx2lib.pyをimportするだけで済みます。
#html{{
<pre class="brush: python;">
from dx2lib import *  # dx2libをインポート
</pre>
}}
なおdx2lib.pyはctypesによるDLLの単純なラッパーに過ぎませんので、Pythonならではの抽象的な定義は何一つ受け付けてくれません。Pythonからプログラミングを始めた方は微妙に扱いづらいかと思いますので、詳細はサンプルコードを参考にしてください。

LinuxやmacOSの場合は予め[[ライブラリを再構築>#w5c096b8]]しておいて下さい。

***Java [#ceff395d]

***MathWorks MATLAB [#mad2ebed]
[[MATLAB:http://www.mathworks.co.jp/products/matlab]]からの使用例を紹介します。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して下さい。また、mex-setupにて[[Cコンパイラを選択>http://www.mathworks.co.jp/jp/help/matlab/matlab_external/building-mex-files.html#f23734]]しておく必要があります。~
+事前準備
~まずはMATLAB起動後、「ファイル(F)」→「パス設定(H)」でdx2lib_x32.dll(MATALBが64bitの場合はdx2lib_x64.dll)とdx2lib_matlab.hの格納されたパスを指定します。dx2lib.hはMATLABでは解釈できない記述が多いため使用しないでください。~
+DLLのロード
 loadlibrary('dx2lib_x32.dll','dx2lib_matlab.h','alias','dx2lib')
+ポートのオープン
~ロードされたdx2libのDX2_OpenPortを呼出します。関数名の後はポートとボーレートです。
 devid = calllib('dx2lib','DX2_OpenPort','\\.\COM3',1000000)
+TErrorCodeの取得
~TErrorCodeはポインタで引き渡しているため、事前に型宣言をしておきます。値はErr.Valueで取得可能です。必要なければ0を指定しても構いません。
 Err = libpointer('uint16Ptr', 0);
 Ret = calllib('dx2lib', 'DX2_Ping', devid, 1, Err);
 fprintf('%x', Err.Value);
+ポートのクローズ
~DX2_OpenPortを行ったので、DX2_ClosePortを使用してポートを閉じます。
 calllib('dx2lib','DX2_ClosePort',devid)
+DLLのアンロード
 unloadlibrary('dx2lib')

***Linux & macOS[#w5c096b8]
LinuxないしmacOS上でのdx2libのコンパイル方法を紹介します。~
+ダウンロードと展開~
ライブラリのアーカイブファイルをダウンロードし展開~
#html{{
<pre class="brush: bash;">
wget https://www.besttechnology.co.jp/download/DX2LIB_V3.0.zip
unzip DX2LIB_V3.0.zip
</pre>
}}
+ライブラリ及び共有ライブラリの生成~
DXLIB2ディレクトリに移動し同梱のスクリプトファイルを実行~
gccは予めインストールされている必要がある
#html{{
<pre class="brush: bash;">
cd DX2LIB_v3.0/DX2LIB
bash ./build_dx2lib.sh
</pre>
}}
コンパイルが成功するとライブラリファイルがサンプルディレクトリにコピーされる
+ユーザプログラムとのリンク~
生成したライブラリファイルと自身のソースをリンクする。~
ポート・ボーレート等は使用する環境に合わせて適宜追加・修正する。~
ライブラリ検索パスは必要に合わせて変更する。~
#html{{
<pre class="brush: bash;">
gcc sample.c -L. -ldx2lib -o sample
</pre>
}}

'SampleCode\C'のサンプルプログラムはmakeを使ってコンパイルできます。
#html{{
<pre class="brush: bash;">
make sample2_ping2 (特定のソースのみコンパイル)
make (カレントの全ソースをコンパイル)
</pre>
}}
コンパイルや実行にあたってI/Fやカーネル・ディストリビューションに依存しますので、そのまま使用できない場合は適宜ソースを修正下さい。またWindowsを前提とした_DYNAMICLOADマクロが宣言されているとコンパイルできません。~
なおI/Fのポート名やボーレート等はサンプル共通として「dxmisc.h」に記述してありますので、環境に応じて修正した上でコンパイルして下さい。~
またmacOSの場合のポート名は「/dev/tty.usbserial-????」ではなく「/dev/cu.usbserial-????」を指定してください。更に最近のmacOSにおける標準の機能ではlatency timeを変更できなかったので、以下のようなコードで対応してみてください(USB I/Fの抜き挿しの度に実行する必要がありますが...)。

#html{{
<pre class="brush: c;">
// brew install libftdi
// cc -I/opt/homebrew/include/libftdi1 -L/opt/homebrew/lib -lftdi1 setlatency.c -o setlatency

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdbool.h&gt;
#include &lt;ftdi.h&gt;

int main (void) {
  int result = EXIT_FAILURE;
  struct ftdi_context *ftdic;
  struct ftdi_device_list *devlist;
  bool f = true, b = false;

  if ((ftdic = ftdi_new ()) != 0) {
    ftdi_set_interface (ftdic, INTERFACE_ANY);
    int num = ftdi_usb_find_all (ftdic, &amp;devlist, 0, 0);
    if (num &gt; 0) {
      for (int i = 0; i &lt; num; i++) {
        printf ("%d: ",i);
        if (ftdi_usb_open_dev (ftdic, devlist[i].dev) == 0) {
          char s[2][512];
          unsigned char prev_latency;
          if (ftdi_read_eeprom(ftdic) == 0 &amp;&amp; ftdi_eeprom_decode(ftdic,0) == 0 &amp;&amp; ftdi_eeprom_get_strings(ftdic, s[0], 512, s[1], 512, NULL, 0) == 0)
            printf("[%s][%s] ", s[0], s[1]);
          if (ftdi_get_latency_timer (ftdic, &amp;prev_latency) == 0) {
            b = (ftdi_set_latency_timer (ftdic, 1) == 0);
            printf ("prev latency = %i to %s\n", prev_latency, b ? "1" : "?");
          } else b = false;
          f = f &amp;&amp; b;
        }
        ftdi_usb_close (ftdic);
      }
    } else printf ("no device found.\n");

    if (f &amp;&amp; b) result = EXIT_SUCCESS;
    ftdi_list_free (&amp;devlist);
    ftdi_free (ftdic);
  }
  return result;
}
</pre>
}}

**API [#ybae1454]
Dynamixel Libraryではシリアル通信を直接意識するコードを記述せずに、対象IDのデバイスのコントロールテーブルへの読み書き行うAPIを用意しています。~
C言語のソースにdx2lib.hをインクルードすれば、APIを使用するのに必要なプロトタイプとマクロの定義がなされます。

''注意事項'':~
DynamixelのStatus Return Levelを必ず''2''に設定した上で使用する事。それ以外の値が設定されていた場合はAPIが想定した応答が得られず、タイムアウトするまでAPIから返らない。

***DX2_OpenPort [#zbd2f6ef]
ライブラリの内部情報を初期化すると同時に指定されたCOMポートをオープンし、[[DX2_SetBaudrate>#ba9f52b8]]を使用して通信速度を設定した後、ユニークな[[TDeviceID>#TDeviceID]]を返す。以後はこの[[TDeviceID>#TDeviceID]]を使用して各APIを使用する。~
複数のCOMポートを使用する場合は使用するポート毎にDX2_OpenPortを行い、各々のポートに対して[[TDeviceID>#TDeviceID]]を取得しなくてはならない。~
なお、Linuxにおけるボーレートの指定に関しては、[[DX2_SetBaudrate>#ba9f52b8]]の解説に注意の事。
 TDeviceID DX2_OpenPort (char *name, uint32_t baud);
-パラメータ
--char '''*name'''
~インターフェースが提供するCOMポート名。~
Windowsの場合の記述方法は[[こちら:https://support.microsoft.com/ja-jp/kb/115831]]の情報に従う。
--long '''baud'''
~インターフェースとデバイス間の通信速度[bps]。
-戻り値
--[[TDeviceID>#TDeviceID]]~
~オープンに成功した場合は0以外の値、失敗した場合は0を返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID dev;
// COM10を9600bpsでオープン
dev = DX2_OpenPort ("\\\\.\\COM10", 9600);
</pre>
}}

***DX2_ClosePort [#w1ab7cbb]
DX2_OpenPortで開いたCOMポートを閉じる。~
DX2_ClosePortが実行された以後は[[TDeviceID>#TDeviceID]]は使用できなくなる。
 bool DX2_ClosePort (TDeviceID dvid);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
-戻り値
--bool
~クローズに成功した場合はtrue、失敗した場合はfalseを返す。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID dev;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 9600);
if (dev) {
  ... (中略)
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_SetBaudrate [#ba9f52b8]
既にオープンされている[[TDeviceID>#TDeviceID]]の通信速度の変更を行う。~
実行すると強制的に受信バッファがクリアされる。~
 bool DX2_SetBaudrate (TDeviceID dvid, long baud);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--long '''baud'''~
~新しい通信速度[bps]。
-戻り値
--bool
~通信速度の変更が成功するとtrue、失敗するとfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID dev;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 9600);
if (dev) {
  // 通信速度を1M[bps]に変更
  DX2_SetBaudrate (dev, 1000000);
  ... (中略)
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_Active [#ie20e4a7]
指定された[[TDeviceID>#TDeviceID]]のポートが開かれており、使用可能であるかを確認する。~
USB接続等によりインターフェース自体が取り外し可能な場合に、実際に使用可能であるかを判断するために使用するが、状況によっては正確に判断できない場合もある。
 bool DX2_Active (TDeviceID dvid);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
-戻り値
--bool
~指定されたdvidが使用可能な場合はtrue、使用不可の場合はfalseを返す。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID dev;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 9600);
if (dev) {
  while (DX2_Active (dev)) {
    ... (中略)
  }
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_SetTimeOutOffset [#h4a1b54e]
I/FやOSの都合で生じるであろうタイムラグを予め設定する。~
内部で算出している受信タイムアウト時間とタイムアウトオフセット時間を加算した時間を超えた場合に、タイムアウトエラーとして処理する。~
デフォルトは30[ms]。
 void DX2_SetTimeOutOffset (TDeviceID dvid, uint32_t offsettime);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint32_t '''offsettime'''
~タイムアウトオフセット時間[ms]
-戻り値
--bool
~指定されたdvidが使用可能な場合はtrue、使用不可の場合はfalseを返す。

***DX2_Ping [#v393b505]
PINGインストラクションを使用して対象IDからの応答を確認する。
 bool DX2_Ping (TDeviceID dvid, uint8_t id, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 57143);
if (dev) {
  // ID=1にPINGを発行
  if (DX2_Ping (dev, 1, &amp;err))
    printf ("Found [%08X]\n", err);
  else
    printf ("Not found [%08X]\n", err);
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_Ping2 [#g16504b3]
PINGインストラクションでBROADCASTING IDを指定して不特定の対象の応答を確認する。~
BROADCASTING IDを指定した場合の応答時間はデバイスによって差があるため、異なるデバイスが混在している環境では正確な情報を取得できない場合がある。
 bool DX2_Ping2 (TDeviceID dvid, uint32_t *num, TDxAlarmStatus *AlarmStatus, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint32_t '''*num'''
~検索する最大数及び検索で見つかったデバイス数の保存先。
--[[TDxAlarmStatus>#TDxAlarmStatus]] '''*AlarmStatus'''
~検索で見つかったデバイス情報の保存先。~
少なくともnumで指定したサイズ分の領域を確保しておく必要がある。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~1台以上のデバイスからの応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID   dev;
TErrorCode  err;
uint8_t     id;
TDxAlarmStatus stat[254];
int         i;
uint32_t    num = 252;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 57143);
if (dev) {
  // 不明な対象に対してPINGを発行
  if (DX2_Ping2 (dev, &amp;num, stat, &amp;err)) {
    for (i = 0; i &lt; num; i++)
      printf ("Found ID=%d %02X\n", stat[i].id, stat[i].Status);
  }
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_Reset [#fd640394]
RESETインストラクションを使用して対象IDを出荷時の状態に初期化する。
 bool DX2_Reset (TDeviceID dvid, uint8_t id, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 57143);
if (dev) {
  // ID=1にRESETを発行
  if (DX2_Reset (dev, 1, &err))
    printf ("Success [%08X]\n", err);
  else
    printf ("Fail [%08X]\n", err);
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_Reboot [#becb91ef]
REBOOTインストラクションを使用して対象IDを再起動する。
 bool DX2_Reboot (TDeviceID dvid, uint8_t id, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 57143);
if (dev) {
  // ID=1にREBOOTを発行
  if (DX2_Reboot (dev, 1, &amp;err))
    printf ("Success [%08X]\n", err);
  else
    printf ("Fail [%08X]\n", err);
  // クローズ
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadByteData [#u7d86432]
対象IDのコントロールテーブルから1バイトのデータを読み出す。
 bool DX2_ReadByteData(TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *rdata, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint8_t '''*rdata'''
~読み出した値の保存先。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    dat;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320からLEDの状態を取得
  if (DX2_ReadByteData (dev, 1, 25, &amp;dat, &amp;err)) {
    printf ("LED STAT=%d\n", dat);
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteByteData [#ma2205f0]
対象IDのコントロールテーブルへ1バイトのデータを書き込む。
 bool DX2_WriteByteData(TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t dat, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint8_t '''dat'''~
~書き込む値。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    dat;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320からLEDの状態を取得
  if (DX2_ReadByteData (dev, 1, 25, &amp;dat, &amp;err)) {
    dat = (dat + 1) &amp; 7;
    // ID=1のXL-320へLEDの状態を設定
    DX2_WriteByteData (dev, 1, 25, dat, &amp;err);
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadWordData [#x202d573]
対象IDのコントロールテーブルから1ワード(2バイト)のデータを読み出す。
 bool DX2_ReadWordData(TDeviceID dvid, uint8_t id, uint16_t adr, uint16_t *rdata, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint16_t '''*rdata'''
~読み出した値の保存先。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint16_t   dat;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320から現在位置を取得
  if (DX2_ReadWordData (dev, 1, 30, &amp;dat, &amp;err)) {
    printf ("PRESENT POS=%d\n", dat);
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteWordData [#pcc1b3ce]
対象IDのコントロールテーブルへ1ワード(2バイト)のデータを書き込む。
 bool DX2_WriteWordData(TDeviceID dvid, uint8_t id, uint16_t adr, uint16_t dat, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint16_t '''dat'''
~書き込む値。
--[[TErrorCode>#TErrorCode]] '''*errcode'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320へ位置(511)を指令
  DX2_WriteWordData (dev, 1, 30, 511, &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadLongData [#d27bfdc2]
対象IDのコントロールテーブルからロング(4バイト)のデータを読み出す。
 bool DX2_ReadLongData(TDeviceID dvid, uint8_t id, uint16_t adr, uint32_t *rdata, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint32_t '''*rdata'''
~読み出した値の保存先。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint32_t   dat;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXM430から現在位置を取得
  if (DX2_ReadWordData (dev, 1, 132, &amp;dat, &amp;err)) {
    printf ("PRESENT POS=%d\n", dat);
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteLongData [#c3bc7240]
対象IDのコントロールテーブルへロング(4バイト)のデータを書き込む。
 bool DX2_WriteLongData(TDeviceID dvid, uint8_t id, uint16_t adr, uint32_t dat, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint32_t '''dat'''
~書き込む値。
--[[TErrorCode>#TErrorCode]] '''*errcode'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
// オープン
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXM430へ位置(2047)を指令
  DX2_WriteWordData (dev, 1, 116, 2047, &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadBlockData [#b8a1ae1e]
対象IDのコントロールテーブルから指定サイズのデータを読み出す。
 bool DX2_ReadBlockData (TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *rdata, uint32_t len, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint8_t '''*rdata'''
~読み出したデータの保存先。
--uint32_t '''len'''
~読み出すデータのサイズ。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    gain[3];
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320からPIDゲインのデータを取得
  if (DX2_ReadBlockData (dev, 1, 26, gain, 3, &amp;err) {
    printf (
     "D=%d I=%d P=%d\n",
     gain[0], gain[1], gain[2]
    );
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteBlockData [#fcf55aa0]
対象IDのコントロールテーブルへ指定サイズのデータを書き込む。
 bool DX2_WriteBlockData(TDeviceID dvid, uint8_t id, uint16_t adr, const uint8_t *dat, uint32_t len, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252, 254)。
--uint16_t '''adr'''
~コントロールテーブルのアドレス。
--uint8_t '''*dat'''
~書き込むデータの保存先。
--uint32_t '''len'''
~書き込むデータのサイズ。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    gain[3] = { 1, 1, 1 };
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のXL-320のPIDゲインを変更
  DX2_WriteBlockData (dev, 1, 26, gain, 3, &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadSyncData [#iac9751e]
SYNC READインストラクションを使用して複数IDからブロック読み出しを行う。~
読み出されるデータの1軸分の構造は[ID(8bit)][ERR(16bit)][DATA1(8bit)]...[DATAn(8bit)]となり、複数軸の場合は本データが軸数分だけスタックする。
 bool DX2_ReadSyncData (TDeviceID dvid, const TSyncReadParam *param, uint32_t *num, uint8_t *dat, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--[[TSyncReadParam>#TSyncReadParam]] '''*param'''
~パラメータデータを指定。
--uint32_t '''*num'''
~読み出すデバイス数を指定。APIの処理後に応答したデバイス数が入る
--uint8_t '''dat'''
~取得データの保存先。((受信データ長 + 3) * num)バイト以上を確保の事。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~指定したデバイス数が応答したらtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
// XM430の120番地から2バイト分のデータをid=1,2,3より読み出すパラメータ
const TSyncReadParam param = {
  addr:120,
  length:2,
  ids:{1,2,3},
};

// 読み出しすデータの構造体
typedef struct {
  uint8_t     id;
  TErrorCode  err;
  uint16_t    RTTick;
} __attribute__ ((gcc_struct, __packed__)) TSyncR[3];

TSyncR      rdat;
TDeviceID   dev;
TErrorCode  err;
if ((dev = DX2_OpenPort ("\\\\.\\COM5", 1000000))) {
  uint32_t num = 3; // 3軸
  DX2_ReadSyncData (dev, &amp;param, &amp;num, (uint8_t *)&amp;rdat, &amp;err);
  printf("resul num=%d\n", num);
  for (int i = 0; i &lt; num; i++) {
    printf("ID:%d ERR:%04X tick=%d\n", rdat[i].id, rdat[i].err, rdat[i].RTTick);
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteSyncData [#v566e16b]
SYNCインストラクションを使用して複数IDへブロック書き込みを行う。~
書き込まれるデータの構成はユーザに委ねられる。
 bool DX2_WriteSyncData (TDeviceID dvid, uint8_t *dat, uint32_t size, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''*dat'''
~書き込むパラメータの保存先。
--uint32_t '''size'''
~パラメータのサイズ。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
// 2台のXM430へ位置を指令する想定の構造体
typedef struct {
  uint16_t    addr;
  uint16_t    length;
  struct {
    uint8_t   id;
    uint32_t  goalpos;
  } __attribute__ ((gcc_struct, __packed__)) data[2];
} __attribute__ ((gcc_struct, __packed__)) TSyncW;

TSyncW syncw = {
  116,  // アドレス (Goal Position)
  4,    // データ長 (4 byte)
  {{ 1, 3072 },  // 1軸目 ID=1, GoalPosition=3072
   { 2, 1024 }}  // 2軸目 ID=2, GoalPosition=1024
};

TDeviceID  dev;
TErrorCode err;

dev = DX2_OpenPort ("\\\\.\\COM5", 1000000);
if (dev) {
  // 2台のXM430へ個別の位置を指令
  DX2_WriteSyncData (dev, (uint8_t *)&amp;syncw, sizeof(syncw), &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_ReadBulkData [#wf7d9427]
BULK READインストラクションを使用して複数IDの指定アドレス・サイズでブロック読み出しを行う。~
読み出されるデータの1軸分の構造は[SIZE(16bit)][ID(8bit)][ERR(16bit)][DATA1(8bit)]...[DATAn(8bit)]とし、DATAの前にSIZE(SIZEを含む1軸分のデータ長)・ID・ERRの計5バイトが付与される。複数軸の場合はSIZEから始まる本データが軸数分連続して取得される。
 bool DX2_ReadBulkData (TDeviceID dvid, const TBulkReadParam *param, uint32_t *num, uint8_t *dat, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--[[TBulkReadParam>#TBulkReadParam]] '''*param'''
~パラメータデータを指定。
--uint32_t '''*num'''
~読み出すデバイス数を指定。APIの処理後に応答したデバイス数が入る
--uint8_t '''dat'''
~取得データの保存先。十分な領域を確保の事。~
[[TBulkReadResult>#TBulkReadResult]]を介して解析すると便利。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~指定したデバイス数が応答したらtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    rdat[1000]; // 読み出したデータの保存先

const TBulkReadParam param[3] = {
  {1,100,20}, // ID=1の100番地から20バイト分
  {2,124,12}, // ID=2の124番地から12バイト分
  {3,  0, 7}  // ID=3の0番地から7バイト分
};

dev = DX2_OpenPort ("\\\\.\\COM5", 1000000);
if (dev) {
  uint32_t num = 3; // 3軸
  PBulkReadResult pr = (void *)rdat;
  DX2_ReadBulkData (dev, &amp;param[0], &amp;num, (uint8_t *)&amp;rdat, &amp;err);
  printf("resul num=%d err=$%04x\n", num, err);
  for (int i = 0; i &lt; num; i++) {
    if (pr-&gt;size &gt; 0) {
      printf("\nID:%d err:$%04X ",pr-&gt;id, pr-&gt;err);
      for (int j = 0; j &lt; pr-&gt;size - 5; j++) printf("%02X ", pr-&gt;dat[j]);
      pr = (void *)pr + pr-&gt;size; // 次のデータ用にポインタを更新
    }
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_WriteBulkData [#r6a06745]
BULKインストラクションを使用して複数の個別なID・アドレス・データサイズで書き込みを行う。
 bool DX2_WriteBulkData (TDeviceID dvid, uint8_t *dat, uint32_t size, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''*dat'''
~書き込むパラメータの保存先。
--uint32_t '''size'''
~パラメータのサイズ。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
--bool
~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。~
-使用例
#html{{
<pre class="brush: c;">
// 3台のXM430へ位置を指令する想定の構造体
typedef struct {
  uint8_t  id;
  uint16_t addr;
  uint16_t len;
  int32_t  pos;
} __attribute__ ((gcc_struct, __packed__)) TBW[3];
TBW BW = {
  {1, 116, 4, 0},    // 1軸目 ID=1, アドレス=116, サイズ=4, GPos=0
  {2, 116, 4, 2047}, // 2軸目 ID=1, アドレス=116, サイズ=4, GPos=2047
  {3, 116, 4, 4095}  // 3軸目 ID=1, アドレス=116, サイズ=4, GPos=4095
};

TDeviceID  dev;
TErrorCode err;

dev = DX2_OpenPort ("\\\\.\\COM5", 1000000);
if (dev) {
  // 3台のXM430へ個別の情報を書き込み
  DX2_WriteBulkData (dev, (uint8_t *)&amp;BW, sizeof(BW), &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_TxPacket [#r051327a]
任意のインストラクションパケットを送信する。
 bool DX2_TxPacket (TDeviceID dvid, uint8_t id, TInstruction inst, uint8_t *param, uint32_t len, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id'''
~対象とするID (0~252)。
--[[TInstruction>#TInstruction]] '''inst'''
~使用するインストラクション。
--uint8_t '''*param'''
~送信するパラメータの保存先。
--uint32_t '''len'''~
~送信するパラメータのサイズ。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。
-使用例
#html{{
<pre class="brush: c;">
TDeviceID  dev;
TErrorCode err;
uint8_t    param[2] = {
  25,    // アドレス (LED)
  0,     // データ
};
dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のAX-12+のLEDを消灯
  DX2_TxPacket (dev, 1, INST_WRITE, param, 2, &amp;err);
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2_RxPacket [#r280cda8]
ステータスパケットを受信する。~
基本的にDX2_TxPacketとペアで使用する。ステータスパケットが得られない状況で使用するとタイムアウトするまで返らない。~
なお、本APIは[[DX2_SetTimeOutOffset>#h4a1b54e]]で設定されたオフセット値は使用せず、引数で指定された受信タイムアウトのみが適用される。
 bool DX2_RxPacket (TDeviceID dvid, uint8_t *rdata, uint32_t rdatasize, uint32_t *rlen, uint32_t timeout, TErrorCode *err);
-パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid'''
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''*rdata'''
~受信バッファ。~
ステータスパケットを受信するのに十分なサイズを確保しておく必要がある。
--uint32_t '''readsize'''
~rdataのサイズ。~
--uint32_t '''*rlen'''
~実際に受信されたステータスパケットのサイズ。
--int '''timeout'''
~受信タイムアウト[ms]。
--[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。
-戻り値
~受信成功時はtrue、それ以外はfalseを返す。
-使用例
#html{{
<pre class="brush: c;">
int        i;
uint32_t   len;
TDeviceID  dev;
TErrorCode err;
uint8_t    param[2] = {
  25,    // アドレス (LED)
  1,     // サイズ
};

dev = DX2_OpenPort ("\\\\.\\COM10", 1000000);
if (dev) {
  // ID=1のAX-12+からLEDの状態を読み出す要求
  if (DX2_TxPacket (dev, 1, INST_READ, param, 2, &amp;err)) {
    // ステータスパケットを受信
    DX2_RxPacket (dev, dat, sizeof (dat), &amp;len, 100, &amp;err);
    for (i = 0; i &lt; len; i++) {
      printf ("[%02X]", dat[i]);
    }
  }
  DX2_ClosePort (dev);
}
</pre>
}}

***DX2LIBのオリジナルな定義 [#af9ca340]
&aname(TDeviceID);
:TDeviceID | ''(uint32_t|uint64_t)''~
DX2_OpenPortにて自動的に生成されるユニークな値。
&aname(TInstruction);~
:TInstruction | ''(uint8_t)''~
DX2_TxPacketにてインストラクションパケットを送信する場合に使用される。~
使用可能なマクロは以下の通り。~
~INST_PING~
INST_READ~
INST_WRITE~
INST_REG_WRITE~
INST_ACTION~
INST_RESET~
INST_REBOOT~
INST_STATUS~
INST_SYNC_READ~
INST_SYNC_WRITE~
INST_BULK_READ~
INST_BULK_WRITE
&aname(TDxAlarmStatus);
:TDx2AlarmStatus | struct {&br;&nbsp;&nbsp;uint8_t id;&br;&nbsp;&nbsp;TErrorCode Status;&br;
}~
idとTErrorCodeを対にした構造体でアライメントは1バイト。[[DX2_Ping2>#g16504b3]]で使用される。
&aname(TSyncReadParam);
:TSyncReadParam | struct {&br;&nbsp;&nbsp;uint16_t addr;&br;&nbsp;&nbsp;uint16_t length;&br;&nbsp;&nbsp;uint8_t  ids[256];&br;}~
addr, length, idsをまとめた構造体でアライメントは1バイト。[[DX2_ReadSyncData>#iac9751e]]で使用される。
&aname(TBulkReadParam);
:TBulkReadParam | struct {&br;&nbsp;&nbsp;uint8_t id;&br;&nbsp;&nbsp;uint16_t addr;&br;&nbsp;&nbsp;uint16_t length;&br;}~
id, addr, lengthをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で使用される。
&aname(TBulkReadResult);
:TBulkReadResult| struct {&br;&nbsp;&nbsp;uint16_t size;&br;&nbsp;&nbsp;uint8_t id;&br;&nbsp;&nbsp;TErrorCode err;&br;&nbsp;&nbsp;uint8_t dat[];&br;}~
size, id, err, datをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で読み出されたデータのアクセスに使用される。
&aname(TErrorCode);
:TErrorCode | ''(uint16_t)''~
API内で検出される16ビットのエラーコード。上位8ビットはAPI内部で検出したエラー、下位8ビットはステータスパケットに含まれるエラーフラグが割り当てられている。~
|CENTER:|LEFT:|LEFT:|c
|bit|macro name| |h
|15|ERR_INVALID_DEVID|使用できないTDeviceID |
|14|ERR_INVALID_ID|指定できないID |
|13|ERR_DIFF_ID|異なるIDからの応答 |
|12|ERR_ILLEGAL_SIZE|異常なデータサイズ |
|11|ERR_INVALID_PARAM|異常なパラメータ |
|10|ERR_COMM|シリアルポートエラー |
|9|ERR_CHECKSUM|異常なチェックサム |
|8|ERR_TIMEOUT|受信タイムアウト |
|7|ERR_DX2_ALERT|ハード的な異常検出 |
|6|ERR_DX2_ACCESS=7&br;ERR_DX2_DATALIMIT=6&br;ERR_DX2_DATALENGTH=5&br;ERR_DX2_DATARANGE=4&br;ERR_DX2_CRC=3&br;ERR_DX2_INSTRUCTION=2&br;ERR_DX2_RESULT=1|パケットの処理や数値範囲に関するエラー |
|5|~|~|
|4|~|~|
|3|~|~|
|2|~|~|
|1|~|~|
|0|~|~|

**追加API [#ac9f5496]
#include(DXL_intuitive,notitle)

« Prev[3]