喫茶XRAYトップページ

[スレッド全体
]

[5683] GPIB返信 削除
2012/1/28 (土) 22:52:32 たてぐや
 また困ったときのここだのみで済みません。
 友人に測定器から来るGPIBのデータを受信してExcelのセルに表示するものを
作ってくれないか、と頼まれました。セルに表示することは過去にも経験があ
りますので、安心しているのですが、肝心のデータを受け取るやり方が解りま
せん。一応GPIB→USBの変換器にサンプルプログラムが付いているのですが、こ
れだと受信ボタンを押した一瞬だけデータを受信するものの、連続してデータを
取り込むようにはなっていません。GPIBの受信の手順が解る方がいらっしゃいま
したら教えて下さい。

[5685] Re:GPIB返信 削除
2012/1/29 (日) 13:03:28 真空管
▼ たてぐやさん

 12年ほど前ですが、インピーダンス計を使って自動測定・

作図を手がけたことがあります。

測定器は横河HPのHP=4192A、GPIBはRATOC sytemsの

REX-USB220です。

GPIBのITFは付属のDLL(U2GPLIB.DLL)をそのまま使い、

DLLの呼び出しは付属のDelphi用の定義ファイルが使えました。

ツールはDelphi4。


 昔のことですっかり忘れてしまい、今はリタイアモードで

小原章介やってまして、参考にもならないと思いますが

GPIB絡みの部分を以下に抜き出して見ました。

// 少々長くてごめんなさい。


   IDS_MYGPIBADRS: TEdit;

    IDE_GPIBADRS: TEdit;

    IDS_STATUS: TEdit;

  end;


 MyGpibAdrs: Integer; // USB-GPIBのGPIBアドレス

  GpAdrsBuf: String;        // 使用するGPIB機器のGPIBアドレス


procedure TMainForm.FormCreate(Sender: TObject);

var DtLen:integer;

begin


   // USB-GPIBアドレスを初期化

    //MyGpibAdrs := 0;

    IDS_MYGPIBADRS.Text := IntToStr(MyGpibAdrs);

    // GPIB機器アドレスを初期化

    //GpAdrsBuf := '1';

    IDE_GPIBADRS.Text := GpAdrsBuf;

end;


// GPIB 初期化ボタン

procedure TMainForm.BtnGPINITClick(Sender: TObject);

var

    GpStatus: Integer;        szCommand: String;

begin

  szCommand := 'H0KM01';


 IDS_STATUS.Text := '';

  MainForm.Refresh(); // 再描画


        // GPIBコントローラ初期化

        GpStatus := gp_init(MyGpibAdrs, 0, 0);

        if GpStatus <> 0 then

        begin

                szBuf := 'gp_init() error [' + IntToStr(GpStatus) + ']';

                IDS_STATUS.Text := szBuf;

                Exit;

        end;


        // IFCラインをTRUEにする

        gp_cli();


        // RENラインをTRUEにする

        gp_ren();


        // HP3478Aで設定されているGPIB機器アドレス取得

        GpAdrsBuf := IDE_GPIBADRS.Text;


        // GPIBバスタイムアウト時間を3秒に設定

        GpStatus := gp_tmout(3);

         if GpStatus <> 0 then

        begin

                szBuf := 'gp_tmout() error [' + IntToStr(GpStatus) + ']';

                IDS_STATUS.Text := szBuf;

                Exit;

        end;


        // SDCコマンド送出

        GpStatus := gp_clr(GpAdrsBuf);

         if GpStatus <> 0 then

        begin

                szBuf := 'gp_clr() error [' + IntToStr(GpStatus) + ']';

                IDS_STATUS.Text := szBuf;

                Exit;

        end;


        // LLOコマンド送出

        GpStatus := gp_llo();

         if GpStatus <> 0 then

        begin

                szBuf := 'gp_llo() error [' + IntToStr(GpStatus) + ']';

                IDS_STATUS.Text := szBuf;

                Exit;

        end;


        // HP3478A GPIBコマンド送信

       {        GpStatus := gp_wrt(GpAdrsBuf, szCommand);

         if GpStatus <> 0 then

        begin

                 szBuf := 'gp_wrt() error [' + IntToStr(GpStatus) + ']';

                IDS_STATUS.Text := szBuf;

                Exit;

        end;     }


        IDS_STATUS.Text := '初期化正常終了';

        GPIBinz := True;

  IDB_START.Enabled := TRUE;

end;


// GPIBコマンド送信ボタン

procedure TMainForm.Button1Click(Sender: TObject);

var

    GpStatus: Integer;   txStr: string;

begin

   txStr := Edit7.Text;

   GpStatus := gp_wrt(GpAdrsBuf,txStr);

   if GpStatus <> 0 then

   begin

    szBuf := 'gp_wrt() error [' + IntToStr(GpStatus) + ']';

    IDS_STATUS.Text := szBuf;

    Exit;

   end;

   HPOK := True;

end;


// 受信ボタン

procedure TMainForm.Button2Click(Sender: TObject);

var

  Status: Integer; // 関数の戻り値を示す

  RxBuf: String; // 受信データ格納用バッファ

  RxLen: Integer; // 受信バッファサイズ

begin


 // テキストボックス初期化

  IDS_STATUS.Text := '受信中・・・';

  Application.ProcessMessages;


 // 受信用バッファの初期化

  RxLen := 1024;

  RxBuf := StringOfChar(#0, RxLen);

  Status := gp_red(GpAdrsBuf, RxBuf, RxLen);

  if Status <> 0 then

  begin

    IDS_STATUS.Text := '';

    szBuf := 'gp_red() error: ' + IntToStr(Status);

    MessageBox(Handle, PChar(szBuf),'GPIB受信', MB_OK);

  end

  else

  begin

    IDS_STATUS.Text := '受信完了';

    // 受信データ表示

    Edit8.Text := RxBuf;

  end;


 // ハンドシェイク数の取得

  Status := gp_count();

  IDT_RXCNT.Caption := IntToStr(Status);


end;


Procedure TMainForm.MeasEx;       //測定実行

var state:integer;  i: integer; rxs:string;

begin


  for i := 0 to  Fsteps - 1 do

   begin

     Edit7.Text := 'EX';   //トリガ

     Button1Click(self);   // 送信ボタン

     WaitnMs(100);

     state := gp_wsrq(5);  //5秒間SQR待ち

     Button2Click(self);   // 受信ボタン

     if (state <> 0) or Chudan then Exit;]




[5694] Re2:GPIB返信 削除
2012/2/1 (水) 22:22:17 たてぐや
▼ 真空管さん

>   for i := 0 to  Fsteps - 1 do
>
>    begin


 このFstepsはどうやって取得しているのでしょうか? 多分ハンドシェイク
数ではないかと想像しているのですが、取得方法が解りません。

[5695] Re3:GPIB返信 削除
2012/2/2 (木) 10:55:40 真空管
▼ たてぐやさん

>  このFstepsはどうやって取得しているのでしょうか? 多分ハンドシェイク
> 数ではないかと想像しているのですが、


 そうです、Fstepsはグローバル変数で「測定スタート周波数」
「ストップ周波数」「ステップ周波数」からデータ取得回数を
測定実行前に求めています。

 ずいぶん昔の事で自分でも理解しきれないまま、GPIB絡みを
適当に抜き出してしまいました、ペコリ!!。

 お気付きかと思いますが、gp_xxxx(xxx)はU2GPLIB.DLLの
関数です。REX-USB220はまだ現役のようで、マニュアルが
RATOC sytemsのサイトからダウンロードできます。

 もう一つ気になる事ですが、ここで使った測定器は古い物で
ステップ周波数を指定するステップ掃引ですが、新しいものは
連続掃引で、データ取得方法が異なります。予算の折り合いが
つかずに手付かずのままです。


[5698] Re4:GPIB返信 削除
2012/2/2 (木) 22:24:36 たてぐや
▼ 真空管さん

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

>  そうです、Fstepsはグローバル変数で「測定スタート周波数」
> 「ストップ周波数」「ステップ周波数」からデータ取得回数を
> 測定実行前に求めています。


 ここのコードはどこに書いてあるのでしょうか? 頼りっきりで済みません。
RS-232Cならお手の物なのですがGPIBは初めて使うもので、要領がつかめません。

[5702] Re5:GPIB返信 削除
2012/2/3 (金) 11:24:32 真空管
▼ たてぐやさん

>  ここのコードはどこに書いてあるのでしょうか?

 Fstepsは一回の測定で取得するデータ数で深い意味は有りません、
 余計なものが色々ですが、[MeasEx; //測定実行]までの流れが
コメントからなんとなく分かるかと思います。以下がその部分です。

//*************** 測定開始 ************
procedure TMainForm.BitBtn1Click(Sender: TObject);
begin
  Chudan := False; Teishi := False;
  BitBtn1.Enabled := False;  //測定ボタン
  BitBtn2.Enabled := True;  //中断ボタン
  BitBtn3.Enabled := True;  //一時停止ボタン
  RichEdit1.Clear;          //生データ.クリア
  DrawBox1;                 //グラフ・クリア
  Panel2.Color := GraphBack;//グラフ・パネル色
  Panel2.Font.Color := GraphTxt; //グラフ文字色
  Label53.Font.Color := GraphTxt;
  HPOK := False;

  SelDispUnit();    //表示の単位設定
  ForceSelScale;    //スケールの強制選択

  SetUnit;      //単位,unitStr, unitF 設定
  WRfreqNote;   //グラフ周波数書込み,fLow, fMid,fHigh 計算
  WrGraphNotes; //グラフにその他情報記入'WRgraph'
  CalStep;      //stepF, Fsteps 計算
  TextFileHead;
  if not GPIBinz then  BtnGPINITClick(self) // GPIB 初期化ボタン
  else  gp_clr(GpAdrsBuf);

  if GPIBinz then
  begin
   MeasSetUp;    //測定器を設定
   if RadioMeasItem.ItemIndex = 0 then ZcalDispInit; //Z結果表示を****
   MeasEx;       //測定実行

   //ShowMessage('測定中');


CalStepでFstepsを計算です。

Procedure TMainForm.CalStep;      //stepF, Fsteps 計算
var n:integer; stps:real;
begin
   stepF := StrToFloat(Edit3.Text);
   stps :=  (fHigh - fLow) * unitF / stepF;
   n := Trunc(stps) + 1;
   Fsteps := n;
end;

stepFはユーザが測定開始前にEditに書き込みます。
fHigh,fLow,unitF(Hz,KHz等の単位)もユーザがEditに書いたもの。

MeasSetUp;でMeasEx;(測定実行)の前に測定器を設定ですが、
これもついでに。

Procedure TMainForm.MeasSetUp;    //測定器を設定
var cmdtxt, strt, fin, step:string;  f:real;
begin
   Edit7.Text := 'OL' + Edit9.Text + 'EN';  //OSCレベル
   Button1Click(self);   // 送信ボタン

   case RadioMeasItem.ItemIndex of  //測定項目
    0 : cmdtxt := 'A1B1';
    1 : cmdtxt := 'A4B2';
    2 : cmdtxt := 'A4B1';
    3 : cmdtxt := 'A3B2';
    4 : cmdtxt := 'A3B1';
   end;
   cmdtxt := cmdtxt + 'T3F1';
   Edit7.Text := cmdtxt;  //メンテナンス・ページ
   Button1Click(self);   // 送信ボタン
   if not HPOK then Exit;

   f := fLow * unitF / 1000;
   strt := FloatTostrF(f,ffFixed,8,3); //スタートF
   f := fHigh * unitF / 1000;
   fin  := FloatTostrF(f,ffFixed,8,3); //ストップF
   f := stepF / 1000;
   step := FloatTostrF(f,ffFixed,8,3); //ステップF
   cmdtxt := 'SF' + step + 'ENTF' + strt + 'ENPF' + fin + 'EN';
   Edit7.Text := cmdtxt;  //メンテナンス・ページ
   Button1Click(self);   // 送信ボタン
   if not HPOK then Exit;

   Edit7.Text := 'D1';   //Date ready - ON
   Button1Click(self);   // 送信ボタン
   if not HPOK then Exit;

   Edit7.Text := 'W1W2';   //AUTO, STEP UP
   Button1Click(self);   // 送信ボタン
   if not HPOK then Exit;
end;


[5703] Re6:GPIB返信 削除
2012/2/3 (金) 22:18:29 たてぐや
▼ 真空管さん

 早速にありがとうございます。
 結局GPIBでは終了信号というのはないので、予測されるより多い数値をユー
ザーが決めてループを組み、ボタンを押すなどの何らかのメソッドでループを
抜け出す、ということでよろしいのでしょうか?

[5708] Re7:GPIB返信 削除
2012/2/5 (日) 11:21:27 真空管
▼ たてぐやさん

 スミマセン、ご質問の意味が良く分からないのですが。たぶん
私の示した例が不適当だったのでは。
 それに、難しくお考え過ぎのようにも思えるのですが。

 私もGPIBを何度も手がけた訳ではないので間違いもあるかと
思いますが、GPIBについての私の認識を紹介しておきます。
 バイト単位のパラレル転送で、昔のプリンタITFだったセントロ
標準と比べるとデータは双方向、複数機器を接続可能
とするためにアドレスを設けた(例外もあり)、そのためにセントロ
標準よりも制御線と約束事が複雑になったものです。
 昔のプリンタITFでも、Ack,Ready信号も汎用パラレルポートで
プログラムして印字できたように、GPIBも全て汎用パラレルポートで
インターフェースも可能です。数十年前にZ80(6809だったかな)で
この方法で測定器のデータを読み出した記憶があります。
今ではその方法をすっかり忘れてしまってますが。Delphiのときは
GPIB-USB変換のメーカーが用意してくれたDLLを使えたので
ややっこしい事は思い出さなくても済んでしまいました。

 さて、Dephiでやった私の例のGPIBに関わる流れですが、
初期化(// GPIB 初期化ボタン)の実行後は、DLL関数のgp_wrt()で
文字列にデリミタ(私の場合はCR LF)を付加して測定器へのコマンドと
して送り、gp_red()でデリミタまでの文字列を測定器から受信。
これを必要な回数(Fsteps)繰り返します。
 この辺はRS-232Cでコマンドを送り、結果を受信と、測定器等を
操作するのと変わることはありません。
(使用するGPIB-ITFによってはもう少し低レベルのところまで
プログラムの必要があるかもしれませんが)

△例外について
 昔はGPIBインターフェースのプリンタがありました。測定器を
これに直接つないで簡便に測定値を印字する方法として、
「トーカー・オンリー」と言うのもありました。これは、測定器が
勝手に一測定終了する度に結果の文字列とデリミタを吐き出し、
ジコジコと印字するものだったと思います。まさかこのタイプの
測定器ではないですよね。

なにか遠回りをさせてしまったようですが、少しでもお役に
立てれば幸いです。


[5713] Re8:GPIB返信 削除
2012/2/5 (日) 22:56:23 たてぐや
▼ 真空管さん

 何度も済みません。
> 今ではその方法をすっかり忘れてしまってますが。Delphiのときは
> GPIB-USB変換のメーカーが用意してくれたDLLを使えたので
> ややっこしい事は思い出さなくても済んでしまいました。


 使おうとしているのは同じRATCOCのREX-USB220です。大変幸運でした。サン
プルで付属してきたプログラムは、依頼主が色々試してみたそうですが、動作
がよく理解できなかったそうです。

>  さて、Dephiでやった私の例のGPIBに関わる流れですが、
> 初期化(// GPIB 初期化ボタン)の実行後は、DLL関数のgp_wrt()で
> 文字列にデリミタ(私の場合はCR LF)を付加して測定器へのコマンドと
> して送り、gp_red()でデリミタまでの文字列を測定器から受信。
> これを必要な回数(Fsteps)繰り返します。


 最初に送る文字列は決まっているのでしょうか? まずここが解らないので
す。PC側から何らかの文字列を送信すると機器からの送出が始まると考えてい
いのでしょうか?
 これが決まってしまえば適当な回数ループさせて、機器からの送出が終わっ
てもループを抜けないようなら停止させる、という具合に真空管さんのコード
を読みました。(chudanというフラグ)
 何度もお手をわずらわせて済みません。なにせ実機がない状態でコーディン
グしなければならないので、手探り状態なのです。週明けに一度実機のあると
ころへ行ってためしてみるつもりでいます。

[5722] Re9:GPIB返信 削除
2012/2/6 (月) 18:48:10 真空管
▼ たてぐやさん

>  最初に送る文字列は決まっているのでしょうか? まずここが解らないので
> す。PC側から何らかの文字列を送信すると機器からの送出が始まると考えてい
> いのでしょうか?


 ああ!、これがRS-232Cと最も違うところかも。RS-232Cならば「結果吐き出せ」
とコマンドを送れば向こうから勝手に送ってきますが。GPIBでは測定器側で
吐き出すデータが用意できたらマスタ(PC)が読み出します。

 私のコードの例では、「Procedure TMainForm.MeasEx;//測定実行」の
「//トリガ」が測定開始コマンドで、WaitnMs(100);は100mSの待ちです
(必要ないかも)。次に適当に待ってから読みに行ってもよいのですが、
gp_wsrq(5);でステートの「リクエストサービス」を待ちます。
これからリターンしたら「Button2Click(self);// 受信ボタン」で測定
結果を読み込みます。

>  これが決まってしまえば適当な回数ループさせて、機器からの送出が終わっ
> てもループを抜けないようなら停止させる、という具合に真空管さんのコード
> を読みました。(chudanというフラグ)


 いやいや、Fstepsは作図に必要な測定回数で、Fsteps回上記のトリガと
受信を繰り返します。 chudanはユーザが強制的に上記の測定ループを
中止させるためです。このアプリは測定中にも取得済みデータで逐次グラフを
更新しています。それを見ているユーザが「これはいらん」と思えば
「中断」ボタンをクリックでchudanフラグが立つと言うわけで。

  測定器とのGPIB通信を最初に試みたときのパネルを添付して置きます。
「初期化」「送信」「受信」の三つのボタンで済みます。
「初期化」に対応のprocedureが1月29日返信の「// GPIB 初期化ボタン」
これで送信・受信の用意ができる訳で、「送信」ボタン上のEditに
測定器の設定コマンドを書いて「送信」、最後に測定実行コマンドを書いて
「送信」で測定結果が測定器に用意されているはずなので「受信」でその上の
Editに読み出されます。
 「送信」「受信」のコードも1月29日返信の「//GPIBコマンド送信ボタン」
「// 受信ボタン」。

 これが動けば後は気楽なもので、ホンチャンのコードではこのパネルの
ボタンclick()を呼び出し元がselfで呼び出して自動運転、このパネルは
隠しておしまい。


[5723] Re10:GPIB返信 削除
2012/2/6 (月) 20:55:12 たてぐや
▼ 真空管さん

 何度も丁寧にほんとうにありがとうございます。
 なるほどと少し理解できてきました。今日明日くらいでテスト版を作って実
機がある所で試してみます。

> ボタンclick()を呼び出し元がselfで呼び出して自動運転、このパネルは
> 隠しておしまい。


 で、読み込み結果ですが、一回ごとにテキスト的に一行来る、という理解で
よろしいのでしょうか?

[5725] Re11:GPIB返信 削除
2012/2/7 (火) 10:05:07 真空管
▼ たてぐやさん

> > ボタンclick()を呼び出し元がselfで呼び出して自動運転、このパネルは
> > 隠しておしまい。
>
>  で、読み込み結果ですが、一回ごとにテキスト的に一行来る、という理解で
> よろしいのでしょうか?


 はい、使う測定器の仕様がよほどへそ曲がりでない限り、その通りです。
納品版でもこの隠したEditの.textをcopyして使っています。
 昔、GPIBのプリンタがあった時代の習慣かと思いますがASCIIコードが
普通で、デリミタは[CR LF]が普通のようです。U2GPLIB.dllのデフォルトも
送信文字列に[CR LF]を付加、受信のデリミタは[LF]で、そのまま使いました。

[5727] Re12:GPIB返信 削除
2012/2/7 (火) 22:02:15 たてぐや
▼ 真空管さん
> ▼ たてぐやさん
>
> > > ボタンclick()を呼び出し元がselfで呼び出して自動運転、このパネルは
> > > 隠しておしまい。
> >
> >  で、読み込み結果ですが、一回ごとにテキスト的に一行来る、という理解で
> > よろしいのでしょうか?
>
>  はい、使う測定器の仕様がよほどへそ曲がりでない限り、その通りです。


 実機がある所で試してきました。コードはほとんど真空管さんのものを引用
させて頂きました。結果、初期化は難なく成功しましたが、データ読み込みは
うまくいきませんでした。測定器の素子の動きを見ているとどうやら連続掃引
のような気がしてきました。状況としては、ハンドシェイク数が6で終わってし
まいます。送信-受信ボタンを押したところデータは来ているようなのですが、
連続自動運転させるとなにも上がって来ませんでした。うーむ、どうしたもの
か…

[5731] Re13:GPIB返信 削除
2012/2/8 (水) 10:49:02 真空管
▼ たてぐやさん

> させて頂きました。結果、初期化は難なく成功しましたが、データ読み込みは
> うまくいきませんでした。測定器の素子の動きを見ているとどうやら連続掃引
> のような気がしてきました。状況としては、ハンドシェイク数が6で終わってし
> まいます。送信-受信ボタンを押したところデータは来ているようなのですが、
> 連続自動運転させるとなにも上がって来ませんでした。うーむ、どうしたもの
> か…


 うーむ、残念ですが私がアドバイスできるのはここまでかと。
数年前に、「新しいインピーダンス計で試みたら動かない、対応してほしい」
と要請がありました。依頼主はコマンドやデータ・フォーマットの違い程度
と思ったようでしたが、新しい仕様を見てみると掃引のしかたが異なり、
データ取得の方法もそっくり作り直しが必要と分かり、前にも述べたとおり
手付かずのままで、HPの新しいインピーダンス計でしたら私も未経験なのです。
スミマセン.


[5781] Re14:GPIB返信 削除
2012/2/17 (金) 18:33:34 たてぐや
▼ 真空管さん、Mr.XRAYさん

 スレッド堀かえして済みません。何とかなったという報告です。結局測定器
は連続掃引で、勝手にだらだらとデータを垂れ流してくるだけ、という単純な
仕組みでした。難しく考え過ぎた感があります。垂れ流してくるのならこっち
はただ口を開けて待っていればよかったのです。これさえ出来ればあとは一気
呵成。受け取ったデータをTListboxに保持させておいて、Excelのセルに書きこ
んでおしまいでした。
 色々とご助言・情報ありがとうございました。


[5784] Re15:GPIB返信 削除
2012/2/18 (土) 10:08:23 真空管
▼ たてぐやさん

>  スレッド堀かえして済みません。何とかなったという報告です。

 いやー、よかったよかった。
私のいいかげんなアドバイスでかえって余計な苦労をさせてしまったのではと
心配でした。
 ほんとにご苦労様でした。

[▼次のスレッド]
INCM/CMT
Cyclamen v3.82