Custom timer function timing query

I am trying to create a timer that accepts 3 inputs: An integer, and two floats representing times.
(input, time1, time2)
The timer will output, (we'll call it y), 1 if the input has been 1 for at least as long as the first time, and output 2 if the input has been 2 for at least as long as the second time. I have basically two levels of confirmation, where I need to know if my initial signal has been 1 long enough or 2 long enough. 1 and 2 are the only possibilities of input. The output, y, will start as 0. To describe the behavior a little more specifically, allow me to define two variables, t1 and t2.
t1 is true if the input has been 1 for at least as long as time1
t2 is true if the input has been 2 for at least as long as time2
And a quick logical chart:
t1 t2 y
0 0 No change
1 0 Set to 1
0 1 Set to 2
1 1 Not possible due to input being either 1 or 2
I need y to remain whatever it was for the 0 0 case. If t1 asserts and sets y to 1, but then t1 deasserts, I need y to remain as a 1.
Here is what I have so far:
function [y] = custom_timer(input, time1, time2)
y = 0; %y starts at 0
duration_1 = seconds(input == 1); %Set duration_1 to the number of seconds that input has equaled 1
duration_2 = seconds(input == 2);
if(duration_1 >= time1) %If we've been 1 long enough, set y to 1
y = 1;
elseif(duration_2 >= time2)
y = 2;
else
y = y; %Not really sure if I need this here, I just want Y to remain whatever it was if 0 0 case is met
end
end
When I set x to 1 directly, and the times to any arbitrary numbers, I always get y = 0. Is this because of the initial instantiation of y? Or is this due to my function not processing long enough for duration_1 to meet time1? If I comment out the initial instantiation of y entirely I get an error. I have also tried using the duration function instead of seconds but that gives me an error (duration(line 239)), so I switched to seconds(boolean) instead since I am measuring in seconds.
Eventually my input will not be just a number, it will be the output of some other function, and the value will change over time, it may be 1 for 10 seconds, and then be 2 for 30 seconds, etc.
Any help is appreciated, I have just started using Matlab and have little experience doing any other coding as well.

5 comentarios

madhan ravi
madhan ravi el 10 de Jul. de 2018
Maybe you can lookup tic toc function.
It's not really clear what it is you want to implement. Note that a timer is an object that executes a function at regular intervals. So strictly, speaking a timer does not have inputs or outputs (the function it executes has).
Assuming you were to use a timer to execute a function at regular intervals (what interval?), I'm still not clear how you'd use it. Where does the y go? What is the consumer of that output?
I think you need to explain a bit more the purpose of what you're trying to do.
----
y = y; %Not really sure if I need this here
Well of course, not. It does nothing.
Emerson Butler
Emerson Butler el 10 de Jul. de 2018
I guess strictly speaking it is just a function that needs to involve timing an input.
The original signal will be a 60Hz sinusoidal signal that is sampled at 240Hz (4 times per cycle, 1 cycle being 0.01667 seconds). The magnitude of this sinusoidal wave will be either 1 or 2. We have another function that will get the magnitude of this signal at that sampling frequency of 240Hz. That magnitude signal is what is getting fed into my function. So every 4.167 ms my input signal will update and possibly change from a 1 to a 2, or from a 2 to a 1, or remain at whatever value it was.
Basically I have been tasked with, given this magnitude input signal which will update every 4.167 ms, detect if the magnitude signal has been 1 for 5 seconds, or if the magnitude has been 2 for 3 seconds. The function should output a 0 at initialization, update to 1 if the input signal has been 1 for 5 seconds, update to 2 if the input signal has been 2 for 3 seconds, hold the previous signal if neither of those signals are met continuously. So If I get a 1 for 5 seconds, after those 5 seconds my function will output a 1 continuously, and will continue to output a continuous 1 signal until my input magnitude signal has been 2 for 3 seconds. Then my output signal would update to 2, and remain 2 continuously until the input signal has been 1 for 5 seconds. If the signal is never again a 1 for 5 seconds, it would just remain at 2.
Based on whether my function is outputting a 1 or a 2 (or a 0 as it would at the start) there is a machine that will adjust some things that may have an effect on the original sinusoidal wave. 1 is the optimal output, it means we have been stable at a 1 magnitude for a long enough time to meet our criteria. 2 is too high, so if my function is outputting a 2, then the machine will adjust various things to try to get back to the 1 output, but due to some high sensitivities, we need to be stable at these values for the set time before taking any possible corrective action.
Thank you for your help, hopefully I have been clear. I have to remain somewhat vague due to company confidentiality purposes.
Guillaume
Guillaume el 10 de Jul. de 2018
I don't think the details of the hardware matter nor the properties of the signal, so there's no need for you to break confidentiality.
So, if I understood correctly, your function would be called at regular interval by ... something. Is this something you've got sorted out or are you asking help with that?
What would be passed to the function, just the latest sample(s) or the whole signal? Would the function be passed the time since last call, should it work it out, or is it guaranteed to be constant?
Emerson Butler
Emerson Butler el 10 de Jul. de 2018
Yes, the function would be called at regular intervals, every 4.167 ms. To be frank, I need to do more research on modeling continuous systems. The function output would be read by another function at the same interval, every 4.167 ms. The only thing being passed to the function would be the latest sample, so I probably need to devise a way to store the previous x number of inputs (5 seconds @ 240 samples/second = 1200 previous inputs). Maybe I could use some kind of loop to do that. The function wouldn't be passed the time since last call, the whole system will be guaranteed an accurate 240Hz sampling frequency, so essentially the inputs and outputs would be updated every 4.167 ms.
I also would like to note that I am an intern, I have a long time to do this, and I just got started on this aspect. My boss has tasked me with modeling this system as a learning exercise, to learn about the system itself and Matlab as I go along. My actual output won't have any impact on anything this year, but it may next year when I try to implement my model on actual hardware. The questions you have asked so far have made me realize how much more I need to learn about the overall system. This function is just a small part of what I will be doing, but it all needs to fit together

Iniciar sesión para comentar.

 Respuesta aceptada

Guillaume
Guillaume el 10 de Jul. de 2018
Editada: Guillaume el 10 de Jul. de 2018
I probably need to devise a way to store the previous x number of inputs
That's fairly easy to do. It does not involve loops but persistent variables. However, I don't think you need to keep x previous samples. Just the last one and a running count of how long the signal has been the same. You'd reset the count each time the signal changes.
So it'll be something like:
function state = signal_counter(sample, dt)
%sample: current value of signal
%dt: time since last call. Since it's a constant, it could just be hardcoded in the function
persistent lastsample runningtime currentstate;
if isempty(lastsample)
%first call to function, initialise all variables
lastsample = 0;
runningtime = 0;
currentstate = 0;
end
if sample == lastsample
%signal has not changed, increase running time
runningtime = runningtime + dt;
else
%signal changed, reset running time
lastsample = sample;
runningtime = 0;
end
%update currentstate if given conditions are met otherwise, leave as is
if runningtime >= 3 && sample == 2
currentstate = 2;
elseif runningtime >= 5 && sample == 1
currentstate = 1;
end
state = currentstate; %you cannot use a persistent variable as output variable.
end
You may want to keep the running count in term of samples or accumulate frequency instead of period so everything is integer to avoid accumulation errors on floating point values

Más respuestas (0)

Productos

Versión

R2017a

Preguntada:

el 9 de Jul. de 2018

Editada:

el 10 de Jul. de 2018

Community Treasure Hunt

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

Start Hunting!

Translated by