Delay function to slow down while loop - matlab

I'm new to MATLAB and I've got a question to ask. I am currently doing up this UI which includes a code which is shown below.
% --- Executes on button press in Start.
function Start_Callback(hObject, eventdata, handles)
% hObject handle to Start (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global s brightness a t;
t = 0.1
a = 1;
readasync(s);
while (a == 1)
brightness = str2double(fscanf(s, '%s', 8));
set(handles.brightness, 'String', num2str(brightness));
disp(brightness);
if brightness < 87
if brightness < 44
fprintf(s, '%s',1);
else
fprintf(s,'%s',2);
end
else
if brightness < 130
fprintf(s, '%s',3);
else
fprintf(s, '%s',4);
end
end
if(a==0)
break;
end
pause(1/10);
end
As you can see, I am currently using a pause function to delay the while loop. However my mentor in college suggested that I use tic toc instead of pause to delay the loop. I do not know how should I go about with it. He has given me this function but I do not know how to implement it. Any advice?
function delay(t)
tic;
while toc < t
end
end

Where you have pause(1/10), just write delay(1/10) instead. They are not quite the same thing, as pause has a side effect of flushing any graphics updates and GUI callbacks that may have queued up.

As excaza indicated you can replace the line pause(1/10); by delay(1/10); but the function delay must be visible to where it is being called (so for example you can create a file in the same directory called delay.m that contains the code from your mentor).
It might be helpful to point out that replacing the code pause(1/10); by tic; while toc < 1/10 end; accomplishes the same thing functionally, even though this isn't as good from a coding practice/readability perspective.

Related

Stop plotting on MATLAB

I have a question about stopping a plot on matlab. I use given code to plot my trajectory.
But the case here is that, I have a drop-down menu and I'm trying to control my plot speed using drop-down( pop-up) menu.
Pop-up menu works as given below:
function animation_speed_Callback(hObject, eventdata, handles)
% hObject handle to threeDOF_animation_speed (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global plot_step
switch get(handles.animation_speed,'Value')
case 1
run('create_animation.m')
case 2
run('create_animation.m')
end
and here is the create_animation.m file :
if get(handles.animation_speed,'Value')==1
plot_step=5;
elseif get(handles.animation_speed,'Value')==2
plot_step=10;
end
for i = 1:plot_step:length(x)
addpoints(trajectory,y(i),x(i))
drawnow
hold on
end
The problem is when I select option '1' (plot_step=5) and then change it as '2' (plot_step=10) without waiting the finishing of the loop, it works like that:
It starts to plot my points with case 1 and then it turns to case 2. ( Everything is normal untill now.)
However, it continue to plot case 1. I do not want to see case 1 again.
How can I fix this?
(PS: I attached a gif file I select 2x at the beginning and then I select 8x. After it finish to plot 8x it starts to continue 2x again.)
Thanks in advance!

How to maximize a MATLAB GUI figure/window on startup?

I am currently evaluating GUIs in MATLAB and was wondering how to maximize a GUI window on startup, without the need for user interaction. The function I am using is stated hereafter and works fine if called on a button press, but calling it in the figure's OpeningFcn won't help.
http://www.mathworks.com/matlabcentral/fileexchange/25471-maximize
Any help on some startup section to place the function call, which is executed after the GUI window has been drawn? I searched for solutions related to startup code in MATLAB GUIs, but there were no results to date.
Thanks in advance for your efforts.
Since many people seem to be interested in this and there is still no public solution, I will describe my approach:
In the YourGUIName_OpeningFcn(hObject, eventdata, handles, varargin) function, append the following lines:
% Initialize a timer, which executes its callback once after one second
timer1 = timer('Period', 1, 'TasksToExecute', 1, ...
'ExecutionMode', 'fixedRate', ...
'StartDelay', 1);
% Set the callback function and declare GUI handle as parameter
timer1.TimerFcn = {#timer1_Callback, findobj('name', 'YourGUIName')};
timer1.StopFcn = #timer1_StopFcn;
start(timer1);
Declare the timer1_Callback and timer1_StopFcn functions:
%% timer1_Callback
% --- Executes after each timer event of timer1.
function timer1_Callback(obj, eventdata, handle)
% Maximize the GUI window
maximize(handle);
%% timer1_StopFcn
% --- Executes after timer stop event of timer1.
function timer1_StopFcn(obj, eventdata)
% Delete the timer object
delete(obj);
Declare the maximize function:
function maximize(hFig)
%MAXIMIZE: function which maximizes the figure withe the input handle
% Through integrated Java functionality, the input figure gets maximized
% depending on the current screen size.
if nargin < 1
hFig = gcf; % default: current figure
end
drawnow % required to avoid Java errors
jFig = get(handle(hFig), 'JavaFrame');
jFig.setMaximized(true);
end
Source of the maximize function:
http://www.mathworks.com/matlabcentral/fileexchange/25471-maximize

Load text file on Matlab with a GUI

I have a question about how can I write a code to create a GUI in Matlab. I've created the graphic interface with a simple button. I want that, pressing that button, load a text file and after a loop, load an image and create the different bands (this process is because it's a multispectral image with different bands). This code works well if I execute on a .m file. This is the code:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
Dates=load ('C:\Users\Desktop\dates.txt');
NombImages=load ('images.txt');
Nimages= numel(Dates);
fileimg=NombImages(1);
fileistr=int2str(fileimg);
image1 = imread(fileistr);
size=size(imagen1); nrows= size(1);
ncolumns= size(2);
nbands= size(3);
Images = zeros(nrows, ncolumns, nbands, Mimages, 'uint16');
imagess = zeros(nrows, ncolumns, nbands);
for image= 1: Nimages
fileimg=NombImagen(image);
fileistr=int2str(fileimg);
imagess = imread(fileistr);
Images(:,:,:,image)=imagess;
end
DN= double(Images);
Band1 = Images(:,:,1);
Band2 = Images(:,:,2);
Band3 = Images(:,:,3);
end
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
Maybe it seems a bit complicated but it's because of the format of the images (16 bits, etc.). I don't want to visualize the bands, only load it with that code.
Any help would be appreciated. Thanks in advance,
here we go:
you recieve an error-message, which indicates, that there is an "end" at the end of your function (the pushbutton-callback-fcn).
In Matlab it is possible to end functions without ending them with an end :)
When using GUIDE for example, this is the default. GUIDE creates functions without ending them with "end".
So the problem is: if you put an "end"-statement somwhere to end a function, Matlab is expecting an end after EVERY function!!
In your special case:
remove the "end" at the end of your code:
...
Band1 = Images(:,:,1);
Band2 = Images(:,:,2);
Band3 = Images(:,:,3);
end%<-this one :)
Another option of course is, to an end after every function...
edit
to store data within a GUI you can (or should) use the handles-structure. How to use it in detail is explained here:
TMW: guidata
A short version:
store data within the handles-structure like this:
handles.myVar = ...
and dont forget to update the structure by this command:
guidata(hObject,handles)
For you it should look like:
handles.Band1=Band1; %or directly: ...=Images(:,:,1);
...
guidata(hObject,handles)
and later on you can retrieve the data within another function (that knows about the handles-structure of course!) just like this:
handles.Band1

Global variables set in GUI with no values - Matlab

I created a GUI to set parameters and use those parameters in another m-File. I know that the variables created in GUI are in a different workspace from the input variables to the m-File. For that reason, I'm trying to use global variables, but not sucesfully: the variables goes to the m-File empty.
I have a GUI which has 3 edit boxes, that the user can set parameters (0 or 1), using this code (showing the code for only one edit box):
function density_Callback(hObject, eventdata, handles)
% hObject handle to density (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 density as text
% str2double(get(hObject,'String')) returns contents of density as a double
global density
density = str2double(get(hObject, 'String'));
global Variavel_1
assignin('base', 'Variavel_1', density);
The m-File are called from a GUI BUTTON, using this code:
function calculate_Callback(hObject, eventdata, handles)
% hObject handle to calculate (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
test %m-File that uses variables set in GUI
And the m-File should use this Variavel_1 and the others from the remaining editboxes in this code (test.m):
global Variavel_1
global Variavel_2
global sum
Variavel_1
Variavel_2
sum = Variavel_1 + Variavel_2
But all I have is all those variables empty!
(I know I can put this code inside the GUI code, but that's not the real propouse because this simple m-File to sum will be much more complex, so I need the variables to go to a m-File).
Variavel_1 = []
Variavel_2 = []
Sum = []
Can anyone understand why the global variables fails?
Thanks in advance!
In auto generated OpeningFcn callback, if you're using GUIDE
You can define variables/fields in handle structure.
This is initialization part. The data used by this can be shared across all widgets on the GUI.
So, in this callback, for variable_1,variable_2, sum, etc. you can have something like following:
handles.variable_1 = 1;
handles.variable_1 = 2;
handles.sum = handles.variable_1 + handles.variable_1 = 1;
% At end update handles structure
handles.output = hObject;
guidata(hObject, handles);
In other callback, say your Button or Edit callback
you can update these values as normal like following
handles.variable_1 = 12;
handles.variable_1 = 23;
handles.sum = handles.variable_1 + handles.variable_1 = 1;
% Now, at end of callback save the change you made to the structure
guidata(hObject,handles)
To verify these values type handles at command window.
Ref :Store or retrieve GUI data for more details.
To use these variables from GUI to other script simple assign them in workspace
like assignin('base','variable_1',handles.variable_1); ,etc in any of the callback where variable_1 is getting updated.
Then, in your m-script you can directly use these variables.
I think you could just define your test function (saved in "test.m") as:
function sum = test(x, y)
sum = x + y;
And then call your test function from your calculate_CallBack function using:
sum = test(Variavel_1, Variavel_2);
Admittedly, I am not well versed in GUI programming in MATLAB, so there may be some really obvious reason for which you cannot do this, but this avoids using global variables, which often makes for cleaner code.

Matlab GUI using GUIDE : Want to dynamically update graphs

I've written a Matlab script that reads in data using a virtual COMM port in real-time. I've done a significant amount of signal processing in an mfile.
Next, I felt the need to have a compact GUI that displays the information as summary.
I only recently started digging and reading more of Matlab's built-in GUI tool, GUIDE. I've followed a few tutorials and am successfully able to get my graphs to display on my GUI after a button-press.
However, I want the GUI to update in real-time. My data vector is constantly updating (reading in data from the COMM port). I want the GUI to keep updating the graphs with the newer data, as opposed to relying on a button press for an update. Can someone please point me in the right direction for background updating?
Here is the relevant code currently for the GUI:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global data
global time
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
EDIT Changed code:
% --- Executes on button press in pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
%Setting it to display something when it ends
% t = timer('TimerFcn', 'timerOn=false; disp(''Updating GUI!'')',...
t = timer(...
'TasksToExecute', 10, ... % Number of times to run the timer object
'Period', 3, ...
'TimerFcn', GUIUpdate());
%Starting the timer
start(t)
function GUIUpdate()
global data
global time
%Parameters below axes
global min
global max
% Time domain plot
axes(handles.timeDomainPlot);
cla;
plot (time, data);
%Other parameters:
set(handles.mean, 'String', mean);
set(handles.max, 'String', max);
The error that I get is:
??? Error using ==> GUI_Learning>GUIUpdate
Too many output arguments.
Error in ==>
#(hObject,eventdata)GUI_Learning('pushbutton1_Callback',hObject,eventdata,guidata(hObject))
??? Error while evaluating uicontrol Callback
Here is an example using a timer with a timerFcn callback. I made a simple GUI with 1 axes and 1 button.
In the opening function I initialize the plot and create the timer. In the start button callback I start the timer and start manipulating the data. The timer function callback the just updates the y-data of the line via its handle. Below are the relevant functions from the GUI's M-file (snipped init section and output fcn.
function testTimer_OpeningFcn(hObject, eventdata, handles, varargin)
global y x
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
handles.plot = plot(handles.axes1,x,y);
handles.timer = timer('ExecutionMode','fixedRate',...
'Period', 0.5,...
'TimerFcn', {#GUIUpdate,handles});
handles.output = hObject;
guidata(hObject, handles);
% --- Executes on button press in startButton.
function startButton_Callback(hObject, eventdata, handles)
global y x
start(handles.timer)
for i =1:30
y = sin(x+i/10);
pause(1)
end
function GUIUpdate(obj,event,handles)
global y
set(handles.plot,'ydata',y);
You may want a Stop button to stop the timer depending on how your GUI is structured and were/how the data is updated.
Edit: Basic handles info some of this is pretty basic and you may already know it:
An individual handle to an object contains a bunch of properties that you can read with the get() function or set with the set() function. So for example maybe I wanted to change the text of the startButton for some reason in my GUI.
set(handles.startButton,'String','Something Other Than Start');
You may just want to set a break point in your code somewhere (maybe in a button press) and play around with the handles struct. Running get() commands on various objects to learn their properties.
Now the handles structure contains all of the ... umm... handles to your GUI's objects as well as any custom items that may be convenient for your to store there. Most GUI callbacks automatically get passed the handles struct so you have easy access to all parts of the GUI.
Ex. The 'startButton' callback was automatically passed handles. So I had easy access to the timer object via handles.timer.
Which brings me to sticking custom things into handles. In the opening function I added a new item to the handles structure handles.timer and handles.plot because I knew they would be useful in other callbacks (like button press and the timerFcn callback).
However, to store these things permanently you need to use the 'guidata' function. This function basically either stores the modified handles struct or retrieves a copy of handles depending on how you call it. So the following line in the opening function is storing the modified handles structure (added .timer and .plot) into the main GUI.
guidata(hObject,handles);
Basically any time you add something in handles you should have that line to make the change permanent.
Now the other method of calling it is:
handles = guidata(hObject); %hObject can be any handle who is a child of the main GUI.
This will retrieve the handles structure for the GUI.
And last handles.output = hObject is just the default output when you launch your GUI. IF you call your GUI via Matlab's command line like this h = myGUI; it should return the handle to your GUI.
You need to use a timer object. Set the callback to be the function that updates the plots.
Take a look at Making Graphs Responsive with Data Linking
and the linkdata command.
If the same variable appears in plots in multiple figures, you can
link any of the plots to the variable. You can use linked plots in
concert with Marking Up Graphs with Data Brushing, but also on their
own. Linking plots lets you
Make graphs respond to changes in variables in the base workspace or within a function
Make graphs respond when you change variables in the Variable Editor and Command Line
Modify variables through data brushing that affect different graphical representations of them at once
Create graphical "watch windows" for debugging purposes
Watch windows are useful if you program in the MATLAB language. For
example, when refining a data processing algorithm to step through
your code, you can see graphs respond to changes in variables as a
function executes statements.
I made a quick and dirty test seen below and I am not sure how this will work in a GUI verses a function but may do the trick.
Note 1: I had to add a break point in my subroutine where it modifies the global y to actually see the plot auto-update. You may need some combination of drawnow, pause, or a timer if data is getting changed rapidly.
function testLinking()
global x y
%Links failed if the global did not also exist in the base workspace
evalin('base','global x y');
x = 0:.1:3*pi; % Make up some data and plot
y = sin(x);
h = plot(x,y,'ydatasource','y','xdatasource','x');
linkdata on
testSub
function testSub()
%Test to see if a sub can make a linked global refresh
global x y
for i = 1:10
%This should automatically update the plot.
y = sin(x+i/10);
end
Edit: there may be ways around the use of globals depending on how your functions are structured ... but I don't have time to dig into it to much.
You can add a callback on the serial object that executes a plotting function. You must attach the callback to the 'BytesAvailableFcn' event on the object (see this for more details on the properties of the com object).
Essentially, when there are bytes available on the com port, you instruct matlab to run a specific function. In your case, it will be the function updating the GUI. If you need to process the incoming data first, then your callback function will first do the signal processing and then do the plotting commands.