function varargout = FunctionGeneratorBasic(varargin)
%Written by Philbert S. Tsai
%   on 07/17/2011
%last updated 07/28/2011

% FUNCTIONGENERATORBASIC M-file for FunctionGeneratorBasic.fig
%      FUNCTIONGENERATORBASIC, by itself, creates a new FUNCTIONGENERATORBASIC or raises the existing
%      singleton*.
%
%      H = FUNCTIONGENERATORBASIC returns the handle to a new FUNCTIONGENERATORBASIC or the handle to
%      the existing singleton*.
%
%      FUNCTIONGENERATORBASIC('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in FUNCTIONGENERATORBASIC.M with the given input arguments.
%
%      FUNCTIONGENERATORBASIC('Property','Value',...) creates a new FUNCTIONGENERATORBASIC or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before FunctionGeneratorBasic_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to FunctionGeneratorBasic_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help FunctionGeneratorBasic

% Last Modified by GUIDE v2.5 27-Jul-2011 00:10:20

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @FunctionGeneratorBasic_OpeningFcn, ...
                   'gui_OutputFcn',  @FunctionGeneratorBasic_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT






% --- Executes just before FunctionGeneratorBasic is made visible.
function FunctionGeneratorBasic_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to FunctionGeneratorBasic (see VARARGIN)

% Choose default command line output for FunctionGeneratorBasic
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes FunctionGeneratorBasic wait for user response (see UIRESUME)
% uiwait(handles.figure1);




%%%%%%%%
%MY CODE
%%%%%%%%
%Written by Phil Tsai 07/26/2011
%Last modified 07/26/2011
% % 
global gds

gds.handles = handles;
gds.cycleDurationSec = 5;  %seconds
gds.frequencyMaxHz = 200;
gds.amplitudeMaxVolts = 7;
gds.clockRateHz = 10000;    % Pixel clock rate [Hz]
gds.xScanAmplitude = 1;         % Maximum scan voltage to x-scan mirror (0-4)
gds.yScanAmplitude = 1;         % Maximum scan voltage to y-scan mirror (0-4)
gds.xScanFrequency = 1;
gds.yScanFrequency = 1;
gds.startButtonFlag = 0;
set(gds.handles.xFreqEdit,'String',num2str(gds.xScanFrequency,'%0.2f'));
set(gds.handles.yFreqEdit,'String',num2str(gds.yScanFrequency,'%0.2f'));
set(gds.handles.xAmpEdit,'String',num2str(gds.xScanAmplitude,'%0.2f'));
set(gds.handles.yAmpEdit,'String',num2str(gds.yScanAmplitude,'%0.2f'));
set(gds.handles.xFreqSlider,'Value',gds.xScanFrequency / gds.frequencyMaxHz);
set(gds.handles.yFreqSlider,'Value',gds.yScanFrequency / gds.frequencyMaxHz);
set(gds.handles.xAmpSlider,'Value',gds.xScanAmplitude / gds.amplitudeMaxVolts);
set(gds.handles.yAmpSlider,'Value',gds.yScanAmplitude / gds.amplitudeMaxVolts);

daq.reset
gds.clockRateHz = 20000;
gds.inputVoltageRange = 5;
vSession = daq.createSession('ni');
addAnalogInputChannel(vSession,'Dev1','ai0','Voltage');
addAnalogInputChannel(vSession,'Dev1','ai1','Voltage');
addAnalogOutputChannel(vSession,'Dev1','ao0','Voltage');
addAnalogOutputChannel(vSession,'Dev1','ao1','Voltage');
% vSession.Channels(1).TerminalConfig = 'PseudoDifferential';
% % % vSession.Channels(1).TerminalConfig = 'Differential';
vSession.Channels(1).TerminalConfig = 'SingleEnded';
vSession.Channels(1).Coupling = 'DC';
vSession.Rate = gds.clockRateHz;
vSession.Channels(1).Range = [-gds.inputVoltageRange gds.inputVoltageRange];

    
  

gds.vSession = vSession;

% % gds.ai.InputType = 'Differential';
% % gds.ao.chan = addchannel(gds.ao,0:1);
% % gds.outChannels = addchannel(gds.ai,1:2);
% % set([gds.ai gds.ao],'TriggerType','Manual')
% % set(gds.ai,'ManualTriggerHwOn','Trigger')
% % set(gds.ai,'SamplesPerTrigger',gds.clockRateHz * gds.cycleDurationSec)
% % ActualRate = setverify(gds.ai,'SampleRate',gds.clockRateHz);
% % set(gds.ai,'SampleRate',ActualRate)
% % ActualRate = setverify(gds.ao,'SampleRate',gds.clockRateHz);
% % set(gds.ao,'SampleRate',ActualRate)
% % gds.clockRateHz = ActualRate;

GenerateWaveforms;



% --- Outputs from this function are returned to the command line.
function varargout = FunctionGeneratorBasic_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;




% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
% hObject    handle to startButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global gds
gds.startButtonFlag = 1;
while gds.startButtonFlag ==1,
    GenerateWaveforms;
    RestartOutput;
end

% --- Executes on button press in stopButton.
function stopButton_Callback(hObject, eventdata, handles)
% hObject    handle to stopButton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
global gds
gds.startButtonFlag = 0;






% --- Executes on slider movement.
function xFreqSlider_Callback(hObject, eventdata, handles)
% hObject    handle to xFreqSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global gds
sliderVal = get(hObject,'Value');
gds.xScanFrequency = sliderVal * gds.frequencyMaxHz;
set(gds.handles.xFreqEdit,'String',num2str(gds.xScanFrequency,'%0.2f'));




function xFreqEdit_Callback(hObject, eventdata, handles)
% hObject    handle to xFreqEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of xFreqEdit as text
%        str2double(get(hObject,'String')) returns contents of xFreqEdit as a double
global gds
maxVal = gds.frequencyMaxHz;
minVal = 0;
validEntryFlag = 0;
tempString = get(hObject,'String');
tempNum = str2num(tempString);
if ~isempty(tempNum),
    if tempNum >= minVal && tempNum <= maxVal
        validEntryFlag = 1;
    end%if tempNum >= ...
end%if ~isempty(tempNum);
%---
if validEntryFlag == 1,
    gds.xScanFrequency = tempNum;
    sliderVal = tempNum/gds.frequencyMaxHz;
    set(gds.handles.xFreqSlider,'Value',sliderVal);
else%if validEntryFlag == 1,
    set(hObject,'String',num2str(gds.xScanFrequency,'%0.2f'));
end%if validFlag == 1


% --- Executes on slider movement.
function xAmpSlider_Callback(hObject, eventdata, handles)
% hObject    handle to xAmpSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global gds
sliderVal = get(hObject,'Value');
gds.xScanAmplitude = sliderVal * gds.amplitudeMaxVolts;
set(gds.handles.xAmpEdit,'String',num2str(gds.xScanAmplitude,'%0.2f'));


    

function xAmpEdit_Callback(hObject, eventdata, handles)
% hObject    handle to xAmpEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of xAmpEdit as text
%        str2double(get(hObject,'String')) returns contents of xAmpEdit as a double
global gds
maxVal = gds.amplitudeMaxVolts;
minVal = 0;
validEntryFlag = 0;
tempString = get(hObject,'String');
tempNum = str2num(tempString);
if ~isempty(tempNum),
    if tempNum >= minVal && tempNum <= maxVal
        validEntryFlag = 1;
    end%if tempNum >= ...
end%if ~isempty(tempNum);
%---
if validEntryFlag == 1,
    gds.xScanAmplitude = tempNum;
    sliderVal = tempNum/gds.amplitudeMaxVolts;
    set(gds.handles.xAmpSlider,'Value',sliderVal);
else%if validEntryFlag == 1,
    set(hObject,'String',num2str(gds.xScanAmplitude,'%0.2f'));
end%if validFlag == 1





% --- Executes on slider movement.
function yFreqSlider_Callback(hObject, eventdata, handles)
% hObject    handle to yFreqSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global gds
sliderVal = get(hObject,'Value');
gds.yScanFrequency = sliderVal * gds.frequencyMaxHz;
set(gds.handles.yFreqEdit,'String',num2str(gds.yScanFrequency,'%0.2f'));



function yFreqEdit_Callback(hObject, eventdata, handles)
% hObject    handle to yFreqEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of yFreqEdit as text
%        str2double(get(hObject,'String')) returns contents of yFreqEdit as a double
global gds
maxVal = gds.frequencyMaxHz;
minVal = 0;
validEntryFlag = 0;
tempString = get(hObject,'String');
tempNum = str2num(tempString);
if ~isempty(tempNum),
    if tempNum >= minVal && tempNum <= maxVal
        validEntryFlag = 1;
    end%if tempNum >= ...
end%if ~isempty(tempNum);
%---
if validEntryFlag == 1,
    gds.yScanFrequency = tempNum;
    sliderVal = tempNum/gds.frequencyMaxHz;
    set(gds.handles.yFreqSlider,'Value',sliderVal);
else%if validEntryFlag == 1,
    set(hObject,'String',num2str(gds.yScanFrequency,'%0.2f'));
end%if validFlag == 1




% --- Executes on slider movement.
function yAmpSlider_Callback(hObject, eventdata, handles)
% hObject    handle to yAmpSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider
global gds
sliderVal = get(hObject,'Value');
gds.yScanAmplitude = sliderVal * gds.amplitudeMaxVolts;
set(gds.handles.yAmpEdit,'String',num2str(gds.yScanAmplitude,'%0.2f'));
GenerateWaveforms;





function yAmpEdit_Callback(hObject, eventdata, handles)
% hObject    handle to yAmpEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of yAmpEdit as text
%        str2double(get(hObject,'String')) returns contents of yAmpEdit as a double
global gds
maxVal = gds.amplitudeMaxVolts;
minVal = 0;
validEntryFlag = 0;
tempString = get(hObject,'String');
tempNum = str2num(tempString);
if ~isempty(tempNum),
    if tempNum >= minVal && tempNum <= maxVal
        validEntryFlag = 1;
    end%if tempNum >= ...
end%if ~isempty(tempNum);
%---
if validEntryFlag == 1,
    gds.yScanAmplitude = tempNum;
    sliderVal = tempNum/gds.amplitudeMaxVolts;
    set(gds.handles.yAmpSlider,'Value',sliderVal);
else%if validEntryFlag == 1,
    set(hObject,'String',num2str(gds.yScanAmplitude,'%0.2f'));
end%if validFlag == 1












% --- Executes during object creation, after setting all properties.
function xFreqSlider_CreateFcn(hObject, eventdata, handles)
% hObject    handle to xFreqSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end






% --- Executes during object creation, after setting all properties.
function xFreqEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to xFreqEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --- Executes during object creation, after setting all properties.
function xAmpSlider_CreateFcn(hObject, eventdata, handles)
% hObject    handle to xAmpSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end






% --- Executes during object creation, after setting all properties.
function xAmpEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to xAmpEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes during object creation, after setting all properties.
function yFreqSlider_CreateFcn(hObject, eventdata, handles)
% hObject    handle to yFreqSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end









% --- Executes during object creation, after setting all properties.
function yFreqEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to yFreqEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end





% --- Executes during object creation, after setting all properties.
function yAmpSlider_CreateFcn(hObject, eventdata, handles)
% hObject    handle to yAmpSlider (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end





% --- Executes during object creation, after setting all properties.
function yAmpEdit_CreateFcn(hObject, eventdata, handles)
% hObject    handle to yAmpEdit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


function GenerateWaveforms
global gds
gds.timeVector = linspace(0,gds.cycleDurationSec,gds.cycleDurationSec*gds.clockRateHz)';
gds.xVector = gds.xScanAmplitude * sin(2 * pi * gds.timeVector * gds.xScanFrequency);
gds.yVector = gds.yScanAmplitude * cos(2 * pi * gds.timeVector * gds.yScanFrequency);


function RestartOutput
global gds
vSession = gds.vSession;
queueOutputData(vSession,[gds.xVector,gds.yVector]);
vData = startForeground(vSession);
    

function StopOutput
global gds
vSession = gds.vSession;
%Reset to zero
zeroData = zeros(100,1);
queueOutputData(vSession,[zeroData,zeroData]);
vData = startForeground(vSession);
% wait(gds.ao,1)

