Skip to content

Commit 4f4569b

Browse files
committed
Initial commit
1 parent 47dad11 commit 4f4569b

4 files changed

Lines changed: 3291 additions & 0 deletions

File tree

bistim.m

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
classdef bistim < magstim &handle
2+
properties (SetAccess = private)
3+
highRes = 0; %Bistim High Resolution Time Setting Mode
4+
end
5+
6+
methods
7+
function self = bistim(PortID)
8+
self = self@magstim(PortID);
9+
end
10+
end
11+
12+
methods
13+
14+
function [errorOrSuccess, deviceResponse] = setAmplitudeB(self, power, varargin)
15+
% Inputs:
16+
% power<double> : is the desired power amplitude for stimulator B
17+
% varargin<bool> refers to getResponse<bool> that can be True (1) or False (0)
18+
% indicating whether a response from device is required or not.
19+
% The default value is set to false.
20+
21+
% Outputs:
22+
% deviceResponse: is the response that is sent back by the
23+
% device to the port indicating current information about the device
24+
% errorOrsuccess: is a boolean value indicating succecc = 0 or error = 1
25+
% in performing the desired task
26+
27+
%% Check Input Validity:
28+
if nargin < 2
29+
error('Not Enough Input Arguments');
30+
end
31+
if length(varargin) > 1
32+
error('Too Many Input Arguments');
33+
end
34+
if nargin < 3
35+
getResponse = false ; %Default Value Set To 0
36+
else
37+
getResponse = varargin{1};
38+
end
39+
if (getResponse ~= 0 && getResponse ~= 1 )
40+
error('getResponse Must Be A Boolean');
41+
end
42+
43+
if rem(power,1)~=0
44+
error('power Must Be A Number');
45+
end
46+
if (power < 0 || power > 100)
47+
error('power Must Be A Positive Value Less Than Or Equal To 100');
48+
end
49+
50+
if length(power) > 1
51+
error('Invaid Power Amplitude. It Must be A Single Numeric');
52+
end
53+
54+
%% Create Control Command
55+
56+
[errorOrSuccess, deviceResponse] = self.processCommand(['A' sprintf('%03s',num2str(power))], getResponse, 3);
57+
58+
end
59+
60+
function [errorOrSuccess, deviceResponse] = setPulseInterval(self, ipi,checkWarning, varargin)
61+
% Inputs:
62+
% ipi<double> : is the desired interpulse interval
63+
% checkWarning<bool> : is a boolean determining whether to
64+
% check for potential warnings in the ipi boundries
65+
% varargin<bool>: refers to getResponse<bool> that can be True (1) or False (0)
66+
% indicating whether a response from device is required or not.
67+
% The default value is set to false.
68+
69+
% Outputs:
70+
% deviceResponse: is the response that is sent back by the
71+
% device to the port indicating current information about the device
72+
% errorOrsuccess: is a boolean value indicating succecc = 0 or error = 1
73+
% in performing the desired task
74+
75+
%% Check Input Validity:
76+
if nargin < 2
77+
error('Not Enough Input Arguments');
78+
end
79+
if length(varargin) > 1
80+
error('Too Many Input Arguments');
81+
end
82+
if nargin < 4
83+
getResponse = false ; %Default Value Set To 0
84+
else
85+
getResponse = varargin{1};
86+
end
87+
if (getResponse ~= 0 && getResponse ~= 1 )
88+
error('getResponse Must Be A Boolean');
89+
end
90+
91+
if ~(isnumeric(ipi))
92+
error('ipi Must Be A Number');
93+
end
94+
95+
if self.highRes == 1 % Device already set to highRes Mode
96+
if rem(ipi,0.1)~=0
97+
error('ipi Can Have Up To Just A Single Decimal Place In High Resolution Mode');
98+
end
99+
else % Not known whether in highRes mode
100+
101+
ipicheck = ipi;
102+
decimalPlaces = 0; % no of places after decimal initialized to 0.
103+
temp = floor(ipicheck);
104+
diff = ipicheck - temp;
105+
while(diff > 0)
106+
decimalPlaces = decimalPlaces + 1;
107+
ipicheck = ipicheck * 10;
108+
temp = floor(ipicheck);
109+
diff = ipicheck - temp;
110+
end
111+
112+
if decimalPlaces == 1
113+
if checkWarning ==1
114+
warning('ipi Value Can Be A Fractional Only In High Resolution Mode');
115+
end
116+
elseif decimalPlaces~=0 && decimalPlaces~=1
117+
error('ipi Can Have Up To Just A Single Decimal Place In High Resolution Mode');
118+
end
119+
120+
end
121+
122+
%% Create Control Command
123+
124+
[errorOrSuccess, deviceResponse] = self.processCommand(['C' sprintf('%03s',num2str(ipi))], getResponse, 3);
125+
126+
127+
128+
end
129+
130+
function [errorOrsuccess, deviceResponse] = highResolutionMode(self, enable, varargin)
131+
% Inputs:
132+
% enable<boolean> is a boolean that can be True(1) to
133+
% enable and False(0) to disable the High Resolution Time Setting Mode
134+
% varargin<bool> refers to getResponse<bool> that can be True (1) or False (0)
135+
% indicating whether a response from device is required or not.
136+
% The default value is set to false.
137+
138+
% Outputs:
139+
% DeviceResponse: is the response that is sent back by the
140+
% device to the port indicating current information about the device
141+
% errorOrsuccess: is a boolean value indicating succecc = 0 or error = 1
142+
% in performing the desired task
143+
144+
%% Check Input Validity
145+
if nargin < 2
146+
error('Not Enough Input Arguments');
147+
end
148+
if length(varargin) > 1
149+
error('Too Many Input Arguments');
150+
end
151+
if nargin < 3
152+
getResponse = false ;
153+
else
154+
getResponse = varargin{1};
155+
end
156+
157+
if (enable ~= 0 && enable ~= 1 )
158+
error('enable Must Be A Boolean');
159+
end
160+
if (getResponse ~= 0 && getResponse ~= 1 )
161+
error('getResponse Must Be A Boolean');
162+
end
163+
164+
%% Create Control Command
165+
166+
if enable %Enable
167+
commandString = 'Y@';
168+
else %Disable
169+
commandString = 'Z@';
170+
end
171+
[errorOrsuccess, deviceResponse] = self.processCommand(commandString, getResponse, 3);
172+
end
173+
174+
175+
function [errorOrSuccess, deviceResponse] = getParameters(self)
176+
% Outputs:
177+
% DeviceResponse: is the response that is sent back by the
178+
% device to the port indicating current information about the device
179+
% errorOrsuccess: is a boolean value indicating succecc = 0 or error = 1
180+
% in performing the desired task
181+
182+
%% Check Input Validity
183+
if nargin < 1
184+
error('Not Enough Input Arguments');
185+
end
186+
187+
%% Create Control Command
188+
[errorOrSuccess, deviceResponse] = self.processCommand('J@', true, 12);
189+
if self.highRes
190+
deviceResponse.IPI = deviceResponse.IPI / 10;
191+
end
192+
end
193+
end
194+
195+
methods (Access = 'protected')
196+
%%
197+
function info = parseResponse(self, command, readData)
198+
%% Getting Instrument Status (always returned)
199+
statusCode = bitget(double(readData(1)),1:8);
200+
info = struct('InstrumentStatus',struct('Standby', statusCode(1),...
201+
'Armed', statusCode(2),...
202+
'Ready', statusCode(3),...
203+
'CoilPresent', statusCode(4),...
204+
'ReplaceCoil', statusCode(5),...
205+
'ErrorPresent', statusCode(6),...
206+
'ErrorType', statusCode(7),...
207+
'RemoteControlStatus', statusCode(8)));
208+
209+
%% Getting All Information
210+
%Get commands
211+
if command == 'J' %getParameters
212+
info.PowerA = str2double(char(readData(2:4)));
213+
info.PowerB = str2double(char(readData(5:7)));
214+
info.IPI = str2double(char(readData(8:10)));
215+
elseif command == 'F' %getTemperature
216+
info.CoilTemp1 = str2double(char(readData(2:4))) / 10;
217+
info.CoilTemp2 = str2double(char(readData(5:7))) / 10;
218+
end
219+
220+
end
221+
end
222+
end

0 commit comments

Comments
 (0)