第 5 章 チュートリアル(DLL編) 61
5.2 データ送受信(非コントローラモード)
次に非コントローラモードでデータ送受信を行うプログラムを作成します。
『26ページ 第4章 チュートリアル(高機能版ActiveXコントロール)』の図「チュートリアルでの 接続例」に示したように2枚のGP-IB I/Oモジュールをコントローラ,非コントローラとして使用し ます。これにより2台のPCでデータの送受信が可能になります。
Visual C++を起動し新しいプロジェクト(プロジェクト名:GpibTrans_s_Dll)を作成し、環境設定まで 行います。(『61ページ 5.1 データ送受信(コントローラモード)』のStep1,Step2を参照してくだ さい)
1. OnCreate関数を追加し、OnCreate関数,OnDestroy関数にコードを記述します。
OnCreate関数には(List 2-7)を記述し、OnDestroy関数には(List 2-8)を記述します。『61ページ ( 5.1 データ送受信(コントローラモード)』のStep3を参照)
(List 2-7:CGpibTrans_s_DllDlgクラスのOnCreate関数のコード)
int CGpibTrans̲m̲DllDlg::OnCreate(LPCREATESTRUCT lpCreateStruct) {
if (CDialog::OnCreate(lpCreateStruct) == ‑1) return ‑1;
INT nRet; // 関数の実行結果 CString szErrMsg; // エラーメッセージ
//I/Oモジュールアクセス番号BoardNoのI/Oモジュールを初期化 nRet = PciGpibExInitBoard(BoardNo, 0);
if (nRet != GP‑IB̲SUCCESS) {
szErrMsg.Format("I/Oモジュールアクセス番号%dのI/Oモジュールが初期化できません(%d)",BoardNo,nRet);
MessageBox(szErrMsg,"実行エラー",MB̲ICONERROR);
exit(0); // プログラム終了 }
return 0;
}
2. 同様に、「OnDestroy」をダブルクリックし、OnDestroy関数に(List 2-8)の網掛け部分を追加し ます。
(List 2-8:CGpibTrans_s_DllDlgクラスのOnDestory関数のコード)
void CGpibTrans̲m̲DllDlg::OnDestroy() {
CDialog::OnDestroy();
INT nRet; // 関数の戻り値
CString szErrMsg; // エラーメッセージ
// I/Oモジュールアクセス番号BoardNoのI/Oモジュールを使用終了 nRet = PciGpibExFinishBoard(BoardNo);
if(nRet != GP‑IB̲SUCCESS) {
szErrMsg.Format("I/Oモジュールの終了に失敗しました(%d)",nRet);
MessageBox(szErrMsg,"実行エラー",MB̲ICONERROR);
} }
データ送受信(非コントローラモード)用のダイアログボックスを作成します。基本的にデータ送受 信(コントローラモード)と変わりはありません。変更点は以下の2点です。『61ページ 5.1 デー タ送受信(コントローラモード))』のStep4を参照に行ってください。
(変更点)
コントローラモード 非コントローラモード
プロジェクト名 GpibTrans_m_Dll GpibTrans_s_ Dll クラス名 CGpibTrans_m_ Dll CGpibTrans_s_ Dll
1. 作成したOnSend関数,OnRecv関数にそれぞれ(List 2-9),(List 2-10)の網掛け部分を記述します。
(List 2-9:CGpibTrans_s_ Dll クラスのOnSend関数のコード)
void CGpibTrans̲s̲DllDlg::OnSend() {
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の戻り値
char SendBuf[32]; // 送信データ Cstring szErrMsg; // エラーメッセージ
UpdateData(TRUE);
// データ送信
strcpy(SendBuf, m̲szSendData);
nRet = PciGpibExSlavSendData(BoardNo, strlen(SendBuf),SendBuf, WM̲NULL);
if(nRet != GP‑IB̲SUCCESS) {
szErrMsg.Format("データ送信に失敗しました(%d)",nRet);
MessageBox(szErrMsg,"実行エラー",MB̲ICONERROR);
} }
(List 2-10:CGpibTrans_s_ Dll クラスのOnRecv関数のコード)
void CGpibTrans̲s̲ActvXDlg::OnRecv() {
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください INT nRet; // 関数の戻り値
ULONG nLen; // 受信サイズ CString szErrMsg; // エラーメッセージ
UpdateData(TRUE);
nLen = sizeof(RecvBuf);
if(!nLen){
AfxMessageBox("受信データはありません");
}
else{ //データ受信
nRet = PciGpibExSlavRecvData(BoardNo, &nLen, RecvBuf, WM̲NULL);
if(nRet != GP‑IB̲SUCCESS) {
szErrMsg.Format("データ受信に失敗しました(%d)",nRet);
MessageBox(szErrMsg,"実行エラー",MB̲ICONERROR);
} else {
m̲szRecvData = RecvBuf;
UpdateData(FALSE);
} } }
では、コントローラモードと非コントローラモードの設定を以下のように行い、送受信を行って みます。
コントローラモード 非コントローラモード
(1)動作モードをMASTERに設定 (2)1次アドレスは0に設定 (3)送信デリミタをEOIに設定 (4)受信デリミタをEOIに設定
(5)動作モードをSLAVEに設定 (6)1次アドレスは22に設定 (7)送信デリミタをEOIに設定 (8)受信デリミタをEOIに設定
コントロールパネルの「InterfacePCIGPIB」の設定
(1) (2)
(3)
(4) (5)
(6)
(7) (8)
非コントローラモードの場合は相手は計測器でなくGP-IB I/Oモジュールになります。計測器は機 器固有のアドレスを持っていますが、GP-IB I/Oモジュールにも固有のアドレスを与えてやらなけ ればなりません。
このアドレスは自由に決めてもよいのでこの場合22を指定しています。このアドレスを変更する 場合はコントロールパネルの「InterfacePCI/CardBus GP-IB」の設定の変更はもちろんですが、コ ントロール側のプログラムも変更が必要です。(List2-4)のアドレステーブルの値も変更したアドレ スを指定してください。
ただし、複数枚でデータ送受信を行う場合は各I/Oモジュールに重複しないアドレスを指定してく ださい。
ではプログラムを保存して実行してみてください。『74ページ 5.2 データ送受信(非コントロー ラモード)』のデータ送受信と同様にコントロール側と非コントロール側でデータの送受信が行え ると思います。
では入力したプログラムを読み取ってみましょう。
(List2-9)では非コントロール側からのデータ送信を行っています。データの送信には PciGpibExSlavSendData関数を使用します。
「使用例」
nRet = PciGpibExSlavSendData(BoardNo, strlen(SendBuf), SendBuf, WM_NULL);
I/O モジュールアクセ ス番号を指定します。
関 数 が 失 敗 す る と エ ラ ー コ ー ド が 格 納されます。
非同期動作終了時にアプリ ケーションに通知されるメ ッセージを指定します。
送信データ領域へのポ インタを指定します。
送信 デ ータ 長 を 指定します。
PciGpibExMastSendDataとの違いは、入力機器アドレスの指定を行う必要がないことです。
(List 2-10)ではコントローラ側からのデータの受信を行います。
データの受信にはPciGpibExSlavRecvData関数を使用します。
「使用例」
nRet = PciGpibExSlavRecvData(BoardNo, &nLen, RecvBuf, WM_NULL);
I/O モジュールアクセ ス番号を指定します。
関数が失敗するとエラー コードが格納されます。
非同期動作終了時にアプリ ケーションに通知されるメ ッセージを指定します。
受信バッファサイズが格 納されている変数へのポ インタを指定します。
受信バッファ領域へのポイ ンタを指定します。
※1 受信バッファ領域(RecvBuf)は、実際に受信するデータ長+デリミタサイズ(CRLFなら ば2バイト,LFのみならば1バイト)以上の領域を確保する必要があります。
※2 受信バッファサイズ(nLen)にはPciGpibExSlavRecvData関数を呼び出す前に受信バッファ領域 のサイズを格納しておく必要があります。
ここまでがDLLによるデータ送受信(非コントロールモード)のプログラム例です。