Chiarimento sul comando map

Salve a tutti.
Ho realizzato un piccolissimo aerogeneratore con una ventola di pc che utilizzo come sonda anemometrica, che mi servirà in un futuro spero non troppo lontano come segnale per l'attivazione del freno di una pala eolica ad asse verticale vera e propria che ho in costruzione.
Ora che non ho ancora la pala realizzata mi sto esercitando piano piano con qualche comando.
L'obiettivo di questo piccolissimo sketch è quello di avere sul monitor seriale il valore di tensione prodotto dal piccolo generatore.
Partendo dai dati di targa del motorino, veniva alimentato a 12 volts e anche se il numero di giri non è dichiarato, credo giri a qualcosa come 12500 rpm.
Quindi, la tensione che è in grado di produrre è direttamente proporzionale al numero di giri, ossia,Max 12V a 12500rpm.
Posto che non riuscirò mai a far girare la ventolina a 12500 rom senza l'uso di un moltiplicatore, mi aspetto quindi di farlo girare al massimo a 2-3000 giri, e avere di conseguenza dei valori di tensione bassi.
Infatti, realizzato il tutto, sono andato lì col tester e misurato tensioni non superiori a 1.3V con un vento medio di cui non conosco la vera intensità espressa in m/s.
Quindi lo sketch:

int anemometro; //dichiarazione anemometro
float tensione; //segnale dell'anemometro
void setup () {
   Serial.begin (9600);
}V
void loop () {
   anemometro = analogRead (A0);  
   tensione = map (anemometro, 0,1023,0,12);
   Serial.println (tensione);
   delay (500);
}

Ecco, in questo modo ho la variabile tensione di tipo float, però al monitor leggo qualcosa tipo
0.00 (varie volte)
E quando il vento aumenta leggo
1.00
Qualche volta ho letto
2.00

Insomma, le cifre dopo la virgolaci sono solo per bellezza.
Sarà sbagliata la proporzione all'interno del map?
Sicuramente per la quasi totalità di voi sembrerà una cosa molto banale, ma vi prego non lancia temi le molotov, grazie :wink:
Spero di aver usato la funzione giusta per scrivere il codice ...
Comunque grazie a chiunque mi voglia chiarire la questione.

Se avessi letto il reference (... cosa da fare sempre prima di usare una funzione) avresti scopeto che ...

The map() function uses integer math so will not generate fractions, when the math might indicate that it should do so. Fractional remainders are truncated, and are not rounded or averaged.

Guglielmo

P.S.: Però puoi scriverti tu una funzione che fa la stessa cosa usando i float ... basta che gli dai un nome diverso, es. fmap() :smiley:

Ah .... Ecco ....
Io di questo referente non ne conoscevo l'esistenza, ti ringrazio. Vado a cercare cos'è questo fmap () che mi consigli.

ciao Washe85 ,

permettimi di dire che sarà una ricerca molto lunga ed estenuante :smiley:

Guglielmo ti ha scritto:

P.S.: Però puoi scriverti tu una funzione che fa la stessa cosa usando i float ... basta che gli dai un nome diverso, es. fmap()

cioè...mentre map() è già presente e basta richiamarla...questa fmap() la devi scrivere tu...fuori dal loop() e dal setup()...e poi usarla/chiamarla nel loop o nel setup...

per aiutarti...guarda alla fine della descrizione di map() nelle reference..

>Washe85: Infatti ho scritto esattamente "... puoi scriverti tu una funzione ..." e ti ho detto che per distinguerla gli DEVI dare un nome diverso, ad esempio fmap() ... non che la trovi già bella che fatta !

Comunque, ti basta prende la map() (che trovi nel core di Arduino) e farla uguale usando i float :wink:

Guglielmo

Mi raccomando di non usare questi float, non vanno bene per Arduino. :smiley:

ahahah allora ragazzi grande svolta!!!
innanzitutto grazie per non avermi dato la pappa già pronta, quello è sicuramente il metodo peggiore per imparare.
ho cercato un po questa permettetemi di dirlo meraviglioas funzione map per i decimali e ho trovato quello che fa al caso mio.
praticamente, come adesso leggo, e come mi pare di aver capito, posso "creare" una nuova funzione, dandogli tutti i parametri per poterla far funzionare, descrivendogli per filo e per segno tutto quello che dovrà trattare.
ho capito che gli devo dichiarare tutte le variabili di tipo float fuori dal loop e dal setup, e, in un argomento a parte prima del loop creo la funzione che ho chiamato fMap con il suo "return" che adesso ancora sintatticamente non mi è troppo chiara la logica di funzionamento, ma ho capito che quel "return" serve per validare la funzione sopra esposta per poterla usare, per dirgli come deve trattare le cariabili, e questo è molto interessante, perchè significa che posso inventarmi con metodi simili tutte le funzioni che voglio.. (ma che non conosco).
quindi ho ricostruito lo sketch e ho verificato che ho potuto ottenere gli stessi valori che mi dava il voltmetro ai capi della ventolina, solo che a quanto pare funziona(veniva alimentata dal pc) con 5V, e i 12 (forse) era la Vmax.. bah vabbè dettagli.
comunque adesso cercherò di postare il nuovo codice se ritrovo il pulsante code[] ecc ecc.
la mossa successiva sarà quella di eliminare il delay che a quanto ho capito mette in standby tutto l'arduino, vorrei fare dei campionamenti costanti nel tempo (tipo 10,15 al minuto), e quando il valore di tensione della ventolina supera una determinata soglia, aziona un servo motore in modo lento e controllato, e credo che avrò bisogno per questo degli array, dei cicli do while, di includere la libreria del servo ecc...
ma per questo se avrò bisogno aprirò un nuovo thread.
quindi un grazie particolare a Gpb01 che mi ha illuminato, a orso2001 e astrobeed :slight_smile:

1: una funzione o non torna nulla (non ha il return) e quindi è di tipo void o ritorna una qualche cosa da qui il tipo che si mette davanti al nome ed il return ritorna quel qualche cosa.

2: una funzione può NON avere parametri (normalmente si mette anche li void) o avere uno o più parametri di vario tipo.

Esempi:

(void) pippo(void) {
...
}

... non torna nulla e non accetta nessun parametro.

int pippo (void) {
   int pluto;
   ...
   ...
   return pluto;
}

... torna un int e non accetta alcun parametro.

int pippo(int a, int b) {
   int c;
   ...
   ...
   return c;
}

... torna un int, vuole due int come parametri.

Tutto chiaro ?

Guglielmo

... nel tuo caso la fmap() sarà definita come:

float fmap(float value, float fromLow, float fromHigh, float toLow, float toHigh) {
  ...
}

... ed, ovviamente, al suo interno ci sarà la return di un float.

Guglielmo

int anemometro;
float tensione=0;
float inMin=0;
float inMax=1023;
float tensMin=0;
float tensMax=5;

void setup() {
  Serial.begin(9600);
}
float fmap (float tensione, float inMin, float inMax, float tensMin, float tensMax)
  {
    return (tensione - inMin) * (tensMax - tensMin) / (inMax - inMin) + tensMin;
  }
void loop() {
  anemometro = analogRead(A0);
  tensione = fmap(anemometro,inMin,inMax,tensMin,tensMax);
  Serial.println(tensione);
  delay(500);
}

si gpb01 a livello concettuale mi è abbastanza chiaro, naturalmente non avendo dimestichezza ho difficoltà a ragionare in questi termini, ma con l'esercizio riuscirò a fare tutto.