There's probably a really simple mathematical way to do this, but maths isn't my strong point so maybe the following brute-strength approach.
It's only a problem in the 360/0 boundary area. So let's define a band around that of maybe +-10, ie 350 to 10. Any readings outside this band are treated normally.
However if you get readings inside the band you switch to a mode that adds 360 to any values < 350, does the averaging, then subtracts 360 if the results is > 360.
If you get an average that falls outside the band you revert to the standard method.
i made a code that seems to work at the moment.
This will not work if there is odd spikes in the readings, but that's alright ill be able to ignore those.
int total = 0;
for (int _sample = 0; _sample < 10; _sample++) {
read(); // read the magnometer values
heading_samples[_sample] = heading((vector){0,-1,0}); //create heading
if ( (heading_samples[_sample] > 350 ) || (heading_samples[_sample] < 10 )){
hstate = 1;
}
if (hstate != 1)
{
hstate = 2; //if no numbers above 350 or below 10 take normal average
}
}
switch(hstate)
{
case 1:
for(int _sample = 0; _sample < 10; _sample++){
if ( heading_samples[_sample] < 350 )
{
heading_samples[_sample] += 360; //add 360 if below 10
}
total += heading_samples[_sample]; //sum up readings
}
total /= 10;
heading = total;
if (heading >= 360){
heading - 360;
}
return heading
hstate =0;
break;
case 2:
for(int _sample = 0; _sample < 10; _sample++){
total += heading_samples[_sample];
}
total /= 10;
heading = total;
hstate =0;
return heading
break;
}
}
any suggestions to clean up code please do
thanks again
I had a think about this after switching off my computer last night. I think all you need to detect is the case when 2 or more readings differ by more than the expected jitter.
So I modified your code to do this, plus simplified the rest of the code. I hope I didn't stuff it up on the process
#define FUDGE_FACTOR 100 // any number > the expected jitter will do
#define SPECIAL 1
#define NORMAL 2
#define N_SAMPLES 10
#define BAND 10
int heading_samples[N_SAMPLES];
int hstate;
// dummy funcs just to get it to compile
void setup () {}
void loop () {}
int read () {}
int getHeading () {
int total = 0, min = 0, max = 0;
for (int _sample = 0; _sample < N_SAMPLES; _sample++) {
read(); // read the magnometer values
// I don't have "vector" so commented the next line out
//heading_samples[_sample] = heading((vector){0,-1,0}); //create heading
if (heading_samples[_sample] < min) min = heading_samples[_sample];
if (heading_samples[_sample] > max) max = heading_samples[_sample];
hstate = (max - min > FUDGE_FACTOR) ? SPECIAL : NORMAL;
}
for(int _sample = 0; _sample < N_SAMPLES; _sample++){
total += heading_samples[_sample]; //sum up readings
if ( heading_samples[_sample] < 360 - BAND && hstate == SPECIAL)
{
total += 360; //add 360 if not above 350
}
}
total /= N_SAMPLES;
if (total >= 360){
total -= 360;
}
return total;
}