Timer doesn't display only once
Show older comments
Hello! I am a begginer in Matlab. I am trying to control a wheelchair by eye tracking. I need to stop and start the system by forced blinking.
The code displays 'Blink' if the blink takes longer than 3 seconds, but I need to display it only once, no matter how much the 3 second deadline is exceeded! I don't know how to do this. If I blink for 5-6 seconds, for example, the program displays 'Blink' continuously for 3-4 times.
if SkinPerc >=90
t = timer;
t.StartDelay = 3;
t.ExecutionMode='singleShot';
t.TasksToExecute=1;
t.TimerFcn = @(myTimerObj, thisEvent)disp('Blink');
start(t)
3 Comments
Ameer Hamza
on 29 Apr 2020
The question description is not clear. Are you saying that the TimerFcn runs multiple times, even though the ExecutionMode is singleShot?
Delia Dragusin
on 29 Apr 2020
Edited: Delia Dragusin
on 29 Apr 2020
Ameer Hamza
on 29 Apr 2020
That is not the documented behavior of singleShot ExecutionMode. Maybe you can try the code in my answers, which explicitly deletes the timer after execution.
Answers (2)
Ameer Hamza
on 29 Apr 2020
You can write you timer callback such that it will automatically delete the timer object after it runs once.
t = timer;
t.StartDelay = 3;
t.ExecutionMode='singleShot';
t.TimerFcn = @timerCB;
start(t)
function timerCB(myTimerObj, thisEvent)
disp('Blink')
stop(myTimerObj);
delete(myTimerObj);
end
4 Comments
Delia Dragusin
on 30 Apr 2020
Ameer Hamza
on 30 Apr 2020
How have you defined timerCB? The easiest way is to include the function definition at the very end of your file. The other way is to create a file named timerCB.m and place the function definition
function timerCB(myTimerObj, thisEvent)
disp('Blink')
stop(myTimerObj);
delete(myTimerObj);
end
inside the file.
Delia Dragusin
on 30 Apr 2020
Ameer Hamza
on 30 Apr 2020
If this solution is not working, then I guess the Walter pointed you in the right direction. The condition SkinPerc >=90 is true in several loop iterations, which creates a new timer object in each iteration.
Walter Roberson
on 29 Apr 2020
Your code is starting a new 3 second timer every time it finds SkinPerc >=90 . It is not the case that each individual timer is repeating multiple times: instead you have multiple timers going.
I suggest that you store a variable in an accessible location, and when you find SkinPerc >=90, check to see if the variable is already set; if it is, then skip creating a timer. If the variable is clear, then set the variable true and create the timer and start it. One of the things the timer should do is clear the variable. For information on how to share variables see
http://matlab.wikia.com/wiki/FAQ#How_can_I_share_data_between_callback_functions_in_my_GUI.28s.29.3F
However, it looks to me as if you are approaching this wrong. Instead, I would suggest that you use a structure such as
in_blink = false;
blink_recorded = false;
blink_start_time = tic;
...
if SkinPerc >=90
if in_blink
if ~blink_recorded & toc(blink_start_time) > 3
disp('Blink')
blink_recorded = true;
end
else
in_blink = true;
blink_recorded = false;
blink_start_time = tic;
end
else
in_blink = false;
end
8 Comments
Delia Dragusin
on 30 Apr 2020
Walter Roberson
on 30 Apr 2020
This code expects that you are looping reading values that get converted into SkinPerc readings, and assumes that SkinPerc >= 90 is the indicator for "blink started", and that it will continue to be true continuously for several iterations of the loop, including for more than 3 real-time seconds.
These are all guesses on my part as to how your code really functions.
For example, my code is not designed to (for example) measure eyelid height with the idea that some particular pattern of heights for a particular time is "blinking". The code assumes that SkinPerc (whatever that is) is continually true for 3 seconds or more in order as the case to display Blink.
Delia Dragusin
on 30 Apr 2020
Edited: Delia Dragusin
on 30 Apr 2020
Walter Roberson
on 30 Apr 2020
Sorry, I am too busy with volunteering to take on a private consulting contract at this time (code sent to me privately is a private consulting contract). If you post the code publicly here I will look at it later (after I sleep.)
Delia Dragusin
on 30 Apr 2020
Edited: Delia Dragusin
on 30 Apr 2020
Steven Lord
on 30 Apr 2020
You could try creating the timer (but leaving it stopped) well before you run whatever code you have that loops and polls for the blink. When you detect a blink, start the timer. If the blink ends before the timer's StartDelay finishes, stop it. Otherwise let it execute its TimerFcn and return to being stopped.
This would avoid the need to check if the timer exists, since it always will exist. It just may not be actively running.
Walter Roberson
on 1 May 2020
What is the difference between a blink that lasts more than 3 seconds, compared to closing the eyes for more than 3 seconds?
"Blink" is usually considered a fast process, 100 ms typically and up to 400 ms. Someone could deliberately hold their eyes closed for 3 seconds, or someone could deliberately repeatedly blink for 3 seconds, but the repeated blink option involves a pattern of SkinPerc going above and below 90.
The code I posted already deals with the "deliberately closed for 3 seconds" possibility. If you want the "blink repeatedly" possibility, then you need to define a time period with no blink that is considered to stop the pattern. People blink roughly every 3 to 4 seconds normally, so just noticing two blinks within a 3 second interval is probably not reliable enough.
If the pattern is a certain number of blinks within a particular time (3 seconds) then should the action be registered when the last of that particular number of blinks happens, or should the action be deferred until the timer interval expires? Deferring the action would allow for the possibility of defining more blinks as meaning something different, or the possibility of a cancel action (such as closing the eyes for a particular time) being defined.
per isakson
on 1 May 2020
Before trying to fix the problems see: Debug a MATLAB Program
After the line
if SkinPer>=90
add the statement
disp('A timer will be created')
and run the code
Categories
Find more on Startup and Shutdown 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!