Arduino Forum

International => Italiano => Software => Topic started by: crix87 on Aug 28, 2013, 02:49 pm

Title: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 02:49 pm
Ciao a tutti, sono nuovo nel forum ed ho iniziato ad usare Arduino da poco, tuttavia sono a corto di tempo e necessiterei di qualche delucidazione.
Ho fatto una ricerca tra i vari contagiri RPM ma non riesco a trovare una risposta all'idea del software adeguata.
Tanto per iniziare, ho realizzato il seguente circuito: http://mckgyver.pbworks.com/w/page/20654133/Arduino_Tachometer
l'ho testato con il codice presente sotto e funziona, tuttavia non riesce a mantenere un numero costante di giri, ma ha un errore abbastanza alto( a 2500 giri, varia +/- di circa 100 giri).
Invece di contare il numero di impulsi in un certo intervallo, ritengo sia più preciso misurare il tempo trascorso tra due impulsi, ed ho provato ad utilizzare il pulseIn.
Inserendo il seguente sketch e testando con un fan F6015B12LY (9 pale, max 3000 giri/min), la durata tra un segnale ad un'altro è assurda (+1000000 us suppongo); inoltre non riesce a leggere i giri/min.
Lo sketch è il seguente, cos'è che sto sbagliando?
è sensato inoltre dire che contando gli la durata tra due impulsi, la misura dovrebbe essere più precisa?

Code: [Select]

//Pulsein code for rpm counting

//Define Variables
const float pi = 3.14;
unsigned long holes__angle = pi/2;
unsigned long duration;  //
unsigned long rad_sec;  //
unsigned long rpm;  //
unsigned long timeout = 10000000;  //
int ledPin = 2;             // LED connected to digital pin (changes state with each tic of code wheel)
int statusPin = 13;             // LED connected to digital pin (changes state with each tic of code wheel)

void setup()
{
   Serial.begin(115200);
   Serial.println("CLEARDATA"); //clean excel spreadsheet
   Serial.println("LABEL,Time,Duration,RPM"); //clean excel spreadsheet
   pinMode(statusPin, OUTPUT); //
   pinMode(ledPin, INPUT); //
}
void loop()
{
   duration=pulseIn(ledPin,HIGH,timeout);
   rad_sec=(holes__angle*1000000)/duration;
   rpm=(rad_sec*60)/(2*pi);
   Serial.print("DATA,TIME,");Serial.print(duration);Serial.println(rpm);
    }

Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 03:05 pm
http://forum.arduino.cc/index.php?topic=157511.0
Ciao
Io permetto di suggerirti di dare un'occhiata a questo mio topic
Ho sbattuto un bel po il muso pure io su pulse in senza ricavarne nullA di buono sostanzialmente
Se vai al penultimo post della prima pagina trovi il codice che ho fatto per avere rpm con interrupt
Non blocca il codice come pulsein ed e molto preciso in quanto riesco senza problemi a governare l, accensione di un motore a benzina
Spero possa esserti di aiuto
EDIT
Una cosa che ho imparato nei miei mesi di prove e che spesso la lettura imprecisa non arriva dal sensore ma da quello che fai con la lettura
Se fai operazioni con numeri interi ogni volta ti taglia via i decimali e a ogni passaggio perdi in precisione
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: leo72 on Aug 28, 2013, 03:17 pm
Concordo con lucaleo sia sulla lentezza ed imprecisione dei calcoli con i float sia sull'uso degli interrupt al posto della pulseIn.
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 03:46 pm

Concordo con lucaleo sia sulla lentezza ed imprecisione dei calcoli con i float sia sull'uso degli interrupt al posto della pulseIn.


questa la incornicio ahaha
è la prima volta che su due cose che scrivo non c'è manco una cagata :D

in ogni caso crix87 ho guardato un po' il tuo codice e onestamente non capisco bene come funziona (o meglio quello che mi pare di aver capito non può andare)

pulsein ti restituisce il tempo trascorso (in millisecondi? non ricordo, ma attenzione perchè non è detto che sia quello che pensi di usare) durante HIGH o LOW a seconda delle tue preferenze
tuttavia tu devi GIA SAPERE a quanti gradi corrisponde quel segnale sulla rotazione totale (puoi calcolarla sommando la durata di high e low se hai un solo dente a un regime stabile di giri o moltiplicando la somma per il numero di high e low dentro a un giro a seconda di quante pale, denti eccetera tu abbia)

il motivo è molto semplice, vedrai che a parità di dente se tu allontani o avvicini il sensore  al centro della rotazione la velocità angolare sarà sempre uguale, ma quella lineare cambia e quindi cambia anche l'ampiezza in gradi di un dente di esempio 3 millimetri di dente a 3 cm da centro o a 1 cm dal centro non sono per niente la stessa cosa

una volta che hai il sensore posizionato e lo hai calibrato allora da li non avrai grossi problemi, solo non fare un hardware ballerino perchè butti via ore e ore a caso (te lo garantisco  :P)

spero di non aver scritto tutto ciò inutilmente e che ti sia di aiuto ahaha

EDIT
ultima info per rendere tutto più comprensibile
non farti ingannare dal fatto che stai misurando una ventola

poniamo caso che hai 6 pale

un conto è guardare quando ci metti a leggere 6 pale e dividere un minuto per quel tempo ottenendo rpm (che va bene)

un conto è misurare quando dura una pala
di istinto viene da pensare 6 pale, 6 spazi quindi 6 pale 180° e 6 spazi 180° quindi ogni pala e ogni spazio valgono 30°
ma non è detto che sia così!!
6 pale e 6 spazi potrebbero anche essere 240° le pale e 120° gli spazi (a seconda di come è fatta la ventola) quindi ogni pala misurerebbe 40° e ogni spazio 20°

per questo per sfruttare la durata della pala o dello spazio è FONDAMENTALE sapere a quanti gradi corrisponde quella pala o quello spazio a quella DETERMINATA distanza dal centro della rotazione
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 04:58 pm
Cari Lucaleo e Leo72, vi ringrazio per le risposte.
Lucaleo, in realtà probabilmente la mia situazione è più semplice, perchè devo testare delle turbine eoliche, il sensore misurerà la rotazione di un volano su cui andrò ad eseguire 4 fori (credo bastino, che ne dite), quindi spaziati di 90° (pi/2 radianti).
Ho capito la questione sulla distanza dal centro, ma non ho capito se si applichi al mio caso, in quanto io misurerei solo velocità angolari, non lineari, o mi sbaglio?
Adesso provo ad implementare il codice che mi hai suggerito, sperando che le cose migliorino! 8)
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 05:07 pm
tutto dipende da come affronti il problema
se tu "conti i buchi" non ti interessa nulla di quello che ho scritto sul calcolo dei gradi
se tu conti "quanto dura un buco" devi per forza mettere questo dato in relazione a quanto dura un giro e per "indovinare" quanto dura il giro devi per forza sapere a quanti gradi su 360 corrisponde il buco
se misuri gli spazi senza buco moltiplicando per 4 avrai una misura molto vicina alla realtà ma ti mancheranno sempre i micros dei buchi che non puoi stimare se non sai quanti gradi sono :D

nel tuo caso potresti anche ottenere un buon risultato tramite gli interrupt (se usi pulsein blocchi tutto in continuazione) misurando sia la durata di un buco che la durata dello spazio senza, sommare i valori e moltiplicare per 4 e ottenere il tempo di un giro senza sapere a quanti gradi corrisponde il buco e lo spazio

oppure ancora più preciso fai un contatore, poi prendi i valori di ogni buco che passa e ogni spazio vuoto fino a quando non sono passati 4 buchi e 4 spazi, sommi tutto e hai il tempo esatto di ogni giro

io sul motore non posso usare questi metodi perchè devo sapere quanti giri sto facendo e in che posizione sono del giro prima di un certo momento, ma tu non hai questo limite credo
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 05:12 pm
Mi consola il fatto che il codice dovrebbe essere più semplice di quello ce hai postato nell'altro topic  :)

Quindi, per misurare i giri, posso ripartire da qui:
http://mckgyver.pbworks.com/w/page/20654133/Arduino_Tachometer
Tuttavia, invece di far aumentare i giri, come faccio a calcolare il tempo tra gli interrupt? uso sempre la libreria stopwatch o ci sono funzioni più semplici?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 05:28 pm
guarda stopwatch l'ho usata perchè sono scarso e non riesco a usare la funzione millis o micros che sia  :smiley-roll-sweat:

tuttavia prendo spunto dal codice che hai postato e provo a modificarlo per quello che serve a te

magari imparo qualcosa su millis intanto :D

Code: [Select]

 //Arduino Code
 
 /*
 
  * Tachometer
 
  *
 
  * M.G.McKinley
 
  * 6/1/2009
 
  * Adjust
 
  */
 
 //Define Variables
 
 int ticsPerRev = 16;       // define number of tics per rev of code wheel
 
 float rpm = 0.0;  // I prefer float for rpm
 
 volatile int rpmcount =0;  // volitile because the variable is manipulated during the interrupt
 
 unsigned long timeold = 0; // used to calculate d_t= millis()-timeold;
 
 int d_t;
 
 
 
 
 
 void setup()
 
 {
 
   Serial.begin(9600);
 
   //Interrupt 0 is digital pin 2, so that is where the IR detector is connected
 
   //Triggers on FALLING (change from HIGH to LOW)
 
   attachInterrupt(0, rpm_fun, FALLING);
 
 
 
 
 
 }
 
 void loop()
 
 {
 
   //Update RPM every second
 
 
 
   //Don't process interrupts during calculations
 
   detachInterrupt(0);
 
   d_t=millis()-timeold;
 
 
 
   if (d_t >= 1000)
 
   {
 
     rpm = float(60.0*1000.0)/float((d_t))*float(rpmcount)/ticsPerRev;
 
 
 
     timeold = millis();
 
     d_t=0; //reset d_t
 
 
 
     //Serial Port Output
 
 
 
     Serial.println(rpm);
 
 
 
     rpmcount = 0; //reset rpmcount
 
 
 
   }
 
   //Restart the interrupt processing
 
   attachInterrupt(0, rpm_fun, FALLING);
 
 }
 
 void rpm_fun()
 
 {
 
   //This interrupt is run at each codewheel tic
 
   detachInterrupt(0); //im not sure if this is necessary here
 
 
 
   rpmcount++; //update rpmcount
 
 
 
 
 
 
 
   attachInterrupt(0, rpm_fun, FALLING);
 
   }


ho tolto un po' di roba che faceva confusione per capire la dinamica del codice

così DOVREBBE funzionare, non sono per nulla bravo...

prova :D

ah mi raccomando ricordati di modificare il numero delle pale, per ora sono 16
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 05:40 pm
grazie per la revisione, in effetti sembra andare meglio!
Li tolgo i float dal codice? meglio dichiarare le variabili con long?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 06:10 pm
mah dipende da quanto può durare la rotazione forse puoi usare pure int visto che usi millis
però non me ne intendo... ho capito qualcosina da poco

in ogni caso quel codice non è pensato per essere molto preciso secondo me, quello imposta un intervallo per il loop di 1 secondo e ogni secondo guarda quanti denti sono passati e con qualche calcolo ti dice i giri

io proverei a far partire un contatore alla prima pala e fermarlo quando inizia la 16esima (con falling quando inizia la pala tu hai l'interrupt), in questo modo avresti il vero tempo di un giro

se ho scritto delle boiate che qualcuno mi corregga :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: leo72 on Aug 28, 2013, 06:12 pm
Millis restituisce un unsigned long, quindi devi usare questo tipo di dato per immagazzinare il valore restituito dalla funzione.
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 06:17 pm

Millis restituisce un unsigned long, quindi devi usare questo tipo di dato per immagazzinare il valore restituito dalla funzione.


possibile che tu mi abbia appena spiegato perchè non sono mai riuscito a usare millis :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 06:29 pm
Vi allego il codice aggiornato - credo funzioni ma la ventola di prova non è attendibile :)

Code: [Select]

//Arduino Code
/*
* Tachometer
*
* M.G.McKinley
* 6/1/2009
* Adjust
*/
//Define Variables

int ticsPerRev = 7;       // define number of tics per rev of code wheel
unsigned long rpm;  //
volatile int rpmcount;  // volitile because the variable is manipulated during the interrupt
unsigned long timeold; // used to calculate d_t= millis()-timeold;
unsigned long d_t;
 
void setup()
{
  Serial.begin(9600);
  Serial.println("CLEARDATA"); //clean excel spreadsheet
  Serial.println("LABEL,Time,RPM"); //clean excel spreadsheet
  attachInterrupt(0, rpm_fun, FALLING);
}

void loop()
{
  detachInterrupt(0);
  d_t=micros()-timeold;
  if (d_t >=500000)
   {
     rpm = (60*1000000)/((d_t))*(rpmcount)/ticsPerRev;
     timeold = micros();
     d_t=0; //reset d_t

//Serial Port Output
     Serial.print("DATA,TIME,");Serial.println(rpm);
     rpmcount = 0; //reset rpmcount
  }
     attachInterrupt(0, rpm_fun, FALLING);
}

void rpm_fun()
{
    detachInterrupt(0); //im not sure if this is necessary here
    rpmcount++; //update rpmcount
    attachInterrupt(0, rpm_fun, FALLING);

}
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 06:33 pm
Tuttavia come detto non è ancora abbastanza accurato, stavo pensando di spostare l'INPUT dal pin2 al pin8 e utilizzare il timer1 inserito nel codice. tuttavia il timer1 non mi è chiarissimo e non riesco ad utilizzarlo:
1) credete che sia possibile utilizzardo, spostando solo un filo a livello hardware?
2) consigli a livello software? non riesco a trovare degli sketch adeguati per un rpm! :smiley-roll-sweat:
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 06:38 pm
ma cosa devi fare?
è più semplice aiutarti se lo sappiamo
e poi sono curioso ;)
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 06:43 pm
devo fare dei test in galleria del vento di una piccola turbina eolica, praticamente partendo da zero devo misurare la velocità massima della turbina e il tempo con cui ha raggiunto il massimo dei giri (per intenderci, ad 1 m/s di velocità d'aria, la turbina magari gira a 200 rpm, arduino mi deve indicare nel modo più accurato in quanto tempo la turbina partendo da zero è arrivata a 200 rpm).
In poche parole al momento il codice non va bene perchè non resta stabile ad un picco di giri, in quanto magari varia di +/- 100 giri a 2500rpm, ed inoltre il software non sembra capace di leggere i giri al di sotto dei 15 rpm. L'hardware invece va bene perchè è stato testato con l'oscilloscopio, quindi è solo una questione di software!
Fatemi sapere se vi viene in mente una soluzione!!  :smiley-roll-sweat:
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: leo72 on Aug 28, 2013, 06:53 pm

Tuttavia come detto non è ancora abbastanza accurato, stavo pensando di spostare l'INPUT dal pin2 al pin8 e utilizzare il timer1 inserito nel codice. tuttavia il timer1 non mi è chiarissimo e non riesco ad utilizzarlo:

Se vuoi usare il timer 1 come Input Capture con timestamp, il timestamp altro non è che il valore del registro del timer 1 stesso,. Dovresti impostare una certa frequenza, altrimenti quel valore è inutilizzabile, poi volta che viene registrato l'evento, il timer 1 ti salva il contenuto del suo registro in un altro registro. A quel punto devi far sollevare un interrupt, dall'interrupt estrarre il valore e poi resettare il contatore.
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 06:58 pm
se invece utilizzassi Stopwatch senza Interrupt per capire il tempo tra due HIGH?
Ha senso dire nelle variabili byte status = LOW ; poi fare un loop che attivi lo StopWatch al momento dell'HIGH (Stopwatch_start), e lo fermi al secondo HIGH (Stopwatch_stop), per poi riportare Stopwatch_start=Stopwatch_stop e calcolare i giri tramite la different Stopwatch_stop-Stopwatch_start?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 07:09 pm
prova questo

Code: [Select]

#include <StopWatch.h>



const byte pin2 = 2;     // interrupt startt
const byte pin3 = 3;     // interrupt stopp

volatile int statestartt = HIGH;    // stato normale startt
volatile int statestopp=HIGH;       // stato normale stopp

StopWatch sw_micros(StopWatch::MICROS);    // timer durata dente



long time = 0;           //valore durata dente microsecondi



int rpm = 0;             //numero giri
int gradidente = 6;     //ampiezza dente in gradi

void setup() {
Serial.begin(9600);     //comunicazione seriale

 pinMode(pin2, INPUT_PULLUP);
 pinMode(pin3, INPUT_PULLUP);
 attachInterrupt(0, startt, FALLING);   //interrupt in inizio dente
 attachInterrupt(1, stopp, RISING);     //interrupt fine dente
}

void loop()
{
 //se il dente è iniziato
 if(statestartt == LOW){
   sw_micros.start();//inizia a contare durata dente
   statestartt=HIGH;// reimposta startt
 }

 //se il dente è finito
 if(statestopp == LOW) {
   time=sw_micros.elapsed();                  //memorizza durata dente
   
 
   statestopp = HIGH;                         //reimposta stopp
   sw_micros.reset();     //azzera timer durata dente
 
    rpm=60000000/((time/gradidente)*360);      //calcolo rpm
Serial.println(rpm);                       //stampo rpm
 
 

   
 
 }


 
} // End Loop

void startt()//interrupt startt
{
 statestartt = !statestartt;  //inverti startt
}

void stopp()//interrupt stopp
{
 statestopp = !statestopp;    //inverti stopp
}


devi solo calcolare i gradi della pala (misura il raggio dal sensore al centro, fai la circonferenza, misura la larghezza della pala a quel raggio e ottieni una buona approssimazione
dovresti ottenere una stampa di rpm ogni pala alla fine della pala (quindi nello spazio vuoto dandoti il tempo di fare calcoli e stampare)

collega il filo del sensore sia al pin 2 e al pin 3
per legere i buchi o gli spazi inverti rising e falling negli interrupt

prova :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 07:34 pm
Perfetto lo provo subito! L'unico problema è che mi dice che sulla riga
Stopwatch sw_micros(Stopwatch::MICROS);    // timer durata dente
non mi rileva stopwatch e la variabile sw_micros
non è questa la libreria stopwatch?
http://www.avdweb.nl/arduino/hardware-interfacing/stopwatch.html#h0-1-5-1-stopwatchh
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 07:39 pm
risolto per la libreria, era questa: http://playground.arduino.cc/Code/StopWatchClass
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 28, 2013, 07:53 pm
esatto
poi se ti metti a giocare un po' con le operazioni e soprattutto il tipo di dato con cui le fai puoi ottenere risultati di rpm più precisi
a me non è mai servito quindi un po' approssima rpm fatto così
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 28, 2013, 08:03 pm
più tardi lo testo e vi aggiorno sui risultati!
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: PaoloP on Aug 28, 2013, 08:17 pm
Discussione interessante.  ;)
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 11:23 am
Non sono ancora riuscito a testare lo sketch, spero di testarlo nel pomeriggio.
Nel frattempo ho trovato questo sito:
http://www.fiz-ix.com/2012/11/measuring-signal-frequency-with-arduino/
ed ho provato a cambiare la porta di ingresso da 2 a 8 per usare il timer.
Non avendo il display ho tolto alcune righe relative all'LCD, ed ho modificato lo sketch (vedere sotto), tuttavia il sensore legge dati in continuo. Credo che il problema sia nel while e nella formula per contare la frequenza, non capisco perchè divide le pulsazioni per 13???

Code: [Select]

//define all the variables
int inputpin = 2;
unsigned long stateChanges;
//double freq;
unsigned long freq;
unsigned long rpm;
unsigned long temp = 0;
int state1 = 0;
int state2 = 0;
unsigned long prerpm;

void setup(){
  pinMode(inputpin, INPUT);
  pinMode(13,OUTPUT);
  Serial.begin(9600);
  freq = 0;
  rpm = 0;
  stateChanges = 0;
  prerpm = 0;
}

void loop(){
  state1 = digitalRead(inputpin);
  delayMicroseconds(10);
  state2 = digitalRead(inputpin);             //check for debounces...
  if (state1 == state2) {                     //check if both readings are same
  temp = micros();
  while((micros()-temp) < 1000000) {         //Wait for 1 second and measure number of state changes during that interval.
    if(digitalRead(inputpin) != state2) {    //check if state has changed..
      stateChanges++;                     
      state2 = digitalRead(inputpin);
    }
   }
  freq = (stateChanges)/13;            //calculate frequency...
  rpm = freq*60;                            //calculate rpm
  Serial.println(rpm);
  prerpm = rpm;
  stateChanges = 0;
  freq = 0;
  rpm = 0;
  }
}
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 29, 2013, 02:19 pm
buongiorno :)
secondo il mio modesto parere quel 13 significa che sul suo hardware aveva 6 pale e 6 spazi

se tu provi a disegnare una croce su un pezzo di carta e metti un numero prima e dopo ogni riga (un cambio stato a inizio pala, uno a fine pala eccetera) vedrai che per fare un giro completo devi avere 9 cambi di stato e non 8, quindi li 13 e non 12, ma è solo una teoria :)
1 e 9 dovrebbero essere lo stesso punto dopo un giro

lui in pratica conta i cambi di stato in un secondo e lo divide per il numero di cambi in un ciclo, ottiene giri al secondo e moltiplica per 60 che sono rpm

per la lettura in continuo non capisco cosa intendi, direi che quel codice deve stampare rpm ogni secondo circa

tra l'altro è carino sto codice :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 03:27 pm
Buongiorno Lucaleo  8)
infatti non è male lo sketch, grazie per la delucidazione sul 13!
per continuo intendo che il software legge impulsi senza inserire la turbina in mezzo!
Quale parte del software è sbagliata??
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 03:32 pm
torniamo al caro vecchio sketch iniziale updated by Lucaleo:
Code: [Select]
//Arduino Code
/*
* Tachometer
*
* M.G.McKinley
* 6/1/2009
* Adjust
*/
//Define Variables

int ticsPerRev = 7;       // define number of tics per rev of code wheel
unsigned long rpm = 0.0;  // I prefer float for rpm
volatile int rpmcount =0;  // volitile because the variable is manipulated during the interrupt
unsigned long timeold = 0; // used to calculate d_t= millis()-timeold;
unsigned long d_t;
 
void setup()
{
  Serial.begin(115200);
  attachInterrupt(0, rpm_fun, FALLING);
}

void loop()
{
  detachInterrupt(0);
  d_t=micros()-timeold;
  if (d_t >= 500000)
   {
     rpm = (60*1000000)/((d_t))*(rpmcount)/ticsPerRev;
     timeold = micros();
     d_t=0; //reset d_t

//Serial Port Output
     Serial.println(rpm);
     rpmcount = 0; //reset rpmcount
  }
     attachInterrupt(0, rpm_fun, FALLING);
}

void rpm_fun()
{
    detachInterrupt(0); //im not sure if this is necessary here
    rpmcount++; //update rpmcount
    attachInterrupt(0, rpm_fun, FALLING);

}


Visto che l'hardware funziona e che il contagiri a 550 rpm max sembra sfalsare di +/-50 rpm, c'è qualche algoritmo che mi permetta di ottenere una media più decente?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 29, 2013, 06:06 pm
Mah.... io abbandonerei quel codice o per lo meno va riscritto tutto perche secondo me non arriverai mai a una grande precisione....
Il codice che ti ho messo modificando quello mio della centralina credo che sia quello che ci vuole, prova a vedere se funzionicchia poi possiamo metterci un contatore e stampare rpm una volta al giro invece che ogni pala o qualunque altra cosa ti serva
Senza considerare che quel codice che ho messo se tu invece che lavorare con rpm ottenuto tramite calcoli lavori direttamente con i micros (con un hardware fisso tu puoi sapere con un po di matematica quando ci mettera il tuo buco a passare davanti al sensore a un qualunque numero di giri) di essere estremamente preciso nella misurazione ;)
Invece che lavorare con rpm potrai lavorare cosi
Sai che (numeri inventati) a 200 rpm il tuo buco passa in 1060 micros e a 201 in 1050
Se hai una lettura di 1057 potrai dire di essere a 200 rpm con un'ottima precisione :)
Il valore stampato di rpm sara sempre arrotondato nei vari calcoli ma i micros no, sono cosi come.escono....

EDIT
tra l'altro per misurare quanto ci metti da 0rpm a x rpm in maniera accurata devi avere rpm una volta al giro almeno, con quel codice avrai sempre un errore misterioso di +- 2 secondi max dato dal fatto che il contagiri ti aggiorna una volta al secondo sia quando inizia a girare che quando arrivi a rpm max ma non puoi sapere se hai iniziato a girare all'inizio o alla fine di quel secondo e lo stesso quando arrivi a rpm max

ha ragione paolo, è interessante sto problema :D
tra l'altro guardando i giri da un'ottica diversa da quelli del motore mi stanno venendo delle idee per modificare il mio di progetto :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 07:00 pm
Grazie Lucaleo per il feedback, la prossima settimana ho anche un maggiore supporto nella parte software quindi dovremo essere in grado di realizzare qualcosa di interessante.
Per quanto riguarda l'hardware, che schema hai usato?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 29, 2013, 07:03 pm

Grazie Lucaleo per il feedback, la prossima settimana ho anche un maggiore supporto nella parte software quindi dovremo essere in grado di realizzare qualcosa di interessante.
Per quanto riguarda l'hardware, che schema hai usato?


io ho brutalmente infilato un sensore di hall a3144 su arduino
il + a 5v
gnd a gnd
signal sui pin di interrupt
va benissimo :D
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 07:07 pm
alla grande!  :)
appena posso lo provo!
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 29, 2013, 07:15 pm
è comodo poi basta che attacchi una scaglietta di calamita con un po' di super attack dove ti serve e hai fatto il riscontro senza dover fare dei fori che se non precisi possono decisamente sbilanciare un volano (se noti sui volani spesso ci sono dei fori non passanti di varia profondità che servono proprio al bilanciamento)
in più visto che il volano immagino che voi lo usiate (visto che a quello serve :D ) per immagazzinare energia se nella configurazione di test fai dei buchi magari anche piuttosto distanti dal centro che non esistono nella produzione reale avrai un sistema che accelera più rapidamente e che decelera allo stesso modo (e quindi più irregolare anche come regime di rpm diventando più sensibile alle variazioni del vento)
ma forse sto esagerando con le pippe mentali ahahah
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 07:34 pm
Lucaleo sei troppo professional! :)
infatti avevo già pensato di usare l'effetto hall perchè lo ritenevo più preciso, ma non ho ancora comprato i pezzi per il circuito, appena ho tempo lo monto su e via con i tests!!!
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 29, 2013, 07:45 pm
beh la precisione la trovi dai tempi di rising e falling sul datasheet del componente
più sono brevi quei tempi più è preciso
fortunatamente rising e falling generalmente sono quasi uguali quindi si annullano e quindi semplicemente "spostano" un po' la lettura sul giro ma il tempo rimane corretto
comunque su un volano di qualche chilo di diametro di 50cm togliere del peso magari a 23 cm dal centro comporta delle differenze sulla reattività anche sensibili
basta pensare che alleggerire il volano su una macchina comporta cambiamenti percepibili nonostante anche cambio e ruote e tutti i vari organi in rotazione fanno anche loro da volano quindi i kg in rotazione sono gia parecchi (magari 30 o 40 senza problemi anche se con diametri abbastanza ridotti a parte ruote e volano ovviamente )

ho sulle spalle centinaia di ore di google mica noccioline ahahah
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 29, 2013, 11:14 pm
cmq ho trovato un tachimetro che sembra molto preciso ed è fatto con il PIC
http://www.ikalogic.com/99-000-rpm-contact-less-digital-tachometer/
che ne dite?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 30, 2013, 12:08 am
Bel progetto anche se fuori dalla mia portata  :smiley-roll-sweat:
Ma poi una volta che hai fatto quello sei capace di far quello che serve a te?
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: cyberhs on Aug 30, 2013, 02:58 am
Anche io sono curioso.

Che razza di turbina hai? O è una semplice pala eolica? Mi sembra stano che parli di 2500-3000 rpm che corrispondono a 40-50 rivoluzioni per secondo!

Se è un pala eolica non credo superi le 20 rivoluzioni al secondo.
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: crix87 on Aug 30, 2013, 11:17 am
Lucaleo, con il giusto supporto di un paio di persone probabilmente, da solo no :) cmq adesso contatto gli interessati e vi aggiorno!
cyberhs, è un minieolico ed in scala, sto facendo dei test anche a 30m/s quindi sono velocità limite e senza carico!
Title: Re: Contagiri con LED - riduzione dell'errore con pulseIn
Post by: lucaleo on Aug 30, 2013, 12:43 pm
Capisco capisco :)
Prova a farlo con arduino pero secondo me perche dovrebbe essere piu che sufficiente e si riesce senza problemi a fare tutto quello che ti serve compreso misurare l'accelerazione e ottenere dati finiti