Saturday, January 5, 2013

Arduino and MATLAB GUI

Hello Guys,
I hope you are enjoying there...
Last month, i was doing small project based on Arduino and Matlab GUI. I was wondering how to handle Arduino with MATLAB GUI. I have searched over the net. And finally got it.
So, let's build our own...
Tools you need is following:

Software
Arduino Environment
MATLAB


Hardware
Arduino Board (Arduino UNO Rev3)
Breadboard
LED
Register (1 k ohm)
Jumper Wires

Circuit Diagram
Connect the Components as shown in following circuit...



Now, Go to following link and download MATLAB to ARDUINO integration...

https://docs.google.com/file/d/0B5uLbDqa8uuxaDV4ZHJvdl9MbzA/edit

It is in .rar or .zip format. Extract it to the desktop (or any comfortable location like my documents). Rename that folder with Matduino. so it's easy to find out.



Arduino Environment:

Now, open Arduino Environment... Go to FILE->OPEN
Locate to extracted files. Go to desktop and open Matduino.
There will be some folders. Just follow the following path
pde\adosrv\
Now there will be one file name with adiosrv.pde. Open that file in Arduino Environment.
Connect the board with PC via USB cable...

If you are new to Ardunio follow this link how to connect board with PC and upload driver.
http://arduino.cc/en/Guide/Windows#toc4

Upload to your board by FILE->UPLOAD or Ctrl+U.
Now close the Arduino Environment window.


MATLAB:

Open MATLAB. Locate to Matduino folder on Desktop which you have extracted earlier. Now In matlab command window, write a command
GUIDE
and press enter. This will open new window as shown in following figure.



Click on Blank GUI(Default) in Create New GUI Tab as shown in Above figure. And Click on OK. This will led to another window.




Now Click on Push Button as shown in above figure. And draw a button. It is shown in following figure.



Double click on that button. So in new window you can find out the properties. Goto background colour. And Change to Green. Follow the figures...


Choose color as 'Green' and Hit OK.
Now scroll down and find the field 'FontSize'.


Change FontSize value to 40 as shown in following figure. Scroll down to String tab.


Change 'String' value to ON
Close this Window. And check out the GUI window. This will look exactly following if you have make same changes as mine.



Same way make new button named OFF in Red Color by same procedure. So the GUI will look as shown below.

Go to FILE->SAVE AS and save the file in Matduino folder with LED_MATGUI.fig.
It will open an Editor window which may have some inbuilt code.
Press Ctrl+F and find the code
function LED_MATGUI_OpeningFcn(hObject, eventdata, handles, varargin)

In that function you can find the line

guidata(hObject, handles);

On next line write 4 line of code. In my case Arduino board is in 'COM3' port. So in 3rd line it is written as a= arduino ('COM3'); For your configuration, find out where arduino board connected as shown in link at http://arduino.cc/en/Guide/windows#toc8

clear all;
global a;
a = arduino('COM3');
a.pinMode(4,'output');

Now again press Ctrl+F and find the code
function pushbutton1_Callback(hObject, eventdata, handles)

Within that Function Write following code
global a;
a.digitalWrite(4,1);

Again Press Ctrl+F and find the code
function pushbutton2_Callback(hObject, eventdata, handles)

Now within this function Write this 2 line of code
global a;
a.digitalWrite(4,0);

Save this file by Ctrl+S. And Run the file by pressing F5. So the figure window will open which will have same look as GUI window. Make sure you have done exactly same thing which i have done. Now Click on ON button, this will glow LED. And same way Press OFF button. This will make LED off. If this works perfect skip the Error part. Otherwise go through it.

For Errors
If you get Error, do it again. Still if you are getting Error follow the steps.
In matlab command window write
edit LED_MATGUI_export
which will open new editer window. Copy the following code and paste it in this editor window.
function varargout = LED_MATGUI_export(varargin)
% LED_MATGUI_export MATLAB code for LED_MATGUI_export.fig
%      LED_MATGUI_export, by itself, creates a new LED_MATGUI_export or raises the existing
%      singleton*.
%
%      H = LED_MATGUI_export returns the handle to a new LED_MATGUI_export or the handle to
%      the existing singleton*.
%
%      LED_MATGUI_export('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in LED_MATGUI_export.M with the given input arguments.
%
%      LED_MATGUI_export('Property','Value',...) creates a new LED_MATGUI_export or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before LED_MATGUI_export_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to LED_MATGUI_export_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 LED_MATGUI_export

% Last Modified by GUIDE v2.5 05-Jan-2013 13:38:01

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

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

% Update handles structure
guidata(hObject, handles);

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


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


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


% --- Creates and returns a handle to the GUI figure. 
function h1 = LED_MATGUI_export_LayoutFcn(policy)
% policy - create a new figure or use a singleton. 'new' or 'reuse'.

persistent hsingleton;
if strcmpi(policy, 'reuse') & ishandle(hsingleton)
    h1 = hsingleton;
    return;
end

appdata = [];
appdata.GUIDEOptions = struct(...
    'active_h', [], ...
    'taginfo', struct(...
    'figure', 2, ...
    'pushbutton', 7), ...
    'override', 0, ...
    'release', 13, ...
    'resize', 'none', ...
    'accessibility', 'callback', ...
    'mfile', 1, ...
    'callbacks', 1, ...
    'singleton', 1, ...
    'syscolorfig', 1, ...
    'blocking', 0, ...
    'lastSavedFile', 'C:\Users\Sagar\Documents\MATLAB\Matuino\LED_MATGUI_export.m', ...
    'lastFilename', 'C:\Users\Sagar\Documents\MATLAB\Matuino\LED_MATGUI.fig');
appdata.lastValidTag = 'figure1';
appdata.GUIDELayoutEditor = [];
appdata.initTags = struct(...
    'handle', [], ...
    'tag', 'figure1');

h1 = figure(...
'Units','characters',...
'PaperUnits',get(0,'defaultfigurePaperUnits'),...
'Color',[0.941176470588235 0.941176470588235 0.941176470588235],...
'Colormap',[0 0 0.5625;0 0 0.625;0 0 0.6875;0 0 0.75;0 0 0.8125;0 0 0.875;0 0 0.9375;0 0 1;0 0.0625 1;0 0.125 1;0 0.1875 1;0 0.25 1;0 0.3125 1;0 0.375 1;0 0.4375 1;0 0.5 1;0 0.5625 1;0 0.625 1;0 0.6875 1;0 0.75 1;0 0.8125 1;0 0.875 1;0 0.9375 1;0 1 1;0.0625 1 1;0.125 1 0.9375;0.1875 1 0.875;0.25 1 0.8125;0.3125 1 0.75;0.375 1 0.6875;0.4375 1 0.625;0.5 1 0.5625;0.5625 1 0.5;0.625 1 0.4375;0.6875 1 0.375;0.75 1 0.3125;0.8125 1 0.25;0.875 1 0.1875;0.9375 1 0.125;1 1 0.0625;1 1 0;1 0.9375 0;1 0.875 0;1 0.8125 0;1 0.75 0;1 0.6875 0;1 0.625 0;1 0.5625 0;1 0.5 0;1 0.4375 0;1 0.375 0;1 0.3125 0;1 0.25 0;1 0.1875 0;1 0.125 0;1 0.0625 0;1 0 0;0.9375 0 0;0.875 0 0;0.8125 0 0;0.75 0 0;0.6875 0 0;0.625 0 0;0.5625 0 0],...
'IntegerHandle','off',...
'InvertHardcopy',get(0,'defaultfigureInvertHardcopy'),...
'MenuBar','none',...
'Name','LED_MATGUI',...
'NumberTitle','off',...
'PaperPosition',get(0,'defaultfigurePaperPosition'),...
'PaperSize',get(0,'defaultfigurePaperSize'),...
'PaperType',get(0,'defaultfigurePaperType'),...
'Position',[103.8 29.3076923076923 112 32.1538461538462],...
'Resize','off',...
'HandleVisibility','callback',...
'UserData',[],...
'Tag','figure1',...
'Visible','on',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton5';

h2 = uicontrol(...
'Parent',h1,...
'Units','characters',...
'FontUnits','pixels',...
'BackgroundColor',[0 1 0],...
'Callback',@(hObject,eventdata)LED_MATGUI_export('pushbutton5_Callback',hObject,eventdata,guidata(hObject)),...
'FontSize',40,...
'Position',[11.8 22.3076923076923 25.8 4.23076923076923],...
'String','ON',...
'Tag','pushbutton5',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );

appdata = [];
appdata.lastValidTag = 'pushbutton6';

h3 = uicontrol(...
'Parent',h1,...
'Units','characters',...
'FontUnits','pixels',...
'BackgroundColor',[1 0 0],...
'Callback',@(hObject,eventdata)LED_MATGUI_export('pushbutton6_Callback',hObject,eventdata,guidata(hObject)),...
'FontSize',40,...
'Position',[53 22.2307692307692 27 4],...
'String','OFF',...
'Tag','pushbutton6',...
'CreateFcn', {@local_CreateFcn, blanks(0), appdata} );


hsingleton = h1;


% --- Set application data first then calling the CreateFcn. 
function local_CreateFcn(hObject, eventdata, createfcn, appdata)

if ~isempty(appdata)
   names = fieldnames(appdata);
   for i=1:length(names)
       name = char(names(i));
       setappdata(hObject, name, getfield(appdata,name));
   end
end

if ~isempty(createfcn)
   if isa(createfcn,'function_handle')
       createfcn(hObject, eventdata);
   else
       eval(createfcn);
   end
end


% --- Handles default GUIDE GUI creation and callback dispatch
function varargout = gui_mainfcn(gui_State, varargin)

gui_StateFields =  {'gui_Name'
    'gui_Singleton'
    'gui_OpeningFcn'
    'gui_OutputFcn'
    'gui_LayoutFcn'
    'gui_Callback'};
gui_Mfile = '';
for i=1:length(gui_StateFields)
    if ~isfield(gui_State, gui_StateFields{i})
        error('MATLAB:gui_mainfcn:FieldNotFound', 'Could not find field %s in the gui_State struct in GUI M-file %s', gui_StateFields{i}, gui_Mfile);
    elseif isequal(gui_StateFields{i}, 'gui_Name')
        gui_Mfile = [gui_State.(gui_StateFields{i}), '.m'];
    end
end

numargin = length(varargin);

if numargin == 0
    % LED_MATGUI_EXPORT
    % create the GUI only if we are not in the process of loading it
    % already
    gui_Create = true;
elseif local_isInvokeActiveXCallback(gui_State, varargin{:})
    % LED_MATGUI_EXPORT(ACTIVEX,...)
    vin{1} = gui_State.gui_Name;
    vin{2} = [get(varargin{1}.Peer, 'Tag'), '_', varargin{end}];
    vin{3} = varargin{1};
    vin{4} = varargin{end-1};
    vin{5} = guidata(varargin{1}.Peer);
    feval(vin{:});
    return;
elseif local_isInvokeHGCallback(gui_State, varargin{:})
    % LED_MATGUI_EXPORT('CALLBACK',hObject,eventData,handles,...)
    gui_Create = false;
else
    % LED_MATGUI_EXPORT(...)
    % create the GUI and hand varargin to the openingfcn
    gui_Create = true;
end

if ~gui_Create
    % In design time, we need to mark all components possibly created in
    % the coming callback evaluation as non-serializable. This way, they
    % will not be brought into GUIDE and not be saved in the figure file
    % when running/saving the GUI from GUIDE.
    designEval = false;
    if (numargin>1 && ishghandle(varargin{2}))
        fig = varargin{2};
        while ~isempty(fig) && ~ishghandle(fig,'figure')
            fig = get(fig,'parent');
        end
        
        designEval = isappdata(0,'CreatingGUIDEFigure') || isprop(fig,'__GUIDEFigure');
    end
        
    if designEval
        beforeChildren = findall(fig);
    end
    
    % evaluate the callback now
    varargin{1} = gui_State.gui_Callback;
    if nargout
        [varargout{1:nargout}] = feval(varargin{:});
    else       
        feval(varargin{:});
    end
    
    % Set serializable of objects created in the above callback to off in
    % design time. Need to check whether figure handle is still valid in
    % case the figure is deleted during the callback dispatching.
    if designEval && ishghandle(fig)
        set(setdiff(findall(fig),beforeChildren), 'Serializable','off');
    end
else
    if gui_State.gui_Singleton
        gui_SingletonOpt = 'reuse';
    else
        gui_SingletonOpt = 'new';
    end

    % Check user passing 'visible' P/V pair first so that its value can be
    % used by oepnfig to prevent flickering
    gui_Visible = 'auto';
    gui_VisibleInput = '';
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        % Recognize 'visible' P/V pair
        len1 = min(length('visible'),length(varargin{index}));
        len2 = min(length('off'),length(varargin{index+1}));
        if ischar(varargin{index+1}) && strncmpi(varargin{index},'visible',len1) && len2 > 1
            if strncmpi(varargin{index+1},'off',len2)
                gui_Visible = 'invisible';
                gui_VisibleInput = 'off';
            elseif strncmpi(varargin{index+1},'on',len2)
                gui_Visible = 'visible';
                gui_VisibleInput = 'on';
            end
        end
    end
    
    % Open fig file with stored settings.  Note: This executes all component
    % specific CreateFunctions with an empty HANDLES structure.

    
    % Do feval on layout code in m-file if it exists
    gui_Exported = ~isempty(gui_State.gui_LayoutFcn);
    % this application data is used to indicate the running mode of a GUIDE
    % GUI to distinguish it from the design mode of the GUI in GUIDE. it is
    % only used by actxproxy at this time.   
    setappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]),1);
    if gui_Exported
        gui_hFigure = feval(gui_State.gui_LayoutFcn, gui_SingletonOpt);

        % make figure invisible here so that the visibility of figure is
        % consistent in OpeningFcn in the exported GUI case
        if isempty(gui_VisibleInput)
            gui_VisibleInput = get(gui_hFigure,'Visible');
        end
        set(gui_hFigure,'Visible','off')

        % openfig (called by local_openfig below) does this for guis without
        % the LayoutFcn. Be sure to do it here so guis show up on screen.
        movegui(gui_hFigure,'onscreen');
    else
        gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        % If the figure has InGUIInitialization it was not completely created
        % on the last pass.  Delete this handle and try again.
        if isappdata(gui_hFigure, 'InGUIInitialization')
            delete(gui_hFigure);
            gui_hFigure = local_openfig(gui_State.gui_Name, gui_SingletonOpt, gui_Visible);
        end
    end
    if isappdata(0, genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]))
        rmappdata(0,genvarname(['OpenGuiWhenRunning_', gui_State.gui_Name]));
    end

    % Set flag to indicate starting GUI initialization
    setappdata(gui_hFigure,'InGUIInitialization',1);

    % Fetch GUIDE Application options
    gui_Options = getappdata(gui_hFigure,'GUIDEOptions');
    % Singleton setting in the GUI M-file takes priority if different
    gui_Options.singleton = gui_State.gui_Singleton;

    if ~isappdata(gui_hFigure,'GUIOnScreen')
        % Adjust background color
        if gui_Options.syscolorfig
            set(gui_hFigure,'Color', get(0,'DefaultUicontrolBackgroundColor'));
        end

        % Generate HANDLES structure and store with GUIDATA. If there is
        % user set GUI data already, keep that also.
        data = guidata(gui_hFigure);
        handles = guihandles(gui_hFigure);
        if ~isempty(handles)
            if isempty(data)
                data = handles;
            else
                names = fieldnames(handles);
                for k=1:length(names)
                    data.(char(names(k)))=handles.(char(names(k)));
                end
            end
        end
        guidata(gui_hFigure, data);
    end

    % Apply input P/V pairs other than 'visible'
    for index=1:2:length(varargin)
        if length(varargin) == index || ~ischar(varargin{index})
            break;
        end

        len1 = min(length('visible'),length(varargin{index}));
        if ~strncmpi(varargin{index},'visible',len1)
            try set(gui_hFigure, varargin{index}, varargin{index+1}), catch break, end
        end
    end

    % If handle visibility is set to 'callback', turn it on until finished
    % with OpeningFcn
    gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
    if strcmp(gui_HandleVisibility, 'callback')
        set(gui_hFigure,'HandleVisibility', 'on');
    end

    feval(gui_State.gui_OpeningFcn, gui_hFigure, [], guidata(gui_hFigure), varargin{:});

    if isscalar(gui_hFigure) && ishghandle(gui_hFigure)
        % Handle the default callbacks of predefined toolbar tools in this
        % GUI, if any
        guidemfile('restoreToolbarToolPredefinedCallback',gui_hFigure); 
        
        % Update handle visibility
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);

        % Call openfig again to pick up the saved visibility or apply the
        % one passed in from the P/V pairs
        if ~gui_Exported
            gui_hFigure = local_openfig(gui_State.gui_Name, 'reuse',gui_Visible);
        elseif ~isempty(gui_VisibleInput)
            set(gui_hFigure,'Visible',gui_VisibleInput);
        end
        if strcmpi(get(gui_hFigure, 'Visible'), 'on')
            figure(gui_hFigure);
            
            if gui_Options.singleton
                setappdata(gui_hFigure,'GUIOnScreen', 1);
            end
        end

        % Done with GUI initialization
        if isappdata(gui_hFigure,'InGUIInitialization')
            rmappdata(gui_hFigure,'InGUIInitialization');
        end

        % If handle visibility is set to 'callback', turn it on until
        % finished with OutputFcn
        gui_HandleVisibility = get(gui_hFigure,'HandleVisibility');
        if strcmp(gui_HandleVisibility, 'callback')
            set(gui_hFigure,'HandleVisibility', 'on');
        end
        gui_Handles = guidata(gui_hFigure);
    else
        gui_Handles = [];
    end

    if nargout
        [varargout{1:nargout}] = feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    else
        feval(gui_State.gui_OutputFcn, gui_hFigure, [], gui_Handles);
    end

    if isscalar(gui_hFigure) && ishghandle(gui_hFigure)
        set(gui_hFigure,'HandleVisibility', gui_HandleVisibility);
    end
end

function gui_hFigure = local_openfig(name, singleton, visible)

% openfig with three arguments was new from R13. Try to call that first, if
% failed, try the old openfig.
if nargin('openfig') == 2
    % OPENFIG did not accept 3rd input argument until R13,
    % toggle default figure visible to prevent the figure
    % from showing up too soon.
    gui_OldDefaultVisible = get(0,'defaultFigureVisible');
    set(0,'defaultFigureVisible','off');
    gui_hFigure = openfig(name, singleton);
    set(0,'defaultFigureVisible',gui_OldDefaultVisible);
else
    gui_hFigure = openfig(name, singleton, visible);
end

function result = local_isInvokeActiveXCallback(gui_State, varargin)

try
    result = ispc && iscom(varargin{1}) ...
             && isequal(varargin{1},gcbo);
catch
    result = false;
end

function result = local_isInvokeHGCallback(gui_State, varargin)

try
    fhandle = functions(gui_State.gui_Callback);
    result = ~isempty(findstr(gui_State.gui_Name,fhandle.file)) || ...
             (ischar(varargin{1}) ...
             && isequal(ishghandle(varargin{2}), 1) ...
             && (~isempty(strfind(varargin{1},[get(varargin{2}, 'Tag'), '_'])) || ...
                ~isempty(strfind(varargin{1}, '_CreateFcn'))) );
catch
    result = false;
end

Save this file by Ctrl+S. And run by pressing F5. This time it will surely run.
If still you are getting errors. Make sure you have connected Arduino in correct port.

Demo:
You can see this project in progress. Here is the video.


video


6 comments:

  1. Hey! the .pde file is not in the link! could you help me there please. thanks!

    ReplyDelete
    Replies
    1. Sorry. I forgot to add that file.
      Download from following link.
      https://docs.google.com/file/d/0B5uLbDqa8uuxaDV4ZHJvdl9MbzA/edit

      Delete
  2. When trying your code, I got errors as below. Can u suggest some possible solution regarding these errors?

    Undefined function 'arduino' for input
    arguments of type 'char'.

    Error in
    LED_MATGUI>LED_MATGUI_OpeningFcn (line
    62)
    a = arduino('COM1');

    Error in gui_mainfcn (line 221)
    feval(gui_State.gui_OpeningFcn,
    gui_hFigure, [],
    guidata(gui_hFigure),
    varargin{:});

    Error in LED_MATGUI (line 42)
    gui_mainfcn(gui_State,
    varargin{:});

    ReplyDelete
    Replies
    1. Hi Mujahidah,

      Can you please check the Port where Arduino is connected? In this post, i assumed that it is connected at 'COM1'. Please make necessary changes to COM port and try again.

      If still error remains, let me know.

      Delete
  3. Can u tell me how i can send any character to arduino using GUI?

    ReplyDelete
  4. Im having trouble with your code it says there ins't enough input arguments on line 247

    ReplyDelete