views:

1821

answers:

4

I'm sampling a real-world sensor, and I need to display it's filtered value. The signal is sampled at a rate of 10Hz and during that periode it could rise as much as 80 per cent of the maximum range.

Earlier I've used Root Mean Square as a filter and just applying it to the last 5 values I've logged. For this application this wouldn't be good because I don't store unchanged values. In other word, I need to consider time in my filter...

I've read at DSP Guide but I didn't get much out of it. Is there a tutorial that's pinned specifically at programmers, and not Mathcad engineers? Any simple code snippets that could help me?

Edit: After several spreadsheet tests I've taken the executive decision to log all samples, and apply a Butterworth filter.

+2  A: 

I don't have a tutorial that will help you, but in C# you may want to consider using reactive linq: http://tomasp.net/blog/reactive-ii-csevents.aspx

as a way to get the events, so you can do your processing without having to store all the values. It would just do the processing as you get the next event in.

To consider time you could just use an exponential with a negative exponent to decrease the impact of the past measurements.

James Black
+1 for the link, seems to be a very nice idea. However, it seems a bit out-of-context for his actual problem... For me it seems his main problem is that he only stores changes, not signal over time, where for his calculation he would need the latter. Storing the time or changing the logging itself would probably suffice.
gimpf
It seems that he wants to keep one value, but to add time to it the value needs to decrease before adding in the new value. This will reduce older values more, over time, and by using reactive linq he can better have one algorithm that will do what he needs.
James Black
A: 

these guys seem on it http://www.mitov.com/html/signallab.html I believe their tutorials have sample snipps if nothing else

- take care & BOL

puddler
Can't see how this page relates to anything relevant for this question beside having signal processing placed all over it.
gimpf
+1 the link is to a component that the asker could use in a C# application to do DSP. Totally relevant to the the question.
MusiGenesis
+4  A: 

You always need to store some values (but not necessarily all input values). A filter's current output depends on a number of input values and possibly some past output values.

The simplest filter would be a first order Butterworth low-pass filter. This would only require you to store one past output value. The (current) output of the filter, y(n) is:

y(n) = x(n) - a1 * y(n-1)

where x(n) is the current input and y(n-1) is the previous output of the filter. a1 depends on the cut-off frequency and the sampling frequency. The cut-off frequency frequency must be less than 5 Hz (half the sampling frequency), sufficiently low to filter out the noise, but not so low that the output will be delayed with respect to the input. And of course not so low that the real signal is filtered out !

In code (mostly C#):

double a1 = 0.57; //0.57 is just an example value.
double lastY = 0.0;
while (true)
{
    double x = <get an input value>;

    double y = x - a1 * lastY;
    <use y somehow>
    lastY = y;   
}

Whether a first order filter is sufficient depends on your requirements and the charactetistics of the input signal (a higher order filter may be able to supppress more of the noise at the expense of higher delay of the output signal).

For higher order filters more values would have to be stored and the code becomes a little bit more complicated. Usually the values need to be shifted down in arrays; in an array for past y values and in an array for past x values.

Peter Mortensen
+2  A: 

In DSP, the term "filter" usually refers to the amplification or attenuation (i.e. "lowering") of frequency components within a continuous signal. This is commonly done using Fast Fourier Transform (FFT). FFT starts with a signal recorded over a given length of time (the data are in what's called the "time domain") and transforms these values into what's called the "frequency domain", where the results indicate the strength of the signal in a series of frequency "bins" that range from 0 Hz up to the sampling rate (10 Hz in your case). So, as a rough example, an FFT of one second's worth of your data (10 samples) would tell you the strength of your signal at 0-2 Hz, 2-4 Hz, 4-6 Hz, 6-8 Hz, and 8-10 Hz.

To "filter" these data, you would increase or decrease any or all of these signal strength values, and then perform a reverse FFT to transform these values back into a time-domain signal. So, for example, let's say you wanted to do a lowpass filter on your transformed data, where the cutoff frequency was 6 Hz (in other words, you want to remove any frequency components in your signal above 6 Hz). You would programatically set the 6-8 Hz value to zero and set the 8-10 Hz value to 0, and then do a reverse FFT.

I mention all this because it doesn't sound like "filtering" is really what you want to do here. I think you just want to display the current value of your sensor, but you want to smooth out the results so that it doesn't respond excessively to transient fluctuations in the sensor's measured value. The best way to do this is with a simple running average, possibly with the more recent values weighted more heavily than older values.

A running average is very easy to program (much easier than FFT, trust me) by storing a collection of the most recent measurements. You mention that your app only stores values that are different from the prior value. Assuming you also store the time at which each value is recorded, it should be easy for your running average code to fill in the "missing values" by using the recorded prior values.

MusiGenesis
You are correct, I do not want to mess with FFT. I don't mind math or anything, but when I see a FFT implementation (or function) I get a cold chill down my back.
rozon
It's actually fun, once you get through the initial pain, and it opens up a lot of doors as far as signal processing goes.
MusiGenesis