function varargout = PCBmotorControlMicro4(varargin)
% PCBMOTORCONTROLMICRO4 MATLAB code for PCBmotorControlMicro4.fig
%      PCBMOTORCONTROLMICRO4, by itself, creates a new PCBMOTORCONTROLMICRO4 or raises the existing
%      singleton*.
%
%      H = PCBMOTORCONTROLMICRO4 returns the handle to a new PCBMOTORCONTROLMICRO4 or the handle to
%      the existing singleton*.
%
%      PCBMOTORCONTROLMICRO4('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in PCBMOTORCONTROLMICRO4.M with the given input arguments.
%
%      PCBMOTORCONTROLMICRO4('Property','Value',...) creates a new PCBMOTORCONTROLMICRO4 or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before PCBmotorControlMicro4_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to PCBmotorControlMicro4_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 PCBmotorControlMicro4

% Last Modified by GUIDE v2.5 29-Oct-2012 10:27:46

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @PCBmotorControlMicro4_OpeningFcn, ...
                   'gui_OutputFcn',  @PCBmotorControlMicro4_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 PCBmotorControlMicro4 is made visible.
function PCBmotorControlMicro4_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 PCBmotorControlMicro4 (see VARARGIN)

% Initialise PCB Motor
% Find a serial port object.
PCBmotor = instrfind('Type', 'serial', 'Port', '/dev/ttyUSB1', 'Tag', '');  % Linux
%PCBmotor = instrfind('Type', 'serial', 'Port', 'COM4', 'Tag', '');  % Windows
%PCBmotor = instrfind('Type', 'serial', 'Port', '/dev/tty.usbserial1', 'Tag', '');  % Mac (untested!)


% Create the serial port object if it does not exist, otherwise use the object that was found.
if isempty(PCBmotor)
    PCBmotor = serial('/dev/ttyUSB1'); % Linux
    %PCBmotor = serial('COM4'); % Windows
    %PCBmotor = serial('/dev/tty.usbserial1'); % Mac (untested!)
else
    fclose(PCBmotor);
    PCBmotor = PCBmotor(1)
end

% Configure instrument object
set(PCBmotor, 'BaudRate', 19200, 'ByteOrder', 'littleEndian', 'DataBits', 8, 'DataTerminalReady', 'off', 'FlowControl', 'none', 'InputBufferSize', 6000, 'OutputBufferSize', 512, 'Parity', 'none', 'RequestToSend', 'on', 'StopBits', 1, 'Terminator', {'CR','CR'}, 'Timeout', 0.1);

handles.PCBmotor = PCBmotor;


% Initialise Microcontroller
% Find another serial object
microController = instrfind('Type', 'serial', 'Port', '/dev/ttyUSB0', 'Tag', '');  % Linux
%microController = instrfind('Type', 'serial', 'Port', 'COM5', 'Tag', '');   % Windows
%microController = instrfind('Type', 'serial', 'Port', '/dev/tty.usbserial2', 'Tag', '');  % Mac (untested!)


% Create the serial port object if it does not exist, otherwise use the object that was found.
if isempty(microController)
    microController = serial('/dev/ttyUSB0'); % Linux
    %microController = serial('COM5');   % Windows
    %microController = serial('/dev/tty.usbserial2'); % Mac (untested!)

else
    fclose(microController);
    microController = microController(1)
end

% Configure instrument object
set(microController, 'BaudRate', 9600, 'ByteOrder', 'littleEndian', 'DataBits', 8, 'DataTerminalReady', 'on', 'FlowControl', 'none', 'InputBufferSize', 24, 'OutputBufferSize', 24, 'Parity', 'none', 'RequestToSend', 'on', 'StopBits', 1, 'Terminator', {'CR','CR'}, 'Timeout', 10.0);

handles.microController = microController;

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

% Update handles structure
guidata(hObject, handles);

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



% --- Outputs from this function are returned to the command line.
function varargout = PCBmotorControlMicro4_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 connectbutton.
function connectbutton_Callback(hObject, eventdata, handles)
% hObject    handle to connectbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% Connect to object
fopen(handles.PCBmotor);


function entercommands_Callback(hObject, eventdata, handles)
% hObject    handle to entercommands (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 entercommands as text
%        str2double(get(hObject,'String')) returns contents of entercommands as a double

flushinput(handles.PCBmotor);
pause(0.1)

commandstring = get(hObject,'String');
fprintf(handles.PCBmotor,commandstring);
pause(0.1)  % Pauses are required to avoid timeout warnings
scan1 = fscanf(handles.PCBmotor);
pause(0.1)
scan2 = fscanf(handles.PCBmotor);
pause(0.1)
outputstring = [scan1 scan2];
handles.outputstring = outputstring;
set(handles.deviceoutput,'String',handles.outputstring);

guidata(hObject, handles);      % updates GUI object



% --- Executes during object creation, after setting all properties.
function entercommands_CreateFcn(hObject, eventdata, handles)
% hObject    handle to entercommands (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 motoroutput_Callback(hObject, eventdata, handles)
% hObject    handle to deviceoutput (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 deviceoutput as text
%        str2double(get(hObject,'String')) returns contents of deviceoutput as a double


% --- Executes during object creation, after setting all properties.
function deviceoutput_CreateFcn(hObject, eventdata, handles)
% hObject    handle to deviceoutput (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 on button press in disconnectbutton.
function disconnectbutton_Callback(hObject, eventdata, handles)
% hObject    handle to disconnectbutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

fclose(handles.PCBmotor);


function enterscript_Callback(hObject, eventdata, handles)
% hObject    handle to enterscript (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 enterscript as text
%        str2double(get(hObject,'String')) returns contents of enterscript as a double

scriptname = get(hObject,'String');
eval(scriptname);
guidata(hObject, handles);



% --- Executes during object creation, after setting all properties.
function enterscript_CreateFcn(hObject, eventdata, handles)
% hObject    handle to enterscript (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 on button press in zerobutton3.
function zerobutton3_Callback(hObject, eventdata, handles)
% hObject    handle to zerobutton3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Activate motor 3
flushinput(handles.PCBmotor);
pause(0.1)
fprintf(handles.PCBmotor,'m3');
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)

commandstring = 's1';

voltage_ch1 = 2.5;    % initial value
voltage_m3_stored = [];

fopen(handles.microController);

% Zeroing loop
while voltage_ch1 >= 1
    
    fprintf(handles.PCBmotor,commandstring);
    pause(0.1)
    scan1 = fscanf(handles.PCBmotor);
    pause(0.1)
    scan2 = fscanf(handles.PCBmotor);
    pause(0.1)
    readMotor = [scan1 scan2];
    
    flushinput(handles.microController);
    flushinput(handles.microController);
    junkscan = fscanf(handles.microController);    % throw this out, since first scan is usually incomplete
    
    % Read voltages for each channel
    for channels = 1:1:4
        
        microOutput = fscanf(handles.microController);
        output_string = sscanf(strtrim(microOutput),'Channel %g = %g V');
        
        if output_string(1) == 1
            voltage_ch1 = output_string(2);
        elseif output_string(1) == 2
            voltage_ch2 = output_string(2);
        elseif output_string(1) == 3
            voltage_ch3 = output_string(2);
        elseif output_string(1) == 4
            voltage_ch4 = output_string(2);
        else
            sprintf('Something is wrong!')    
        end
        
    end
    
        voltage_m3_stored = [voltage_m3_stored voltage_ch1];
    
end

voltage_m3_stored

fprintf(handles.PCBmotor,'z');
pause(0.1)
scan1 = fscanf(handles.PCBmotor);
pause(0.1)
scan2 = fscanf(handles.PCBmotor);
pause(0.1)
readMotorEnd = [scan1 scan2]

fclose(handles.microController);

% Bug workaround for some systems
fclose(handles.PCBmotor)
pause(0.1)
fopen(handles.PCBmotor)
pause(0.1)

guidata(hObject, handles);


% --- Executes on button press in zerobutton4.
function zerobutton4_Callback(hObject, eventdata, handles)
% hObject    handle to zerobutton4 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Activate motor 4
flushinput(handles.PCBmotor);
pause(0.1)
fprintf(handles.PCBmotor,'m4');
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)

commandstring = 's1';

voltage_ch2 = 0;    % initial value
voltage_m4_stored = [];

fopen(handles.microController);

% Zeroing loop
while voltage_ch2 <= 2.2
    
    fprintf(handles.PCBmotor,commandstring);
    pause(0.1)
    scan1 = fscanf(handles.PCBmotor);
    pause(0.1)
    scan2 = fscanf(handles.PCBmotor);
    pause(0.1)
    readMotor = [scan1 scan2];
    
    flushinput(handles.microController);
    flushinput(handles.microController);
    junkscan = fscanf(handles.microController);    % throw this out, since first scan is usually incomplete
    
    % Read voltages for each channel
    for channels = 1:1:4
        
        microOutput = fscanf(handles.microController);
        output_string = sscanf(strtrim(microOutput),'Channel %g = %g V');
        
        if output_string(1) == 1
            voltage_ch1 = output_string(2);
        elseif output_string(1) == 2
            voltage_ch2 = output_string(2);
        elseif output_string(1) == 3
            voltage_ch3 = output_string(2);
        elseif output_string(1) == 4
            voltage_ch4 = output_string(2);
        else
            sprintf('Something is wrong!')    
        end
        
    end
    
        voltage_m4_stored = [voltage_m4_stored voltage_ch2];
    
end

voltage_m4_stored

fclose(handles.microController);

fprintf(handles.PCBmotor,'z');
pause(0.1)
scan1 = fscanf(handles.PCBmotor);
pause(0.1)
scan2 = fscanf(handles.PCBmotor);
pause(0.1)
readMotorEnd = [scan1 scan2]

% Bug workaround for some systems
fclose(handles.PCBmotor)
pause(0.1)
fopen(handles.PCBmotor)
pause(0.1)

guidata(hObject, handles);

function enterm3position_Callback(hObject, eventdata, handles)
% hObject    handle to enterm3position (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 enterm3position as text
%        str2double(get(hObject,'String')) returns contents of enterm3position as a double

goto_position_string = get(hObject,'String');
goto_position_value = sscanf(goto_position_string,'%g');

% Activate motor 3
flushinput(handles.PCBmotor);
pause(0.1)
fprintf(handles.PCBmotor,'m3');
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)

% Necessary to always maintain clockwise movement
fprintf(handles.PCBmotor,'rd96');
pause(0.1)
scan1 = fscanf(handles.PCBmotor);
pause(0.1)
scan2 = fscanf(handles.PCBmotor);
pause(0.1)
%scan = [scan1 scan2];
present_position_value = sscanf(strtrim(scan2),'Memory# 96(+1): %g');
rescaled_position = rem(present_position_value,400);

if rescaled_position ~= goto_position_value
    
    if rescaled_position < goto_position_value
        number_of_steps = goto_position_value - rescaled_position;
    else
        number_of_steps = 400 - abs(goto_position_value - rescaled_position);
    end  
    
    commandstring = ['s' num2str(number_of_steps)];    
    fprintf(handles.PCBmotor,commandstring);
    pause(0.1)
    scan1 = fscanf(handles.PCBmotor);
    pause(0.1)
    scan2 = fscanf(handles.PCBmotor);
    pause(0.1)
    outputstring = [scan1 scan2];
    handles.outputstring = outputstring;
    set(handles.deviceoutput,'String',handles.outputstring);
    
else
    outputstring = 'Already there!';
    handles.outputstring = outputstring;
    set(handles.deviceoutput,'String',handles.outputstring);
end


%flushinput(handles.PCBmotor);
guidata(hObject, handles);      % updates GUI object


% --- Executes during object creation, after setting all properties.
function enterm3position_CreateFcn(hObject, eventdata, handles)
% hObject    handle to enterm3position (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 enterm4position_Callback(hObject, eventdata, handles)
% hObject    handle to enterm4position (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 enterm4position as text
%        str2double(get(hObject,'String')) returns contents of enterm4position as a double

goto_position_string = get(hObject,'String');
goto_position_value = sscanf(goto_position_string,'%g');

% Activate motor 4
flushinput(handles.PCBmotor);
pause(0.1)
fprintf(handles.PCBmotor,'m4');
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)
fscanf(handles.PCBmotor);
pause(0.1)

% Necessary to always maintain clockwise movement
fprintf(handles.PCBmotor,'rd120');
pause(0.1)
scan1 = fscanf(handles.PCBmotor);
pause(0.1)
scan2 = fscanf(handles.PCBmotor);
pause(0.1)
%scan = [scan1 scan2];
present_position_value = sscanf(strtrim(scan2),'Memory# 120(+1): %g');
rescaled_position = rem(present_position_value,400);

if rescaled_position ~= goto_position_value
    
    if rescaled_position < goto_position_value
        number_of_steps = goto_position_value - rescaled_position;
    else
        number_of_steps = 400 - abs(goto_position_value - rescaled_position);
    end  
    
    commandstring = ['s' num2str(number_of_steps)];    
    fprintf(handles.PCBmotor,commandstring);
    pause(0.1)
    scan1 = fscanf(handles.PCBmotor);
    pause(0.1)
    scan2 = fscanf(handles.PCBmotor);
    pause(0.1)
    outputstring = [scan1 scan2];
    handles.outputstring = outputstring;
    set(handles.deviceoutput,'String',handles.outputstring);    
    
else
    outputstring = 'Already there!';
    handles.outputstring = outputstring;
    set(handles.deviceoutput,'String',handles.outputstring);
end


%flushinput(handles.PCBmotor);
guidata(hObject, handles);      % updates GUI object


% --- Executes during object creation, after setting all properties.
function enterm4position_CreateFcn(hObject, eventdata, handles)
% hObject    handle to enterm4position (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 on button press in readmicrocontroller.
function readmicrocontroller_Callback(hObject, eventdata, handles)
% hObject    handle to readmicrocontroller (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

fopen(handles.microController);

flushinput(handles.microController);
flushinput(handles.microController);
junkscan = fscanf(handles.microController);    % throw this out, since first scan is usually incomplete

% Read voltages for each channel
for channels = 1:1:4
    
    microOutput = fscanf(handles.microController);
    micro_data = sscanf(strtrim(microOutput),'Channel %g = %g V');
        
    if micro_data(1) == 1
        voltage_ch1 = micro_data(2);
    elseif micro_data(1) == 2
        voltage_ch2 = micro_data(2);
    elseif micro_data(1) == 3
        voltage_ch3 = micro_data(2);
    elseif micro_data(1) == 4
        voltage_ch4 = micro_data(2);
    else
        sprintf('Something is wrong!')    
    end
end

fclose(handles.microController);

% Bug workaround for some systems
fclose(handles.PCBmotor)
pause(0.1)
fopen(handles.PCBmotor)
pause(0.1)

% Display output in GUI
v1_string = ['Channel 1 = ' num2str(voltage_ch1,'%1.2f\n') ' V'];
v2_string = ['Channel 2 = ' num2str(voltage_ch2,'%1.2f\n') ' V'];
v3_string = ['Channel 3 = ' num2str(voltage_ch3,'%1.2f\n') ' V'];
v4_string = ['Channel 4 = ' num2str(voltage_ch4,'%1.2f\n') ' V'];
outputstring = [v1_string; v2_string; v3_string; v4_string];
handles.outputstring = outputstring;
set(handles.deviceoutput,'String',handles.outputstring);

guidata(hObject, handles);      % updates GUI object
