0
$\begingroup$


I have a signal, in which i want to detect the period of the peaks, that exist within this signal: for example : After each 5mm or (5 seconds depending on the sampling rate and speed of my motor) i have a peak in my motor current.
I though of using the FFT, but then i had some problems with the sampling rate which lead me to look for the ununiform fft, but i wasnt very successfull.
I also tried using the Savitzky golay filter to smooth the data, since i read that it actually helps finding peaks within the signal, but not the period.
I tried appliying the FFT to the smoothed data, but I wasn't able to find any frequence.
So i was wondering is there is an algorithm that detects the periodicity of peaks within a signal.
this is the Normal Signal plot .
enter image description here


The signal in display(20mm/s) has been smoothed using the Savitzky golay filter, with a window of 51.
enter image description here

$\endgroup$
  • $\begingroup$ do you have a model for the peaks? which kind of signal is it? $\endgroup$ – LJSilver May 3 '16 at 9:38
  • $\begingroup$ Any feedback on my answer? $\endgroup$ – Peter K. Aug 31 '16 at 12:52
1
$\begingroup$

Before applying the algorithm below, you should first apply a DC blocking filter. That should remove the DC offset (and partially the step at the beginning), which will allow more usual periodicity techniques to be used.


You can try using the average square difference function. There is a nice write up on this answer and a way to implement it in an efficient manner here.

Here's an example plot. The $\color{red}{\bf red}$ circle shows the selected minimum. Note how the "octave" problem shows up: if the signal is periodic with period $P$, it's also periodic with period $N P$ where $N$ is an integer.

enter image description here


R Code Below

#30511

pulse <- 16 - seq(-4,4)^2
len <- length(pulse)

T <- 1000
P <- 49

ix <- seq(1,T - len, P)

data <- rep(0,T)

for (this_one in ix)
{
  data[this_one + seq(0,len-1)] <- pulse
}

data <- data #+ rnorm(T,0,1)

plot(data, type="l")

asdf <- function(data, Pmax)
{
  N <- length(data)
  asdf <- rep(0,Pmax)
  for (p in seq(1,Pmax))
  {    
    ix <- seq(p+1,N)
    asdf[p] <- sum((data[1:length(ix)] - data[ix])^2)
  }

  return(asdf)
}

calc <- asdf(data, 5*P)

par(mfrow=c(2,1))
plot(data, type="l")
title('Repeating pulses')

plot(1:(5*P), calc, type="l")
period <- which.min(calc)
points(P, calc[P], col="grey", lwd = 12)
points(period, calc[period], col="red", lwd = 5)
title('ASDF')
$\endgroup$
  • $\begingroup$ Peter, I have never seen that SO post regarding a "fast" ASDF. i don't know what the difference is between x1 and x2. $\endgroup$ – robert bristow-johnson Jan 29 '17 at 3:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.