How to extract time period of sensor signals

3 views (last 30 days)
Hai Lee
Hai Lee on 10 May 2022
Commented: Mathieu NOE on 12 May 2022
I have current profiles from a sensor. I want to extract a table of how long the sensors has been on at each period. How can I extract this from the data?
Hai Lee
Hai Lee on 11 May 2022
I tried this:
% open data file
close all;
% read in data
readData=textscan(fid, '%f %f','HeaderLines',1,'Delimiter',',');
%extract data from readData
%plot data
cla; hold on; grid on;
%find peaks, apply minimum distance between 2 peaks
%[pks, locs]=findpeaks(current,'MinPeakDistance',400,'MinPeakHeight',20000');
[pks, locs, w]=findpeaks(current,'MinPeakDistance',400,'MinPeakHeight',20000');
yyaxis left
ylabel('current consumption[uA]')
%plot(time, current);
plot(time, current, '-',time(locs),pks,'or');
% plot on secondary axis the FWHM of each peak
yyaxis right
ylabel('FWHM[seconds] of each peak')
ylim([0 100])
It worked patially:
(1) sometimes there are 2 peaks instead of 1
(2) FWHM sometimes doesnot capture the square signal when the peaks are too sharp.
I've attached the data file.

Sign in to comment.

Answers (1)

Mathieu NOE
Mathieu NOE on 11 May 2022
see my demo below - for constant and non constant frequency signals. the last plot shows the time diffeence between the rising and falling side of the signals - test it with your data and adapt the threshold value.
NB : the crossing point time values are obtained by linear interpolation , so it has better time accuracy as simply finding the nearest sample of the measured data;
hope it helps !
% dummy data
x= 10*(0:n-1)/n;
y1 = sin(6*x -0.5);
y2 = sin(x.^2 -0.5);
threshold = max(y1)*0.75; % your value here
[t0_pos1,s0_pos1,t0_neg1,s0_neg1]= crossing_V7(y1,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"
[t0_pos2,s0_pos2,t0_neg2,s0_neg2]= crossing_V7(y2,x,threshold,'linear'); % positive (pos) and negative (neg) slope crossing points
% periods
period1 = (t0_neg1 - t0_pos1); % time delta
t_period1 = (t0_neg1 + t0_pos1)/2; % time value (plot) = mid point
period2 = (t0_neg2 - t0_pos2); % time delta
t_period2 = (t0_neg2 + t0_pos2)/2; % time value (plot) = mid point
subplot(3,1,1),plot(x,y1,'b',t0_pos1,s0_pos1,'dr',t0_neg1,s0_neg1,'dg','linewidth',2,'markersize',12);grid on
legend('signal','signal positive slope crossing points','signal negative slope crossing points');
subplot(3,1,2),plot(x,y2,'b',t0_pos2,s0_pos2,'dr',t0_neg2,s0_neg2,'dg','linewidth',2,'markersize',12);grid on
legend('signal','signal positive slope crossing points','signal negative slope crossing points');
subplot(3,1,3),plot(t_period1,period1,t_period2,period2,'linewidth',2,'markersize',12);grid on
legend('signal 1 period','signal 2 period');
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
% 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!');
% check the level input
if nargin < 3
% set standard value 0, if level is not given
level = 0;
% check interpolation method input
if nargin < 4
imeth = 'linear';
% 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;
% 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);
% empty output
ind_pos = [];
t0_pos = [];
s0_pos = [];
% extract the negative slope crossing points
ind_neg = [];
t0_neg = [];
s0_neg = [];

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!