# Comparing two values but with a constrain of x amount of degrees

Hiya doing what I call theoretical programming while I wait for a part to arrive so that I have code ready to test it on. Basically, the essence of what I want to do is take two inputs from the same sensor (Compass) detect if there has been change between those two values (Which I have). But I want something to trigger if that varible of change is greater than a number of 15.

Eg If the first measurement of the compass was 15 Degrees and the second measurement was 35 Degrees calculate if the change was positive; yes change is positive and the change was by 20 degrees since 20 is above the thresh hold active pin 4. Here is the code so far most of it is from the library demo

``````void setup(void)
{
Serial.begin(9600);
Serial.println("HMC5883 Magnetometer Test"); Serial.println("");

/* Initialise the sensor */
if(!mag.begin())
{
/* There was a problem detecting the HMC5883 ... check your connections */
Serial.println("Ooops, no HMC5883 detected ... Check your wiring!");
while(1);
}

/* Display some basic information on this sensor */
displaySensorDetails();
}

void loop(void)
{
/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);

/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
// Calculate heading when the magnetometer is level, then correct for signs of axis.

// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 0.22;

// Correct for when signs are reversed.

// Check for wrap due to addition of declination.

delay(500);

/* Get a new sensor event */
sensors_event_t event;
mag.getEvent(&event);

/* Display the results (magnetic vector values are in micro-Tesla (uT)) */
Serial.print("X: "); Serial.print(event.magnetic.x); Serial.print("  ");
Serial.print("Y: "); Serial.print(event.magnetic.y); Serial.print("  ");
Serial.print("Z: "); Serial.print(event.magnetic.z); Serial.print("  ");Serial.println("uT");

// Hold the module so that Z is pointing 'up' and you can measure the heading with x&y
// Calculate heading when the magnetometer is level, then correct for signs of axis.

// Find yours here: http://www.magnetic-declination.com/
// Mine is: -13* 2' W, which is ~13 Degrees, or (which we need) 0.22 radians
// If you cannot find your Declination, comment out these two lines, your compass will be slightly off.
float declinationAngle = 0.22;

// Correct for when signs are reversed.

// Check for wrap due to addition of declination.

digitalWrite(4, HIGH);

}

digitalWrite(5, HIGH);

}

delay(500);

digitalWrite(4, LOW);
digitalWrite(5, LOW);

delay(100);

}
``````

Something like this

``````if (abs(readingA - readingB) > threshold) {
// do stuff
}
``````

...R

Robin2:
Something like this

``````if (abs(readingA - readingB) > threshold) {
``````

// do stuff
}

``````

...R
``````

That won't handle readings across 360 though, will it?

If we had 5 degrees and 355 degrees they're 10 degrees apart, less than the 15 degree threshold mentioned. But abs(5-355) is 350....

sayHovis:
That won't handle readings across 360 though, will it?

Very true I had overlooked that.

It would be necessary to check if either value was close to 0 or to 360 and take that into account.

I wonder would it be useful to calculate two numbers being the difference between each reading and 360. Then the test could be for the difference between the differences? Just a thought - might be rubbish.

...R

There was a post the other day whose details I forget, but it explained how to work across the 0/360 line.

You basically need to think of each bearing as a vector (which they are, of course, of some constant length which may as well be unity) and calculate the resultant just as if they were forces or velocities or whatever. So you use the sin and cos of the bearing to get the x and y values of each one, and pretty much add those up. (Trig rule of All St Tastes Cp applies, so a bearing of 350 say has +ve sin but -ve cos, so that pulls the resultant across to the left, so to speak.) Then arctan takes you back to a resultant bearing.

I wish I could recall the name of the branch of maths someone called it; he or she linked to a very good wiki article.