Author Topic: Peak detection find algorithm  (Read 1824 times)

0 Members and 1 Guest are viewing this topic.

Offline rvalenteTopic starter

  • Frequent Contributor
  • **
  • Posts: 722
  • Country: br
Peak detection find algorithm
« on: October 20, 2021, 04:03:55 pm »
Hello Mates,

I'm looking for a better way to detect peaks in a signal sample

The signal is a sinusoidal from VR sensor and tone ring wheel with 40 to 140 teeth, the output frequency is from 40 to 200Hz, this signal is then rectified (80 to 400Hz) and sampled in the uC ADC, 12bits, 0 to 5V.

The sample rate is adjusted so 1.2 revolutions of the tone ring can be captured. Usually the tone ring has 100 teeth and the algorithm finds 239 to 240 Peaks, which is correct

The current algorithm is pretty simple it basically looks for a number of consecutive signal samples which are bigger than the previous, if not the increments the "fall" counter, when the fall counter is a given number (8 by now) is the peak is saved to a array. As the sample rate is now 20 times the non rectified frequency the number 8 for the fall counter works just fine.

The thing is: this works but, I feel I need to make it better, I'd like to have this fall number self adjusted or to find a better and proven peak detection algorithm

Anyway, I'd like some suggestions from you guys

Code: [Select]
///////// SEARCH FOR SIGNAL PEAKS /////////
for(point=0; point<samples; point++)
{
if(buffer[point] > buffer[point-1])
{
fall = 0;
pointBuffer = point;
}
else
{
fall++;
if(fall == FALLS) //This FALLS constant is set to 8, I'd like it to be adjustable
{
if (peaks < expectedPeaks && firstPeak)
{//Make sure the array wont be overwritten
peakArray[peaks] = buffer[pointBuffer]; //Salva posição do pico
timeArray[peaks] = pointBuffer; //Salva tempo do pico na posição
peaks++;
}
firstPeak = 1; //Set first peak has passed already, save later peaks
if (peaks >= expectedPeaks)
{//Check for excessive readings
eturn(EXCESSIVE_PEAKS);
}
}
}
}
 

Offline ledtester

  • Super Contributor
  • ***
  • Posts: 3032
  • Country: us
Re: Peak detection find algorithm
« Reply #1 on: October 20, 2021, 04:31:51 pm »
The algorithm you use might depend on the kind of data you expect to collect.

This one might be worth trying out:

https://stackoverflow.com/questions/22583391/peak-signal-detection-in-realtime-timeseries-data
 
The following users thanked this post: rvalente

Online SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14309
  • Country: fr
Re: Peak detection find algorithm
« Reply #2 on: October 20, 2021, 05:32:32 pm »
As I see it, the algorithm you're using is more or less equivalent to low-pass filtering the signal and then determining a local maximum from the numeric derivative's sign change.

Of course the approach to use all depends on your requirements. One issue with the one you use is that, while trying to avoid local peaks from noise, it's also less time-accurate.

There's a bunch of articles on peak detection out there. Probably more than you'll have time to read.
One way I know of smoothing data while not having the drawbacks of simple low-pass filtering (/moving averages/...) is to use Savitzky–Golay filters. https://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter
I've used that successfully.

There are more efficient approaches as well. Probably you should first determine what exactly your requirements are:
- what you consider a valid 'peak' in the signals you're dealing with;
- what kind of noise you're expecting;
- what you expect in terms of time accuracy for peak detection.
 
The following users thanked this post: rvalente

Offline rvalenteTopic starter

  • Frequent Contributor
  • **
  • Posts: 722
  • Country: br
Re: Peak detection find algorithm
« Reply #3 on: October 20, 2021, 06:55:58 pm »
Hello mates,

you've given a buch of useful information, I'm already studying.

Would you have some code to share?
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5835
  • Country: es
Re: Peak detection find algorithm
« Reply #4 on: October 20, 2021, 07:04:38 pm »
Edit: I wrote this thinking you wanted to get rid of the spikes.
But it can be useful too. o exactky this to have a clean, spikes-less signal.
Apply new readings to the EMA filtering, then compare the reading with the updated EMA value.
Now you can apply any threshold/percentage you want to consider the reading a spike or not.

You can make a simple EMA fitering, you'll get some delay but much cleaner signal.
https://www.norwegiancreations.com/2016/08/double-exponential-moving-average-filter-speeding-up-the-ema/

The basic EMA code implementation is:
Code: [Select]

  #define k 0.5f                             // coefficient. 0=use 0% of new, 100% of old(won't update) . 1=100% of new, 0% of old(no filtering).
                                             // Play with the coefficient to find the best value.
static float stored_ema;                     // Stored average

void reset_ema(uint32_t new_read){
  stored_ema = new_read;                     // Some times you'll need this to avoid the initial delay, as the average needs to build up (ex. first ADC reading).
}

uint32_t ema(unt32_t new_read){ 
  stored_ema= (1.0-k)*stored_ema+ k*new_read;
  return stored_ema;
}

Also, you can apply a pre-filter. As I see in your waveforms, there're quite a lot of spikes. If you don't want them, simply use a threshold a window.
You know the signal is supossed to change progressively, so any reading that exceeds ex. 10% of last reading could be ignored.
That and a small EMA filtering for the high frequency changes will clean the signal a lot.
« Last Edit: October 20, 2021, 07:26:07 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline rvalenteTopic starter

  • Frequent Contributor
  • **
  • Posts: 722
  • Country: br
Re: Peak detection find algorithm
« Reply #5 on: October 20, 2021, 07:14:59 pm »
Are you expecting to measure those high spikes, or do you want to remove them?
Your average signal has slow transitions, so you know that at any given time, the readign shpuld be much different from the last one.
So allow ex. 10% of changes between readings, and discard those not meeting this.

I need to read the high spikes, they're the defect I'm want to detect (a teeth defect in the tone ring).
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5835
  • Country: es
Re: Peak detection find algorithm
« Reply #6 on: October 20, 2021, 08:19:13 pm »
Following my post: I took an excel sheet I made long time ago for my T12 firmware.
It lets you see how the EMA/DEMA and filtering works, apply random noise, change the filter constant... not reinventing the wheel here but could help.

This looks interesting: If you split the signal into low and high frequencies, you'll get your peak noise:
https://stackoverflow.com/questions/7105962/how-do-i-run-a-high-pass-or-low-pass-filter-on-data-points-in-r

Digital filtering is not my field...
« Last Edit: October 20, 2021, 08:45:08 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: rvalente

Offline rvalenteTopic starter

  • Frequent Contributor
  • **
  • Posts: 722
  • Country: br
Re: Peak detection find algorithm
« Reply #7 on: October 21, 2021, 09:55:43 am »
Following my post: I took an excel sheet I made long time ago for my T12 firmware.
It lets you see how the EMA/DEMA and filtering works, apply random noise, change the filter constant... not reinventing the wheel here but could help.

This looks interesting: If you split the signal into low and high frequencies, you'll get your peak noise:
https://stackoverflow.com/questions/7105962/how-do-i-run-a-high-pass-or-low-pass-filter-on-data-points-in-r

Digital filtering is not my field...

The signal is not really noisy, not that it seems to bother. What I really wanna improve is the peakArray detection algorithm. any tips on that?
 

Offline JOEBOBSICLE

  • Regular Contributor
  • *
  • Posts: 63
  • Country: gb
Re: Peak detection find algorithm
« Reply #8 on: October 21, 2021, 04:02:50 pm »
Sounds like you could label up some data and use it to train a LSTM neural network. Sometimes this is easier than figuring out a classical algorithm
 

Offline profdc9

  • Frequent Contributor
  • **
  • Posts: 318
  • Country: us
Re: Peak detection find algorithm
« Reply #9 on: October 21, 2021, 09:27:58 pm »
If you have the processing power, you can run a running median filter over the time series to get rid of outliers, decimate the sequence, and keep the samples as peaks where a sample is greater than its two neighbors.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf