0
votes

How can I get filtered first derivative from a noisy signal that has slowly changing slope in form of y=kx+b? k can slowly change in time, and I want to estimate its value.

slope noise

I have tried 3 different approaches:

  1. Take derivative as dx(i) = (x(i)-x(i-99))/100
  2. Smooth with sliding mean window = 100, then take derivative as dx(i) = (x(i)-x(i-99))/100
  3. Simple IIF filters (e.g. y(i) = 0.99*y(i-1) + 0.01*x(i), then take derivative as dx(i) = y(i)-y(i-1) and again filter with similar IIR, e.g. dy(i) = 0.95*dx(i-1) + 0.05*dx(i)

Problems:

  1. Least-squares, regression and FIR filters (except rectangular window) have high computational cost, since I have to translate it to micro-controller with no DSP. That is why I can use only rectangular windows and IIR filters (they have low order).
  2. If I find first derivative first, then smooth, it will be very noisy. So, I should smooth the original signal first, then find derivative from smoothed signal (and perhaps smooth the derivative again!).
  3. I should play with filter parameters manually and it is hard to understand the frequency response of the whole system.

Question:

Maybe there is a single special (optimal?) IIR filter for this specific problem - finding smoothed first derivative from signal with noisy slope?

2
isnt this question about signal-processing only (ie not about code / C++) ? Not sure, but I would guess that there is a better place for the question.463035818_is_not_a_number
You could use the RANSAC algorithm. Performant and easy to integrate.Patrick Hart

2 Answers

0
votes

Perform a linear least squares fit of the data (or parts of the data if it is slowly varying), i.e., y=a*x+b. Then a is an approximation of the derivative you are looking for.

0
votes

Generally you get the instantaneous derivative x(i)-x(i-1) and then apply a standard IIR low-pass filter from here: https://www.mathworks.com/help/signal/ug/iir-filter-design.html

It does not matter what order you perform these operations in, since the result is exactly the same either way.

You can merge the two operations into a single IIR filter by applying your derivative operation to the b array that you get back from matlab, but that will increase the array length by 1 and won't save you any time when you translate it to code for your microcontroller. In fact, you'll probably separate it out again in the implementation anyway.

On the microcontroller, you will probably want to do the derivative operation first, since that will probably result in a signal with less amplitude, which reduces the chance of clipping.