diff --git a/OOequipment/Equipment.m b/OOequipment/Equipment.m index 2b54948..0f747f2 100644 --- a/OOequipment/Equipment.m +++ b/OOequipment/Equipment.m @@ -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 \ No newline at end of file