NI製品ディスカッション

キャンセル
次の結果を表示 
次の代わりに検索 
もしかして: 

GPIB-32.DLL ibrd データを読んでいるのにibcntlが0になる

解決済み
解決策を見る

現在,VB.net 2010+USB-GPIB-HSでGPIB-32.dll経由でデバイスと通信しています。

 

ibrd / ibrdi等でデバイスからエータを読み込んだ際に、バッファーにはデータが入っているにもかかわらず、ibcntlが0なります。

NI I/O-Traceで確認しても正常に終了していることになっています。

 

読みだしたデータのバイト数を取得する方法はありますか?

 

 

 

0 件の賞賛
メッセージ1/12
5,203件の閲覧回数

ながらく返信が付いていませんがその後状況は如何でしょう?

 

ibcntlが本来読み込んだデータのバイト数を表しているはずなのに変ですね。I/O Traceのログ上では読み取りコマンドに対して何かメッセージが出てきているのでしょうか?

 

GPIBの通信相手は何でしょうか?他のPCでは正常に読み取れるのでしょうか?たとえばMAXからGPIB機器と通信して「*IDN?」をクエリすると応答は返ってくるのでしょうか?

 

以下の手順でインストールされるサンプルプログラムの動作結果はどうでしょうか。

 

C#またはVB.NETを使用してVISAおよびGPIBアプリケーション開発をする - National Instruments
http://digital.ni.com/public.nsf/allkb/AF15E1F8654C0E2E862571BD00281FA5

 

よろしくお願いします。

0 件の賞賛
メッセージ2/12
4,933件の閲覧回数

TAKASU

 

現在、NIのサポートからメールでサポートを受けておりますが、解決に至っておりません。

 

I/O Traceのログ上ではエラーなく終了して、読み取りカウントも正常な値になっています。

 

GPIBデバイスはSRS DG535 / SRS SR245 / シグマ光機Shot204等ですが、単体で動作させるプログラムでは問題なく動作していますが、

複数のデバイスを組み合わせ始めると発生するようです。問題が発生するデバイスはどのデバイスでも発生しています。

 

PCに関しては複数のPC、OSもXP/Vista(32)/7(32/64)/8.1(64)で検証していますが目立った違いはありません。

 

VISAに関しましては、NIのサポートの方にも勧められて検証を始めていますが、ほかの問題もあり進まない状況です。

 

 

 

 

0 件の賞賛
メッセージ3/12
4,915件の閲覧回数

回答ありがとうございます。プログラミングの問題ということになりますでしょうか。「I/O Traceのログ上ではエラー無く終了」という点が分かりかねますが、ひとまず単独のサンプルプログラムでは問題なく動作しているのですね。

 

具体的にどのようなコードで試されているか教えていただくことは可能でしょうか。

 

0 件の賞賛
メッセージ4/12
4,869件の閲覧回数

NIGLOBAL.vb/Vbib-32.vbを御使いだと思うのですが.NET用に型変換されてますか?
も気になります。

 

VB.NET/VB6.0/CLR/C/C++/Win32API 型一覧表
http://www.nda.co.jp/memo/dim.html

 

0 件の賞賛
メッセージ5/12
4,854件の閲覧回数

TAKASU

 

回答ありがとうございます。

 

実際に行っている事を具体的に説明するのは難しいですが、ソフトウェアの構造としては

 

各デバイスはクラスライブラリー化されていて、そのデバイスのクラスライブラリーからは通信用のクラスライブラリー

を呼び出し通信しています。通信用のクラスライブラリーはGPIBDLLへのアクセスと設定の管理、通信ログ等を行っています。

 

メインアプリは複数のデバイスのクラスライブラリーを呼び出して制御しています。

 

 

 

0 件の賞賛
メッセージ6/12
4,841件の閲覧回数

su-sann5073

 

アドバイスありがとうございます。

 

NIGLOBAL.vb/Vbib-32.vbに関しては、

 

VB NET 2003 Simple GPIB using GPIB-32.DLL

http://www.ni.com/example/29525/en/

 

を修正したものを利用してます。

 

NIのサポートの方の指摘で、FindLstnの AnyはLongではなくShortにする事で使用できるようになっています。

 

それ以外は

ni4882.h (C/C++ )

Vbib-32.bas (VB6)

Vbib-32.vb 上記のもの

Vbib-32.vb

修正・検証

int

Long

Integer

Int32/Integer

Addr4882_t *

Any

Long

Int16/Short

unsigned int

Long

 Integer

UInt32/Integer

 で変換しています。

 

Integerに関しては、念のためInt32/UInt32でも試しましたが、結果は同じでした。

 

0 件の賞賛
メッセージ7/12
4,839件の閲覧回数

むささ様

 

詳細レスどうもです。
型の件は、.NET用サンプルをお使いのようなので問題無いかと思います。

 

ibrd データを読んで、ibcntlを参照する間に他のデバイスのI/Oが割り込んだりはしてないでしょうか?
その処理の影響で、グローバル変数(ibcntl等)の値が書き変わってしまっているとか?
①ibcntlが0になる場合のステップにブレークを入れてるようにしてみて
②NI I/O-Traceでibrd後にI/Oが実行されて無いかを確認
③ThreadIbcntlを確認←GPIB-32.DL​L内の変数が読めるんだと思います。

 

>読みだしたデータのバイト数を取得する方法はありますか?

サンプル使ってみました。 IndexOfメソッドは如何でしょう?

 

            Debug.WriteLine("ibcntl=" & ibcntl)
            DisplayStr = VB.Left(ValueStr.Value, ibcntl - 1)
            Debug.WriteLine("DisplayStr=[" & DisplayStr & "]")
            'ibcntlの代用①
            Dim c As Char = ""
            DisplayStr = VB.Left(ValueStr.Value, ValueStr.Value.IndexOf(c))
            Debug.WriteLine("DisplayStr=[" & DisplayStr & "]")
            'ibcntlの代用②ターミネータ
            c = vbLf
            DisplayStr = VB.Left(ValueStr.Value, ValueStr.Value.IndexOf(c))
            Debug.WriteLine("DisplayStr=[" & DisplayStr & "]")

 

0 件の賞賛
メッセージ8/12
4,827件の閲覧回数

su-sann5073

 

アドバイスありがとうございます。

 

サンプルを作っていただきありがとうございました、出張が終わったら試させていただきます。

 

>①ibcntlが0になる場合のステップにブレークを入れてるようにしてみて

>②NI I/O-Traceでibrd後にI/Oが実行されて無いかを確認
>③ThreadIbcntlを確認←GPIB-32.DL​L内の変数が読めるんだと思います。

①②に関しては、ibwrtでコマンドを送ってからibrdまでステップ・バイ・ステップで実行しても結果は同じでした。

ThreadIbcntlに関しては試していないので試してみます。

 

 

根本的なところになってしまいますが、1つのアプリケーション内に別々にGPIB-32.DLLにアクセスする

クラスライブラリーがあっても問題ないでしょうか?

今回のケースでは、ステップ・バイ・ステップで実行して他のデバイス用のライブラリーが同時にアクセスしないような状態で

テストをしていますが、そもそもこのようなプログラムの構造に問題が無いのか確信が持てなくなってきています。

 

よろしくお願いします。

0 件の賞賛
メッセージ9/12
4,803件の閲覧回数
解決策
トピック作成者むささが受理

むささ様

 

>根本的なところになってしまいますが、1つのアプリケーション内に別々にGPIB-32.DLLにアクセス​する
>クラスライブラリーがあっても問題ないでしょうか?

 

なるほど、そうだったのですね。 そこが原因だと思います。

 

NIGLOBAL.vb/Vbib-32.vbのソース及び動作から判断すると
GPIB-32.DLLは、ステータスの3つのグローバル変数を持って各Functionの基本的な動作は

 

①RegisterGPIBGlobalsでLongibsta/Longiberr/Longibcntに格納できるように確保している
 (一回のみ実行される、確保されていると解放して新たに確保する)
②各APIが実行されるとLongibsta/Longiberr/Longibcntに格納(されているはず)
③copy_ibvarsでibsta/iberr/ibcnt/ibcntlへコピー

 

したがって複数クラスで上記の処理を持つFunctionを実行すると
GPIB-32.DLLは、ステータスを最後に実行されたクラスの変数Longibsta/Longiberr/Longibcntに格納していると思います。

 

例えば、
「クラス1でOpen(ibfind/ibdev等)」→「クラス2でOpen(ibfind/ibdev等)」→クラス1で「*IDN?」をクエリ(Ibwrt→Ibrd)→クラス2で「*IDN?」をクエリ(Ibwrt→Ibrd)・・・

と実行した場合、クラス1では、ibsta/iberr/ibcnt/ibcntはOpen時のままで
最後のクラス2のibsta/iberr/ibcnt/ibcntだけ変化する。

 

ステータスだけの問題だと思うので、Threadxxxで直接DLLから取得すれば問題は回避できると思います。

(GPIBglobalsRegistered/Longibsta/Longiberr/Longibcnt/bufと bytebufは使ってないですが念のため?はpublicにModuleで宣言)

 

>そもそもこのようなプログラムの構造に問題が無いのか確信が持てなくなってきていま​す。

 

.NETクラス用のNationalInstruments.NI4882を使った方が良かったと思います(GPIB-32.DL​Lの機能は一通り持ってるようです)。

後は、「NIGLOBAL.vb/Vbib-32.vbあたりをModuleのままで使うとか」、「RegisterGPIBGlobalsをはずしてThreadxxxでステータスを取得するように書き換える。」とかでしょうか?

 

.NET 用 GPIB の Language Interface は、どこにありますか
http://digital.ni.com/public.nsf/allkb/8CEF253ECD00CF8286256ECC0017D111

 

メッセージ10/12
4,788件の閲覧回数