Efficient way to get the absolulte difference of two 16 bit signed integers on atmel AVR 8bit gcc?

StackOverflow https://stackoverflow.com/questions/23594769

Pergunta

I am getting 16 bit signed integers from the I2C bus and store them in a local int16 variable.
The sensor is a MEMS gyroscope and it regularly spikes high or low data values, it seems to be a general problem with many MEMS gyroscopes.

So normal reading would be -2 to +2, and from time to time (depending on my polling rate) I get very large values (like -30000 or 25000) in between.

I did not find a way to solve that in hardware, I want to solve it in software. I look for an efficient way to do something like this without going to 32 bit:

Pseudo code:

#define SPIKE 0x3000; // a change of SPIKE or larger is ignored
int16_t currentvalue=-2330; // the current value (last sensor result)
int16_t newvalue=-31000; // the new value from sensor, a spike


difference = abs(abs(newvalue) - abs(lastvalue)); // would need some branches more

if (difference < SPIKE) currentvalue = newvalue; // if SPIKE the new value is just not taken

I could not find a nice and efficient way to keep in 16 bit space and get the absolute difference between old and new without having a wood of if branches.
I am sure there is a nice efficient way to do that, I am just not experienced enough in dealing with signed values.

I do not even need to actually calculate the absolute difference, it is enough to get a working detection if the absolute difference would be larger than SPIKE.

I want to avoid 32 bit space.

Foi útil?

Solução

Your arithmetic seems flawed. As written, you would allow a jump from 10000 to -10000 as okay. Instead, you want to use abs() only once.

difference = abs(newvalue - lastvalue);

You can also avoid abs() altogether.

difference = newvalue - lastvalue; 
if (difference < 0) difference *= -1;

if (difference < SPIKE) currentvalue = newvalue;

or

difference = newvalue - lastvalue; 

if (difference > -1*(SPIKE) && difference < SPIKE) currentvalue = newvalue;

These might all be similarly efficient. If there is any difference, the last one might be best because the multiplication occurs in the compiler. I leave it to you to test for yourself.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top