Visto che una buona soluzione è stata pubblicata mi permetto di mostrare cosa avevo pensato io
per prima cosa uso di una funzione, certamente,
funzione che deve restituire una stringa (ovvero char *)
ecco il suo prototipo
char * direzione(int bussola);
poi ho pensato di renderla parametrica e di usare una tabella (array) locale
e quindi un array di stringhe (puntatore a carattere)
char * nomi[]={};
e naturalmente tra le parentesi graffe ci va l'elencazione dei punti cardinali, compresi tra virgolette (essendo singole stringhe) e separati da virgole (essendo un'elencazione di elementi di un array)
poi ho pensati di renderla parametrica, calcolando il "passo di cambio" dei punti cardinali passando per due "sizeof"
e serve comunque di tenere in conto che il Nord comincia "prima" dell'angolo "zero", quindi serve di calcolare un offset da aggiungere, offset che sarà, banalmente, pari a mezzo passo
il tutto deve essere calcolato in aritmetica a virgola mobile, per tenere conto che se si volessero più dei classici e canonici 4 punti cardinali serve tenere conto di angoli minori o uguali a 22 gradi e mezzo
ecco quindi che servirà:
un giochino con un operatore modulo 360
un calcolo del passo
un calcolo dell'offset
una ulteriore operazione di modulo, ma stavolta eseguita in aritmetica float
e usare il valore così ottenuto come indice che indica il corretto elemento nell'array dei puntatori a carattere
puntatore a carattere che sarà oggetto del return della funzione
naturalmente i valori che non cambiano da una esecuzione e la successiva devono essere "static" per non dover ricalcolare tutte le volte
ecco quindi la funzione fatta e finita
char * direzione(int bussola)
{
#ifndef CARDINALI
#define CARDINALI "N","NE","E","SE","S","SW","W","NW"
#endif
static char * nomi[] = {CARDINALI};
bussola = bussola % 360;
static int n = sizeof nomi / sizeof nomi[0];
static float passo = 360 / n;
static float offset = passo / 2;
float grezzo = (bussola + offset);
if (grezzo > 360)
{
grezzo = grezzo - 360;
}
return nomi[(int)(grezzo / passo)];
}
e un suo programma di prova minimale
void setup(void)
{
Serial.begin(9600);
for (int i = 0; i < 360; i += 10)
{
Serial.print(i);
Serial.print(" ");
Serial.println(direzione(i));
}
}
void loop(void)
{
// nulla da fare
}
provare per credere
e già che ci siete, dato che la funzione è parametrica basta aggiungere in testa al programma questa riga:
#define CARDINALI "Settentrione","Oriente","Mezzogiorno","Occidente"
per avere una deliziosa sorpresa
naturalmente si possono usare tutte le direzioni che si desidera, anche non multiple di quattro