Executing two timer functions continuously. GUI.

16 views (last 30 days)
Dear experts,
this is Carlos Andreu. Several months ago, You helped me to refresh continously a textbox with a timer function. This solution has worked perfectly. Now, I would like to add other timer function in order to refresh two text boxes at the same time. I have tried it with the following code:
function myGUI(handles,hObject)
TimerH = timer('UserData', handles.text5, 'TimerFcn', @myTimerFcn, 'Period', 0.5, ...
'ExecutionMode', 'fixedRate');
drawnow;
TimerH2 = timer('UserData', handles.text9, 'TimerFcn', @myTimerFcn2, 'Period', 0.6, ...
'ExecutionMode', 'fixedRate');
drawnow;
start([TimerH TimerH2]);
function myTimerFcn(TimerH,eventData,handles,hObject)
global distance
global flag_tracker
if flag_tracker == 1
TextH = get(TimerH, 'UserData');
distancia = Guardar_pos(TextH);
pause(0.5)
set(TextH,'String',num2str(distance))
drawnow();
else
TextH = get(TimerH, 'UserData');
set(TextH,'String','Measuring...');
end
function myTimerFcn2(TimerH2,eventData,handles,hObject)
global distance2
global flag_tracker
if flag_tracker == 1
TextH2 = get(TimerH2, 'UserData');
distancia_fija = Guardar_pos3(TextH2);
pause(0.5)
set(TextH2,'String',num2str(distance2))
drawnow();
else
TextH2 = get(TimerH2, 'UserData');
set(TextH2,'String','Measuring...');
end
The problem is the textbox of timerH works, but textbox of timerH2 doesn't.
Please, Can you help me?
Thank you in advance,
Carlos.

Accepted Answer

Jan
Jan on 29 Nov 2017
Using global variables is a bad idea in general. If you see a way to avoid them, do this.
You did not mention, what is not working. Do you get an error message? Is the timer function entered?
Why do you calculate the values.
distancia = Guardar_pos(TextH);
and
distancia_fija = Guardar_pos3(TextH2);
when the variables are not used at all? What is "Guardar_pos" and "Guarder_pos3"?
If you define the TimerFcn as "@myTimerFcn2", it is called with 2 inputs: The handle of the timer and the EventData struct. Then requesting 4 inputs is not smart, although it is not an error, when the not provided inputs are not used in the function:
function myTimerFcn2(TimerH2,eventData,handles,hObject)
% Better:
function myTimerFcn2(TimerH2,eventData)
There is no need for a drawnow after creating a timer object. But after setting a string, drawnow is required to see the changes. A simplified timer callback:
function myTimerFcn2(TimerH2,eventData)
global distance2 flag_tracker
TextH2 = get(TimerH2, 'UserData');
if flag_tracker == 1
% distancia_fija = Guardar_pos3(TextH2); % Is this needed at all?
% pause(0.5)
set(TextH2, 'String', num2str(distance2))
else
set(TextH2, 'String', 'Measuring...');
end
drawnow;
  2 Comments
Carlos
Carlos on 29 Nov 2017
Dear Jan,
first of all, thank you for your quick answer. The GUI that I use is quiet complex and I share different variables in the whole program. For that, I use global variables. Anyway, thank you for your advice ;-) Sorry, I was mistaken. Since I work in Spain, I usually work with Spanish words. I have tried to translate these words, but I think it has been a bad idea. Please, let me show you the code again.
function myGUI(handles,hObject)
TimerH = timer('UserData', handles.text5, 'TimerFcn', @myTimerFcn, 'Period', 0.5, ...
'ExecutionMode', 'fixedRate');
drawnow;
TimerH2 = timer('UserData', handles.text9, 'TimerFcn', @myTimerFcn2, 'Period', 0.6, ...
'ExecutionMode', 'fixedRate');
drawnow;
start([TimerH TimerH2]);
function myTimerFcn(TimerH,eventData,handles,hObject)
global flag_tracker
if flag_tracker == 1
TextH = get(TimerH, 'UserData');
distancia = Guardar_pos(TextH);
set(TextH,'String',num2str(distancia))
drawnow();
else
TextH = get(TimerH, 'UserData');
set(TextH,'String','Measuring...');
end
function myTimerFcn2(TimerH2,eventData,handles,hObject)
global flag_tracker
if flag_tracker == 1
TextH2 = get(TimerH2, 'UserData');
distancia_fija = Guardar_pos3(TextH2);
set(TextH2,'String',num2str(distancia_fija))
drawnow();
else
TextH2 = get(TimerH2, 'UserData');
set(TextH2,'String','Measuring...');
end
The values distancia and distancia_fija are those I would like to show in the text boxes (handles.text5) and (handles.text9). Both values are double, so I do a cast previous to set the text boxes (num2str). My problem is that both text boxes don't change or refresh with the new values of distance and distance_fija. I mean the text box of myTimerFunc works but the text box of myTimerFunc2 doesn't refresh at all. In both text boxes, a starting value is set. Then, the timer functions should change the values of each text boxes according to the period. The text box 5 works perfectly but the text box 9 doesn't change this starting value.
I suppose my matlab code is not suitable to execute two timer functions
I look forward to your responses.
Thank you.
Jan
Jan on 30 Nov 2017
@Carlos: You observe that myTimerFcn2 does not change the contents of a specific text field. This can have different reasons:
  1. The timer is not running
  2. The string is changed, but always to the same number
  3. A different text field is accessed, perhaps hidden behind another one.
You can check these 3 problems using the debugger. Set a breakpoint inside myTimerFcn2, e.g. on the "if flag_tracker==1" line. Then start the code. Is the function entered at all? Then point 1 can be excluded. Step forward until distancia_fija is calculated. It looks strange, that you need the handle of the text field to calculate a distance. Is the expected value replied by Guardar_pos3()? IF so, point 2 is excluded. Now try to set the string of the field manually during the dbugging:
set(TextH2, 'String', 'Hello!')
Does it work? Then point 3 is not the problem also.
The only difference between the two callback function is "Guardar_pos" and "Guardar_pos3". If this difference could be avoided, you could use myTimerFcn as callback for both timer objects.
Some notes to the code (partially repeated):
  • In "myTimerFcn2(TimerH2,eventData,handles,hObject)" the variables "handles" and "hObject" are neither used nor defined. This is not a bug but confusing. But as soon as "handles" or "hObject" would be used, the code would crash. Prefer "myTimerFcn2(TimerH2,eventData)".
  • The drawnow is not called after setting the string to 'Measuring...'. Then this change might not be displayed. Move all redundant code out of the different IF-branches for clarity:
function myTimerFcn2(TimerH2,eventData)
global flag_tracker
TextH2 = get(TimerH2, 'UserData');
if flag_tracker == 1
distancia_fija = Guardar_pos3(TextH2);
set(TextH2,'String',num2str(distancia_fija))
else
set(TextH2,'String','Measuring...');
end
drawnow();
Leaner code without redundant commands offers less chances for typos and if the code must be changed, you do not have to apply the changes repeatedly, but once only, which is less prone to bugs.

Sign in to comment.

More Answers (0)

Categories

Find more on Code Execution in Help Center and File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!