ROBO-ONEにおいて各社のアクチュエータで異なる通信方式をDXLIBをベースとしたAPIレベルで標準化する試みが行われました。その成果物として、RS LibraryはFUTABAコマンド式サーボの通信プロトコルをサポートした製品をWindows等のOSから操作するためのライブラリとしてとりまとめました。
本APIを介する事でシリアル通信である事をほとんど意識すること無くアプリケーションの作りこみに専念できます。
なお、PCとRSC-U485・BTE061D・BTE061E・BTE068・BTE068B・BTE082のいずれかがUSBケーブルで接続され、PC上にWindowsのデバイスとして仮想COMポートが増設された状態で使用するものとします。
以下のリンクよりライブラリ及びサンプルプログラムをアーカイブしたファイルがダウンロードできます。
アーカイブファイルには以下のファイルが同梱されます。必要に応じて解凍してください。なおファイル名のサフィックスが_x32は32ビット、_x64は64ビットのWindowsアプリ用です。
RSLIB1.1 | rslib_x32.dll | ライブラリ本体 | |
rslib_x64.dll | |||
librslib_x32.a | GCC用ライブラリ(定義のみ) | ||
librslib_x64.a | |||
rslib_x32.llb | MSVC用ライブラリ(定義のみ) | ||
rslib_x64.lib | |||
rslib.c | ライブラリソース | ||
rslib.h | ライブラリヘッダ | ||
rsmemmap.h | 仮想メモリマップ定義ヘッダ | ||
makelib.bat | ライブラリ再構築用バッチ コンパイルにはGCC Developer Liteとlib.exeが必要 | ||
83.bat | |||
SampleCode | test1.c | サンプルプログラム | |
test2.c | |||
test3.c | |||
test4.c | |||
test5.c | |||
test.vi | LabVIEWのサンプルとAPIのラッパvi | ||
RS_OpenPort.vi | |||
RS_ClosePort.vi | |||
RS_SetBaudrate.vi | |||
RS_WriteByte.vi | |||
RS_ReadByte.vi | |||
RS_WriteWord.vi | |||
RS_ReadWord.vi | |||
RS_WriteBlock.vi | |||
RS_ReadBlock.vi | |||
ArrayToElement.vi | |||
ErrorCheck.vi |
RS Libraryではシリアル通信を直接意識するコードを記述せずに、対象IDのデバイスの仮想メモリマップへの読み書き行うAPIを用意しています。
C言語のソースにrslib.hをインクルードすれば、APIを使用するのに必要なプロトタイプとマクロの定義がなされます。
ライブラリの内部情報を初期化すると同時に指定されたCOMポートをオープンし、RS_SetBaudrateを使用して通信速度を設定した後、ユニークなTDeviceIDを返す。以後はこのTDeviceIDを使用して各APIを使用する。
複数のCOMポートを使用する場合は、使用するポート毎にRS_OpenPortを行いTDeviceIDを取得しなくてはならない。
なお、Linuxにおけるボーレートの指定に関しては、RS_SetBaudrateの解説に注意の事。
TDeviceID RS_OpenPort (char *name, uint32_t baud);
RS_OpenPortで開いたCOMポートを閉じる。
RS_ClosePortが実行された以後は指定されたTDeviceIDでの通信が行えなくなる。
bool RS_ClosePort (TDeviceID dvid);
既にオープンされている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 RS_SetBaudrate (TDeviceID dvid, long baud);
指定されたTDeviceIDのポートが開かれており、使用可能であるかを確認する。
USB接続等によりインターフェース自体が取り外し可能な場合に、実際に使用可能であるかを判断するために使用するが、状況によっては正確に判断できない場合もある。
bool RS_Active (TDeviceID dvid);
I/FやOSの都合で生じるであろうタイムラグを予め設定する。
内部で算出している受信タイムアウト時間とタイムアウトオフセット時間を加算した時間を超えた場合に、タイムアウトエラーとして処理する。
デフォルトは20。
void RS_SetTimeOutOffset (TDeviceID dvid, uint32_t offsettime);
対象IDからの応答を確認する。
bool RS_Ping (TDeviceID dvid, uint8_t id, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (0~31)。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
TDeviceID dev; TErrorCode err; // オープン dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1にPINGを発行 if (RS_Ping (dev, 1, &err)) printf ("Found [%08X]\n", err); else printf ("Not found [%08X]\n", err); // クローズ RS_ClosePort (dev); }
対象IDのコントロールテーブルから1バイトのデータを読み出す。
bool RS_ReadByteData(TDeviceID dvid, uint8_t id, uint8_t adr, uint8_t *rdata, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127)。
コントロールテーブルのアドレス。
読み出した値の保存先。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
TDeviceID dev; TErrorCode err; int8_t dat; // オープン dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1の温度を取得 if (RS_ReadByteData (dev, 1, 50, &dat, &err)) { printf ("TEMP=%d\n", dat); } RS_ClosePort (dev); }
対象IDのコントロールテーブルへ1バイトのデータを書き込む。
bool RS_WriteByteData(TDeviceID dvid, uint8_t id, uint8_t adr, uint8_t dat, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127, 255)。
コントロールテーブルのアドレス。
書き込む値。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
BROADCASTING ID(255)を指定した場合は応答待ちを行わない。
TDeviceID dev; TErrorCode err; // オープン dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1のトルクONを指令する RS_WriteByteData (dev, 1, 36, 1, &err); RS_ClosePort (dev); }
対象IDのコントロールテーブルから1ワード(2バイト)のデータを読み出す。
bool RS_ReadWordData(TDeviceID dvid, uint8_t id, uint8_t adr, uint16_t *rdata, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127)。
コントロールテーブルのアドレス。
読み出した値の保存先。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
TDeviceID dev; TErrorCode err; int16_t dat; // オープン dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1から現在位置を取得 if (RS_ReadWordData (dev, 1, 42, &dat, &err)) { printf ("PRESENT POS=%d\n", dat); } RS_ClosePort (dev); }
対象IDのコントロールテーブルへ1ワード(2バイト)のデータを書き込む。
bool RS_WriteWordData(TDeviceID dvid, uint8_t id, uint8_t adr, uint16_t dat, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127, 255)。
コントロールテーブルのアドレス。
書き込む値。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
BROADCASTING ID(255)を指定した場合は応答待ちを行わない。
TDeviceID dev; TErrorCode err; // オープン dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1へ位置(0)を指令 RS_WriteWordData (dev, 1, 30, 0, &err); RS_ClosePort (dev); }
対象IDのコントロールテーブルから指定サイズのデータを読み出す。
bool RS_ReadBlockData (TDeviceID dvid, uint8_t id, uint8_t adr, uint8_t *rdata, uint32_t len, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127)。
コントロールテーブルのアドレス。
読み出したデータの保存先。
読み出すデータのサイズ。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
TDeviceID dev; TErrorCode err; uint8_t dat[60]; int i; dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1から全データ(アドレス0から60バイト)を取得 if (RS_ReadBlockData (dev, 1, 0, comp, 60, &err) { for (i = 0; i < 60; i++) printf ("%02X", dat[i]); } RS_ClosePort (dev); }
対象IDのコントロールテーブルへ指定サイズのデータを書き込む。
bool RS_WriteBlockData(TDeviceID dvid, uint8_t id, uint8_t adr, uint8_t *dat, uint32_t len, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127, 255)。
コントロールテーブルのアドレス。
書き込むデータの保存先。
書き込むデータのサイズ。
エラーコード。
正常な応答が得られた場合はtrue、それ以外はfalseを返す。
BROADCASTING ID(255)を指定した場合は応答待ちを行わない。
TDeviceID dev; TErrorCode err; uint8_t comp[4] = { 1, 1, 10, 10 }; dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1のコンプライアンスを変更 RS_WriteBlockData (dev, 1, 24, comp, 4, &err); RS_ClosePort (dev); }
ロングパケットを使用して複数IDへブロック書き込みを行う。
書き込まれるデータの構成はユーザに委ねられる。
bool RS_WriteSyncData (TDeviceID dvid, uint8_t *dat, uint32_t size, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
書き込むパラメータの保存先。
パラメータのサイズ。
エラーコード。
インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。
#define _POS1 (-1500) #define _POS2 (1500) TDeviceID dev; TErrorCode err; uint8_t param[9] = { 30, // 開始アドレス (Goal Position) 3, // 1軸あたりのデータバイトサイズ (id + data1 + data2 + ...) 2, // 軸数 1, // 1軸目ID _POS1 & 0xff, // data1 _POS1 >> 8, // data2 2, // 2軸目ID _POS2 & 0xff, // data1 _POS2 >> 8 // datg2 }; dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // 2軸同時に位置を指令 RS_WriteSyncData (dev, param, 9, &err); RS_ClosePort (dev); };
任意のショートないしロングパケットを送信する。
bool RS_TxPacket (TDeviceID dvid, uint8_t id, uint8 cflag, uint8_t *param, uint32_t len, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
対象とするID (1~127, 255)。
使用するフラグ。
送信するパラメータの保存先。
送信するパラメータのサイズ。
エラーコード。
インターフェースより送信が行われた場合はtrue、それ以外はfalseを返す。
TDeviceID dev; uint8_t param[] = {0xff, 0, 0}; dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ID=1のFLASH書込と再起動 if (RS_TxPacket (dvid, 1, 0x40, param, 3, NULL)) { Sleep (100); RS_TxPacket (dvid, 1, 0x20, param, 3, NULL); } RS_ClosePort (dev); }
リターンパケットを受信する。
基本的にRS_TxPacketとペアで使用する。リターンパケットが得られない状況で使用するとタイムアウトするまで返らない。
なお、本APIはRS_SetTimeOutOffsetで設定されたオフセット値は使用せず、引数で指定された受信タイムアウトのみが適用される。
bool RS_RxPacket (TDeviceID dvid, uint8_t *rdata, uint32_t rdatasize, uint32_t *rlen, uint32_t timeout, TErrorCode *err);
RS_OpenPortで開いた際のTDeviceID。
受信バッファ。
リターンパケットを受信するのに十分なサイズを確保しておく必要がある。
rdataのサイズ。
実際に受信されたリターンパケットのサイズ。
受信タイムアウト[ms]。
エラーコード。
受信成功時はtrue、それ以外はfalseを返す。
#define ORGID 1 #define NEWID 50 int l; TDeviceID dev; uint8_t param[50], rbuf[50]; dev = RS_OpenPort ("\\\\.\\COM10", 115200); if (dev) { // ORGIDのIDをNEWIDに書き換え param[0] = 4; // IDのアドレス param[1] = 1; // データ長 param[2] = 1; // カウント param[3] = NEWID; // 新しいID if (RS_TxPacket (dev, ORGID, 0x03, param, 4, NULL)) { // 新しいIDに書き換わった応答を受信 if (RS_RxPacket (dev, rbuf, sizeof (rbuf), &l, 100, NULL)) { // 受信データを確認 if (rbuf[2] == NEWID && rbuf[11] == NEWID) { // FLASHの更新 param[0] = 0xff; param[1] = 0; param[2] = 0; RS_TxPacket (dev, NEWID, 0x40, param, 3, NULL); } } } RS_ClosePort (dev); }
bit | macro name | |
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_RS_TEMP | 温度リミットエラー |
6 | ||
5 | ERR_RS_TEMPALARM | 温度リミットアラーム |
4 | ||
3 | ERR_RS_FLASH | フラッシュROM書き込みエラー |
2 | ||
1 | ERR_RS_PACKET | 受信パケット処理不可能エラー |
0 |