Zero detection in online signal
8 views (last 30 days)
Show older comments
Hi.. I am acquiring a signal from an EEG from a matlab script. I know approximatly the frequency of the signal (0.5Hz to 4 Hz).
I need to play a sound when the signal does a negative zero crossing. So I need to detect the correct instant to fire the audio in real ltime.
500 samples make 1 second of the signal.
I would have to band pass the signal to remove high frequencies (otherwhise, it could incur spurious zero crossing). For example, I could band pass 10 samples (which would take me 20 ms ) .
%s - > acquired signal (10 samples)
x = filter (s) % x is the bandpassed signal
for ii = 1:10
if (x(ii-1) > 0 && x(ii) < 0 ) % lets say that this happend for the fifth element of x (ii = 5)
sound('pinknoise.wav')
end
end
I tought about using the following as a filter because it has linear delay.
%%%%%
h = fdesign.bandpass('fst1,fp1,fp2,fst2,ast1,ap,ast2', Fstop1, Fpass1, Fpass2, Fstop2, Astop1, Apass, Astop2, Fs);
Hd = design(h, 'equiripple', 'MinOrder', 'any');
y = filter(Hd,x);
%%%%%
However, I am not sure about the delay that the filter would introduce. It Introduces a phase shift (delay) of 2 samples. Therefore is it correct to say that the negative zero crossing happened at the (5 - 2) third element of s?
How to get this delay? Is this zero cossing algorithm reasonable? Are there otherS best than this one?
Best
0 Comments
Answers (1)
Jon
on 8 Nov 2023
Edited: Jon
on 8 Nov 2023
Your filtering idea, could probably be made to work. As an alternative, you might consider the use of a Schmidt trigger, to "debounce" the signal. It is extremely simple. You would adjust the lower threshold to be large enough to avoid false triggers.
Even with this approach there will be a tradeoff between false alarms, and the delay to detect them. With a large threshold and a slowly descending signal there will be a some samples of delay between the true zero crossing and when the lower threshold is crossed, and the trigger event occurs.
If you aren't familiar with Schmidt triggers you can Google them, and find lots of references.
Here's a rough example:
% Parameters
aNoise = 0.1; % noise amplitude
f = 1; % example signal frequency [Hz]
a = 3; % example signal amplitude
numCycles = 10; % number of signal cycles
fsmpl = 100; % sampling frequency [Hz]
xLower = 0.3; % Lower Schmidt Threshold
xUpper = 0; % Upper Schmidt Threshold
% Generate noisy signal
T = 1/f; % signal period
Tsmpl = 1/fsmpl;
t = 0:Tsmpl:numCycles*T;
x = a*sin(2*pi/T*t) + aNoise*randn(size(t));
% Loop through signal values one sample at a time to simulate real time
% application
val = zeros(size(t));
soundOn = zeros(size(t));
prevVal = 0;
for k = 1:numel(x)
% Pass signal through Schmidt Trigger
val(k) = schmidt(x(k),xLower,xUpper);
% Check if this was a zero crossing (schmidt changed state)
if (val(k) - prevVal) > 0
soundOn(k) = 1;
end
prevVal = val(k);
end
% Plot results
plot(t,x,t,val,t,soundOn,'o')
grid
legend('signal','schmidtState','soundOn')
function val = schmidt(x,xLower,xUpper)
persistent isNeg % trigger state
% initialize
if isempty(isNeg)
isNeg = false;
end
if x <= xLower && ~isNeg
isNeg = true;
end
if x > xUpper && isNeg
isNeg = false;
end
% Compute output signal, as zero or 1 numerical value
val = double(isNeg);
end
16 Comments
Jon
on 14 Nov 2023
Before getting to the details of that, what is the signal that you are applying the Schmidt trigger to?
In my example of applying a Schmidt trigger, I have assumed that the input signal is varying about zero, and you are looking for where it crosses zero. You could also have a signal that varied about some other constant and subtract off that constant to transform it to a zero crossing problem. In any case it was not intended for a ramp signal such as the one you attached. Have you found a way to first "detrend" the data, so you now have a signal that varies above and below some constant value, rather than a ramp signal as you now have?
See Also
Categories
Find more on Frequency Transformations in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!