perplessità con pulseIn()

ciao a tutti

sono nuovo di arduino e sto cercando di impostare un frequenzimetro

mi è stato detto di usare pulseIn(), ma se utilizzo l'esempio indicato qui http://www.arduino.cc/en/Reference/PulseIn non so come recuperare i dati e visualizzarli

un aiuto:question

per calcolare la frequenza col pulsein misuri solo una semionda: qindi il calcolo sarà: frequenza = 500000/duration; //calculate frequency

ciao!

grazie

capisco che 500000 è in microsecondi, e che serve a misurare mezzo ciclo secondo la formula f = 1/t

ovviamente, in caso di cicli asimmetrici, deduco che bisognerà fare due misure

io però sono proprio un principiante, e avrei bisogno di uno sketch che, partendo dall’esempio citato:

int pin = 7;
unsigned long duration;

void setup()
{
  pinMode(pin, INPUT);
}

void loop()
{
  duration = pulseIn(pin, HIGH);
}

mi permetta di leggere sul serial monitor la frequenza presente sul pin 7

ciao :slight_smile:

int pin = 7;
unsigned long duration;
unsigned long frequenza;

void setup()
{
  pinMode(pin, INPUT);
Serial.begin(9600);      // opens serial port, sets data rate to 9600 bps

}

void loop()
{
  duration = pulseIn(pin, HIGH);

frequenza = 500000/duration; //calculate frequency

Serial.print(frequenza); //oltre i 32767 hz potrebbe inviare dati errati

delay(500); // pausa di 0,5 sec  
}

però la prox vota sforzati un poco, eh? :wink:

per quanto riguarda i cicli asimmetrici esatto occorre fare 2 misurazioni semioda pos + neg per avere il periodo completo
ciao

ti sembrerà roba da pre-principiante, ma erano tre settimane che cercavo la soluzione

adesso, grazie alla tua risposta, posso cominciare 8-)

ciao

tranquillo tutti abbiamo iniziato da prinicipianti

se hai ancora problemi posta che vediamo di risolverli ciao

ne approfitto, sta tranquillo tu :)

e infatti il problema si è presentato subito

per prima cosa ho creato uno sketch sulla base delle tue indicazioni

int pin = 7;
unsigned long duration;
unsigned long frequenza;

void setup()
{
  pinMode(pin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  duration = pulseIn(pin, HIGH);
  frequenza = 500000/duration; //calculate frequency
  Serial.println("frequenza");
  Serial.println(frequenza);
  delay(500); 
}

a questo punto ho fatto un test con un generatore di segnali e ho ottenuto queste letture :-[

[u]frequenza lettura 1 lettura 2[/u]

1 KHz 834 844 2 KHz 1253 2512 5 KHz 5050 5050 10 KHz 8474 8474 20 KHz 12820 26315 50 KHz 50000 55000

anche sommando le due letture e dividendo per 2, i risultati non sono attendibili; per esempio, nel caso dei 2 KHz si ottiene 1882 KHz, e nel caso dei 20 KHz si ottiene 19567 KHz

dove sto sbagliando?

sei sicuro che i collegamenti erano stabili? il generatore è affidabile come frequenza? io per tarare uso i 50 hertz della corrente di casa: trasformatore non raddrizzato e si squadra l'onda. prova e facci sapere

[smiley=undecided.gif] il generatore ha una base dei tempi al quarzo; testato con un Philips 2618, la differenza fra i due è [u]al massimo[/u] di 1-2 Hz su tutte le frequenze da 1 kHz a 100 kHz

comunque, per scrupolo, ho provato il metodo del trasformatore (col quale ho scoperto che la frequenza di rete può oscillare fra 48 e 52 Hz)

ho rettificato l'onda e perciò, a causa della rettificazione della semionda negativa, ho ottenuto una frequenza di 100 Hz

la lettura ottenuta con lo sketch ha variato da 85 a 86

mi sembra complessa da risolvere

ciao

non so che dire, hai percaso modificato la freq del processore?

prova con questo codice se viene una misura esatta sennò sono problemi di collegamento o tensioni parassite

//variabili
int sigPin = 7; //signal pin
int state; //the state of the input
int oldstate;
unsigned long t; //timer
unsigned long s; //samples
unsigned long c; //count
unsigned long f; //frequency


//nell loop

c = 0;
   
   t = millis(); // read time at start of sampling
   for(s=0; s<10000; s++){ //take a number of samples
      state = digitalRead(sigPin); //read state
      if (state != oldstate){ //if state changes:
         c++; //increment counter
         oldstate = state; //and reset current state
      }

   }
   t = millis() - t; //read time at end of sampling

   c = c/2; // need to divide by 2 because counter incremented on each change - two changes per cycle

   f = 1000*c/t; //calculate frequency

no, non l'ho manomesso, non so neanche come si altera il clock del processore se eseguo il tuo nuovo codice arduino evidenzia questa riga c = 0; e dà questo messaggio d'errore: error: expected constructor, destructor, or type conversion before '=' token

:o

gli hai introdotti nel loop e setup?

//variabili
int sigPin = 7; //signal pin
int state; //the state of the input
int oldstate;
unsigned long t; //timer
unsigned long s; //samples
unsigned long c; //count
unsigned long f; //frequency


void setup()
{
  pinMode(sigPin, INPUT);
  Serial.begin(9600);
}

void loop()
{
  c = 0;
  
   t = millis(); // read time at start of sampling
   for(s=0; s<10000; s++){ //take a number of samples
      state = digitalRead(sigPin); //read state
      if (state != oldstate){ //if state changes:
         c++; //increment counter
         oldstate = state; //and reset current state
      }

   }
   t = millis() - t; //read time at end of sampling

   c = c/2; // need to divide by 2 because counter incremented on each change - two changes per cycle

   f = 1000*c/t; //calculate frequency 

  Serial.println("frequenza");
  Serial.println(f);
  delay(500);
}

[smiley=2vrolijk_08.gif] funziona!

legge correttamente tutte le frequenze da 1 kHz a 20 kHz, sbagliandosi al massimo di 30 Hz (più giù è la frequenza maggiore è la precisione); a 50 kHz dà i numeri (non quelli della frequenza..), ma questa è un'altra storia

in conclusione, ti sono grato

per aumentare la precisione ma con essa anche il tempo aumenta i campionamenti che sono il 10000 che vedi qui sotto

for(s=0; s<10000; s++){ //take a number of samples

aumentando questo valore dovrebbe darti valori corretti anche per valori superiori ai 50khz

in effetti, aumentando i campionamenti a 100000, la precisione e la stabilità della lettura risultano migliorate fino a 20kHz, e aumentandoli a 1000000 ancora di più, la lettura non fluttua, ma salendo di frequenza le cose non migliorano

con 1000000 di campionamenti, se genero 50 kHz la lettura che ottengo è 30.921 kHz

[smiley=huh.gif]/me

ciao... sono nuovo del forum...ho seguito l'argomento e vorrei chiedervi se è possibile applicare questo codice per la lettura della frequenza della bobina delle automobili per prelevare il numero di giri del motore... grazie!!! :D

Io vorrei chiederve da perfetto neofita in elettronica e di arduino...di cosa stavate parlando...non ci capisco un tubo!!

Quale e' il soggetto ? cosa voleva fare e perche' ? :-[

ciao nospda

la prova che ho descritto in un post precedente mi ha mostrato che la precisione, fino a 20000 hz, è notevole: uno sbaglio di 3-4 hz su 20000 mi sembra accettabile nella maggior parte dei casi

non conosco le automobili, ma se il massimo numero di giri che raggiungono è inferiore a 20000 il codice dovrebbe funzionare

io avrei paura, però, a usare il metodo che hai descritto, perchè credo che la tensione ai capi della bobina dì accensione vari fra 20mila e 40mila volt, roba da restare secchi; e come fare ad abbassare questa tensione fino a 5 volt per renderla compatibile con arduino?

ciao Khendal

il problema era il mio, volevo sapere come si misura una frequenza con arduino

per esempio la frequenza di un suono, ::) del numero di scatti di una macchina fotografica, ::) del numero di giri di una ruota di bicicletta

moltissimi sensori utilizzabili con arduino danno come risultato della misura una frequenza: per esempio, un sensore di temperatura da zero a cento gradi può generare una frequenza variabile da 0 a 10000, in modo tale che, se noi leggiamo con arduino una frequenza di 3759, la temperatura misurata è di 37,59 gradi

mi auguro di aver risposto a quello che volevi sapere