您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

208 行
7.7KB

  1. classdef Equipment < handle
  2. %EQUIPMENT Summary of this class goes here
  3. % Detailed explanation goes here
  4. properties (SetAccess=private)
  5. name
  6. tcp
  7. channel
  8. locked
  9. end
  10. properties (Dependent, SetAccess=private)
  11. error
  12. end
  13. methods
  14. function ecq = Equipment(ipAddress,port,channel)
  15. %EQUIPMENT Construct an instance of this class.
  16. % This functions opens the required TCP connection
  17. % for this device. Channel is GPIB-channel on prologix
  18. % converter if used, otherwise set channel to -1.
  19. % Name is queried from device via '*IDN?' command.
  20. ecq.tcp = Equipment.getTCP(ipAddress,port);
  21. ecq.locked = false;
  22. ecq.channel = channel;
  23. ecq.name = ecq.idn();
  24. end
  25. function id = idn(ecq)
  26. %IDN Queries identificantion from device via '*IDN?'.
  27. id = ecq.query_unsafe('*idn?');
  28. end
  29. function clear(ecq)
  30. %CLEAR Sends clear command to device via '*CLS'.
  31. ecq.write_unsafe('*cls');
  32. end
  33. function opc(ecq)
  34. %OPC executes 'operation complete query' to device.
  35. %Function holds untill device returns '1'. Must be
  36. %used to avoid interrupting busy device.
  37. ecq.query_unsafe('*OPC?');
  38. end
  39. function unlock(ecq)
  40. %UNLOCK Sets the device back to 'local control'
  41. %This function only supports devices via the Prologix.
  42. if ecq.channel >= 0
  43. fprintf(ecq.tcp,'++loc');
  44. ecq.locked = false;
  45. end
  46. end
  47. function lock(ecq)
  48. %UNLOCK Sets the device back to 'remote control'
  49. %This function only supports devices via the Prologix.
  50. if ecq.channel >= 0
  51. fprintf(ecq.tcp,'++llo');
  52. ecq.locked = true;
  53. else
  54. warning('Device does not support locking')
  55. end
  56. end
  57. function beep(ecq)
  58. %BEEP Sends the beep command to the device
  59. ecq.write('SYST:BEEP')
  60. end
  61. function write(ecq,message)
  62. %WRITE Sends a command to the channel.
  63. %The function will first check if the device is ready to
  64. %recieve a command via the OPC function. Then send the command
  65. %and eventually check if the device has thrown an error via
  66. %the ERROR function.
  67. %
  68. %See also QUERY
  69. ecq.opc;
  70. ecq.write_unsafe(message);
  71. ecq.error;
  72. end
  73. function output = read(ecq)
  74. %READ Extracts recieved data from the TCP-buffer.
  75. %This
  76. if ecq.channel >= 0
  77. fprintf(ecq.tcp,'++read');
  78. end
  79. output = fscanf(ecq.tcp);
  80. end
  81. function output = query(ecq,message)
  82. %QUERY Sends command to the device and read the respond.
  83. %The command is send via the WRITE and the respond is collected
  84. %
  85. ecq.opc;
  86. output = ecq.query_unsafe(message);
  87. ecq.error;
  88. end
  89. function errorlist = get.error(ecq)
  90. %ERROR Checks for errors on device. If any, throws a warning.
  91. %The function will pull all errors from the device error stack.
  92. %This is up to a maximum of 20 errors. If errors have occured
  93. %the function will throw a warning with all the error messages.
  94. for i = 1:20
  95. output = ecq.query_unsafe('SYSTem:ERRor?'); %Query error message from device.
  96. errorlist(i,1:(length(output))) = output; %Store the error message in the errorlist array.
  97. %GPIB protocol states that the error code '0' means no
  98. %error. The for loop will break if the last recieved error
  99. %code is zero.
  100. if str2double(regexp(output,'\d*','match','once'))==0 %Check if last recieved error code is '0'
  101. % If the 'no error' message is the only error then no
  102. % warning will be trown. However if there is more than
  103. % one error in the list. The function gives a warning
  104. % with all error messages.
  105. if i>1 %check for more than one error message.
  106. warning('Error from device: %s %s',ecq.name,reshape(errorlist(1:i-1,:)',1,[]));
  107. end
  108. ecq.clear;
  109. break;
  110. end
  111. end
  112. end
  113. end
  114. methods (Access = protected)
  115. function write_unsafe(ecq,message)
  116. %WRITE_UNSAFE Sends command to device.
  117. %This function does not check if device is ready or check if an
  118. %error occured after writing. If possible one should always use
  119. %the WRITE function.
  120. %
  121. %See also WRITE
  122. if ecq.channel >= 0
  123. fprintf(ecq.tcp,['++addr ', num2str(ecq.channel)]);
  124. end
  125. fprintf(ecq.tcp, message);
  126. end
  127. function output = query_unsafe(ecq,message)
  128. ecq.write_unsafe(message);
  129. output = read(ecq);
  130. end
  131. end
  132. methods (Access = protected, Hidden)
  133. function delete(ecq)
  134. %DELETE Destructs the current object.
  135. ecq.unlock;
  136. Equipment.getTCP(ecq.tcp.RemoteHost,-ecp.tcp.RemotePort);
  137. end
  138. end
  139. methods (Static)
  140. function tcpobject = getTCP(ipAddress,port)
  141. persistent tcpconnection;
  142. [ipname,ipAddress] = Equipment.ip2structname(ipAddress,abs(port));
  143. if port > 0
  144. if isempty(tcpconnection)
  145. tcpconnection = struct;
  146. end
  147. if ~isfield(tcpconnection, ipname)
  148. tcpconnection.(ipname).tcp = tcpip(ipAddress,port);
  149. tcpconnection.(ipname).nopen = 1;
  150. fopen(tcpconnection.(ipname).tcp);
  151. else
  152. tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen + 1;
  153. end
  154. tcpobject = tcpconnection.(ipname).tcp;
  155. elseif port < 0
  156. if tcpconnection.(ipname).nopen > 1
  157. tcpconnection.(ipname).nopen = tcpconnection.(ipname).nopen - 1;
  158. else
  159. fclose(tcpconnection.(ipname).tcp);
  160. tcpconnection = rmfield(tcpconnection,ipname);
  161. end
  162. else
  163. error([num2str(port),' is not a valid port number try a value between 1 and 65535.']);
  164. end
  165. end
  166. function bool = isnum(input)
  167. bool = isnumeric(input)&&isscalar(input);
  168. end
  169. function num = forceNum(input)
  170. if ~isnumeric(input)
  171. error('Input should be a (single) number.');
  172. end
  173. num = input;
  174. end
  175. function iptest(ipAddress)
  176. 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');
  177. if isempty(validip)
  178. error('Invalid IP-address');
  179. end
  180. end
  181. function [structname,cleanIP] = ip2structname(ipAddress,port)
  182. cleanIP = regexprep(ipAddress,'(?:(?<=\.)|^)(?:0+)(?=\d)','');
  183. Equipment.iptest(cleanIP);
  184. structname = matlab.lang.makeValidName(['ip',cleanIP,'_',num2str(port)]);
  185. end
  186. end
  187. end