| @@ -82,9 +82,10 @@ classdef Equipment < handle | |||
| function output = read(ecq) | |||
| %READ Extracts recieved data from the TCP-buffer. | |||
| %This | |||
| %This function sends the '++read'-command to the Prologix if | |||
| %needed. Will always read the TCP-buffer in matlab. | |||
| if ecq.channel >= 0 | |||
| fprintf(ecq.tcp,'++read'); | |||
| write_unsafe('++read'); | |||
| end | |||
| output = fscanf(ecq.tcp); | |||
| end | |||
| @@ -92,7 +93,9 @@ classdef Equipment < handle | |||
| function output = query(ecq,message) | |||
| %QUERY Sends command to the device and read the respond. | |||
| %The command is send via the WRITE and the respond is collected | |||
| %from the device. | |||
| % | |||
| %See also WRITE, READ | |||
| ecq.opc; | |||
| output = ecq.query_unsafe(message); | |||
| ecq.error; | |||
| @@ -131,7 +134,7 @@ classdef Equipment < handle | |||
| %error occured after writing. If possible one should always use | |||
| %the WRITE function. | |||
| % | |||
| %See also WRITE | |||
| %See also WRITE, QUERY | |||
| if ecq.channel >= 0 | |||
| fprintf(ecq.tcp,['++addr ', num2str(ecq.channel)]); | |||
| end | |||
| @@ -139,6 +142,12 @@ classdef Equipment < handle | |||
| end | |||
| function output = query_unsafe(ecq,message) | |||
| %QUERY_UNSAFE Sends command to device and reads device output. | |||
| %This function does not check if device is ready or check if an | |||
| %error occured after writing. If possible one should always use | |||
| %the QUERY function. | |||
| % | |||
| %See also QUERY, WRITE, READ | |||
| ecq.write_unsafe(message); | |||
| output = read(ecq); | |||
| end | |||
| @@ -155,25 +164,41 @@ classdef Equipment < handle | |||
| methods (Static) | |||
| function tcpobject = getTCP(ipAddress,port) | |||
| persistent tcpconnection; | |||
| [ipname,ipAddress] = Equipment.ip2structname(ipAddress,abs(port)); | |||
| if port > 0 | |||
| %GETTCP Returns TCP-object for TCP-connection. | |||
| %Function makes a TCP-connection for specific ipAddress and | |||
| %port. If TCP-connection already exist no new connection is | |||
| %made and only existing handle is returned. | |||
| %For existing connections the function will store the amount of | |||
| %handles in use. Via the DELETE function the connection will be | |||
| %closed if the connection is not in use anymore. | |||
| %The connection will be removed if the port is negative number. | |||
| persistent tcpconnection; %make variable persistent to share tcp-handles across multiple function calls. | |||
| [ipname,ipAddress] = Equipment.ip2structname(ipAddress,abs(port)); %Get a structname and a cleaned ipaddress. | |||
| if port > 0 %if port number is positive a connection is made. | |||
| if isempty(tcpconnection) | |||
| tcpconnection = struct; | |||
| %if the tcpconnection is empty (first time function | |||
| %call) make a struct in the variable. | |||
| tcpconnection = struct; | |||
| end | |||
| if ~isfield(tcpconnection, ipname) | |||
| tcpconnection.(ipname).tcp = tcpip(ipAddress,port); | |||
| tcpconnection.(ipname).nopen = 1; | |||
| fopen(tcpconnection.(ipname).tcp); | |||
| else | |||
| if ~isfield(tcpconnection, ipname) %check if the handle is already made before. | |||
| tcpconnection.(ipname).tcp = tcpip(ipAddress,port); %Make TCP-connection | |||
| tcpconnection.(ipname).nopen = 1; %Set number of connections in use to 1 | |||
| fopen(tcpconnection.(ipname).tcp); %Open the TCP-connection | |||
| else %If connection already exist. Increase number of connections in use by 1. | |||
| tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen + 1; | |||
| end | |||
| tcpobject = tcpconnection.(ipname).tcp; | |||
| elseif port < 0 | |||
| if tcpconnection.(ipname).nopen > 1 | |||
| tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen - 1; | |||
| tcpobject = tcpconnection.(ipname).tcp; %return the TCP-connection handle. | |||
| elseif port < 0 %If the portnumber is negative the connection is removed. | |||
| if tcpconnection.(ipname).nopen > 1 | |||
| %If more than one object uses this tcp-handle. Decrease | |||
| %the number of connections in use by 1. | |||
| tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen - 1; %Decrease the number by 1. | |||
| else | |||
| %If only one handle uses this connection. The | |||
| %connection is closed and the field is removed from the | |||
| %tcpconnection struct. | |||
| fclose(tcpconnection.(ipname).tcp); | |||
| tcpconnection = rmfield(tcpconnection,ipname); | |||
| end | |||
| @@ -183,10 +208,12 @@ classdef Equipment < handle | |||
| end | |||
| function bool = isnum(input) | |||
| %ISNUM Tests if the input is numeric scalar | |||
| bool = isnumeric(input)&&isscalar(input); | |||
| end | |||
| function num = forceNum(input) | |||
| %FORCENUM Throws an error if the input is not numeric. | |||
| if ~isnumeric(input) | |||
| error('Input should be a (single) number.'); | |||
| end | |||
| @@ -194,15 +221,20 @@ classdef Equipment < handle | |||
| end | |||
| function iptest(ipAddress) | |||
| %IPTEST Checks if the given IPv4-address is valid. | |||
| 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,cleanIP] = ip2structname(ipAddress,port) | |||
| cleanIP = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)',''); | |||
| Equipment.iptest(cleanIP); | |||
| structname = matlab.lang.makeValidName(['ip',cleanIP,'_',num2str(port)]); | |||
| function [structname,cleanip] = ip2structname(ipAddress,port) | |||
| %IP2STRUCTNAME Returns a structname and ip w/out leading zeros. | |||
| %structname to store stuff in struct (especially for GETTCP). | |||
| %cleanip is a shortened ip without leading zeros. | |||
| cleanip = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)',''); | |||
| Equipment.iptest(cleanip); | |||
| structname = matlab.lang.makeValidName(['ip',cleanip,'_',num2str(port)]); | |||
| end | |||
| end | |||
| end | |||