You are on page 1of 12

function softscope(varargin) %SOFTSCOPE Open the Data Acquisition oscilloscope.

% % SOFTSCOPE opens the Data Acquisition oscilloscope setup gui. The setup % gui defines what hardware is used to run the Data Acquisition oscilloscope. % % The setup gui creates an analoginput object based on the specified Adaptor % and ID values. The analoginput object's SampleRate and InputType properties % are configured based on the specified SampleRate and Input Type values. All % available channels are added to the analoginput object. Each channel's InputRange % property is configured to the value specified in the setup UI table. The % oscilloscope is opened when the OK button is pressed with the channels selected % in the setup UI table displayed. % % Data is acquired from the analoginput object and displayed in the oscilloscope % once the trigger button is pressed. % % SOFTSCOPE(OBJ) opens the Data Acquisition oscilloscope configured to display the % data acquired from analoginput object, OBJ. OBJ must be a 1-by-1 analoginput object. % % SOFTSCOPE('FNAME.SI') opens the Data Acquisition oscilloscope using the settings % specified in the SI file, FNAME. FNAME is generated from the Data Acquisition % oscilloscope's Save menu item. % % SOFTSCOPE modifies or uses many properties of the analoginput object. It is % recommended to not change any properties through the command line since it % may result in unexpected behavior. % % See also ANALOGINPUT. % % % % MP 10-03-01 Copyright 1998-2010 The MathWorks, Inc. $Revision: 1.4.2.16 $ $Date: 2010/05/10 17:02:35 $

switch (nargin) case 0 % Create the UI for defining the hardware that is used by the scope. try localLayoutSetupUI;

catch exception % Cleanup in case something bad happened. data = daq.internal.SoftScopeSetupUIManager.getInstance(); if ~isempty(data.frame) awtinvoke(data.frame,'dispose()'); daq.internal.SoftScopeSetupUIManager.deleteInstance(); end error('daqguis:softscope:couldNotCreate', ['SOFTSCOPE can not be started: ' exception.message]); end case 1 data = varargin{1}; if ischar(data) % Create the scope from a saved xml file. try errmsg = localLoadSoftScope(data); if ~isempty(errmsg) error('daqguis:softscope:invalidXMLFile', errmsg); end catch e error('daqguis:softscope:invalidXMLFile', e.message); end elseif isa(data, 'analoginput') if length(data) > 1 error('daqguis:softscope:invalidOBJ', 'OBJ must be a 1-by-1 analoginput object.'); elseif ~isvalid(data) error('daqguis:softscope:invalidOBJ', 'Analoginput object OBJ is an invalid object.'); end % Create the scope from an analoginput object. msg = localCreateSoftScope(data, inputname(1)); if ~isempty(msg) error('daqguis:softscope:couldNotCreate', msg); end else error('daqguis:softscope:invalidArg', 'Invalid first argument. Type ''help softscope'' for more information.'); end otherwise error('daqguis:softscope:invalidSyntax', 'Too many input arguments'); end % --------------------------------------------------------------------function localLayoutSetupUI import com.mathworks.mwswing.*; import java.awt.Font; import java.awt.BorderLayout; % Determine if the GUI is currently open. If so, bring it to the foreground. data = daq.internal.SoftScopeSetupUIManager.getInstance(); if ~isempty(data.frame) data.frame.toFront;

return end

frame = awtcreate('com.mathworks.mwswing.MJFrame'); awtinvoke(frame,'setDefaultCloseOperation(I)',MJFrame.DO_NOTHING_ON_CLOSE ); awtinvoke(frame,'setResizable(Z)',false); % Create a message to display while GUI is initializing. niceMessage = awtcreate('com.mathworks.mwswing.MJLabel','Ljava/lang/String;',' Initializing Softscope Hardware Configuration Tool...'); awtinvoke(niceMessage,'setFont(Ljava/awt/Font;)',Font(get(0,'fixedwidthfo ntname'), 0, 12)); awtinvoke(awtinvoke(frame,'getContentPane()'),'add(Ljava/awt/Component;Lj ava/lang/Object;)',niceMessage, BorderLayout.CENTER); % Set the frames size and make it visible. awtinvoke(frame,'setTitle(Ljava/lang/String;)','Hardware Configuration'); awtinvoke(frame,'setSize(II)',490, 390); awtinvoke(frame,'show()'); % Force AWTQueue to process drawnow(); data.frame = frame; [panel] = privateLayoutPanel(data); % Create the Button panel. [southPanel] = localCreateButtonPanel(data); awtinvoke(panel,'add(Ljava/awt/Component;Ljava/lang/Object;)',southPanel, BorderLayout.SOUTH); % Update the table to reflect the channels that are available for the % currently selected adaptor, id and inputType. privateLayoutPanel(data); % Configure x button to close window. % Configure the callbacks. Turn off 10b warning associated with the % configuration. See geck 639400 cacheEnableJavaAsGObject = feature('EnableJavaAsGObject'); feature('EnableJavaAsGObject',2) set(frame, 'WindowClosingCallback', {@localClose, frame}); feature('EnableJavaAsGObject',cacheEnableJavaAsGObject) % View the frame. awtinvoke(awtinvoke(frame,'getContentPane()'),'add(Ljava/awt/Component;)' ,panel); awtinvoke(frame,'setDefaultCloseOperation(I)',MJFrame.HIDE_ON_CLOSE ) awtinvoke(niceMessage,'setVisible(Z)',0); awtinvoke(frame,'show()'); awtinvoke(data.combobox.adaptor,'requestFocus()'); % ---------------------------------------------------------------------

% Create the button panel that consists of an OK button - opens the scope, % Properties button - opens daqpropedit on the analoginput object, Close % button - closes dialog, Help button - gives users help. function [p, data] = localCreateButtonPanel(data) import java.awt.*; import javax.swing.*; p = awtcreate('com.mathworks.mwswing.MJPanel','Ljava/awt/LayoutManager;',Flow Layout(FlowLayout.RIGHT)); awtinvoke(p,'setBorder(Ljavax/swing/border/Border;)',BorderFactory.create EmptyBorder(0, 0, 0, 5)); p2 = awtcreate('com.mathworks.mwswing.MJPanel','Ljava/awt/LayoutManager;',Grid Layout(1, 3, 5, 0)); p3 = awtcreate('com.mathworks.mwswing.MJPanel','Ljava/awt/LayoutManager;',Bord erLayout); p4 = awtcreate('com.mathworks.mwswing.MJPanel','Ljava/awt/LayoutManager;',Bord erLayout); p5 = awtcreate('com.mathworks.mwswing.MJPanel','Ljava/awt/LayoutManager;',Bord erLayout); okButton = awtcreate('com.mathworks.mwswing.MJButton','Ljava/lang/String;','OK'); closeButton = awtcreate('com.mathworks.mwswing.MJButton','Ljava/lang/String;','Close'); helpButton = awtcreate('com.mathworks.mwswing.MJButton','Ljava/lang/String;','Help'); awtinvoke(p3,'add(Ljava/awt/Component;Ljava/lang/Object;)',okButton, BorderLayout.NORTH); awtinvoke(p2,'add(Ljava/awt/Component;)',p3); awtinvoke(p4,'add(Ljava/awt/Component;Ljava/lang/Object;)',closeButton, BorderLayout.NORTH); awtinvoke(p2,'add(Ljava/awt/Component;)',p4); awtinvoke(p5,'add(Ljava/awt/Component;Ljava/lang/Object;)',helpButton, BorderLayout.NORTH); awtinvoke(p2,'add(Ljava/awt/Component;)',p5); awtinvoke(p,'add(Ljava/awt/Component;)',p2); data.button.ok = okButton; data.button.close = closeButton; data.button.help = helpButton; % Turn off 10b warning associated with the callback % configuration. See geck 639400 cacheEnableJavaAsGObject = feature('EnableJavaAsGObject');

feature('EnableJavaAsGObject',2) set(okButton, 'ActionPerformedCallback', {@localOKButton, data.frame}); set(closeButton, 'ActionPerformedCallback', {@localCloseButton, data.frame}); set(helpButton, 'ActionPerformedCallback', @localHelpButton); feature('EnableJavaAsGObject',cacheEnableJavaAsGObject) % --------------------------------------------------------------------% User closed the dialog with the x window button. Delete the analoginput % object if it exists and close the frame. function localClose(~, ~, ~) data = daq.internal.SoftScopeSetupUIManager.getInstance(); if ~isempty(data.analoginput) delete(data.analoginput); end awtinvoke(data.frame,'dispose()'); daq.internal.SoftScopeSetupUIManager.deleteInstance(); % --------------------------------------------------------------------% The user hit the OK button. Make sure only those channels requested % are added to the analoginput object. Create the oscilloscope with % one display and one channel for each selected channel. Configure the % analoginput object's SampledAcquiredFcn and StopFcn. function localOKButton(~,~, ~) data = daq.internal.SoftScopeSetupUIManager.getInstance(); % Determine the channels to create. chans = awtinvoke(data.table,'getSelectedChannels()'); % If no channels are selected, display a warning dialog and return % without opening the scope. if isempty(chans) privateShowAlert('Too Few Channels',... 'At least one channel must be selected.'); return; end % Create the object. if isempty(data.analoginput) % Try to create. try adaptor = awtinvoke(data.combobox.adaptor,'getSelectedItem()'); id = awtinvoke(data.combobox.id,'getSelectedItem()'); data.analoginput = analoginput(adaptor, id); catch %#ok<CTCH> privateShowAlert('Unavailable Hardware',... 'The hardware does not exist for creating the analoginput object'); return; end else delete(get(data.analoginput, 'Channel'));

end % Configure the InputType and SampleRate. inputTypePropinfo = propinfo(data.analoginput,'InputType'); if ~strcmp(inputTypePropinfo.ReadOnly,'always') set(data.analoginput, 'InputType', awtinvoke(data.combobox.inputType,'getSelectedItem()')); end set(data.analoginput, 'SampleRate', data.samplerate); % Determine which channels have been selected and add them. allChannelInfo = awtinvoke(data.table,'getData()'); % Get the selectedChannels. selectedChannels = []; for i=1:length(allChannelInfo) if allChannelInfo(i,1) == 1 selectedChannels = [selectedChannels i]; %#ok<AGROW> end end % Verify that all the selected Channels have unique names. count=1; allNames = cell(1,numel(selectedChannels)); for i=selectedChannels name = allChannelInfo(i,3); if isempty(name) || any(strcmp(name, allNames)) privateShowAlert('Invalid Channel Name',... 'All channels must have a unique non-empty name.'); return; elseif ~isvarname(name) privateShowAlert('Invalid Channel Name',... 'All channels must have a valid MATLAB variable name.'); return; end allNames{count} = name; count = count+1; end % Add the channels. try count = 1; % Store the warning state. lastwarn(''); s = warning('off'); %#ok<WNOFF> for i=selectedChannels addchannel(data.analoginput, str2double(allChannelInfo(i,2))); % Configure the input range and name. try set(data.analoginput.Channel(count), 'ChannelName', allChannelInfo(i,3), ...

'InputRange', str2num(allChannelInfo(i,5))); %#ok<ST2NM> count = count+1; catch %#ok<CTCH> privateShowAlert('Invalid Input Range',... ['Invalid InputRange value for HW Channel: ' allChannelInfo(i,2)]); % Restore the warning state. warning(s) return; end end if ~isempty(lastwarn) privateShowAlert('Add Channel Warning', lastwarn); end % Restore the warning state. warning(s) catch e % Extract only the message from the error. msg = e.message; index = findstr(sprintf('\n'), msg); if ~isempty(index) msg = msg(index(end)+1:length(msg)); end % Show error in dialog box. privateShowAlert('Add Channel Error', msg); return; end % Create the scope. scope = awtcreate('com.mathworks.toolbox.daq.scope.Scope'); scope.setObject(data.analoginput); % Add all the hardware channels to the scope so that they can be selected % at some later point by the user. sampleRate = get(data.analoginput, 'SampleRate'); count = 1; for i=selectedChannels awtinvoke(scope,'createHardwareChannel(Ljava.lang.String;Ljava.lang.Strin g;IID)',allChannelInfo(i,3), allChannelInfo(i,4), str2double(allChannelInfo(i,2)), count, sampleRate); count = count+1; end % Add the display. display = awtinvoke(scope,'defineDisplay(Ljava.lang.String;)','display1'); % Add the selected channels to the scope. for i=selectedChannels

awtinvoke(scope,'addChannel(Ljava.lang.String;Lcom.mathworks.toolbox.daq. scope.ScopeDisplay;)',allChannelInfo(i,3), display); end % Set up the callback for the analoginput object. channelPane = awtinvoke(scope,'findChannelPanes()'); channelPane = channelPane.elementAt(0); children = awtinvoke(channelPane,'getDataChannels()'); set(data.analoginput, 'TimerFcn', {@localPlotData, children}); set(data.analoginput, 'TimerPeriod', 0.1); set(data.analoginput, 'UserData', children); triggerPanel = awtinvoke(scope,'addTriggerPane(Ljava.lang.String;)','Triggers'); set(data.analoginput, 'RuntimeErrorFcn', {@localStopDueToError, triggerPanel}); set(data.analoginput, 'DataMissedFcn', {@localStopDueToError, triggerPanel}); % Close the figure. awtinvoke(data.frame,'dispose()'); daq.internal.SoftScopeSetupUIManager.deleteInstance(); % Show the scope. awtinvoke(scope,'addToFrame()'); awtinvoke(scope,'autoscale()'); % --------------------------------------------------------------------% The user selected the Close button. Delete the analoginput object if % it exists and close the window. function localCloseButton(~,~, ~) data = daq.internal.SoftScopeSetupUIManager.getInstance(); if ~isempty(data.analoginput) delete(data.analoginput); end awtinvoke(data.frame,'dispose()'); daq.internal.SoftScopeSetupUIManager.deleteInstance(); % --------------------------------------------------------------------% The user selected the Help button. Show help. function localHelpButton(~,~) privateShowHelp('softscope_hardware_configuration', ''); % --------------------------------------------------------------------% Data has been acquired. Plot the data in the scope. function localPlotData(obj, ~, children) try samplesToGet = min(obj.SampleRate * obj.TimerPeriod,obj.samplesAvailable); if samplesToGet <= 0

return end [data, time] = getdata(obj, samplesToGet); index = find(isnan(data(:,1))); if isempty(index) for i=1:length(children) children(i).plot(data(:,children(i).getChannelIndex), time(1)); end else for i=1:length(children) children(i).plot(data(1:index-1, children(i).getChannelIndex), time(1)); children(i).plot(data(index+1:end, children(i).getChannelIndex), time(index+1)); end end catch e if (isvalid(obj)) if isrunning(obj) stop(obj); warndlg(e.message, 'Acquisition Error'); end end end % --------------------------------------------------------------------% Create softscope with the specified analoginput object. function [msg] = localCreateSoftScope(ai, varname) % Initialize variables. msg = ''; % Create the scope. scope = awtcreate('com.mathworks.toolbox.daq.scope.Scope'); scope.setObject(ai); % Add the display. display = awtinvoke(scope,'defineDisplay(Ljava.lang.String;)','display1'); % Extract necessary information from the analoginput object. sampleRate = get(ai, 'SampleRate'); channels = get(ai, 'Channel'); if isempty(channels) msg = 'At least one channel must be added to the analoginput object.'; return; end % Add the hardware channels to the scope. for i=1:length(channels) hardwareID = get(ai.Channel(i), 'HwChannel');

channelIndex = get(ai.Channel(i), 'Index'); awtinvoke(scope,'createHardwareChannel(Ljava.lang.String;Ljava.lang.Strin g;IID)',['CH' num2str(i)], ['Hardware Channel' num2str(hardwareID)], hardwareID,channelIndex, sampleRate); awtinvoke(scope,'addChannel(Ljava.lang.String;Lcom.mathworks.toolbox.daq. scope.ScopeDisplay;)',['CH' num2str(i)], display); end % Set up the callback for the analoginput object. channelPane = awtinvoke(scope,'findChannelPanes()'); channelPane = channelPane.elementAt(0); children = awtinvoke(channelPane,'getDataChannels()'); set(ai, 'TimerFcn', {@localPlotData, children}); set(ai, 'TimerPeriod', 0.1); set(ai, 'UserData', children); triggerPanel = awtinvoke(scope,'addTriggerPane(Ljava.lang.String;)','Triggers'); scope.setDeleteOnClose(0); set(ai, 'RuntimeErrorFcn', {@localStopDueToError, triggerPanel}); set(ai, 'DataMissedFcn', {@localStopDueToError, triggerPanel}); % Show the scope. awtinvoke(scope,'setAnalogInputName(Ljava.lang.String;)',varname); awtinvoke(scope,'addToFrame()'); awtinvoke(scope,'autoscale()'); % --------------------------------------------------------------------% Load the softscope from the XML file. function errmsg = localLoadSoftScope(filename) % Initialize variables. errmsg = ''; try document = xmlread(filename); catch %#ok<CTCH> errmsg = 'The specified file does not exist or could not be read.'; return; end if ~(strcmp(document.getFirstChild.getNodeName, 'Data_Acquisition_Oscilloscope')) errmsg = 'The specified file is not a valid Data Acquisition oscilloscope file.'; return; end reader = com.mathworks.toolbox.daq.scope.ScopeXMLReader(document); scope = awtinvoke(reader,'createScope()'); ai = localCreateAnalogInputObject(scope, document); scope.setObject(ai); localAddToFrame(scope, document);

% --------------------------------------------------------------------% Create the analoginput object from saved parameters in the XML file. function ai = localCreateAnalogInputObject(scope, document) root = document.getFirstChild; childNodes = root.getChildNodes; for i=1:childNodes.getLength if (childNodes.item(i).getNodeName.equals('AnalogInput')) % Extract the AnalogInput element. analogInput = childNodes.item(i); % Extract the information needed to create the analoginput object % from the AnalogInput element. vendor = char(analogInput.getAttribute('Vendor')); % Geck 350051: 'nidaq' if strcmpi(vendor,'nidaqmx') vendor = 'nidaq'; end id = char(analogInput.getAttribute('ID')); sampleRate = str2double(analogInput.getAttribute('SampleRate')); inputType = char(analogInput.getAttribute('InputType')); % Create the object and configure it's properties. ai = analoginput(vendor, id); %#ok<TNMLP> set(ai, 'SampleRate', sampleRate, 'InputType', inputType); % Add the channels and configure their input range value. child = analogInput.getChildNodes; count = 1; for j=1:child.getLength-1 if strcmp(child.item(j).getNodeName, 'Channel') channelID = str2double(child.item(j).getAttribute('HwChannel')); addchannel(ai, channelID); set(ai.Channel(count), 'InputRange', str2num(child.item(j).getAttribute('InputRange'))); %#ok<ST2NM> count = count+1; end end % Set up the callback for the analoginput object. channelPane = awtinvoke(scope,'findChannelPanes()'); channelPane = channelPane.elementAt(0); children = awtinvoke(channelPane,'getDataChannels()'); set(ai, 'TimerFcn', {@localPlotData, children}); set(ai, 'TimerPeriod', 0.1); set(ai, 'UserData', children); % Configure callback properties. triggerPanel = awtinvoke(scope,'findTriggerPanes()'); triggerPanel = triggerPanel.elementAt(0); We need to rename the 'nidaqmx' objects to

set(ai, 'RuntimeErrorFcn', {@localStopDueToError, triggerPanel}); set(ai, 'DataMissedFcn', {@localStopDueToError, triggerPanel}); return; end end % --------------------------------------------------------------------% Add the scope to a frame of the correct size and location. function localAddToFrame(scope, document) root = document.getFirstChild; childNodes = root.getChildNodes; for i=1:childNodes.getLength if (childNodes.item(i).getNodeName.equals('Location')) % Extract the Location element. location = childNodes.item(i); % Extract the attributes from the Location element. width = str2double(location.getAttribute('Width')); height = str2double(location.getAttribute('Height')); x = str2double(location.getAttribute('X')); y = str2double(location.getAttribute('Y')); awtinvoke(scope,'addToFrame(IIII)',x,y,width,height); return; end end % --------------------------------------------------------------------% An error occurred on the object. This is the object's RuntimeErrorFcn % callback. function localStopDueToError(obj, event, triggerPanel) stop(obj); % Enable the triggerPanel controls. awtinvoke(triggerPanel,'enableAllComponents()'); % Open a dialog that gives information on why the acquisition stopped. if (strcmp(event.Type, 'Error')) privateShowAlert('Acquisition Error', event.Data.String); else privateShowAlert('Acquisition Error',... 'The acquisition has stopped due to a data missed event.'); end

You might also like