|
シリアルUSBアダプター、シリアルUSBアダプターHS、Dual USB Adapter
HSなどの製品をPCのUSBポートにつなげると、PCがCOMポートとしてそれを認識します。
RCB-4に送るコマンドの仕様は、「RCB-4コマンドリファレンス20131018.pdf」というドキュメントで公開されていまから、「COMポートにコマンドを書き込んだら、それでサーボモータを制御できるんじゃネ?」ということを思いつきます。実際、RCB−3の時代に、低速のシリアル通信で、これを行うプログラムを書いたことがありますが、それで動いていました。(ショルダーキーボードの操作でPCから無線でコマンドを送出してロボットを操作していました。)今回、
同様のコードをVC++で記述してみましたが、うまく動きませんでした。どうやら、仕様として公開されているコマンドをそのままCOMポートに書き込んでもダメ
なのかなと思い、近藤科学に問い合わせたところ、そのようなことは可能ということで、何か設定が間違っているのではないかということでした。
四苦八苦ののち、動作するようになりました。 |
|
|
Visual Studio 2008を使用しての例を紹介します。
新しいプロジェクトで「MFCアプリケーション」を選択します。(他のでもいいです。)RCB4Controlという名前にしてダイアログベースの設定でプロジェクトを作成しました。(他の設定でもいいです。)文字コードはUnicodeではなくマルチバイトを選択しました。ダイアログボックスをデザインする画面で右クリックでメニューを表示し、「ActiveXコントロールの挿入」というのを選びます。「Microsoft
Communications Control,
version6.0」というのを挿入します。(たぶん、他のバージョンでもいいと思います。プロパティを表示するとSettingの欄が「9600,n,8,1」となっているはずなので、これを「115200,e,8,1」に書き換えますCommPortの欄も近藤科学のUSBに割り当てられた数字に書き換えます。(デバイスマネージャで確認できます。)あとで使うのでボタンを1つ配置しておいてください。 |
|
|
 |
|
|
電話のアイコンを右クリックして「変数の追加」を選択します。「m_ms_comm1」という変数名をつけます。
再度、電話のアイコンをクリックして、プロパティを表示します。プロパティの雷のアイコンをクリックすると、「OnComm」というのが表示されるので、「追加OnCommMscomm1」の操作を行います。
ダイアログ開始時に、通信を開始する処理を書き加えます。終了の処理は省略していますが、どこかに書いてください。 |
|
|
通信のための設定
BOOL CRCB4ControlDlg::OnInitDialog()
{
〜省略〜
// TODO: 初期化をここに追加します。
m_ms_comm1.put_PortOpen(true);
return TRUE; // フォーカスをコントロールに設定した場合を除き、TRUE を返します。
}
|
|
|
ダイアログボックスのデザイン画面に戻り、ボタンをダブルクリックすると、ボタンの処理を行うためのOnBnClickedButton1()が追加され、コードの記述画面になります。
|
|
|
送信側
void CRCB4ControlDlg::OnBnClickedButton1()
{
unsigned char msg[7] ={0x07, 0x0F, 0x00, 0x01, 0x4C, 0x1D,
0x80}; // コマンドの例(これの作り方の仕様は公開されている)
int len = 7-1;
CByteArray msg_array;
unsigned short sum=0;
int i;
for(i=0;i<len;i++)
{
msg_array.Add (msg[i]);
sum = sum + msg[i];
}
unsigned char check_sum = sum%256;
msg_array.Add (check_sum);
COleVariant variant_msg (msg_array);
m_ms_comm1.put_Output(variant_msg);
}
|
|
|
受信側
void CRCB4ControlDlg::OnCommMscomm1()
{
VARIANT variant_msg;
VariantInit(&variant_msg);
BYTE receive_msg[1024];
TRY
{
variant_msg= m_ms_comm1.get_Input();
}
CATCH_ALL(e) // USBが抜かれた
{
AfxMessageBox("error usb");
}
END_CATCH_ALL
int preceive_len=0;
if(variant_msg.vt == (long)(VT_UI1 | VT_ARRAY))
{
long i, lb, ub;
unsigned char **ps;
SAFEARRAY *psa = variant_msg.parray;
SafeArrayLock(psa);
ps = (unsigned char **)psa->pvData;
SafeArrayGetLBound(psa, 1, &lb);
SafeArrayGetUBound(psa, 1, &ub);
for (i = lb; i <= ub; i++)
{
unsigned char
elm;
SafeArrayGetElement(psa, &i, &elm);
receive_msg[preceive_len] = elm;
preceive_len++;
}
SafeArrayUnlock(psa);
}
// メッセージのバイト数 preceive_lenは格納される
// メッセージreceive_msgは格納される
} |
|
|
デバッガで確認すると、preceive_lenにメッセージのバイト数が、receive_msgにメッセージが格納されているのが分かります。
たてつづけにコマンドを送ったり、存在しないサーボにコマンドを送ったりすると、正しく動作しなくなるようです。
※追記 下記の変更を行わないとcommが正しく動作しないようです。
// CWinAppEx::InitInstance();
CWinApp::InitInstance(); |
|