blochの日記

自虐ネタ以外のぐちは書かないようにしましょう

VISAでシリアル制御に二時間

既にvisa32.dll自体は使えるようにしてある。だいぶ前に書いたように、loadlibraryして、ハンドラをゲットして、そのハンドラで各種手続きを呼ぶだけである。ただ、そこに到達するまでが大変。とっても大変。
各種定数の定義、各種関数型の定義、各種関数自体のdll側の定義と、Delphi側の定義、dllから関数名を探して、そのアドレスを関数に割り当て、、、これらをC言語からPascalへ書き換えるのだ、書き換えるのだ!

しかし一旦やってしまえば、今回のシリアル自体の制御は簡単。読むだけなので、viReadだけでOK。パラメタ設定はvisaのツールで手動でやって置く。
ところがもう一つ問題が持ち上がった。今の時代となっては9600bpsというデータ転送速度は結構遅いのだ。昔は取りこぼさないように必死だったけれど、今は逆にウェイトが必要になる。1データ30バイトなので、毎回、数十ミリ秒待ってからでないとviReadエラーになる。ウェイトDOループを咬ませても良いのだけれど、やはりそこはプログラマの意地として、バッファのデータバイト数をゲットしたい。さて、何を見れば良いのか?
visaのプログラミングマニュアルを検索して、availableと言う単語を探した。すると、VI_ATTR_ASRL_AVAIL_NUMと言う長い長い名前の定数だか変数だかが見つかった。これ自体がバイト数を表す変数なのか?そうではない、これを引数にして何かの関数を呼ぶのだ。と言うことは、この定数の定義がどこかにあるはず。
しかし、この手の定数は言語デペンデントなので、マニュアルには一切、記述がない!全く無いのだ。ではどうすれば良いかというと、以前記したように、「何か」を検索して、C言語用か、VB用のvisaの定数定義ファイルを見つけるのだ。visa.hとか、visa32.basとか言うファイルがどこかに見つかる。Google上か、あるいは自分のPC内(visaシステムをインストールした場所)かも知れない。そのファイルの中でVI_ATTR_ASRL_AVAIL_NUMを検索して値を見つけて、

#define VI_ATTR_ASRL_AVAIL_NUM (0x3FFF00ACUL)
などと書いてあるのを、
VI_ATTR_ASRL_AVAIL_NUM=longword($3FFF00AC);
と直すのである。

次に、使用する関数は、この定数が「アトリビュート」なるものに関係したものらしいので、アトリビュートを読みだす関数viGetAttributeを使えるようにしなければならない。上に書いたように、

  1. dll側の型定義
    • TviGetAttribute=function(vi:ViSession; attribute:Viattr; var attrstate:ViAttrState):longword; stdcall;
      • 引数もvisa.hを参考にして書いておく
  2. Delphi側ライブラリ内での関数名定義(変数として定義する)
    • var viGetAttribute: TviGetAttribute;
  3. Delphi側で、ライブラリを呼び出す側の関数名定義
    • procedure vi_Getattr(vi:ViSession; attribute:Viattr; var attrstate:ViAttrState);
      • で、奮闘すること二時間、うまく行かない!プログラムが暴走してしまう。
  4. 関数へのジャンプ先アドレスの割り当て、これを忘れていた。
    • dllを検索してアドレスをゲットして、変数として定義したviGetAttributeのポインタ上に書き込むのだ
    • @viGetAttribute:=GetProcAddress(visa32Lib,'viGetAttribute');

やっと出来た。あとは、sma4が自動起動するようにして、二台の34401からデータを読み込んでファイルにアペンドするだけだ。

大変だけど、ここは、OhさんやKwさんから言われたように、「乗っかって」行くぞ〜!オー。