module CONTROL_FUNCTIONS include RBA require 'fiddle' class Gpib attr_accessor :verbose attr_accessor :devices attr_accessor :classOK #constants #Timeout values and meanings TNONE = 0 unless defined? TNONE # Infinite timeout (disabled) T10us = 1 unless defined? T10us # Timeout of 10 us (ideal) T30us = 2 unless defined? T30us # Timeout of 30 us (ideal) T100us = 3 unless defined? T100us # Timeout of 100 us (ideal) T300us = 4 unless defined? T300us # Timeout of 300 us (ideal) T1ms = 5 unless defined? T1ms # Timeout of 1 ms (ideal) T3ms = 6 unless defined? T3ms # Timeout of 3 ms (ideal) T10ms = 7 unless defined? T10ms # Timeout of 10 ms (ideal) T30ms = 8 unless defined? T30ms # Timeout of 30 ms (ideal) T100ms = 9 unless defined? T100ms # Timeout of 100 ms (ideal) T300ms = 10 unless defined? T300ms # Timeout of 300 ms (ideal) T1s = 11 unless defined? T1s # Timeout of 1 s (ideal) T3s = 12 unless defined? T3s # Timeout of 3 s (ideal) T10s = 13 unless defined? T10s # Timeout of 10 s (ideal) T30s = 14 unless defined? T30s # Timeout of 30 s (ideal) T100s = 15 unless defined? T100s # Timeout of 100 s (ideal) T300s = 16 unless defined? T300s # Timeout of 300 s (ideal) T1000s = 17 unless defined? T1000s # 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 ] unless defined? Stat class Error < StandardError end ############################################################################################################ def initialize() @niDLL_Path = "C:/Windows/System32/ni4882.dll" puts @niDLL_Path if File.exists?(@niDLL_Path) puts @niDLL_Path + " found" @lib_ni4882 = Fiddle.dlopen(@niDLL_Path) puts @niDLL_Path + " opened" @devices = [] setupFunctions() puts "GPIB initialized" @verbose = 5 @classOK = true else puts "FILE not found: " + @niDLL_Path @classOK = false end end ############################################################################################################ ############################################################################################################ ############################################################################################################ def findDevices() (1..30).each do |i| close(i) newDevice = [-1, 0, i, 0, ""] ud = open(newDevice, T1s, 1, 0) listen = ibln(0, i, 0, 1) if listen.strip.length>0 app = RBA::Application.instance app.process_events res = getIDN(ud.to_i, i, 100) if res.length>0 puts "FOUND <#{res}> at GPIB #{i}" newDevice[0] = ud.to_i newDevice[4] = res @devices << newDevice end end res = close(ud) end puts "#{@devices.length} devices" end ############################################################################################################ def getIDN(dev, pad, maxNum) cmd = '*IDN?' cmdEG2001 = "IDN" res = - 1 idn = "" if pad == 1 res = @ibwrt.call(dev, cmdEG2001, cmdEG2001.length) else res = @ibwrt.call(dev, cmd, cmd.length) app = RBA::Application.instance app.process_events end bytes = "" length = 128 (1..length).each {|i| bytes += " "} idn = @ibrd.call(dev, bytes, 128) return bytes.strip end ############################################################################################################ def getDevice(name) retVal = [] @devices.each do |device| dev = device[0] bd = device[1] pad = device[2] sad = device[3] idn = device[4] if idn.include? name retVal = device break end end return retVal end ############################################################################################################ def sendTestCommands_HP4145B(dev, tmo, eot, eos) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] open(dev, tmo, eot, eos) # overwrites dev[0]=ud write(dev, "*RST;"); write(dev, "DE\r\n"); write(dev, "CH1\r\n"); write(dev, "CH2\r\n"); write(dev, "CH3\r\n"); write(dev, "CH4\r\n"); write(dev, "VS1\r\n"); write(dev, "VS2\r\n"); write(dev, "VM1\r\n"); write(dev, "VM2\r\n"); write(dev, "CH1,'VA','IA',1,1\r\n"); write(dev, "CH2,'VC','IC',1,3\r\n"); write(dev, "SS\r\n"); write(dev, "VR1,-1E-1,1E-1,1E-2,1E-2\r\n"); write(dev, "VC2,0E+0,1E-1\r\n"); write(dev, "HT 1\r\n"); write(dev, "DT 0\r\n"); write(dev, "IT1\r\n"); write(dev, "SM\r\n"); write(dev, "DM1\r\n"); write(dev, "XN 'VA',1,-0.1,0.1\r\n"); write(dev, "YA 'IA',1,0,0.1\r\n"); write(dev, "MD\r\n"); write(dev, "DR0\r\n"); write(dev, "BC\r\n"); write(dev, "ME1\r\n"); sPOLL(dev, 100, 5); puts "poll done" write(dev, "BC\r\n"); data = sendAndReceive(dev, "DO \'IA\'\r\n", 1024, tmo) puts data[1].to_s close(dev) end ############################################################################################################ def write(dev, cmd) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] stat,cnt = ibwrt(ud, cmd) if (stat & Stat.assoc("ERR")[1]) > 0 puts "WRITE ERR: " + err_str(stat) end puts "WRITE #{pad}: " + cmd.strip if @verbose > 0 cnt end ############################################################################################################ def sendAndReceive(dev, cmd, maxnum, tmo) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] write(dev, cmd); @ibconfig.call(ud, 3, tmo) # 12 = 3sec, 13 = 10sec timeout data = read(dev, maxnum) return data end ############################################################################################################ def read(dev, size = 1024) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] buf = "\000" * size stat = @ibrd.call(ud, buf,size) cnt = thredibcnt puts "READ #{pad}: #{cnt} bytes" if @verbose > 0 [stat,buf[0,cnt]] end ############################################################################################################ def ibrd(dev, size = 1024) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] buf = "\000" * size stat = @ibrd.call(ud,buf,size) cnt = thredibcnt puts "READ #{pad}: #{cnt} bytes" if @verbose > 0 [stat,buf[0,cnt]] end ############################################################################################################ def setupFunctions() # FROM JAVA #public int ibfind(String boardname); #public int ibdev(int bdaddr, int praddr, int secaddr, int tmo, int eot, int eos); #public int ibclr(int dev); #public int ibonl(int boarddev, int v); #public int ibwrt(int dev, String ToBeSent, int ByteCount); #public int ibrd(int dev, byte[] ToBeRead, long ByteCount); #public int ibln(int board, int pad, int sad, int[] listen); #public int iblines(int board, short clines); #public int ibrsp(int addr, byte[] SerialPollByte); #public int ibask(int boarddev, int option, int istbit); #public int ibconfig(int boarddev, int option, int value); #public int Iberr(); #public int Ibsta(); #public int Ibcnt(); #public int Ibcntl(); @ibfind = Fiddle::Function.new(@lib_ni4882[ 'ibfind'], [Fiddle::TYPE_CHAR], Fiddle::TYPE_CHAR) @ibdev = Fiddle::Function.new(@lib_ni4882[ 'ibdev'], [Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_INT, Fiddle::TYPE_INT, Fiddle::TYPE_INT], Fiddle::TYPE_INT) @ibclr = Fiddle::Function.new(@lib_ni4882[ 'ibclr'], [Fiddle::TYPE_INT ], Fiddle::TYPE_INT ) @ibonl = Fiddle::Function.new(@lib_ni4882[ 'ibonl'], [Fiddle::TYPE_INT , Fiddle::TYPE_INT ] , Fiddle::TYPE_INT ) @ibwrt = Fiddle::Function.new(@lib_ni4882[ 'ibwrt'], [Fiddle::TYPE_INT , Fiddle::TYPE_VOIDP , Fiddle::TYPE_INT ], Fiddle::TYPE_INT) @ibrd = Fiddle::Function.new(@lib_ni4882[ 'ibrd'], [Fiddle::TYPE_INT , Fiddle::TYPE_VOIDP , Fiddle::TYPE_LONG], Fiddle::TYPE_INT) @ibln = Fiddle::Function.new(@lib_ni4882[ 'ibln'], [Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT) @iblines = Fiddle::Function.new(@lib_ni4882[ 'iblines'], [Fiddle::TYPE_INT , Fiddle::TYPE_SHORT ], Fiddle::TYPE_INT) @ibrsp = Fiddle::Function.new(@lib_ni4882[ 'ibrsp'], [Fiddle::TYPE_INT , Fiddle::TYPE_VOIDP ], Fiddle::TYPE_INT) @ibask = Fiddle::Function.new(@lib_ni4882[ 'ibask'], [Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_INT], Fiddle::TYPE_INT) @ibconfig = Fiddle::Function.new(@lib_ni4882[ 'ibconfig'], [Fiddle::TYPE_INT , Fiddle::TYPE_INT , Fiddle::TYPE_INT], Fiddle::TYPE_INT) @iberr = Fiddle::Function.new(@lib_ni4882[ 'Iberr'], [], Fiddle::TYPE_INT) @ibsta = Fiddle::Function.new(@lib_ni4882[ 'Ibsta'], [], Fiddle::TYPE_INT) @ibcnt = Fiddle::Function.new(@lib_ni4882[ 'Ibcnt'], [], Fiddle::TYPE_INT) # @ibcntl = Fiddle::Function.new(@lib_ni4882[ 'Ibcntl'], [], Fiddle::TYPE_INT) # @thredibcntl = Fiddle::Function.new(@lib_ni4882['ThreadIbcntl'], [], Fiddle::TYPE_INT) @thredibcnt = Fiddle::Function.new(@lib_ni4882[ 'ThreadIbcnt'], [], Fiddle::TYPE_INT) @thrediberr = Fiddle::Function.new(@lib_ni4882[ 'ThreadIberr'], [], Fiddle::TYPE_INT) end ############################################################################################################ # higher level commands ############################################################################################################ def sPOLL(dev, clockMilliSec, timeoutsec) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] serialPollByte = " " startSec = Time.new.sec endSec = startSec + timeoutsec curSec = Time.new.sec serialPollByte = ibrsp(ud) # puts serialPollByte[1].to_s while (curSec1) do serialPollByte = ibrsp(ud) RBA::QThread::msleep(clockMilliSec) # puts "sPOLL #{serialPollByte} : <#{serialPollByte[0]}> <#{serialPollByte[1]}>" curSec = Time.new.sec app = RBA::Application.instance app.process_events end end ############################################################################################################ def open(device,tmo=@tmo,eot=1,eos=0) ud = device[0] bd = device[1] pad = device[2] sad = device[3] @ibdev.call(bd, pad, sad, tmo, eot, eos) ud = @ibdev.call(bd, pad, sad, tmo, eot, eos) result = ibclr(ud )#; puts " ==> clear #{result}" result = ibonl(ud, 1)#; puts " ==> onl #{result}" if ud < 0 puts err_str(thrediberr) end device[0] = ud end ############################################################################################################ def close(dev) ud = dev[0] bd = dev[1] pad = dev[2] sad = dev[3] @ibonl.call(ud, 0) end ############################################################################################################ 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 ibonl(dev, online=1) ud = @ibonl.call(dev, online) end ############################################################################################################ def ibdev(bd=0,pad=0,sad=0,tmo=T1s,eot=1,eos=0) ud = @ibdev.call(bd,pad,sad,tmo,eot,eos) ud end ############################################################################################################ def ibfind(name = "dev1") dev = @ibfind.call(name) dev end ############################################################################################################ def ibwait(dev, mask) @ibwait.call(dev,mask) end ############################################################################################################ def ibwrt(dev, str) stat = @ibwrt.call(dev,str,str.size) cnt = ibcnt [stat,cnt] end ############################################################################################################ def ibrd(dev, size = 1024) buf = "\000" * size stat = @ibrd.call(dev,buf,size) cnt = thredibcntl [stat,buf[0,cnt]] end ############################################################################################################ def ibcntl @ibcntl.call end ############################################################################################################ def ibcnt @ibcnt.call end ############################################################################################################ def iberr @iberr.call end ############################################################################################################ def thredibcnt @thredibcnt.call end ############################################################################################################ def thrediberr @thrediberr.call end ############################################################################################################ def ibrsp(dev) rsp = "\0" stat = @ibrsp.call(dev,rsp) [stat, rsp.unpack("c")[0]] end ############################################################################################################ def ibclr(dev) @ibclr.call(dev) end ############################################################################################################ def ibpad(dev, pad) @ibpad.call(dev,pad) end ############################################################################################################ def ibsad(dev, sad) @ibsad.call(dev,sad) end ############################################################################################################ def ibtmo(dev, tmo) @ibtmo.call(dev,tmo) end ############################################################################################################ def ibln(bd, pad, sad, size) buf = "\000" * size @ibln.call(bd, pad, sad, buf) return buf end ############################################################################################################ end #class end #module