03-30-2016 07:22 AM
現在,VB.net 2010+USB-GPIB-HSでGPIB-32.dll経由でデバイスと通信しています。
ibrd / ibrdi等でデバイスからエータを読み込んだ際に、バッファーにはデータが入っているにもかかわらず、ibcntlが0なります。
NI I/O-Traceで確認しても正常に終了していることになっています。
読みだしたデータのバイト数を取得する方法はありますか?
解決済! 解決策の投稿を見る。
05-05-2016 09:20 AM
ながらく返信が付いていませんがその後状況は如何でしょう?
ibcntlが本来読み込んだデータのバイト数を表しているはずなのに変ですね。I/O Traceのログ上では読み取りコマンドに対して何かメッセージが出てきているのでしょうか?
GPIBの通信相手は何でしょうか?他のPCでは正常に読み取れるのでしょうか?たとえばMAXからGPIB機器と通信して「*IDN?」をクエリすると応答は返ってくるのでしょうか?
以下の手順でインストールされるサンプルプログラムの動作結果はどうでしょうか。
C#またはVB.NETを使用してVISAおよびGPIBアプリケーション開発をする - National Instruments
http://digital.ni.com/public.nsf/allkb/AF15E1F8654C0E2E862571BD00281FA5
よろしくお願いします。
05-06-2016 08:56 AM
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のサポートの方にも勧められて検証を始めていますが、ほかの問題もあり進まない状況です。
05-09-2016 12:13 PM
回答ありがとうございます。プログラミングの問題ということになりますでしょうか。「I/O Traceのログ上ではエラー無く終了」という点が分かりかねますが、ひとまず単独のサンプルプログラムでは問題なく動作しているのですね。
具体的にどのようなコードで試されているか教えていただくことは可能でしょうか。
05-09-2016 09:00 PM
NIGLOBAL.vb/Vbib-32.vbを御使いだと思うのですが.NET用に型変換されてますか?
も気になります。
VB.NET/VB6.0/CLR/C/C++/Win32API 型一覧表
http://www.nda.co.jp/memo/dim.html
05-10-2016 04:49 AM
TAKASU 様
回答ありがとうございます。
実際に行っている事を具体的に説明するのは難しいですが、ソフトウェアの構造としては
各デバイスはクラスライブラリー化されていて、そのデバイスのクラスライブラリーからは通信用のクラスライブラリー
を呼び出し通信しています。通信用のクラスライブラリーはGPIBDLLへのアクセスと設定の管理、通信ログ等を行っています。
メインアプリは複数のデバイスのクラスライブラリーを呼び出して制御しています。
05-10-2016 05:00 AM
アドバイスありがとうございます。
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でも試しましたが、結果は同じでした。
05-10-2016 09:23 PM
むささ様
詳細レスどうもです。
型の件は、.NET用サンプルをお使いのようなので問題無いかと思います。
ibrd データを読んで、ibcntlを参照する間に他のデバイスのI/Oが割り込んだりはしてないでしょうか?
その処理の影響で、グローバル変数(ibcntl等)の値が書き変わってしまっているとか?
①ibcntlが0になる場合のステップにブレークを入れてるようにしてみて
②NI I/O-Traceでibrd後にI/Oが実行されて無いかを確認
③ThreadIbcntlを確認←GPIB-32.DLL内の変数が読めるんだと思います。
>読みだしたデータのバイト数を取得する方法はありますか?
サンプル使ってみました。 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 & "]")
05-12-2016 06:40 AM
アドバイスありがとうございます。
サンプルを作っていただきありがとうございました、出張が終わったら試させていただきます。
>①ibcntlが0になる場合のステップにブレークを入れてるようにしてみて
>②NI I/O-Traceでibrd後にI/Oが実行されて無いかを確認
>③ThreadIbcntlを確認←GPIB-32.DLL内の変数が読めるんだと思います。
①②に関しては、ibwrtでコマンドを送ってからibrdまでステップ・バイ・ステップで実行しても結果は同じでした。
ThreadIbcntlに関しては試していないので試してみます。
根本的なところになってしまいますが、1つのアプリケーション内に別々にGPIB-32.DLLにアクセスする
クラスライブラリーがあっても問題ないでしょうか?
今回のケースでは、ステップ・バイ・ステップで実行して他のデバイス用のライブラリーが同時にアクセスしないような状態で
テストをしていますが、そもそもこのようなプログラムの構造に問題が無いのか確信が持てなくなってきています。
よろしくお願いします。
05-12-2016 11:19 PM
むささ様
>根本的なところになってしまいますが、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.DLLの機能は一通り持ってるようです)。
後は、「NIGLOBAL.vb/Vbib-32.vbあたりをModuleのままで使うとか」、「RegisterGPIBGlobalsをはずしてThreadxxxでステータスを取得するように書き換える。」とかでしょうか?
.NET 用 GPIB の Language Interface は、どこにありますか
http://digital.ni.com/public.nsf/allkb/8CEF253ECD00CF8286256ECC0017D111