18: 2022-02-23 (水) 22:14:16 takaboo | 現: 2023-11-12 (日) 00:09:35 takaboo | ||
---|---|---|---|
Line 4: | Line 4: | ||
シリアル通信に関するAPI、タイミングやエラー処理、プロトコルの整合性チェック等をライブラリ内で行うため、シリアル通信である事をほとんど意識する事無くアプリケーションの作りこみに専念できます。 | シリアル通信に関するAPI、タイミングやエラー処理、プロトコルの整合性チェック等をライブラリ内で行うため、シリアル通信である事をほとんど意識する事無くアプリケーションの作りこみに専念できます。 | ||
- | なお、PCと[[BTE061D]]・[[BTE061E]]・[[BTE068]]・[[BTE068B]]・[[BTE068C]]・[[BTE082]]・[[BTE083]]・[[BTE074]]・[[BTE079]]・[[BTE080]]・[[BTE079B]]・[[BTE080B]]・[[BTE079C]]・[[BTE080C]]・[[BTE096]]・[[BTE101]]・[[BTX229>http://emanual.robotis.com/docs/en/parts/interface/u2d2/]]のいずれかがUSBポートに接続され、PCのOSに仮想COMポートが増設された状態で使用するものとします。[[BTE100]]の場合はRaspberry Piに依存します。 | + | なお、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]]を装備した装置を同一ネットワーク上で同時に運用する事は推奨できない。| | |CENTER:BGCOLOR(red): :idea:|[[DYNAMIXEL Communiation Protocol 1.0]]と[[DYNAMIXEL Communiation Protocol 2.0]]を装備した装置を同一ネットワーク上で同時に運用する事は推奨できない。| | ||
Line 10: | Line 10: | ||
**ライブラリおよびサンプルプログラムのダウンロード [#j8bd290f] | **ライブラリおよびサンプルプログラムのダウンロード [#j8bd290f] | ||
以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。 | 以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。 | ||
- | -''2022/3/1 Ver.2.9''~ | + | -''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) | #ref(https://www.besttechnology.co.jp/download/DX2LIB_V2.9.zip) | ||
更新内容 | 更新内容 | ||
Line 147: | Line 152: | ||
動的にDLLを使用する場合はDLL自体をコンパイラオプションへ追記する必要はありません。その代わりソース中でdx2lib.hをインクルードする前に_DYNAMICLOADマクロを定義しておきます。 | 動的にDLLを使用する場合はDLL自体をコンパイラオプションへ追記する必要はありません。その代わりソース中でdx2lib.hをインクルードする前に_DYNAMICLOADマクロを定義しておきます。 | ||
#html{{ | #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;"> | <pre class="brush: c;"> | ||
#define _DYNAMICLOAD | #define _DYNAMICLOAD | ||
Line 293: | Line 306: | ||
#html{{ | #html{{ | ||
<pre class="brush: bash;"> | <pre class="brush: bash;"> | ||
- | wget https://www.besttechnology.co.jp/download/DX2LIB_V2.9.zip | + | wget https://www.besttechnology.co.jp/download/DX2LIB_V3.0.zip |
- | unzip DX2LIB_V2.9.zip | + | unzip DX2LIB_V3.0.zip |
</pre> | </pre> | ||
}} | }} | ||
Line 302: | Line 315: | ||
#html{{ | #html{{ | ||
<pre class="brush: bash;"> | <pre class="brush: bash;"> | ||
- | cd DX2LIB_v2.9/DX2LIB | + | cd DX2LIB_v3.0/DX2LIB |
bash ./build_dx2lib.sh | bash ./build_dx2lib.sh | ||
</pre> | </pre> | ||
Line 326: | Line 339: | ||
コンパイルや実行にあたってI/Fやカーネル・ディストリビューションに依存しますので、そのまま使用できない場合は適宜ソースを修正下さい。またWindowsを前提とした_DYNAMICLOADマクロが宣言されているとコンパイルできません。~ | コンパイルや実行にあたってI/Fやカーネル・ディストリビューションに依存しますので、そのまま使用できない場合は適宜ソースを修正下さい。またWindowsを前提とした_DYNAMICLOADマクロが宣言されているとコンパイルできません。~ | ||
なおI/Fのポート名やボーレート等はサンプル共通として「dxmisc.h」に記述してありますので、環境に応じて修正した上でコンパイルして下さい。~ | なおI/Fのポート名やボーレート等はサンプル共通として「dxmisc.h」に記述してありますので、環境に応じて修正した上でコンパイルして下さい。~ | ||
- | またmacの場合のポート名は「/dev/tty.usbserial-????」ではなく「/dev/cu.usbserial-????」を指定してください。 | + | また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] | ||
Line 472: | Line 531: | ||
if (dev) { | if (dev) { | ||
// ID=1にPINGを発行 | // ID=1にPINGを発行 | ||
- | if (DX2_Ping (dev, 1, &err)) | + | if (DX2_Ping (dev, 1, &err)) |
printf ("Found [%08X]\n", err); | printf ("Found [%08X]\n", err); | ||
else | else | ||
Line 512: | Line 571: | ||
if (dev) { | if (dev) { | ||
// 不明な対象に対してPINGを発行 | // 不明な対象に対してPINGを発行 | ||
- | if (DX2_Ping2 (dev, &num, stat, &err)) { | + | if (DX2_Ping2 (dev, &num, stat, &err)) { |
for (i = 0; i < num; i++) | for (i = 0; i < num; i++) | ||
printf ("Found ID=%d %02X\n", stat[i].id, stat[i].Status); | printf ("Found ID=%d %02X\n", stat[i].id, stat[i].Status); | ||
Line 576: | Line 635: | ||
if (dev) { | if (dev) { | ||
// ID=1にREBOOTを発行 | // ID=1にREBOOTを発行 | ||
- | if (DX2_Reboot (dev, 1, &err)) | + | if (DX2_Reboot (dev, 1, &err)) |
printf ("Success [%08X]\n", err); | printf ("Success [%08X]\n", err); | ||
else | else | ||
Line 613: | Line 672: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320からLEDの状態を取得 | // ID=1のXL-320からLEDの状態を取得 | ||
- | if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { | + | if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { |
printf ("LED STAT=%d\n", dat); | printf ("LED STAT=%d\n", dat); | ||
} | } | ||
Line 649: | Line 708: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320からLEDの状態を取得 | // ID=1のXL-320からLEDの状態を取得 | ||
- | if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { | + | if (DX2_ReadByteData (dev, 1, 25, &dat, &err)) { |
- | dat = (dat + 1) & 7; | + | dat = (dat + 1) & 7; |
// ID=1のXL-320へLEDの状態を設定 | // ID=1のXL-320へLEDの状態を設定 | ||
- | DX2_WriteByteData (dev, 1, 25, dat, &err); | + | DX2_WriteByteData (dev, 1, 25, dat, &err); |
} | } | ||
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
Line 686: | Line 745: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320から現在位置を取得 | // ID=1のXL-320から現在位置を取得 | ||
- | if (DX2_ReadWordData (dev, 1, 30, &dat, &err)) { | + | if (DX2_ReadWordData (dev, 1, 30, &dat, &err)) { |
printf ("PRESENT POS=%d\n", dat); | printf ("PRESENT POS=%d\n", dat); | ||
} | } | ||
Line 721: | Line 780: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320へ位置(511)を指令 | // ID=1のXL-320へ位置(511)を指令 | ||
- | DX2_WriteWordData (dev, 1, 30, 511, &err); | + | DX2_WriteWordData (dev, 1, 30, 511, &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 754: | Line 813: | ||
if (dev) { | if (dev) { | ||
// ID=1のXM430から現在位置を取得 | // ID=1のXM430から現在位置を取得 | ||
- | if (DX2_ReadWordData (dev, 1, 132, &dat, &err)) { | + | if (DX2_ReadWordData (dev, 1, 132, &dat, &err)) { |
printf ("PRESENT POS=%d\n", dat); | printf ("PRESENT POS=%d\n", dat); | ||
} | } | ||
Line 789: | Line 848: | ||
if (dev) { | if (dev) { | ||
// ID=1のXM430へ位置(2047)を指令 | // ID=1のXM430へ位置(2047)を指令 | ||
- | DX2_WriteWordData (dev, 1, 116, 2047, &err); | + | DX2_WriteWordData (dev, 1, 116, 2047, &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 823: | Line 882: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320からPIDゲインのデータを取得 | // ID=1のXL-320からPIDゲインのデータを取得 | ||
- | if (DX2_ReadBlockData (dev, 1, 26, gain, 3, &err) { | + | if (DX2_ReadBlockData (dev, 1, 26, gain, 3, &err) { |
printf ( | printf ( | ||
"D=%d I=%d P=%d\n", | "D=%d I=%d P=%d\n", | ||
Line 863: | Line 922: | ||
if (dev) { | if (dev) { | ||
// ID=1のXL-320のPIDゲインを変更 | // ID=1のXL-320のPIDゲインを変更 | ||
- | DX2_WriteBlockData (dev, 1, 26, gain, 3, &err); | + | DX2_WriteBlockData (dev, 1, 26, gain, 3, &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 909: | Line 968: | ||
if ((dev = DX2_OpenPort ("\\\\.\\COM5", 1000000))) { | if ((dev = DX2_OpenPort ("\\\\.\\COM5", 1000000))) { | ||
uint32_t num = 3; // 3軸 | uint32_t num = 3; // 3軸 | ||
- | DX2_ReadSyncData (dev, ¶m, &num, (uint8_t *)&rdat, &err); | + | DX2_ReadSyncData (dev, &param, &num, (uint8_t *)&rdat, &err); |
printf("resul num=%d\n", num); | printf("resul num=%d\n", num); | ||
for (int i = 0; i < num; i++) { | for (int i = 0; i < num; i++) { | ||
Line 961: | Line 1020: | ||
if (dev) { | if (dev) { | ||
// 2台のXM430へ個別の位置を指令 | // 2台のXM430へ個別の位置を指令 | ||
- | DX2_WriteSyncData (dev, (uint8_t *)&syncw, sizeof(syncw), &err); | + | DX2_WriteSyncData (dev, (uint8_t *)&syncw, sizeof(syncw), &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 994: | Line 1053: | ||
const TBulkReadParam param[3] = { | const TBulkReadParam param[3] = { | ||
- | {1,100,20}, // ID=1の124番地から20バイト分 | + | {1,100,20}, // ID=1の100番地から20バイト分 |
{2,124,12}, // ID=2の124番地から12バイト分 | {2,124,12}, // ID=2の124番地から12バイト分 | ||
{3, 0, 7} // ID=3の0番地から7バイト分 | {3, 0, 7} // ID=3の0番地から7バイト分 | ||
Line 1003: | Line 1062: | ||
uint32_t num = 3; // 3軸 | uint32_t num = 3; // 3軸 | ||
PBulkReadResult pr = (void *)rdat; | PBulkReadResult pr = (void *)rdat; | ||
- | DX2_ReadBulkData (dev, ¶m[0], &num, (uint8_t *)&rdat, &err); | + | DX2_ReadBulkData (dev, &param[0], &num, (uint8_t *)&rdat, &err); |
printf("resul num=%d err=$%04x\n", num, err); | printf("resul num=%d err=$%04x\n", num, err); | ||
for (int i = 0; i < num; i++) { | for (int i = 0; i < num; i++) { | ||
Line 1054: | Line 1113: | ||
if (dev) { | if (dev) { | ||
// 3台のXM430へ個別の情報を書き込み | // 3台のXM430へ個別の情報を書き込み | ||
- | DX2_WriteBulkData (dev, (uint8_t *)&BW, sizeof(BW), &err); | + | DX2_WriteBulkData (dev, (uint8_t *)&BW, sizeof(BW), &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 1090: | Line 1149: | ||
if (dev) { | if (dev) { | ||
// ID=1のAX-12+のLEDを消灯 | // ID=1のAX-12+のLEDを消灯 | ||
- | DX2_TxPacket (dev, 1, INST_WRITE, param, 2, &err); | + | DX2_TxPacket (dev, 1, INST_WRITE, param, 2, &err); |
DX2_ClosePort (dev); | DX2_ClosePort (dev); | ||
} | } | ||
Line 1132: | Line 1191: | ||
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, &err)) { |
// ステータスパケットを受信 | // ステータスパケットを受信 | ||
- | DX2_RxPacket (dev, dat, sizeof (dat), &len, 100, &err); | + | DX2_RxPacket (dev, dat, sizeof (dat), &len, 100, &err); |
for (i = 0; i < len; i++) { | for (i = 0; i < len; i++) { | ||
printf ("[%02X]", dat[i]); | printf ("[%02X]", dat[i]); |