Contagiri con LED - riduzione dell'errore con pulseIn

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

risolto per la libreria, era questa: Arduino Playground - StopWatchClass

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ì

più tardi lo testo e vi aggiorno sui risultati!

Discussione interessante. :wink:

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???

//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;
  }
}

buongiorno :slight_smile:
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 :slight_smile:
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 :smiley:

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??

torniamo al caro vecchio sketch iniziale updated by Lucaleo:

//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?

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 :wink:
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 :slight_smile:
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 :smiley:
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 :smiley:

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?

crix87:
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 :smiley:

alla grande! :slight_smile:
appena posso lo provo!

è 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 :smiley: ) 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

Lucaleo sei troppo professional! :slight_smile:
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!!!

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

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?

Bel progetto anche se fuori dalla mia portata :cold_sweat:
Ma poi una volta che hai fatto quello sei capace di far quello che serve a te?

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.

Lucaleo, con il giusto supporto di un paio di persone probabilmente, da solo no :slight_smile: 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!