4: 2016-08-30 (火) 17:46:22 takaboo ソース 現: 2023-11-12 (日) 00:09:35 takaboo ソース
Line 1: Line 1:
-TITLE:Dynamixel2 Library+TITLE:Dynamixel Protocol 2 Library
**概要 [#va21cbfb] **概要 [#va21cbfb]
-Dynamixel2 LibraryはDynamixel2の通信プロトコルをサポートした製品をWindows等のOSから操作するためのライブラリ集です。+Dynamixel Protocol 2 Libraryは[[DYNAMIXEL Communiation Protocol 2.0]]に対応した製品をWindows等のOSから操作するためのライブラリ集です。
-従来はユーザ自らシリアル通信に関するAPIを使用してタイミングやエラー処理を加えて利用するものでしたが、本APIを介する事でシリアル通信である事をほとんど意識すること無くアプリケーションの作りこみに専念することができるはずです。+シリアル通信に関するAPI、タイミングやエラー処理、プロトコルの整合性チェック等をライブラリ内で行うため、シリアル通信である事をほとんど意識する事無くアプリケーションの作りこみに専念できます。
-なお、PCと[[BTE061D]]・[[BTE061E]]・[[BTE068]]・[[BTE068B]]・[[BTE082]]・[[BTE083]]のいずれかがUSBケーブルで接続され、PC上にWindowsのデバイスとして仮想COMポートが増設された状態で使用するものとします。+なお、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:|Dynamixel2プロトコルと[[旧来のDynamixelプロトコル>DXLIB]]を装備した装置は同一ノードでの運用はできない。|+|CENTER:BGCOLOR(red): :idea:|[[DYNAMIXEL Communiation Protocol 1.0]]と[[DYNAMIXEL Communiation Protocol 2.0]]を装備した装置を同一ネットワーク上で同時に運用する事は推奨できない。|
**ライブラリおよびサンプルプログラムのダウンロード [#j8bd290f] **ライブラリおよびサンプルプログラムのダウンロード [#j8bd290f]
以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。 以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。
--''2016/09/xx Ver.1.3''~ +-''2023/11/6 Ver.3.0''~ 
-#ref(http://www.besttechnology.co.jp/download/DX2LIB_V1.0.zip)+#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/do​wnload/DX2LIB_V2.9.zip) 
 +更新内容 
 +--最新GCC Developer Liteの更新に伴うコンパイル環境の調整 
 +--新しく追加されたDynamixelの定義を追加 
 +--コンパイル用バッチファイルの名称を変更 
 +--バッチファイル中のパスの指定はジャンクションを使用する事で空白を含むファイル名によるコンパイル時の問題を回避 
 +-2021/10/8 Ver.2.8 
 +#ref(https://www.besttechnology.co.jp/do​wnload/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/do​wnload/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/do​wnload/DX2LIB_V2.6.zip) 
 +更新内容 
 +--新しく追加されたDynamixelの定義を追加 
 +--makedll.batとbuild_dx2lib.shの内容を一部変更 
 +-2020/08/04 Ver.2.5~ 
 +#ref(https://www.besttechnology.co.jp/do​wnload/DX2LIB_V2.5.zip) 
 +更新内容 
 +--新しく追加されたDynamixelの定義を追加 
 +--WriteBlockDataの変数定義を変更 
 +-2019/11/16 Ver.2.4~ 
 +#ref(https://www.besttechnology.co.jp/do​wnload/DX2LIB_V2.4.zip) 
 +更新内容 
 +--Visual Studio上での動作検証を行いヘッダを一部修正 
 +--ライブラリソースのエンコードをUTF-8のBOM付きに統一 
 +--新しく追加されたDynamixelの定義を追加 
 +-2019/04/04 Ver.2.3~ 
 +#ref(https://www.besttechnology.co.jp/do​wnload/DX2LIB_V2.3.zip) 
 +更新内容 
 +--拡張APIにおけるDynamixel PRO plus及びDynamixel PRO (A)ファーム正式対応~ 
 +-2019/03/26 Ver.2.2~ 
 +#ref(https://www.besttechnology.co.jp/do​wnload/DX2LIB_V2.2.zip) 
 +更新内容 
 +--拡張API追加~ 
 +--その他修正 
 +-2016/12/05 Ver.1.3beta~ 
 +#ref(https://www.besttechnology.co.jp/do​wnload/DX2LIB_V1.3beta.zip)
内容 内容
---初期リリース~+--ベータリリース~
-アーカイブファイルには以下のファイルが同梱されます。必要に応じて解凍してください。+最新版のアーカイブファイルには以下のファイルが同梱されます。必要に応じて解凍してください。
|DX2LIB|dx2lib_x32.dll|<|ライブラリ本体 | |DX2LIB|dx2lib_x32.dll|<|ライブラリ本体 |
|~|dx2lib_x64.dll|<|~| |~|dx2lib_x64.dll|<|~|
-|~|libdx2lib_x32.a|<|GCC用ライブラリ(定義のみ) |+|~|libdx2lib_x32.a|<|MINGW用ライブラリ(定義のみ) |
|~|libdx2lib_x64.a|<|~| |~|libdx2lib_x64.a|<|~|
|~|dx2lib_x32.llb|<|MSVC用ライブラリ(定義のみ) | |~|dx2lib_x32.llb|<|MSVC用ライブラリ(定義のみ) |
|~|dx2lib_x64.lib|<|~| |~|dx2lib_x64.lib|<|~|
-|~|dx2lib.c|<|ライブラリソース |+|~|dx2lib.cpp|<|ライブラリソース
 +|~|dx2lib_intuitive.cpp|<|~|
|~|dx2lib.h|<|ライブラリヘッダ | |~|dx2lib.h|<|ライブラリヘッダ |
 +|~|dx2memmap.h|<|DXLアイテムアドレス定義ヘッダ |
|~|dx2lib_matlab.h|<|matlab用ヘッダ | |~|dx2lib_matlab.h|<|matlab用ヘッダ |
-|~|makelib.bat|<|ライブラリ再構築用バッチ +|~|dx2lib.py|<|python用モジュール
-|~|83.bat|<|~| +|~|makelib.cmd|<|Windows向けライブラリ再構築用バッチ
-|SampleCode|GCCDeveloperLite|smpl1(templ​ate).c |サンプル +|~|build_dx2lib.sh|<|Linux向けライブラリ再構築用スクリプト
-|~|~|smpl2(ping).c |~| +|SampleCode|C|smpl??.c |サンプル
-|~|~|smpl3(ping2).c |~+|~|~|dxmisc.h |サンプル共通設定
-|~|~|smpl4(reboot).c |~+|~|~|kbhit.h |kbhitエミュレーション
-|~|~|smpl5(byte_rw).c |~+|~|~|makefile |サンプルコンパイル用makefile
-|~|~|smpl6(long_rw).c |~+|~|~|makeexe.cmd|Windows向け再構築用バッチ |
-|~|~|smpl7(sync_rw).c |~+
-|~|~|smpl8(bulk_rw).c |~| +
-|~|~|smpl9(multithread).c |~| +
-|~|~|smpl10(DynamicLoad).c |~| +
-|~|~|smpl11(dualport).c |~| +
-|~|~|whoareyou.h |~|+
|~|~|dx2lib.h |DX2LIBフォルダに収録されるものと同一 | |~|~|dx2lib.h |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2memmap.h |~| |~|~|dx2memmap.h |~|
Line 49: Line 105:
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 | |~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x64.dll |~| |~|~|dx2lib_x64.dll |~|
-|~|LabVIEW2011|sample.vi |サンプル | +|~|Python|smpl??.py |サンプル | 
-|~|~|sample_mx.vi |~+|~|~|kbhit.py |kbhitエミュレーション
-|~|~|synctest.vi |~+|~|~|dx2lib.py |DX2LIBフォルダに収録されるものと同一
-|~|~|dbyte2byte.vi |サブvi +|~|~|dx2lib_x32.dll |~
-|~|~|dbyte2word.vi |~| +|~|~|dx2lib_x64.dll |~| 
-|~|~|errcnt.vi |~|+|~|LabVIEW2011|sample??.vi |サンプル |
|~|~|DX2LIB.llb |DX2LIBラッパーライブラリ | |~|~|DX2LIB.llb |DX2LIBラッパーライブラリ |
 +|~|~|DX2LIB_DXL.llb |DX2LIBラッパーライブラリ |
 +|~|~|DX2LIB_Wrapper.llb |~|
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 | |~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|EXCEL|text.xls |サンプルシート | |~|EXCEL|text.xls |サンプルシート |
|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 | |~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一 |
|~|~|dx2lib_x64.dll |~| |~|~|dx2lib_x64.dll |~|
-|~|Linux|smpl2.c |サンプル | +|~|Ruby|smpl??.rb |サンプル | 
-|~|~|smpl4.c |~| +|~|~|dx2lib_x32.dll |DX2LIBフォルダに収録されるものと同一
-|~|Ruby|SMPL1.c |サンプル | +|~|~|dx2lib_x64.dll |~|
-|~|~|SMPL3.c |~| +
-|~|Python|SMPL1.py |サンプル +
-|~|~|SMPL3.py |~|+
**開発環境毎の設定 [#u3ff03d9] **開発環境毎の設定 [#u3ff03d9]
Line 72: Line 127:
***GCC Developer Lite [#e1d4017c] ***GCC Developer Lite [#e1d4017c]
GCC Developer Liteの詳細については[[こちら>GCC Developer Lite]]。~ GCC Developer Liteの詳細については[[こちら>GCC Developer Lite]]。~
-'SampleCode\GCCDeveloperLite'フォルダにはAPIの基本的な使い方を紹介したサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。+「基本パック」と「WINパック」を[[ダウンロード>GCC Developer Lite#DOWNLOAD]]してインストールしてください。 
 + 
 +'SampleCode\C'フォルダにはAPIの基本的な使い方を紹介したサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。
****DLLの静的リンク [#la562acf] ****DLLの静的リンク [#la562acf]
Line 93: Line 150:
****DLLの動的リンク [#y15bf22f] ****DLLの動的リンク [#y15bf22f]
-動的にDLLを使用する場合はDLL自体をコンパイラオプションへ追記する必要はありません。その代わりにソース中でdx2lib.hをインクルードする前に_DYNAMICLOADマクロを定義しておきます。 +動的にDLLを使用する場合はDLL自体をコンパイラオプションへ追記する必要はありません。その代わりソース中でdx2lib.hをインクルードする前に_DYNAMICLOADマクロを定義しておきます。 
- #define _DYNAMICLOAD +#html{{ 
- #include "dx2lib.h" +<style type="text/css"> 
-これによりヘッダファイル内の諸定義が切り替わり、DLLのロード及びアンロードを行うLoadDLLとUnloadDLLが利用できるようになります。 +    .syntaxhighlighter { 
-  TDeviceID  dev; +     overflow-y: auto !important; 
-  // DLLをロード +     overflow-x: auto !important; 
-  if (LoadDLL ()) { +     max-height: 900px; 
-    if ((dev = DX2_OpenPort (COMPORT, BAUDRATE))) { +     -webkit-text-size-adjust: 100%; 
-      ... +    } 
-      DX2_ClosePort (dev); +</style> 
-    +<pre class="brush: c;"> 
-    // DLLをアンロード +#define _DYNAMICLOAD 
-    UnloadDLL (); +#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] ***Microsoft Visual C++ [#j5a74d33]
Line 134: Line 236:
***DELPHI [#bdd8ef87] ***DELPHI [#bdd8ef87]
'SampleCode\DELPHI'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~ 'SampleCode\DELPHI'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~
-[[DELPHI:http://www.embarcadero.com/jp/p​roducts/delphi]]はPASCAL言語によるPC向け開発ツールであり、外部のDLLへ容易にアクセスする事が出来ます。サンプルに含まれるDX2LIB.pas内にdx2lib_x32.dllないしdx2lib_x64.dllを動的にロードする関数を用意しましたので、ユーザソースのuses節にdx2libを追記すればDynamixel Libraryの各APIへ簡便にアクセスできます。+[[DELPHI:http://www.embarcadero.com/jp/p​roducts/delphi]]はPASCAL言語によるPC向け開発ツールであり、外部のDLLへ容易にアクセスする事ができます。サンプルに含まれるDX2LIB.pas内にdx2lib_x32.dllないしdx2lib_x64.dllを動的にロードする関数を用意しましたので、ユーザソースのuses節にdx2libを追記すればDynamixel Libraryの各APIへ簡便にアクセスできます。
***VB [#p8d7963b] ***VB [#p8d7963b]
Line 142: Line 244:
***Ruby [#r63b1e3e] ***Ruby [#r63b1e3e]
-'SampleCode\Ruby'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。+'SampleCode\Ruby'フォルダにサンプルが同梱されます。ライブラリ名・ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。
-[[Ruby:http://www.ruby-lang.org/ja]]はオープンソースの動的なプログラミング言語で、外部のDLLへ簡易にアクセスすることが出来ます。~ +[[Ruby:http://www.ruby-lang.org/ja]]はオープンソースの動的なプログラミング言語で、外部のライブラリはfiddleを使用してアクセスします。 
-&nbsp; require 'dl/import' +#html{{ 
-  molude dx2lib +&lt;pre class="brush: ruby;"> 
-    extend DL::Importer +require "fiddle/import" 
-    dlload "./dx2lib_x32.dll" + 
-    extern "int DX2_OpenPort( char *, long )" +module DX2LIB 
-  end +  extend Fiddle::Importer 
-  devid = dx2lib.DX2_OpenPort( "ポート名", ボーレート )+  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] ***Python [#mc6a5a49]
-'SampleCode\Ruby'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~ +'SampleCode\Python'フォルダにサンプルが同梱されます。ポート・ボーレート・ID等は使用する環境に合わせて適宜修正して使用します。~ 
-[[Python:http://www.python.jp/Zope]]はオープンソースの動的なプログラミング言語で、外部のDLLへ簡易にアクセスすることが出来ます。+[[Python:http://www.python.jp]]はオープンソースの動的なプログラミング言語で、外部のDLLへ簡易にアクセスできます。
-LinuxでLoadLibraryを呼び出す際はcdllインスタンスを使用します。 +各APIのPython用の宣言を定義したdx2lib.pyをimportするだけで済みます。 
-&nbsp; dx2lib = windll.LoadLibrary( "dx2lib_x32.dll" ) # for window +#html{{ 
-&nbsp; dx2lib = cdll.LoadLibrary( "./dx2lib.so" )  # for linux+&lt;pre class="brush: python;"
 +from dx2lib import * # dx2libをインポート 
 +&lt;/pre> 
 +}} 
 +なおdx2lib.pyはctypesによるDLLの単純なラッパーに過ぎませんので、Pythonならではの抽象的な定義は何一つ受け付けてくれません。Pythonからプログラミングを始めた方は微妙に扱いづらいかと思いますので、詳細はサンプルコードを参考にしてください。 
 + 
 +LinuxやmacOSの場合は予め[[ライブラリを再構築>#w5c096b8]]しておいて下さい。
***Java [#ceff395d] ***Java [#ceff395d]
Line 181: Line 300:
 unloadlibrary('dx2lib')  unloadlibrary('dx2lib')
-***Linux [#w5c096b8] +***Linux & macOS[#w5c096b8] 
-Linux上でのdx2libのコンパイル方法を紹介します。+LinuxないしmacOS上でのdx2libのコンパイル方法を紹介します。
-+コンパイル準備++ダウンロードと展開
-ダウンロードファイルを解凍+ライブラリのアーカイブファイルをダウンロードし展開
-+オブジェクトファイルの作成~ +#html{{ 
-&nbsp; gcc dx2lib.c -o dx2lib.o +&lt;pre class="brush: bash;"> 
-+共有ライブラリの作成+wget https://www.besttechnology.co.jp/download/DX2LIB_V3.0.zip 
-RubyやPython等で使用する場合のみ。+unzip DX2LIB_V3.0.zip 
-&nbsp; gcc -fPIC -shared dx2lib.c -o dx2lib.so +</pre> 
-+コンパイル+}} 
-dx2libのオブジェクトファイルとC言語ソースを合わせてコンパイルする。~++ライブラリ及び共有ライブラリの生成
 +DXLIB2ディレクトリに移動し同梱のスクリプトファイルを実行~ 
 +gccは予めインストールされている必要がある 
 +#html{{ 
 +&lt;pre class="brush: bash;"> 
 +cd DX2LIB_v3.0/DX2LIB 
 +bash ./build_dx2lib.sh 
 +</pre> 
 +}} 
 +コンパイルが成功するとライブラリファイルがサンプルディレクトリにコピーされる 
 ++ユーザプログラムとのリンク
 +生成したライブラリファイルと自身のソースをリンクする。~
ポート・ボーレート等は使用する環境に合わせて適宜追加・修正する。~ ポート・ボーレート等は使用する環境に合わせて適宜追加・修正する。~
-ライブラリは必要に合わせて追加する。+ライブラリ検索パスは必要に合わせて変更する。~ 
-&nbsp; gcc sample.c dx2lib.o -o sample+#html{{ 
 +&lt;pre class="brush: bash;"> 
 +gcc sample.c -L. -ldx2lib -o sample 
 +</pre> 
 +}}
-なお、コンパイルや実行にあたってI/Fやカーネル・ディストリビューションに依存するのがLinuxですので、そのまま使用できない場合は適宜ソースを修正下さい。+'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 <stdio.h> 
 +#include <stdlib.h> 
 +#include <stdbool.h> 
 +#include <ftdi.h> 
 + 
 +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, &devlist, 0, 0); 
 +   if (num > 0) { 
 +     for (int i = 0; i < 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 && ftdi_eeprom_decode(ftdic,0) == 0 && 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, &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 && b; 
 +       } 
 +       ftdi_usb_close (ftdic); 
 +     } 
 +   } else printf ("no device found.\n"); 
 + 
 +   if (f && b) result = EXIT_SUCCESS; 
 +   ftdi_list_free (&devlist); 
 +   ftdi_free (ftdic); 
 +  } 
 +  return result; 
 +
 +</pre> 
 +}}
**API [#ybae1454] **API [#ybae1454]
Dynamixel Libraryではシリアル通信を直接意識するコードを記述せずに、対象IDのデバイスのコントロールテーブルへの読み書き行うAPIを用意しています。~ Dynamixel Libraryではシリアル通信を直接意識するコードを記述せずに、対象IDのデバイスのコントロールテーブルへの読み書き行うAPIを用意しています。~
C言語のソースにdx2lib.hをインクルードすれば、APIを使用するのに必要なプロトタイプとマクロの定義がなされます。 C言語のソースにdx2lib.hをインクルードすれば、APIを使用するのに必要なプロトタイプとマクロの定義がなされます。
 +
 +''注意事項'':~
 +DynamixelのStatus Return Levelを必ず''2''に設定した上で使用する事。それ以外の値が設定されていた場合はAPIが想定した応答が得られず、タイムアウトするまでAPIから返らない。
***DX2_OpenPort [#zbd2f6ef] ***DX2_OpenPort [#zbd2f6ef]
Line 217: Line 409:
~オープンに成功した場合は0以外の値、失敗した場合は0を返す。~ ~オープンに成功した場合は0以外の値、失敗した場合は0を返す。~
-使用例 -使用例
-&nbsp;TDeviceID dev; +#html{{ 
- // COM10を9600bpsでオープン +&lt;pre class="brush: c;"> 
- dev = DX2_OpenPort ("\\\\.\\COM10", 9600);+TDeviceID dev; 
 +// COM10を9600bpsでオープン 
 +dev = DX2_OpenPort ("\\\\.\\COM10", 9600); 
 +</pre> 
 +}}
***DX2_ClosePort [#w1ab7cbb] ***DX2_ClosePort [#w1ab7cbb]
Line 232: Line 428:
~クローズに成功した場合はtrue、失敗した場合はfalseを返す。 ~クローズに成功した場合はtrue、失敗した場合はfalseを返す。
-使用例 -使用例
-&nbsp;TDeviceID dev; +#html{{ 
- // オープン +&lt;pre class="brush: c;"> 
- dev = DX2_OpenPort ("\\\\.\\COM10", 9600); +TDeviceID dev; 
- if (dev) { +// オープン 
-  ... (中略) +dev = DX2_OpenPort ("\\\\.\\COM10", 9600); 
-  // クローズ +if (dev) { 
-  DX2_ClosePort (dev); +  ... (中略) 
-&nbsp;}+  // クローズ 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_SetBaudrate [#ba9f52b8] ***DX2_SetBaudrate [#ba9f52b8]
既にオープンされている[[TDeviceID>#TDeviceID]]の通信速度の変更を行う。~ 既にオープンされている[[TDeviceID>#TDeviceID]]の通信速度の変更を行う。~
実行すると強制的に受信バッファがクリアされる。~ 実行すると強制的に受信バッファがクリアされる。~
-なお、Linux環境におけるボーレートの設定は、POSIX.1でサポートする値(50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3500000, 4000000)であればtcsetattrを使用して処理するが、これらの値に当てはまらない場合はioctrlを使用する。その際I/Fがこれらのボーレートに対応していなかったり、ioctrlをサポートしない場合、本APIは失敗する。 
 bool DX2_SetBaudrate (TDeviceID dvid, long baud);  bool DX2_SetBaudrate (TDeviceID dvid, long baud);
-パラメータ -パラメータ
Line 255: Line 454:
~通信速度の変更が成功するとtrue、失敗するとfalseを返す。~ ~通信速度の変更が成功するとtrue、失敗するとfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID dev; +#html{{ 
- // オープン +&lt;pre class="brush: c;"> 
- dev = DX2_OpenPort ("\\\\.\\COM10", 9600); +TDeviceID dev; 
- if (dev) { +// オープン 
-  // 通信速度を1M[bps]に変更 +dev = DX2_OpenPort ("\\\\.\\COM10", 9600); 
-  DX2_SetBaudrate (dev, 1000000); +if (dev) { 
-  ... (中略) +  // 通信速度を1M[bps]に変更 
-  // クローズ +  DX2_SetBaudrate (dev, 1000000); 
-  DX2_ClosePort (dev); +  ... (中略) 
-&nbsp;}+  // クローズ 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_Active [#ie20e4a7] ***DX2_Active [#ie20e4a7]
Line 277: Line 480:
~指定されたdvidが使用可能な場合はtrue、使用不可の場合はfalseを返す。 ~指定されたdvidが使用可能な場合はtrue、使用不可の場合はfalseを返す。
-使用例 -使用例
-&nbsp;TDeviceID dev; +#html{{ 
- // オープン +&lt;pre class="brush: c;"> 
- dev = DX2_OpenPort ("\\\\.\\COM10", 9600); +TDeviceID dev; 
- if (dev) { +// オープン 
-  while (DX2_Active (dev)) { +dev = DX2_OpenPort ("\\\\.\\COM10", 9600); 
-    ... (中略) +if (dev) { 
-  +  while (DX2_Active (dev)) { 
-  // クローズ +    ... (中略) 
-  DX2_ClosePort (dev); +  } 
-&nbsp;}+  // クローズ 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_SetTimeOutOffset [#h4a1b54e] ***DX2_SetTimeOutOffset [#h4a1b54e]
I/FやOSの都合で生じるであろうタイムラグを予め設定する。~ I/FやOSの都合で生じるであろうタイムラグを予め設定する。~
内部で算出している受信タイムアウト時間とタイムアウトオフセット時間を加算した時間を超えた場合に、タイムアウトエラーとして処理する。~ 内部で算出している受信タイムアウト時間とタイムアウトオフセット時間を加算した時間を超えた場合に、タイムアウトエラーとして処理する。~
-デフォルトは20[ms]。+デフォルトは30[ms]。
 void DX2_SetTimeOutOffset (TDeviceID dvid, uint32_t offsettime);  void DX2_SetTimeOutOffset (TDeviceID dvid, uint32_t offsettime);
-パラメータ -パラメータ
Line 309: Line 516:
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 ~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id''' --uint8_t '''id'''
-~対象とするID (0~254)。+~対象とするID (0~252, 254)。
--[[TErrorCode>#TErrorCode]] '''*err''' --[[TErrorCode>#TErrorCode]] '''*err'''
~エラーコード。 ~エラーコード。
Line 316: Line 523:
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~ ~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- // オープン +TDeviceID  dev; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 57143); +TErrorCode err; 
- if (dev) { +// オープン 
-  // ID=1にPINGを発行 +dev = DX2_OpenPort ("\\\\.\\COM10", 57143); 
-  if (DX2_Ping (dev, 1, &err)) +if (dev) { 
-    printf ("Found [%08X]\n", err); +  // ID=1にPINGを発行 
-  else +  if (DX2_Ping (dev, 1, &amp;err)) 
-    printf ("Not found [%08X]\n", err); +    printf ("Found [%08X]\n", err); 
-  // クローズ +  else 
-  DX2_ClosePort (dev); +    printf ("Not found [%08X]\n", err); 
-&nbsp;}+  // クローズ 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_Ping2 [#g16504b3] ***DX2_Ping2 [#g16504b3]
Line 348: Line 559:
~1台以上のデバイスからの応答が得られた場合はtrue、それ以外はfalseを返す。~ ~1台以上のデバイスからの応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode  err; +&lt;pre class="brush: c;"> 
- uint8_t    id; +TDeviceID  dev; 
- TDxAlarmStatus stat[254]; +TErrorCode  err; 
- int        i; +uint8_t    id; 
- uint32_t    num = 254+TDxAlarmStatus stat[254]; 
- // オープン +int        i; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 57143); +uint32_t    num = 252
- if (dev) { +// オープン 
-  // 不明な対象に対してPINGを発行 +dev = DX2_OpenPort ("\\\\.\\COM10", 57143); 
-  if (DX2_Ping2 (dev, &num, stat, &err)) { +if (dev) { 
-    for (i = 0; i < num; i++) +  // 不明な対象に対してPINGを発行 
-      printf ("Found ID=%d %02X\n", stat[i].id, stat[i].Status); +  if (DX2_Ping2 (dev, &amp;num, stat, &amp;err)) { 
-  +    for (i = 0; i < num; i++) 
-  // クローズ +      printf ("Found ID=%d %02X\n", stat[i].id, stat[i].Status); 
-   DX2_ClosePort (dev); +  } 
- }+  // クローズ 
 +  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, &err)) 
 +   printf ("Success [%08X]\n", err); 
 +  else 
 +   printf ("Fail [%08X]\n", err); 
 +  // クローズ 
 +  DX2_ClosePort (dev); 
 +
 +</pre> 
 +}}
***DX2_ReadByteData [#u7d86432] ***DX2_ReadByteData [#u7d86432]
Line 384: Line 663:
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~ ~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint8_t    dat; +TDeviceID  dev; 
- // オープン +TErrorCode err; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +uint8_t    dat; 
- if (dev) { +// オープン 
-  // ID=1のXL-320からLEDの状態を取得 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { +if (dev) { 
-    printf ("LED STAT=%d\n", dat); +  // ID=1のXL-320からLEDの状態を取得 
-  +  if (DX2_ReadByteData (dev, 1, 25, &amp;dat, &amp;err)) { 
-  DX2_ClosePort (dev); +    printf ("LED STAT=%d\n", dat); 
-&nbsp;}+  } 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_WriteByteData [#ma2205f0] ***DX2_WriteByteData [#ma2205f0]
Line 416: Line 699:
BROADCASTING IDを指定した場合は応答待ちを行わない。 BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint8_t    dat; +TDeviceID  dev; 
- // オープン +TErrorCode err; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +uint8_t    dat; 
- if (dev) { +// オープン 
-  // ID=1のXL-320からLEDの状態を取得 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { +if (dev) { 
-    dat = (dat + 1) & 7; +  // ID=1のXL-320からLEDの状態を取得 
-    // ID=1のXL-320へLEDの状態を設定 +  if (DX2_ReadByteData (dev, 1, 25, &amp;dat, &amp;err)) { 
-    DX2_WriteByteData (dev, 1, 25, dat, &err); +    dat = (dat + 1) &amp; 7; 
-  +    // ID=1のXL-320へLEDの状態を設定 
-  DX2_ClosePort (dev); +    DX2_WriteByteData (dev, 1, 25, dat, &amp;err); 
-&nbsp;}+  } 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_ReadWordData [#x202d573] ***DX2_ReadWordData [#x202d573]
Line 449: Line 736:
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~ ~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint16_t  dat; +TDeviceID  dev; 
- // オープン +TErrorCode err; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +uint16_t  dat; 
- if (dev) { +// オープン 
-  // ID=1のXL-320から現在位置を取得 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  if (DX2_ReadWordData (dev, 1, 30, &dat, &err)) { +if (dev) { 
-    printf ("PRESENT POS=%d\n", dat); +  // ID=1のXL-320から現在位置を取得 
-  +  if (DX2_ReadWordData (dev, 1, 30, &amp;dat, &amp;err)) { 
-  DX2_ClosePort (dev); +    printf ("PRESENT POS=%d\n", dat); 
-&nbsp;}+  } 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_WriteWordData [#pcc1b3ce] ***DX2_WriteWordData [#pcc1b3ce]
Line 481: Line 772:
BROADCASTING IDを指定した場合は応答待ちを行わない。 BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- // オープン +TDeviceID  dev; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +TErrorCode err; 
- if (dev) { +// オープン 
-  // ID=1のXL-320へ位置(511)を指令 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  DX2_WriteWordData (dev, 1, 30, 511, &err); +if (dev) { 
-  DX2_ClosePort (dev); +  // ID=1のXL-320へ位置(511)を指令 
-&nbsp;}+  DX2_WriteWordData (dev, 1, 30, 511, &amp;err); 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_ReadLongData [#d27bfdc2] ***DX2_ReadLongData [#d27bfdc2]
Line 509: Line 804:
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~ ~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint32_t  dat; +TDeviceID  dev; 
- // オープン +TErrorCode err; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +uint32_t  dat; 
- if (dev) { +// オープン 
-  // ID=1のXM430から現在位置を取得 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  if (DX2_ReadWordData (dev, 1, 132, &dat, &err)) { +if (dev) { 
-    printf ("PRESENT POS=%d\n", dat); +  // ID=1のXM430から現在位置を取得 
-  +  if (DX2_ReadWordData (dev, 1, 132, &amp;dat, &amp;err)) { 
-  DX2_ClosePort (dev); +    printf ("PRESENT POS=%d\n", dat); 
-&nbsp;}+  } 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_WriteLongData [#c3bc7240] ***DX2_WriteLongData [#c3bc7240]
Line 541: Line 840:
BROADCASTING IDを指定した場合は応答待ちを行わない。 BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- // オープン +TDeviceID  dev; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +TErrorCode err; 
- if (dev) { +// オープン 
-  // ID=1のXM430へ位置(2047)を指令 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  DX2_WriteWordData (dev, 1, 116, 2047, &err); +if (dev) { 
-  DX2_ClosePort (dev); +  // ID=1のXM430へ位置(2047)を指令 
-&nbsp;}+  DX2_WriteWordData (dev, 1, 116, 2047, &amp;err); 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_ReadBlockData [#b8a1ae1e] ***DX2_ReadBlockData [#b8a1ae1e]
Line 571: Line 874:
~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~ ~正常な応答が得られた場合はtrue、それ以外はfalseを返す。~
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint8_t    gain[3]; +TDeviceID  dev; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +TErrorCode err; 
- if (dev) { +uint8_t    gain[3]; 
-  // ID=1のXL-320からPIDゲインのデータを取得 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  if (DX2_ReadBlockData (dev, 1, 26, gain, 3, &err) { +if (dev) { 
-    printf ( +  // ID=1のXL-320からPIDゲインのデータを取得 
-      "D=%d I=%d P=%d\n", +  if (DX2_ReadBlockData (dev, 1, 26, gain, 3, &amp;err) { 
-      gain[0], gain[1], gain[2] +    printf ( 
-    ); +    "D=%d I=%d P=%d\n", 
-  +    gain[0], gain[1], gain[2] 
-  DX2_ClosePort (dev); +    ); 
-&nbsp;}+  } 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_WriteBlockData [#fcf55aa0] ***DX2_WriteBlockData [#fcf55aa0]
対象IDのコントロールテーブルへ指定サイズのデータを書き込む。 対象IDのコントロールテーブルへ指定サイズのデータを書き込む。
- bool DX2_WriteBlockData(TDeviceID dvid, uint8_t id, uint16_t adr, uint8_t *dat, uint32_t len, TErrorCode *err);+ bool DX2_WriteBlockData(TDeviceID dvid, uint8_t id, uint16_t adr, const uint8_t *dat, uint32_t len, TErrorCode *err);
-パラメータ -パラメータ
--[[TDeviceID>#TDeviceID]] '''dvid''' --[[TDeviceID>#TDeviceID]] '''dvid'''
Line 607: Line 914:
BROADCASTING IDを指定した場合は応答待ちを行わない。 BROADCASTING IDを指定した場合は応答待ちを行わない。
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint8_t    gain[3] = { 1, 1, 1 }; +TDeviceID  dev; 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +TErrorCode err; 
- if (dev) { +uint8_t    gain[3] = { 1, 1, 1 }; 
-  // ID=1のXL-320のPIDゲインを変更 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  DX2_WriteBlockData (dev, 1, 26, gain, 3, &err); +if (dev) { 
-  DX2_ClosePort (dev); +  // ID=1のXL-320のPIDゲインを変更 
-&nbsp;}+  DX2_WriteBlockData (dev, 1, 26, gain, 3, &amp;err); 
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre> 
 +}}
***DX2_ReadSyncData [#iac9751e] ***DX2_ReadSyncData [#iac9751e]
Line 636: Line 947:
~指定したデバイス数が応答したらtrue、それ以外はfalseを返す。~ ~指定したデバイス数が応答したら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},
 +};
- // XM430の120番地から2バイト分のデータをid=1,2,3より読み出すパラメータ +// 読み出しすデータの構造体 
- const TSyncReadParam param = +typedef struct
-  addr:120, +  uint8_t    id; 
-   length:2, +  TErrorCode err; 
-  ids:{1,2,3}, +  uint16_t    RTTick; 
- };+} __attribute__ ((gcc_struct, __packed__)) TSyncR[3];
- // 読み出しすデータの構造体 +TSyncR     rdat; 
- typedef struct { +TDeviceID  dev; 
-   uint8_t    id; +TErrorCode  err; 
-   TErrorCode  err; +if ((dev = DX2_OpenPort ("\\\\.\\COM5", 1000000))) { 
-   uint16_t    RTTick; +  uint32_t num = 3; // 3軸 
- } __attribute__ ((gcc_struct, __packed__)) TSyncR[3]; +  DX2_ReadSyncData (dev, &amp;param, &amp;num, (uint8_t *)&amp;rdat, &amp;err); 
- TSyncR     rdat; +  printf("resul num=%d\n", num); 
- +  for (int i = 0; i < num; i++) { 
- TDeviceID  dev; +    printf("ID:%d ERR:%04X tick=%d\n", rdat[i].id, rdat[i].err, rdat[i].RTTick); 
- TErrorCode  err; +  } 
- if ((dev = DX2_OpenPort ("\\\\.\\COM5", 1000000))) { +  DX2_ClosePort (dev); 
-  uint32_t num = 3; // 3軸 +} 
-  DX2_ReadSyncData (dev, ¶m, &num, (uint8_t *)&rdat, &err); +&lt;/pre>; 
-  printf("resul num=%d\n", num); +}}
-  for (int i = 0; i < num; i++) { +
-    printf("ID:%d ERR:%04X tick=%d\n", rdat[i].id, rdat[i].err, rdat[i].RTTick); +
-  +
-  DX2_ClosePort (dev); +
-&nbsp;};+
***DX2_WriteSyncData [#v566e16b] ***DX2_WriteSyncData [#v566e16b]
Line 681: Line 995:
~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。~ ~インターフェースより送信が行われた場合は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;
- // 2台のXM430へ位置を指令する想定の構造体 +TSyncW syncw = { 
- typedef struct { +  116,  // アドレス (Goal Position) 
-   uint16_t    addr; +  4,    // データ長 (4 byte) 
-   uint16_t    length; +  {{ 1, 3072 },  // 1軸目 ID=1, GoalPosition=3072 
-   struct { +  { 2, 1024 }}  // 2軸目 ID=2, GoalPosition=1024 
-     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; +TDeviceID  dev; 
- TErrorCode err;+TErrorCode err;
- dev = DX2_OpenPort ("\\\\.\\COM5", 1000000); +dev = DX2_OpenPort ("\\\\.\\COM5", 1000000); 
- if (dev) { +if (dev) { 
-  // 2台のXM430へ個別の位置を指令 +  // 2台のXM430へ個別の位置を指令 
-  DX2_WriteSyncData (dev, (uint8_t *)&syncw, sizeof(syncw), &err); +  DX2_WriteSyncData (dev, (uint8_t *)&amp;syncw, sizeof(syncw), &amp;err); 
-  DX2_ClosePort (dev); +  DX2_ClosePort (dev); 
-&nbsp;};+} 
 +&lt;/pre>; 
 +}}
***DX2_ReadBulkData [#wf7d9427] ***DX2_ReadBulkData [#wf7d9427]
Line 729: Line 1046:
~指定したデバイス数が応答したらtrue、それ以外はfalseを返す。~ ~指定したデバイス数が応答したらtrue、それ以外はfalseを返す。~
-使用例 -使用例
 +#html{{
 +<pre class="brush: c;">
 +TDeviceID  dev;
 +TErrorCode err;
 +uint8_t    rdat[1000]; // 読み出したデータの保存先
- TDeviceID  dev; +const TBulkReadParam param[3] = { 
- TErrorCode err; +  {1,100,20}, // ID=1の100番地から20バイト分 
- uint8_t    rdat[1000]; // 読み出したデータの保存先+  {2,124,12}, // ID=2の124番地から12バイト分 
 +  {3,  0, 7}  // ID=3の0番地から7バイト分 
 +};
- const TBulkReadParam param[3] = { +dev = DX2_OpenPort ("\\\\.\\COM5", 1000000); 
-  {1,100,20}, // ID=1の124番地から20バイト分 +if (dev) { 
-  {2,124,12}, // ID=2の124番地から12バイト分 +  uint32_t num = 3; // 3軸 
-  {3, 0, 7}  // ID=3の0番地から7バイト分 +  PBulkReadResult pr = (void *)rdat; 
- };+  DX2_ReadBulkData (dev, &param[0], &num, (uint8_t *)&rdat, &err); 
 +  printf("resul num=%d err=$%04x\n", num, err); 
 +  for (int i = 0; i < num; i++) { 
 +    if (pr->size > 0) { 
 +     printf("\nID:%d err:$%04X ",pr->id, pr->err); 
 +     for (int j = 0; j < pr->size - 5; j++) printf("%02X ", pr->dat[j]); 
 +     pr = (void *)pr + pr->size; // 次のデータ用にポインタを更新 
 +    } 
 + ;
 +  DX2_ClosePort (dev); 
 +
 +</pre> 
 +}}
- dev = DX2_OpenPort ("\\\\.\\COM5", 1000000); +***DX2_WriteBulkData [#r6a06745] 
-&nbsp;if (dev) { +BULKインストラクションを使用して複数の個別なID・アドレス・データサイズで書き込みを行う。 
-&nbsp; uint32_t num = 3; // 3軸 + bool DX2_WriteBulkData (TDeviceID dvid, uint8_t *dat, uint32_t size, TErrorCode *err); 
-   PBulkReadResult pr = (void *)rdat+-パラメータ 
-  DX2_ReadBulkData (dev, ¶m[0], &num, (uint8_t *)&rdat, &err)+--[[TDeviceID&gt;#TDeviceID]] '''dvid''' 
-  printf("resul num=%d err=$%04x\n", num, err)+~DX2_OpenPortで開いた際の[[TDeviceID&gt;#TDeviceID]]。 
-   for (int i = 0; i < num; i++) { +--uint8_t '''*dat''' 
-     if (pr->size > 0) { +~書き込むパラメータの保存先。 
-      printf("\nID:%d err:$%04X ",pr->id, pr->err); +--uint32_t '''size''' 
-      for (int j = 0; j <; pr->;size - 5; j++) printf("%02X ", pr->dat[j]); +~パラメータのサイズ。 
-       pr = (void *)pr + pr-&gt;size; // 次のデータ用にポインタを更新 +--[[TErrorCode>#TErrorCode]] '''*err''' 
-    } +~エラーコード。 
-&nbsp; } +-戻り値 
-  DX2_ClosePort (dev); +--bool 
-&nbsp;};+~インターフェースより送信が行われた場合は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=
 +  {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)
 +&nbsp; // 3台のXM430へ個別の情報を書き込み 
 +  DX2_WriteBulkData (dev, (uint8_t *)&amp;BW, sizeof(BW), &err)
 +  DX2_ClosePort (dev); 
 +} 
 +&lt;/pre>; 
 +}}
***DX2_TxPacket [#r051327a] ***DX2_TxPacket [#r051327a]
Line 763: Line 1126:
~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。 ~DX2_OpenPortで開いた際の[[TDeviceID>#TDeviceID]]。
--uint8_t '''id''' --uint8_t '''id'''
-~対象とするID (0~254)。+~対象とするID (0~252)。
--[[TInstruction>#TInstruction]] '''inst''' --[[TInstruction>#TInstruction]] '''inst'''
~使用するインストラクション。 ~使用するインストラクション。
Line 775: Line 1138:
~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。 ~インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。
-使用例 -使用例
-&nbsp;TDeviceID  dev; +#html{{ 
- TErrorCode err; +&lt;pre class="brush: c;"> 
- uint8_t    param[2] = { +TDeviceID  dev; 
-  25,    // アドレス (LED) +TErrorCode err; 
-  0,    // データ +uint8_t    param[2] = { 
- }; +  25,    // アドレス (LED) 
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +  0,    // データ 
- if (dev) { +}; 
-  // ID=1のAX-12+のLEDを消灯 +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
-  DX2_TxPacket (dev, 1, INST_WRITE, param, 2, &err); +if (dev) { 
-  DX2_ClosePort (dev); +  // ID=1のAX-12+のLEDを消灯 
- }+  DX2_TxPacket (dev, 1, INST_WRITE, param, 2, &amp;err); 
- +  DX2_ClosePort (dev); 
-***DX2_WriteBulkData [#r6a06745] +
-BULKインストラクションを使用して複数の個別なID・アドレス・データサイズで書き込みを行う。 +&lt;/pre
-&nbsp;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を返す。~ +
--使用例 +
- +
- // 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 *)&BW, sizeof(BW), &err); +
-   DX2_ClosePort (dev); +
- };+
***DX2_RxPacket [#r280cda8] ***DX2_RxPacket [#r280cda8]
Line 850: Line 1177:
~受信成功時はtrue、それ以外はfalseを返す。 ~受信成功時はtrue、それ以外はfalseを返す。
-使用例 -使用例
-&nbsp;int        i; +#html{{ 
- uint32_t  len; +&lt;pre class="brush: c;"> 
- TDeviceID  dev; +int        i; 
- TErrorCode err; +uint32_t  len; 
- uint8_t    param[2] = { +TDeviceID  dev; 
-  25,    // アドレス (LED) +TErrorCode err; 
-  1,    // サイズ +uint8_t    param[2] = { 
- };+  25,    // アドレス (LED) 
 +  1,    // サイズ 
 +};
- dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); +dev = DX2_OpenPort ("\\\\.\\COM10", 1000000); 
- if (dev) { +if (dev) { 
-  // ID=1のAX-12+からLEDの状態を読み出す要求 +  // ID=1のAX-12+からLEDの状態を読み出す要求 
-  if (DX2_TxPacket (dev, 1, INST_READ, param, 2, &err)) { +  if (DX2_TxPacket (dev, 1, INST_READ, param, 2, &amp;err)) { 
-    // ステータスパケットを受信 +    // ステータスパケットを受信 
-    DX2_RxPacket (dev, dat, sizeof (dat), &len, 100, &err); +    DX2_RxPacket (dev, dat, sizeof (dat), &amp;len, 100, &amp;err); 
-    for (i = 0; i < len; i++) { +    for (i = 0; i < len; i++) { 
-      printf ("[%02X]", dat[i]); +      printf ("[%02X]", dat[i]); 
-    +   
-  +  } 
-  DX2_ClosePort (dev); +  DX2_ClosePort (dev); 
-&nbsp;};+} 
 +&lt;/pre>; 
 +}}
***DX2LIBのオリジナルな定義 [#af9ca340] ***DX2LIBのオリジナルな定義 [#af9ca340]
Line 893: Line 1224:
INST_BULK_WRITE INST_BULK_WRITE
&aname(TDxAlarmStatus); &aname(TDxAlarmStatus);
-:TDx2AlarmStatus | struct {&br; uint8_t id;&br; TErrorCode Status;&br;+:TDx2AlarmStatus | struct {&br;  ;uint8_t id;&br;  ;TErrorCode Status;&br;
}~ }~
idとTErrorCodeを対にした構造体でアライメントは1バイト。[[DX2_Ping2>#g16504b3]]で使用される。 idとTErrorCodeを対にした構造体でアライメントは1バイト。[[DX2_Ping2>#g16504b3]]で使用される。
&aname(TSyncReadParam); &aname(TSyncReadParam);
-:TSyncReadParam | struct {&br; uint16_t addr;&br; uint16_t length;&br; uint8_t  ids[254];&br;}~+:TSyncReadParam | struct {&br;  ;uint16_t addr;&br;  ;uint16_t length;&br;  ;uint8_t  ids[256];&br;}~
addr, length, idsをまとめた構造体でアライメントは1バイト。[[DX2_ReadSyncData>#iac9751e]]で使用される。 addr, length, idsをまとめた構造体でアライメントは1バイト。[[DX2_ReadSyncData>#iac9751e]]で使用される。
&aname(TBulkReadParam); &aname(TBulkReadParam);
-:TBulkReadParam | struct {&br; uint8_t id;&br; uint16_t addr;&br; uint16_t length;&br;}~+:TBulkReadParam | struct {&br;  ;uint8_t id;&br;  ;uint16_t addr;&br;  ;uint16_t length;&br;}~
id, addr, lengthをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で使用される。 id, addr, lengthをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で使用される。
&aname(TBulkReadResult); &aname(TBulkReadResult);
-:TBulkReadResult| struct {&br; uint16_t size;&br; uint8_t id;&br; TErrorCode err;&br; uint8_t dat[];&br;}~+:TBulkReadResult| struct {&br;  ;uint16_t size;&br;  ;uint8_t id;&br;  ;TErrorCode err;&br;  ;uint8_t dat[];&br;}~
size, id, err, datをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で読み出されたデータのアクセスに使用される。 size, id, err, datをまとめた構造体でアライメントは1バイト。[[DX2_ReadBulkData>#wf7d9427]]で読み出されたデータのアクセスに使用される。
&aname(TErrorCode); &aname(TErrorCode);
Line 919: Line 1250:
|8|ERR_TIMEOUT|受信タイムアウト | |8|ERR_TIMEOUT|受信タイムアウト |
|7|ERR_DX2_ALERT|ハード的な異常検出 | |7|ERR_DX2_ALERT|ハード的な異常検出 |
-|6|ERR_DX2_LENGTHLONG=6&br;ERR_DX2_LENGTHSHORT=5&br;ERR_DX2_OVERRANGE=4&br;ERR_DX2_CRCERROR=3&br;ERR_DX2_UNDEFINST=2&br;ERR_DX2_INSTERROR=1|パケットの処理や数値範囲に関するエラー |+|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|~|~| |5|~|~|
|4|~|~| |4|~|~|
Line 926: Line 1257:
|1|~|~| |1|~|~|
|0|~|~| |0|~|~|
 +
 +**追加API [#ac9f5496]
 +#include(DXL_intuitive,notitle)


トップ   差分 リロード印刷に適した表示   全ページ一覧 単語検索 最新ページの一覧   最新ページのRSS 1.0 最新ページのRSS 2.0 最新ページのRSS Atom