18: 2022-02-23 (水) 22:14:16 takaboo |
現: 2023-11-12 (日) 00:09:35 takaboo |
| シリアル通信に関する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]]を装備した装置を同一ネットワーク上で同時に運用する事は推奨できない。| |
| **ライブラリおよびサンプルプログラムのダウンロード [#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) |
| 更新内容 | | 更新内容 |
| 動的に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 |
| #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> |
| }} | | }} |
| #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> |
| コンパイルや実行にあたって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] |
| 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 |
| 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); |
| 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 |
| 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); |
| } | | } |
| 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); |
| 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); |
| } | | } |
| 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); |
| } | | } |
| 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); |
| } | | } |
| 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); |
| } | | } |
| 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", |
| 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); |
| } | | } |
| 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++) { |
| 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); |
| } | | } |
| | | |
| 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バイト分 |
| 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++) { |
| 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); |
| } | | } |
| 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); |
| } | | } |
| 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]); |