How to update date and time in matlab gui - matlab

function demo1()
H.f = figure('Name','DEMO1');
set(H.f,'Units','Pixels','Position',get(0,'ScreenSize'));% adjust figure size as per the screen size
H.pb1 = uicontrol('style','push',...
'units','pixels',...
'position',[400 800 280 30],...
'fontsize',14,...
'string', datestr(now)); % datestr(now) is used to get current date and time
end
how i can get the real time clock in gui

This is not really an easy task to perform and you may want to think about your design. This could be wrapped in a class, but not necessarily. In case you do not want to do this you may be able to modify the underlying Java objects, but that seems to be overworking this. I have instead structured this in a more C-style manner with placing all data in a struct and writing functions taking the struct as an argument. However, since matlab does not support passing memory locations you need to return the struct after modifying it.
I have chosen to use a timer object for this. You need to store the timer object somewhere since it needs to be deleted when you are not using it anymore. Further, I have added some code for using a start function and stop function as well. For the timer object. This for seeing that the object actually gets finished during development phase. This is not needed for the final project. Further, you may want to handle the case where the window is closed. This will cause the current implementation to crash since the timer is independent of the figure and does not stop when the figure is closed. You probably want to call stop_timer on closing the figure. Anyway here is the code:
function test()
h.f = figure('Name','DEMO1');
set(h.f,'Units','Pixels','Position',get(0,'ScreenSize'));% adjust figure size as per the screen size
h.pb1 = uicontrol('style','push',...
'units','pixels',...
'position',[400 800 280 30],...
'fontsize',14,...
'string', datestr(now)); % datestr(now) is used to get current date and time
h = start_clock(h);
pause on;
pause(15);
pause off;
h = stop_clock(h);
end
function obj = start_clock(obj)
%TasksToExecute calls the timer object N times
t = timer('StartDelay', 0, 'Period', 1,... % 'TasksToExecute', inf, ...
'ExecutionMode', 'fixedRate');
t.StartFcn = {#my_callback_fcn, 'My start message'};
t.StopFcn = { #my_callback_fcn, 'My stop message'};
t.TimerFcn = {#set_time, obj};
obj.t = t;
start(obj.t);
end
function obj = stop_clock(obj)
stop(obj.t);
delete(obj.t);
end
function set_time(obj, event, arg)
arg.pb1.String = datestr(now);
end
function my_callback_fcn(obj, event, arg)
txt1 = ' event occurred at ';
txt2 = arg;
event_type = event.Type;
event_time = datestr(event.Data.time);
msg = [event_type txt1 event_time];
disp(msg)
disp(txt2)
end

Related

Matlab stop function's execution

I have an array. I am processing elements of this array in a for loop inside a function.
function results = processArray(array)
for ii = 1:length(array)
%some stuff here
results(ii) = %getting the results for this particular element
end
end
There might be a lot of elements and computations might take a lot of time. I want to be able to finish execution of the for loop at any arbitrary time when a user wants to do that so that the results for already processed elements would be available.
I was trying to make a figure with a button which would change a boolean flag. Inside the for loop I was checking the value of that boolean. If the boolean changed then the for loop should break.
function results = processArray(array)
fig = figure;
fig.UserData.continue = 1;
uicontrol('Parent', fig', 'Style', 'pushbutton', 'String', 'stop', 'callback', #interrupt)
for ii = 1:length(array)
if(fig.UserData.continue == 0)
break;
end
%some stuff here
results(ii) = %getting the results for this particular element
end
end
function interrupt(obj, ~)
fig = obj.Parent;
fig.UserData.continue = 0;
end
well, that does not work. The figure shows up only after all the computations are done already. If I draw the figure first using something like waitforbuttonpress and proceed to the for loop pressing the button does not stop the execution. I think the callback function is being executed only after the for loop is finished. Is there any way to solve this?
You will need to drawnow after you create the button, so it will show up. You also need to drawnow within the loop to update the button state. Then you should achieve what you want.
drawnow force figure update, so it will slow down your computation a little.

Late updating function output in MATLAB - R2015b

I have the following code; this function is called from a parent script, and produces a GUI that allows the user to select a threshold parameter.
Unfortunately, the output parameter threshold is updated late. For example, the first time the function is run, irrespective of how I use the slider, it reports threshold as being empty, even if I have set thresh_final to 0.9. The next time I run the function, it immediately updates threshold as 0.9, before I can adjust thresh_final. That is, when I run the function at time t, it outputs the value of threshold as the selected value of thresh_final at time t-1.
function threshold = threshold_choose(frames,prob_mat)
global thresh_final
f1 = figure('Visible','on','pos',[100,50,800,800]);
ax1 = axes('Units','Pixels');
work_im = prob_mat(:,:,2);
normali = max(max(work_im));
work_im = work_im ./ normali;
user_choose = work_im > 0.8 ;
demoImage = mat2gray(user_choose);
imshow(demoImage)
sld = uicontrol('Style', 'slider',...
'Min',0,'Max',1,'Value',0.8,...
'Position', [200 50 300 20],...
'Callback', #thresh_change);
function thresh = thresh_change(source,~)
thresh = source.Value;
figure(f1)
user_choose = work_im > thresh ;
demoImage = mat2gray(user_choose);
imshow(demoImage)
thresh_final = thresh;
closeing = uicontrol('Style','pushbutton',...
'String','Close GUI',...
'Position',[700,20,80,80],...
'Callback', #closeAll);
end
function closeAll(~,~)
close all
end
end
threshold = thresh_final;
end
At the moment, to get around this bug, I can simply call the function, adjust the parameter, then close the GUI, and then call the function again, but close the GUI immediately, without adjusting the parameter, but this is not really practical.
I figure that this is because when I call the function, it runs the whole script, including the last line threshold = thresh_final, and then waits to run the nested functions until they are called, but I don't know how to get around this.
Any help would be much appreciated.

Performance loss using Matlab parfeval?

I have a relatively big file and I would like to make an interactive plot using GUIDE which plots a segment of the file and upon scrollEvent the window gets updated. (the data is appropriately replotted).
To this end a buffer of size 4 times that of the window is fetched, and when the window's center reaches 75% of the buffer, the buffer is refetched so that the window is at the center of the new buffer.
The problem with this is that when using fread it of course blocks until done.(which is visually disturbing)
What I tried is to create a separate readData function which gets called with f = parfeval(gcp(),#readData,1,datafile) and on [~,buffer]=fetchNext(f) the buffer is persisted on handles.datafile.
Problem: Even though in my example (see below) readData only gets called once, every subsequent plotting is incredibly slow (10x the runtime of when not using parfeval).
Example:
./test.dat was generated by dd if=/dev/urandom of=test.dat bs=100000 count=1024
**This is the synchronous code to get the asynchronous one, comment out the parfeval and fetchNext function definitions shadowing the parallel ones.
function test()
f = figure('Toolbar','none','Menubar','none');
ax = axes(f);
data = struct( 'file','./test.dat',...
'buffer',[],...
'window',[0,100000]);
p = gcp();
data.fileReader = parfeval(p,#readData,1,data);
handles = struct('axes',ax,'figure',f,'data',data);
guidata(f,handles);
set(f,'WindowScrollWheelFcn',#scrollHandler);
end
function f = parfeval(~,fun,~,in1)
f = struct('output',fun(in1));
end
function [id,out] = fetchNext(f,varargin)
id = 1;
out = f.output;
end
function buffer = readData(data)
file = fopen(data.file,'r');
buffer = fread(file,[128,400000],'int16');
fclose(file);
end
function scrollHandler(hObject, eventdata, ~)
handles = guidata(hObject);
ax = handles.axes;
C = get (ax, 'CurrentPoint');
XLim = get(ax, 'XLim');
YLim = get(ax, 'YLim');
if XLim(1)<=C(1,1) && XLim(2)>=C(1,1) && ...
YLim(1)<=C(1,2) && YLim(2)>=C(1,2)
tic;
window = handles.data.window;
if isstruct(handles.data.fileReader) || handles.data.fileReader ~= -1
fprintf('Reading from file\n');
[~,handles.data.buffer] = fetchNext(handles.data.fileReader);
handles.data.fileReader = -1;
end
if eventdata.VerticalScrollCount > 0 && window(2) < 399000
window = window + 1000;
else
if window(1) > 1000
window = window - 1000;
end
end
handles.data.window = window;
guidata(hObject, handles);
plot(ax,handles.data.buffer(65,window(1)+1:window(2)));
toc
end
end
This is indeed very mysterious. The problem seems to be some sort of interaction with guidata and the parallel.FevalFuture returned by parfeval. As a workaround, you can simply avoid overwriting that element of the struct. In other words, remove the line
handles.data.fileReader = -1;
You'll also need to check handles.data.fileReader.Read to make sure you don't attempt to call fetchNext again on an already-completed future.

Matlab gui with pause function

I am using the GUIDE for matlab gui.
The gui built in order to communicate with keithley current measurement device through GPIB.
When using a toggle button for Current measurement while loop, i am using a pause() function inside the while loop for each iteration and a ytranspose on the y array reading results.
function Measure_Callback(hObject, eventdata, handles)
global GPIB1
global filename
global timeStep
disp('Measurement in progress \n stopwatch starts!');
tic
x=0;
n=0;
while get(hObject,'Value')
fprintf(GPIB1, 'printnumber(smua.measure.i(smua.nvbuffer1))');
fprintf(GPIB1, 'printbuffer(1,1,nvbuffer1)');
A = fscanf(GPIB1);
if length(A)<20
x = x+1;
n = n+1;
t(n) = toc ;
y(x) = str2double(A);
plot(t,y,'-bo',...
'LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor',[.49 1 .63],...
'MarkerSize',10);
grid on
hold on
end
title('Current vs Time','FontSize', 15)
xlabel('Time [s]','FontSize', 15)
ylabel('Current [A]','FontSize', 15)
a = timeStep;
pause(a)
end
disp('Measurement terminated');
disp('Elapsed time: ');
elapsedtime = toc;
elapsedtime_string = num2str(elapsedtime);
disp(elapsedtime_string);
ytrans = transpose(y);
csvwrite(filename,ytrans);
fprintf(GPIB1, 'smua.source.output = smua.OUTPUT_OFF');
For the pause function i'm geting error:
?? Error using ==> pause Error while evaluating uicontrol Callback
For the transpose(y) function i'm also getting a error:
its undefined y.
Cant understand why are those errors and could use some help.
Thank you!
First off, as people say, post the errors and the code. Do you know if length(A) is smaller than 20 in the first time you run the loop? Because if not, A is not defined and you can't transpose something that is not there. Initialize A before the loop to something and see if the error persists (or print out length(A) to make sure the loop gets entered the first run).
As for the pause error, make sure pause is an int or double, not a string. If you get your global timeStep from the GUI field, it is probably a string and you need to covert it to double first.

Variable persisting between function calls

Suppose I want to call a function twice, but I need the function to remember variables it initialized the first time it is called so execution can be changed in subsequent calls.
For example if I have a piece of code like this:
function random
if exist('a','var') == 0
fprintf('hello\n');
a = 1;
else
disp('goodbye\n');
end
end
How could I get MATLAB to remember that a equals 1 when when I call the code again? Specifically, I'm hoping to use this for a push button callback function in a program I'm writing.
MATLAB supports the keyword persistent, which you would use as follows:
function toggleval_persist
% Set up the persistent variable and initialize it.
persistent a;
if isempty(a)
a = 0;
end
if ( a == 0 )
disp('hello');
a = 1;
else
a = 0;
disp('goodbye');
end
end
Also, I wouldn't recommend using a persistent variable for toggling a button state. The button's state is usually available in the object structure for the GUI if you're using MATLAB's UI system.
What you could do (in the optics of using this code in a GUI) is set up a flag telling whether a has been initialized or not and pass it as an argument to the function random. Storing the flag (let's call it a_flag) in the handles structure of the GUI, for instance, would allow you to keep track of its value (actually stored in handles.a_flag) for example.
So in other words,you could set the flag to 0 during the creation of the GUI (or in its Opening_Fcn if you are using GUIDE) as follows:
handles.a_flag = false;
and then in the function called random, which you could call with: random(handles.a_flag):
function random(a_flag)
if ~a_flag
%// Update the flag
a_flag = true;
fprintf('hello\n');
a = 1;
else
fprintf('goodbye\n');
end
end
Even simpler would be to use global variables...but I like that idea better :)
EDIT
The point of my code is to demonstrate that we can use the handles structure of a GUI (as asked by the OP) to store the value of the flag. Since the structure is accessible from every callback pressing the pushbutton will update it the same way a persistent variable would.
Please try this code to see what I mean:
function TestGUI
clear
clc
hFigure = figure('Position',[200 200 200 150]);
handles.Disp_a_title = uicontrol('Style','text','String','a','Position',[20 100 60 20]);
handles.Disp_aflag = uicontrol('Style','text','String','0','Position',[100 100 60 20]);
handles.Button = uicontrol('Style','Push','Position',[50 50 60 20],'String','Update a','Callback',#(s,e) PushCb);
a = 0;
handles.a_flag = false;
guidata(hFigure,handles)
function PushCb(~,~)
handles = guidata(hFigure);
fprintf('Flag is %i\n',handles.a_flag)
if handles.a_flag == false;
disp('hello\n');
a = 1;
handles.a_flag = true;
else
disp('goodbye\n');
end
guidata(hFigure,handles)
end
end
Pressing the button twice results in the following output in the Command Window:
Flag is 0
hello\n
Flag is 1
goodbye\n
Which from what I understood is the expected behaviour the OP is looking for.