void setup() {
Serial.begin(115200);
Serial.println("\nModulo\n");
int a, b, c, d, e;
a = 1;
b = 355;
c = abs(a - b);
d = 360 - c;
e = min(c, d);
Serial.println(e); // prints 6
a = 270;
b = 280;
c = abs(a - b);
d = 360 - c;
e = min(c, d);
Serial.println(e); // prints 10
a = 10;
b = 20;
c = abs(a - b);
d = 360 - c;
e = min(c, d);
Serial.println(e); // prints 6
}
void loop() {
}
The distance between any two numbers is the absolute value of their difference.
In the case of headings, you might be going from 10 to 350, which is 340 degrees, but it is closer to cross over 0, that's just the rest of the circle or 360 - 340 is 20 degrees.
Similar problem solved here
Based on that, this function will do what you want:
bool differBy15DegOrMore(int degreesA, int degreesB) {
int difference = (degreesA - degreesB);
// Force difference to be in range -180 to +180
if (difference < -180) difference += 360;
else if (difference > 180) difference -= 360;
// Return true if difference <=-15 or >=+15
return (difference <= -15 ? true : difference >= +15 ? true : false);
}
This is a sketch with test code for that function
void setup() {
Serial.begin(115200);
doTest(0, 14);
doTest(0, 15);
doTest(0, 346);
doTest(0, 345);
doTest(180, 194);
doTest(180, 195);
doTest(180, 166);
doTest(180, 165);
}
void loop() {
}
bool differBy15DegOrMore(int degreesA, int degreesB) {
int difference = (degreesA - degreesB);
// Force difference to be in range -180 to +180
if (difference < -180) difference += 360;
else if (difference > 180) difference -= 360;
// Return true if difference <=-15 or >=+15
return (difference <= -15 ? true : difference >= +15 ? true : false);
}
void doTest(int degreesA, int degreesB) {
Serial.print("A=");
Serial.print(degreesA);
Serial.print(" : B=");
Serial.print(degreesB);
Serial.print(" : differBy15DegOrMore() return=");
Serial.println(differBy15DegOrMore(degreesA, degreesB) ? "true" : "false");
}
Well, for a similar problem I had for an anemometer returning the wind direction (not for Arduino, it was a C# project I worked on), I needed to know the degrees difference between two readings, to be able to detect wind direction changes. I just did a simple function like this (converted to Arduino-style):
int DiffDeg(int iFrom, int iTo) {
int Delta = (iTo - iFrom);
if (Delta > 180) Delta -= 360;
if (Delta < -180) Delta += 360;
return Delta;
}
This gives the shortest path degrees difference, assuming the wind hasn't dramatically changed (e.g. less than 180 degrees rotation between susequent measurements).
So to show an Arduino example, these are the results with directions crossing the 360 boundary, comments are the function output:
That seems to be the simplest / most obvious method to me. It took me a while the first time I had to solve this problem. I was working on SONAR systems ~30 years ago. I had to calculate the difference between two headings. It's a lesson I've never forgotten.
Naturally I am sticking with the idea in post #2 and the code in #10.
If you are coming from regular maths, and have gotten the idea of measuring distance by absolute value of a subtraction, switching out the result that is greater than 180 for the one that is less is the simple step that gives you the low number of degrees of separation.
All the code that works and gives numbers between 0 and 180 as the result are performing the same calculations.
All the code that does not work, or does something different or additional shows how things like this can go.
Hey! That same code could solve the millis() rollover problem!