CInput.m 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. classdef CInput < handle
  2. % A class of peripheral input device
  3. % Input device:
  4. % 1. keyboard: CInput('k',response values, {KeyName List}). Keys are
  5. % mapped into response values. For example,
  6. % kb = CInput('k',[1 2],{'LeftArrow','RightArrow'); % Left arrow 1, right arrow 2
  7. % by default: kb=CInput('k'); % Left and Right Arrow
  8. % 2. Mouse: CInput('m', [1 2]);% left/right mouse button to 1 ,2
  9. % 3. Parallel port key: CInput('p', [1 2]);
  10. % note: parallel keypad encoding depends on pins, so be checked
  11. % before use this method
  12. % 4. NI input: CInput('n',defaultValues, pins, portname);
  13. % e.g. nk = CInput('n', [0 0], [8 9],'AOut');
  14. % Card 'AOut', pin 8 and 9, default values [0 0]
  15. % Methods:
  16. % 1. wait(); %wait for input
  17. % 2. [kinput ktime x y] = response(bWait); %by default, wait for response.
  18. % when bWait == 0, it samples reponse values only.
  19. % 3. releaseTime = keyRelease();
  20. % return releaseTime
  21. % last modify: 15. March, 2012
  22. % First created: 2nd April, 2001
  23. % created by: Z. Shi, shi@lmu.de
  24. properties
  25. esckey = 41;
  26. key = [80 79];
  27. kval = [1 2];
  28. ktype = 1;
  29. wantStop = 0;
  30. dio ;
  31. end
  32. methods
  33. function obj = CInput(keytype,keyvalues,keys,portname)
  34. try
  35. KbName('UnifyKeyNames');
  36. obj.esckey = KbName('ESCAPE');
  37. switch lower(keytype)
  38. case {'keyboard','k'}
  39. obj.ktype = 1;
  40. if nargin < 3
  41. obj.key = [KbName('LeftArrow') KbName('RightArrow')];
  42. end
  43. if nargin < 2
  44. keyvalues = [1 2];
  45. end
  46. if nargin == 3
  47. for k = 1:length(keys)
  48. obj.key(k) = KbName(keys{k});
  49. end
  50. end
  51. obj.kval= keyvalues;
  52. case {'mouse','m'}
  53. obj.ktype = 2;
  54. if nargin < 2
  55. keyvalues = [1 2];
  56. end
  57. obj.kval = keyvalues;
  58. case {'parallel','p'}
  59. obj.ktype = 3;
  60. % todo
  61. obj.key = keys; % actually parallel port pins
  62. obj.kval = keyvalues;
  63. obj.dio = digitalio('parallel', 'LPT1');
  64. addline(obj.dio,obj.key,'in');
  65. case {'n','nidaq'}
  66. obj.ktype = 4;
  67. obj.key = keys; % pins
  68. obj.kval = keyvalues; % default key values
  69. obj.dio = digitalio('nidaq',portname);
  70. addline(obj.dio,obj.key,'in');
  71. otherwise % default as keyboard
  72. obj.ktype = 1;
  73. obj.key(1) = KbName('LeftArrow');
  74. obj.key(2) = KbName('RightArrow');
  75. obj.kval = [1 0];
  76. end
  77. catch ME
  78. disp(ME.message);
  79. end
  80. end
  81. function wait(obj)
  82. % halt program for key input
  83. switch obj.ktype
  84. case 1 %keyboard
  85. while KbCheck; end %clear buffer
  86. KbWait;
  87. case 2 % mouse
  88. GetClicks;
  89. case 3 % parallel port keypad
  90. % need to test for different parallel port pad
  91. %here assume: initial status: 1111 ...
  92. k = getvalue(obj.dio);
  93. while sum(k) == length(k)
  94. k = getvalue(obj.dio);
  95. end
  96. case 4 %ni daq
  97. k = getvalue(obj.dio);
  98. while sum(xor(obj.kval,k)) == 0 % sum(k) == length(k)
  99. k = getvalue(obj.dio);
  100. end
  101. end
  102. end
  103. %
  104. function [kinput ktime x y] = response(obj,bWaitPress)
  105. % wait for response (by default, it waits for response)
  106. % if bWaitPress == 0, it samples response values
  107. % return input keys, time, and x, y
  108. x = -1;
  109. y = -1;
  110. if nargin < 2
  111. bWaitPress = 1;
  112. end
  113. validKey = 0;
  114. kinput = -1;
  115. ktime = GetSecs;
  116. switch obj.ktype
  117. case 1 %keyboard
  118. while 1
  119. [ keyIsDown, seconds, keyCode ] = KbCheck;
  120. if keyIsDown
  121. if keyCode(obj.esckey)
  122. kinput = -1;
  123. ktime = GetSecs;
  124. obj.wantStop = 1;
  125. break;
  126. end
  127. for k = 1: length(obj.key)
  128. if keyCode(obj.key(k))
  129. kinput = obj.kval(k);
  130. ktime = GetSecs;
  131. validKey = 1;
  132. end
  133. end
  134. if validKey
  135. break;
  136. end
  137. while KbCheck; end %clear buffer
  138. end
  139. if ~bWaitPress
  140. break;
  141. end
  142. end
  143. case 2 % mouse
  144. while 1
  145. [x,y,buttons] = GetMouse;
  146. if buttons(1)
  147. kinput = obj.kval(1);
  148. ktime = GetSecs;
  149. break;
  150. end
  151. if length(buttons)>=2 & buttons(end)
  152. kinput = obj.kval(2);
  153. ktime = GetSecs;
  154. break;
  155. end
  156. % stop running
  157. [ keyIsDown, seconds, keyCode ] = KbCheck;
  158. if keyIsDown && keyCode(obj.esckey)
  159. kinput = -1;
  160. ktime = GetSecs;
  161. obj.wantStop = 1;
  162. break;
  163. end
  164. if ~bWaitPress
  165. break;
  166. end
  167. end
  168. case 3 % parallel port keypad
  169. k = getvalue(obj.dio);
  170. % while sum(k) == length(k)
  171. while sum(xor(obj.kval,k)) == 0
  172. k = getvalue(obj.dio);
  173. if ~bWaitPress
  174. break;
  175. end
  176. % stop running
  177. [ keyIsDown, seconds, keyCode ] = KbCheck;
  178. if keyIsDown && keyCode(obj.esckey)
  179. kinput = -1;
  180. ktime = GetSecs;
  181. obj.wantStop = 1;
  182. break;
  183. end
  184. end
  185. % kidx = find(k == 0);
  186. ktime = GetSecs;
  187. % kinput = obj.kval(kidx(1));
  188. kinput = sum(find(xor(obj.kval,k)));
  189. case 4 %NI
  190. k = getvalue(obj.dio);
  191. while sum(xor(obj.kval,k)) == 0 %sum(k) == length(k)
  192. k = getvalue(obj.dio);
  193. if ~bWaitPress
  194. break;
  195. end
  196. end
  197. % stop running
  198. [ keyIsDown, seconds, keyCode ] = KbCheck;
  199. if keyIsDown && keyCode(obj.esckey)
  200. kinput = -1;
  201. ktime = GetSecs;
  202. obj.wantStop = 1;
  203. end
  204. %kidx = find(k == 0);
  205. ktime = GetSecs;
  206. kinput = sum(find(xor(obj.kval,k)));
  207. %kinput = obj.kval(kidx(1));
  208. end % end of switch
  209. end % end of function response
  210. function releaseTime = keyRelease(obj)
  211. %return release time when key is released,
  212. switch obj.ktype
  213. case 1 %keyboard
  214. while 1
  215. [ keyIsDown, seconds, keyCode ] = KbCheck;
  216. if ~keyIsDown
  217. break;
  218. end
  219. end
  220. case 2 % mouse
  221. while 1
  222. [x,y,buttons] = GetMouse;
  223. if sum(buttons) == 0
  224. break;
  225. end
  226. end
  227. case 3 % parallel port keypad
  228. k = getvalue(obj.dio);
  229. while sum(k) < length(k)
  230. k = getvalue(obj.dio);
  231. end
  232. case 4
  233. %keys are too sensitive, we need to apply filter mechanisms
  234. noise_ticks = 0;
  235. while 1
  236. k = getvalue(obj.dio);
  237. if sum(xor(obj.kval,k))==0 % key releases
  238. noise_ticks = noise_ticks +1;
  239. else
  240. noise_ticks = 0;
  241. end
  242. if noise_ticks >10 % 10 ms key releases
  243. break;
  244. end
  245. WaitSecs(0.001);
  246. end
  247. end % end of switch
  248. releaseTime = GetSecs-0.01; %- 10 ms
  249. % stop running
  250. [ keyIsDown, seconds, keyCode ] = KbCheck;
  251. if keyIsDown && keyCode(obj.esckey)
  252. obj.wantStop = 1;
  253. end
  254. end %end of function keyResease
  255. end
  256. end