2005-11-22

PyVISA - COM ポートをオープンする

PyVISA で COM2 ポートを開くには、Instrument クラスの第1引数にリソース名を指定して、インスタンス化します。



itc4 = Instrument("COM2", term_chars = "\r", timeout = 5)


インスタンス化っぽいものの中身は以下のとおりです。細かいところは省略しまくりです。



class Instrument(ResourceTemplate):
# ...
def __init__(self, resource_name, **keyw):
# ...
# スーパークラスのコンストラクタを呼びます。
ResourceTemplate.__init__(self, resource_name,
**_filter_keyword_arguments(keyw, ("timeout",
"lock")))

class ResourceTemplate(object):

# ...

def __init__(self, resource_name=None, **keyw):

# ...

if self.__class__ is ResourceTemplate:

# ResourceTemplate は継承して使いたいので、

# 直接インスタンス化しようとしたら例外を投げます。

raise TypeError, "trying to instantiate an abstract class"

if resource_name is not None: # is none for the resource manager

# ...

# ここでローレベルモジュール vpp43 の open 関数を呼び出します

# vpp43 の中で、ドライバに直接アクセスします。

# Instrument クラスは、Python で呼び出しやすくするためのラッパーです。

self.vi = vpp43.open(resource_manager.session, resource_name,

keyw.get("lock", VI_NO_LOCK))

# ...



NI-VISA ライブラリは、通信ポートや GPIB 機器など物理的な通信先をリソース名で区別します。いったん、接続やセッションを開いてからは NI-VISA 内部ではハンドラのような ID で区別します。ResrouceTemplate は、この ID を隠してくれます。オブジェクト指向言語でラップするときは、セッションをオブジェクトのプロパティにしてしまうようです。ふーん。



vpp43.py の open メソッドは以下のとおり。




# vpp43.py
def open(session, resource_name, access_mode = VI_NO_LOCK, open_timeout =
VI_TMO_IMMEDIATE):
vi = ViSession()
visa_library().viOpen(session, resource_name, access_mode, open_timeout,
byref(vi))
return vi.value


byref() は ctypes でポインタ渡しするとき関数です。visa_library() は visa32.dll のアクセスポイントのようなものを返します。viOpen() は visa32.dll に含まれる関数です。



結果的に Instrument オブジェクトをインスタンス化したときに、visa32.dll で COM2 への接続を確立することになります。