Combining these makes a fun little test sketch:
#define arrSize(X) sizeof(X) / sizeof(X[0])
int course = 225;
int target = 135;
int bearings[] = { 0, 22.5, 45, 67.5, 90, 112.5, 135, 157.5, 180, 202.5, 225, 247.5, 270, 292.5, 315, 337.5, 360 };
const char* bearingStrings[] = { "N", "NNE", "NE", "ENE", "E", "ESE", "SE", "SSE", "S", "SSW", "SW", "WSW", "W", "WNW", "NW", "NNW", "N" };
void turnLeft() { Serial.println("Left"); }
void turnRight() { Serial.println("Right"); }
// returns the array element ID for the nearest bearing to the target number
int nearestBearing(int target) {
int idx = 0; // by default near first element
int distance = abs(bearings[idx] - target);
for (int i = 1; i < arrSize(bearings); i++) {
int d = abs(bearings[i] - target);
if (d < distance) {
idx = i;
distance = d;
}
else return idx;
}
return idx;
}
void setup() {
Serial.begin(9600);
Serial.println((String)"Current course is: " + bearingStrings[nearestBearing(course)] + " (" + course + " degrees)");
Serial.println((String)"Target course is: " + bearingStrings[nearestBearing(target)] + " (" + target + " degrees)");
Serial.print("Suggested movement: ");
int dif = target - course < 0 ? (360 + target - course) : (target - course);
dif < 180 ? turnRight() : turnLeft();
}
void loop() {
// put your main code here, to run repeatedly:
}
Just know that every time you cast to a String (capital 'S') God kills an innocent Kitten. So best not do that!