# GP-IB library wrapper for National Instruments gpib-32.dll # written in 2003 # bug fix at 2010.8.15 require "Win32API" class Gpib class Error < StandardError end def initialize @dev,@pad,@sad,@tmo = -1,-1,-1,-1 @pad0,@sad0,@tmo0 = @pad,@sad,@tmo #previous setting end attr_accessor :pad attr_accessor :sad attr_accessor :tmo def open(bd=0,pad=@pad,sad=@sad,tmo=@tmo,eot=1,eos=0) @dev = ibdev(bd,pad,sad,tmo,eot,eos) @pad,@sad,@tmo=pad,sad,tmo @pad0,@sad0,@tmo0=pad,sad,tmo raise Gpib::Error, err_str(thrediberr) if @dev < 0 @dev end def write(str) setpara stat,cnt = ibwrt(str) raise Gpib::Error, err_str(stat) if (stat & Stat.assoc("ERR")[1]) > 0 cnt end def wait_rqs setpara mask=(Stat.assoc("TIMO")[1] | Stat.assoc("RQS")[1]) stat=ibwait(mask) raise Gpib::Error, err_str(stat) if (stat & Stat.assoc("ERR")[1]) > 0 end def read(cnt=1024) setpara buf = "" loop do stat,b = ibrd(cnt) raise Gpib::Error, err_str(stat) if (stat & Stat.assoc("ERR")[1]) > 0 buf << b break if (stat & Stat.assoc("END")[1]) > 0 end return buf end def rsp setpara stat, rspr = ibrsp raise Gpib::Error, err_str(stat) if (stat & Stat.assoc("ERR")[1]) > 0 return rspr end def setpara ibpad(@pad) unless @pad==@pad0 ibsad(@sad) unless @sad==@sad0 ibtmo(@tmo) unless @tmo==@tmo0 @pad0,@sad0,@tmo0=@pad,@sad,@tmo end # # #constants #Timeout values and meanings TNONE = 0 # Infinite timeout (disabled) T10us = 1 # Timeout of 10 us (ideal) T30us = 2 # Timeout of 30 us (ideal) T100us = 3 # Timeout of 100 us (ideal) T300us = 4 # Timeout of 300 us (ideal) T1ms = 5 # Timeout of 1 ms (ideal) T3ms = 6 # Timeout of 3 ms (ideal) T10ms = 7 # Timeout of 10 ms (ideal) T30ms = 8 # Timeout of 30 ms (ideal) T100ms = 9 # Timeout of 100 ms (ideal) T300ms =10 # Timeout of 300 ms (ideal) T1s =11 # Timeout of 1 s (ideal) T3s =12 # Timeout of 3 s (ideal) T10s =13 # Timeout of 10 s (ideal) T30s =14 # Timeout of 30 s (ideal) T100s =15 # Timeout of 100 s (ideal) T300s =16 # Timeout of 300 s (ideal) T1000s =17 # Timeout of 1000 s (ideal) # GPIB status bit vector : # global variable ibsta and wait mask Stat=[ ["ERR",1<<15], # Error detected ["TIMO",1<<14], # Timeout ["END",1<<13], # EOI or EOS detected ["SRQI",1<<12], # SRQ detected by CIC ["RQS",1<<11], # Device needs service ["SPOLL",1<<10], ["EVENT",1<<9], ["CMPL",1<<8], # I/O completed ["LOK",1<<7], # Local lockout state ["REM",1<<6], # Remote state ["CIC",1<<5], # Controller-in-Charge ["ATN",1<<4], # Attention asserted ["TACS",1<<3], # Talker active ["LACS",1<<2], # Listener active ["DTAS",1<<1], # Device trigger state ["DCAS",1<<0], # Device clear state ] # Win32API Ibdev=Win32API.new("gpib-32","ibdev",["L","L","L","L","L","L"],"L") Ibfind=Win32API.new("gpib-32","ibfind",["P"],"L") Ibwait=Win32API.new("gpib-32","ibwait",["L","L"],"L") Ibwrt=Win32API.new("gpib-32","ibwrt",["L","P","L"],"L") Ibrd=Win32API.new("gpib-32","ibrd",["L","P","L"],"L") Thredibcntl=Win32API.new("gpib-32","ThreadIbcntl",[],"L") Thrediberr=Win32API.new("gpib-32","ThreadIberr",[],"L") Ibrsp=Win32API.new("gpib-32","ibrsp",["L","P"],"L") Ibclr=Win32API.new("gpib-32","ibclr",["L"],"L") Ibpad=Win32API.new("gpib-32","ibpad",["L","L"],"L") Ibsad=Win32API.new("gpib-32","ibsad",["L","L"],"L") Ibtmo=Win32API.new("gpib-32","ibtmo",["L","L"],"L") def err_str(stat) r = [] for i in 0..15 r << Stat[i][0] if (stat & Stat[i][1])!=0 end "<" + r.join(",") + ">" end # basic commands def ibdev(bd=0,pad=0,sad=0,tmo=T1s,eot=1,eos=0) ud = Ibdev.call(bd,pad,sad,tmo,eot,eos) end def ibfind(name = "dev1") @dev = Ibfind.call(name) end def ibwait(mask) Ibwait.call(@dev,mask) end def ibwrt(str) stat = Ibwrt.call(@dev,str,str.size) cnt = thredibcntl [stat,cnt] end def ibrd(size = 1024) buf = "\000" * size stat = Ibrd.call(@dev,buf,size) cnt = thredibcntl [stat,buf[0,cnt]] end def thredibcntl Thredibcntl.call end def thrediberr Thrediberr.call end def ibrsp rsp = "\0" stat = Ibrsp.call(@dev,rsp) [stat, rsp.unpack("c")[0]] end def ibclr Ibclr.call(@dev) end def ibpad(pad) Ibpad.call(@dev,pad) end def ibsad(sad) Ibsad.call(@dev,sad) end def ibtmo(tmo) Ibtmo.call(@dev,tmo) end end