How do i count the signal within a certain time interval?

the signal shows 1s and 0s. i want to be able to count the 1s with a certain time interval and if it is above a certain figure another signal will show 1 for that time interval.
i want it to go from this to this

 Accepted Answer

One option is to use the movsum function, and then threshold the result —
t = linspace(0, 100, 100);
s = rand(100,1)>0.80; % Create Pulse Data
ms = movsum(s,[2 2]); % Original
d = movsum(s,[2 2]) >= 3.0; % Using Threshold
figure
stem(t,s,'.')
hold on
plot(t, d, '-r', 'LineWidth',2)
plot(t, ms)
hold off
grid
ylim([0 4])
legend('Pulse Signal','‘movsum’ With Threshold','Original ‘movsum’', 'Location','best')
It will likely be necessary for you to refine this to get the result you want.
.

8 Comments

i got this error "Undefined function 'movsum' for input arguments of type 'double'" what do i do
.
The movsum function was introduced in R2016a.
One option is to upgrade (that has many advantages beyond getting the movsum function), another could be to use the filter function:
ms = filter(ones(1,5),1, s);
That will not completely replace the movsum code I posted (it does not have the same behaviour with respect to the bracketed interval, since it is the same as movsum(s,5), not movsum(s,[2 2])), however in the absence of movsum, it is likely the only option.
It works but when i implement in my simulink i get this error
Function 'filter' is not defined for values of class 'logical'.
Interesting, because it works correctly with the logical array I created to test it (in R2022a).
Putting a ‘+’ (unary positive) before the ‘s’ argument will convert it to a double value:
ms = filter(ones(1,5),1, +s);
That should work (and worked when I tested it).
.
now the problem is the function does not show results , could it be because the input data is a timeseries data?
That could be the problem. I have no experience with timeseries arrays. I have never needed to use them.
It may be worthwhile to convert it to a timetable (introduced in R2016a), at least for the purposes of your current project, however if you do not have movsum, you also will not have timetable.
Perhaps converting it to a table temporarily would work, or to an array.

Sign in to comment.

More Answers (1)

hello
below a demo code that look for crossing point between a chirp signal. We detect both the positive and negative slope crossing points (rising / falling signal) and compute the time interval between rising and falling sides
i added a test to show / store only those intervals that comply with min and max values
those points have a black diamond marker on top of the star markers (those shows all crossing points)
the lower subplot is the display of the computed time intervals
you can easily adapt the code to your needs
% dummy data
n=1000;
x= 10*(0:n-1)/n;
y = sin(x.^2);
threshold = max(y)*0.25; % your value here
[t0_pos,s0_pos,t0_neg,s0_neg]= crossing_V7(y,x,threshold,'linear'); % positive (pos) and negative (neg) slope crossing points
% ind => time index (samples)
% t0 => corresponding time (x) values
% s0 => corresponding function (y) values , obviously they must be equal to "threshold"
% periods
period = (t0_neg - t0_pos); % time delta
t_period = (t0_neg + t0_pos)/2; % time value (plot) = mid point
% select valid period values in a range
lower_limit = 0.25;
uper_limit = 0.75;
ind = find(period>=lower_limit & period<=uper_limit);
figure(1)
subplot(2,1,1),plot(x,y,'b',t0_pos,s0_pos,'*r',t0_neg,s0_neg,'*g',t0_pos(ind),s0_pos(ind),'dk',t0_neg(ind),s0_neg(ind),'dk','linewidth',2,'markersize',12);grid on
xlim([min(x) max(x)]);
legend('signal','signal positive slope crossing points','signal negative slope crossing points');
subplot(2,1,2),plot(t_period,period,t_period(ind),period(ind),'dk','linewidth',2,'markersize',12);grid on
xlim([min(x) max(x)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [t0_pos,s0_pos,t0_neg,s0_neg] = crossing_V7(S,t,level,imeth)
% [ind,t0,s0,t0close,s0close] = crossing_V6(S,t,level,imeth,slope_sign) % older format
% CROSSING find the crossings of a given level of a signal
% ind = CROSSING(S) returns an index vector ind, the signal
% S crosses zero at ind or at between ind and ind+1
% [ind,t0] = CROSSING(S,t) additionally returns a time
% vector t0 of the zero crossings of the signal S. The crossing
% times are linearly interpolated between the given times t
% [ind,t0] = CROSSING(S,t,level) returns the crossings of the
% given level instead of the zero crossings
% ind = CROSSING(S,[],level) as above but without time interpolation
% [ind,t0] = CROSSING(S,t,level,par) allows additional parameters
% par = {'none'|'linear'}.
% With interpolation turned off (par = 'none') this function always
% returns the value left of the zero (the data point thats nearest
% to the zero AND smaller than the zero crossing).
%
% check the number of input arguments
error(nargchk(1,4,nargin));
% check the time vector input for consistency
if nargin < 2 | isempty(t)
% if no time vector is given, use the index vector as time
t = 1:length(S);
elseif length(t) ~= length(S)
% if S and t are not of the same length, throw an error
error('t and S must be of identical length!');
end
% check the level input
if nargin < 3
% set standard value 0, if level is not given
level = 0;
end
% check interpolation method input
if nargin < 4
imeth = 'linear';
end
% make row vectors
t = t(:)';
S = S(:)';
% always search for zeros. So if we want the crossing of
% any other threshold value "level", we subtract it from
% the values and search for zeros.
S = S - level;
% first look for exact zeros
ind0 = find( S == 0 );
% then look for zero crossings between data points
S1 = S(1:end-1) .* S(2:end);
ind1 = find( S1 < 0 );
% bring exact zeros and "in-between" zeros together
ind = sort([ind0 ind1]);
% and pick the associated time values
t0 = t(ind);
s0 = S(ind);
if ~isempty(ind)
if strcmp(imeth,'linear')
% linear interpolation of crossing
for ii=1:length(t0)
%if abs(S(ind(ii))) >= eps(S(ind(ii))) % MATLAB V7 et +
if abs(S(ind(ii))) >= eps*abs(S(ind(ii))) % MATLAB V6 et - EPS * ABS(X)
% interpolate only when data point is not already zero
NUM = (t(ind(ii)+1) - t(ind(ii)));
DEN = (S(ind(ii)+1) - S(ind(ii)));
slope = NUM / DEN;
slope_sign(ii) = sign(slope);
t0(ii) = t0(ii) - S(ind(ii)) * slope;
s0(ii) = level;
end
end
end
% extract the positive slope crossing points
ind_pos = find(sign(slope_sign)>0);
t0_pos = t0(ind_pos);
s0_pos = s0(ind_pos);
% extract the negative slope crossing points
ind_neg = find(sign(slope_sign)<0);
t0_neg = t0(ind_neg);
s0_neg = s0(ind_neg);
else
% empty output
ind_pos = [];
t0_pos = [];
s0_pos = [];
% extract the negative slope crossing points
ind_neg = [];
t0_neg = [];
s0_neg = [];
end
end

Community Treasure Hunt

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

Start Hunting!