Author Topic: Writing signal processing/filtering for 6bit gforce sensor  (Read 7577 times)

0 Members and 1 Guest are viewing this topic.

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Writing signal processing/filtering for 6bit gforce sensor
« on: October 19, 2012, 12:30:54 am »
Hey guys, I'm using a 6bit SPI accelerometer for a project. The 6th bit is the sign, so it's really +/- 31  (+/- 1.5G).

I'd like to apply some software processing to the signal so the data a bit more stable. (Currently it jumps around +/- 2 while stationary).

What i need is the stationary jitter removed but as soon as there's a significant change in g-force the processing switches off and the full resolution and response returns.  Does anyone know the best approach to do this?


The core issue i have is the led display for the output (influenced by the g-force value). It doesn't look very professional jumping around. I would like to filter the raw g-force data but if that isn't going to be possible without a downside i can just filter the led display and leave the internal sensor data as is.
« Last Edit: October 19, 2012, 12:43:04 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 18943
  • Country: nl
    • NCT Developments
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #1 on: October 19, 2012, 01:00:33 am »
This usually works well (moving average filtering):
a=sensor value
b=(b* (x-1) + a) / x

If you choose a power of 2 for x (like 2,4,8,16,.. 256 ,etc) then the division becomes a bit shift so its very fast to compute. Most modern microcontroller have a hardware multiplier. Startup may be a 'problem' but if you initialize b with the first sampled value then it should be OK.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #2 on: October 19, 2012, 02:13:01 am »
The problem with a moving average is they slow down the response.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #3 on: October 19, 2012, 03:03:06 am »
i believe your problem is dealing with the "noise", and you want to remove that noise (averaging is the usual and easy trick), well, just as every problem dealing with noise, afaik you'll be in trouble if your signal is closer to noise level, and i believe there's no easy trick for that. so taking an easy step, assuming your signal level is significantly larger than the noise, you can either do the averaging the entire process, or keep detecting some threshold level, ie if the reading difference is lower than this threshold, you'll assume noise and do not change the averaged data, but if its exceeding the threshold, you can stop the averaging and read instantanoues data, but i believe the noise/jitter is still there, in your "legitimate above threshold" reading, except you dont see it much since you signal overshadowing the noise. my best bet will be... continuous averaging! without the hassle to handle every possible situation, it is noise you are dealing with afterall. about the respond time, its a compromise between reading stability vs respond time, ie you use more data, it will be slow respond, but you get more stable reading, and vice versa. YMMV.
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Bored@Work

  • Super Contributor
  • ***
  • Posts: 3932
  • Country: 00
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #4 on: October 19, 2012, 06:17:01 am »
What you are probably looking for is called a Kalman Filter. Not the easiest to do and tune.
I delete PMs unread. If you have something to say, say it in public.
For all else: Profile->[Modify Profile]Buddies/Ignore List->Edit Ignore List
 

Offline Rerouter

  • Super Contributor
  • ***
  • Posts: 4524
  • Country: au
  • Question Everything... Except This Statement
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #5 on: October 19, 2012, 06:28:37 am »
or you use a moving average that passes straight through deviations greater than the noise,

x1= sample 1
x2= sample 2
x3= sample 3

y= reading

IF(x2-x3=OR(>5,<-5),y=(x1+x2+x3)/3)
ELSE(y=x3=x2=x1)

or something like that, where if it deviates by more than a predetermined level it will imediatly move to it, and start averaging from that point follwing it,

technically if you used timers or other methods you could make it lower that deviation limit if the last sample deviated,
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #6 on: October 19, 2012, 11:14:35 am »
What you are probably looking for is called a Kalman Filter. Not the easiest to do and tune.
why dont save a step... artificial intelligence with genetic algorithm, you remember? one guy want to do power management with it :P
Kalman filter takes data in with some "trustability" weight. in this case maybe low difference data may weigh less hence not updated/passed very well into the filter, but jeez with the whole lot of math theory, is it really necessary?
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #7 on: October 19, 2012, 11:16:02 am »
Some good info here, thanks guys.

This will be done on an ATMega at 8Mhz so complex math is out.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #8 on: October 19, 2012, 11:29:52 am »
This will be done on an ATMega at 8Mhz so complex math is out.
kalman filter if i'm not mistaken with good understanding, can be done in simple integer arithmetic, but to get a good understanding you need to read all the math behind it. its pretty much like a weighed averaging if i remember it correctly, but not exactly that :P. YMMV.
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #9 on: October 19, 2012, 11:58:49 am »
oh i forgot but not least... as far as the averaging is concerned, we can always do a quicker programming method in hardware if its feasible, just one line... add a capacitor to the sensor output or if its high impedance stuff, at the sensor's buffer output or the related ADC input :P
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #10 on: October 19, 2012, 12:00:15 pm »
oh i forgot but not least... as far as the averaging is concerned, we can always do a quicker programming method in hardware if its feasible, just one line... add a capacitor to the sensor output or if its high impedance stuff, at the sensor's buffer output or the related ADC input :P

In this case it's a SPI accelerometer, so that isn't possible.
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #11 on: October 19, 2012, 12:06:36 pm »
In this case it's a SPI accelerometer, so that isn't possible.
but hacking the analog side of the module is possible isnt it? since you having problem with this so i guess its cheapo type? and hacking or the less likeliness of damaging it wont hurt? always a pleasure to make a cheapo performs better ;)
« Last Edit: October 19, 2012, 12:11:47 pm by Mechatrommer »
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 9514
  • Country: my
  • reassessing directives...
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #12 on: October 19, 2012, 12:32:35 pm »
another method will be to discard the offending bit(s) or value altogether. since yours is ±2 (i assume decimal number) so you can lump the value say 0-4 into 2 (middle value). the psuedo will probably looks like this:
Code: [Select]
#define DISCARD_VAL 4
remain = value % DISCARD_VAL; mod operation
value = (value - remain) + (DISCARD_VAL / 2);

of if the offender is the 1st least bit
Code: [Select]
val &= 254; // 8 bit value

another compromise! though you will get the stable reading and "on the spot" response, you'll lose resolution ;)
if something can select, how cant it be intelligent? if something is intelligent, how cant it exist?
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #13 on: October 19, 2012, 03:40:32 pm »
What you are probably looking for is called a Kalman Filter. Not the easiest to do and tune.
Is there an "Idiot's Guide to Kalman Filtering" somewhere? Most presentations I've seen of the subject are fairly math intensive.
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 18943
  • Country: nl
    • NCT Developments
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #14 on: October 19, 2012, 04:09:31 pm »
The problem with a moving average is they slow down the response.
What is the samplerate? If you use a small value for x (like 2 or 4) then the impact is minimal.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #15 on: October 19, 2012, 05:16:55 pm »
Hey guys, I'm using a 6bit SPI accelerometer for a project. The 6th bit is the sign, so it's really +/- 31  (+/- 1.5G).

I'd like to apply some software processing to the signal so the data a bit more stable. (Currently it jumps around +/- 2 while stationary).
If your circuit is built correctly, then it seems pretty strange that your 6-bit resolution sensor is functioning only as good as a 4-bit sensor. Does the datasheet say you should expect +/- 2? If not, you should probably try to find the source of that noise rather than massaging the data.

Is your power supply clean? The output of the sensor is digital, but it might have analog innards that are sensitive to noise on the power rails.

Does the noise you're seeing have a particular frequency? I.e., if you sample at different rates, do you still see the same level of noise? Could there be some physical explanation for what the sensor is putting out?
 

Online PA0PBZ

  • Super Contributor
  • ***
  • Posts: 4260
  • Country: nl
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #16 on: October 19, 2012, 07:26:44 pm »
Exactly what I was thinking. If it jumps around for 0.1G you are either doing something wrong or you need to find another sensor.
Keyboard error: Press F1 to continue.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #17 on: October 20, 2012, 01:53:44 am »
Most of the jitter is the LSB, so +/- 1. Occasional you get a 2 though. This is correct according to the datasheet.

Quote
Noise is defined as quantiles given to a sample size.
These are the occurrences of noise: 94% = ±1 count,    5% = ±2 counts,    and 1% = ±3 counts.
So yeah, the LSB is pretty much noise.

The chip is a MMA7660 http://www.freescale.com.cn/files/sensors/doc/data_sheet/MMA7660FC.pdf

The sensor is 6 bit digital and internally takes 3846 samples/s and filters them to selectable 120/s, 64/s, 32/s, 16/s etc. Which you can read over SPI. There is no way to get at the analog side, it's internal.
Because it can detect both directions you only get 5 bits of actual G data,  bit 6 is the sign.
So there are 31 steps from 0G to 1.5G, so 1 step = 0.048G.

Most of the issue is, as you say, the sensor is a bit cheap, it's really meant for cellphones to detect orientation and pretty basic realtime measurements. That's why the resolution is low.  It's only $1 when other sensors are $5
I probably should be using a better sensor but this one is real cheap and it does work ok currently, I'm just trying to tidy it up and make it more professional.

What i'm looking at currently is a running average which changes its length in realtime based on the signal rate of change.
The idea is the running average is really long while the signal is stable but as soon as big changes occur the number of samples reduces to minimal so the response is fast.
« Last Edit: October 20, 2012, 01:58:36 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 18943
  • Country: nl
    • NCT Developments
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #18 on: October 20, 2012, 09:54:54 am »
What i'm looking at currently is a running average which changes its length in realtime based on the signal rate of change.
The idea is the running average is really long while the signal is stable but as soon as big changes occur the number of samples reduces to minimal so the response is fast.
You may not want that. When reading sensors there is always the possibility of a false reading. A signal processing algorithm should ignore / filter such readings.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #19 on: October 20, 2012, 10:20:32 am »
The filtering won't be reduced to zero in the event of a big signal change, just to a minimum level.
A running average of 4 samples seems to work quite well in general.


I'm currently getting it to switch between a 4 sample running average and a 32sample one, with a few stages in-between, depending on the change in data over a 8 sample period.
« Last Edit: October 20, 2012, 10:31:42 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #20 on: October 20, 2012, 11:07:12 am »
ok, so i have the code written and running. It's actually working very well, i'm quite happy with it.
Automatically moves between a 4 and 128 running average based on the change between the current value and the value 8 samples ago

Quote
#define gfsarraylen 128
uint8_t gfsval[gfsarraylen];
--------------------

// sample comes in stored in gvalue and is 0-64 where 31=zero G
// store this sample (gvalue) into the ring buffer at current ring position

gfsval[y_ringpos] = gvalue;
y_ringpos++; // new index for next time
if (y_ringpos >= gfsarraylen)    y_ringpos=0;
         
// Pull out of the ring buffer the sample that occurred 8 samples ago            
if (y_ringpos < 8 )
     oldsample = gfsval[ gfsarraylen - (8 - y_ringpos) ];  // if it would wrap the ring handle that
 else
     oldsample = gfsval[ y_ringpos - 8 ];   

// Compare the sample now to the sample then.
// Based on the difference, set the ring buffer length shorter if the signal is changing more

switch (abs( gvalue - oldsample ))
{                                 
   case 3 ... 4:    if (y_filterlength > 64 ) y_filterlength = 64; break;
   case 5 ... 6:    if (y_filterlength > 32 ) y_filterlength = 32; break;
   case 7 ... 9:    if (y_filterlength > 8 )  y_filterlength = 8; break;
   case 10 ... 255: if (y_filterlength > 4 )  y_filterlength = 4; break;            
}   

// keep trying to return the ring buffer length to its full size by incrementing by 1
if (y_filterlength < gfsarraylen) y_filterlength++;               

// Loop backwards through the ring buffer summing up <filterlength> samples
avgcnt=0;
gfysum=0;
while (avgcnt < y_filterlength)
{
   avgcnt++;
   arrayaddress = (y_ringpos - avgcnt);
   if (arrayaddress < 0) arrayaddress = gfsarraylen + arrayaddress; //if address makes ring buffer wrap
   gfysum = gfysum + gfsval[arrayaddress];
}
// divide by buffer length to get average
y_gforce = (gfysum / y_filterlength);
« Last Edit: October 20, 2012, 11:45:06 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline andyturk

  • Frequent Contributor
  • **
  • Posts: 892
  • Country: us
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #21 on: October 21, 2012, 07:41:23 pm »
The sensor is 6 bit digital and internally takes 3846 samples/s and filters them to selectable 120/s, 64/s, 32/s, 16/s etc. Which you can read over SPI. There is no way to get at the analog side, it's internal.
Well, the chip does have separate analog and digital supplies, which probably means you want to keep the analog rails clean. They're at the same voltage, so you can tie them together and get data out, but connecting analog parts up to a digital supply can cause problems. SPI in particular seems to dump a lot of noise back into the supply rails.

As for the code, what does your filter code do when there are fewer than eight samples? Similarly, what happens if it wants to switch to a longer filter length, but doesn't actually have the data yet?

It also looks like the average is recomputed for each sample. That's a lot of extra processing. A running sum would produce the same result with one addition operation (and one subtraction) per sample as long as the filter length hasn't changed. If the filter length changes, then you'd need to recompute. Better yet, just keep four running sums (one for each filter length) and then the cost of switching drops to zero. This gives you very predictable execution times which are nice to have in interrupt routines.
 

Offline mrflibble

  • Super Contributor
  • ***
  • Posts: 1992
  • Country: nl
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #22 on: October 21, 2012, 09:13:19 pm »
Better yet, just keep four running sums (one for each filter length) and then the cost of switching drops to zero. This gives you very predictable execution times which are nice to have in interrupt routines.

Gets my vote. You simply have your ringbuffer of size N=128. Then an accumulator for every tap you are interested in, so in this case for 4, 8, 32 and 64. And since you're doing the shift in software, I'd do the shift after the select. Saves you 3 shift operations.

So 4 adds and 4 subtracts per update, and then 1 select + 1 shift for each usage. Deterministic timings are indeed nice. :)

Other than that, if all this isn't caused by your power rail .. that seems to be one hell of a noisy part. O_o


Update: On second thought.... do the shift during the update phase, right after you did the add/subtract. Keeps the code simpler AND since you have the result in a register already might be about as fast...
« Last Edit: October 21, 2012, 09:30:43 pm by mrflibble »
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 7514
  • Country: nz
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #23 on: October 22, 2012, 02:19:06 am »
As for the code, what does your filter code do when there are fewer than eight samples? Similarly, what happens if it wants to switch to a longer filter length, but doesn't actually have the data yet?

Yeah, output is only valid once the ringbuffer is full, but that isn't a problem for the application.


Better yet, just keep four running sums (one for each filter length) and then the cost of switching drops to zero. This gives you very predictable execution times which are nice to have in interrupt routines.

Gets my vote. You simply have your ringbuffer of size N=128. Then an accumulator for every tap you are interested in, so in this case for 4, 8, 32 and 64. And since you're doing the shift in software, I'd do the shift after the select. Saves you 3 shift operations.

So 4 adds and 4 subtracts per update, and then 1 select + 1 shift for each usage. Deterministic timings are indeed nice. :)

Other than that, if all this isn't caused by your power rail .. that seems to be one hell of a noisy part. O_o

Update: On second thought.... do the shift during the update phase, right after you did the add/subtract. Keeps the code simpler AND since you have the result in a register already might be about as fast...

Yep, that is definitely a better solution.

Now that i have the concept working i will start optimizing it.
I've already discovered that  the line "  if (y_filterlength < gfsarraylen) y_filterlength++;  " really needs to happen less often, about once in every 5-10 samples, otherwise the buffer expands back too quick and skews the data a little
« Last Edit: October 22, 2012, 02:23:59 am by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline Kremmen

  • Super Contributor
  • ***
  • Posts: 1283
  • Country: fi
Re: Writing signal processing/filtering for 6bit gforce sensor
« Reply #24 on: October 22, 2012, 09:03:33 am »
What you are probably looking for is called a Kalman Filter. Not the easiest to do and tune.
Is there an "Idiot's Guide to Kalman Filtering" somewhere? Most presentations I've seen of the subject are fairly math intensive.

Idiot's Guide? Probably not, unfortunately this is not a topic for rookies. I quickly checked my library and actual textbook material on the theory of Kalman filtering was suprprisingly sparse. I do have one at least that i can recommend with reservations:

Grewal, Mohinder S. and Andrews, Angus P.; "Kalman Filtering: Theory and Practice Using Matlab"; Wiley & Sons; ISBN 0-471-26638-8

The reservations are that it is relatively math intensive because there is no way around that fact. Perhaps a picture from that book's intro illuminates why:



In a way, a concept like Kalman filtering stands on the shoulders of a number of disciplines that must be understood for it to make sense. You cannot begin from the top, so to say.
Nothing sings like a kilovolt.
Dr W. Bishop
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf