classdef Equipment < handle %EQUIPMENT Summary of this class goes here % Detailed explanation goes here properties (SetAccess=private) name tcp channel locked end properties (Dependent, SetAccess=private) error end methods function ecq = Equipment(ipAddress,port,channel) %EQUIPMENT Construct an instance of this class % This functions opens the required TCP connection % for this device. Channel is GPIB-channel on prologix % converter if used, otherwise set channel to -1. % Name is queried from device via '*IDN?' command. ecq.tcp = Equipment.getTCP(ipAddress,port); ecq.locked = false; ecq.channel = channel; ecq.name = ecq.idn(); end function id = idn(ecq) %IDN Queries identificantion from device via '*IDN?'. id = ecq.query_unsafe('*idn?'); end function clear(ecq) %CLEAR Sends clear command to device via '*CLS'. ecq.write_unsafe('*cls'); end function opc(ecq) %OPC executes 'operation complete query' to device. %Function holds untill device returns '1'. Must be %used to avoid interrupting busy device. ecq.query_unsafe('*OPC?'); end function unlock(ecq) if ecq.channel >= 0 fprintf(ecq.tcp,'++loc'); ecq.locked = false; end end function lock(ecq) if ecq.channel >= 0 fprintf(ecq.tcp,'++llo'); ecq.locked = true; else warning('Device does not support locking') end end function beep(ecq) ecq.write('SYST:BEEP') end function delete(ecq) ecq.unlock; Equipment.getTCP(ecq.tcp.RemoteHost,-1); end function write(ecq,message) ecq.opc; ecq.write_unsafe(message); ecq.error; end function write_unsafe(ecq,message) if ecq.channel >= 0 fprintf(ecq.tcp,['++addr ', num2str(ecq.channel)]); end fprintf(ecq.tcp, message); end function output = read(ecq) if ecq.channel >= 0 fprintf(ecq.tcp,'++read'); end output = fscanf(ecq.tcp); end function output = query(ecq,message) ecq.opc; output = ecq.query_unsafe(message); ecq.error; end function output = query_unsafe(ecq,message) ecq.write_unsafe(message); output = read(ecq); end function errorlist = get.error(ecq) for i = 1:20 output = ecq.query_unsafe('SYSTem:ERRor?'); errorlist(i,1:(length(output))) = output; %errorcode = regexp(output,'\d*','match','once'); if str2double(regexp(output,'\d*','match','once'))==0 if i>1 warning('Error from device: %s %s',ecq.name,reshape(errorlist(1:i-1,:)',1,[])); ecq.clear; end break; end end end end methods (Static) function tcpobject = getTCP(ipAddress,port) persistent tcpconnection; ipname = Equipment.ip2structname(ipAddress); if port > 0 if isempty(tcpconnection) tcpconnection = struct; end if ~isfield(tcpconnection, ipname) tcpconnection.(ipname).tcp = tcpip(ipAddress,port); tcpconnection.(ipname).nopen = 1; fopen(tcpconnection.(ipname).tcp); else tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen + 1; end tcpobject = tcpconnection.(ipname).tcp; elseif port == -1 if tcpconnection.(ipname).nopen > 1 tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen - 1; else fclose(tcpconnection.(ipname).tcp); tcpconnection = rmfield(tcpconnection,ipname); end else error([num2str(port),' is not a valid port number try a value between 1 and 65535.']); end end function bool = isnum(input) bool = isnumeric(input)&&isscalar(input); end function num = forceNum(input) if ~isnumeric(input) error('Input should be a (single) number.'); end num = input; end function iptest(ipAddress) validip = regexp(ipAddress,'^(?:(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9]))$', 'once'); if isempty(validip) error('Invalid IP-address'); end end function structname = ip2structname(ipAddress) Equipment.iptest(ipAddress); ipmatch = regexprep(ipAddress,'\.','_'); structname = ['ip',ipmatch]; end end end