Go Down

Topic: Misura di frequenza con arduino (Read 1 time) previous topic - next topic

Manukun

Salve, dovrei misurare la frequenza (circa 31 kHz) di un segnale ad onda quadra in uscita da un TLC556/TLC555 in configurazione astabile, ho dimensionato le resistenze del circuito in modo tale da avere un duty cycle di circa 50%. Sto utilizzando la funzione PulseIn() per la misura, il problema è che il valore che misuro non è stabile (avvolte ho dei valori indesiderati che si discostano anche di molto dal valore vero). Vorrei sapere se è proprio la funzione PulseIn() ad essere poco precisa o sono io che sbaglio. Grazie in anticipo.

reizel

#1
May 14, 2012, 08:21 pm Last Edit: May 14, 2012, 08:23 pm by reizel Reason: 1
una volta qualcuno mi aveva dato questo sketch per misurare la frequenza, funzionava

Code: [Select]
//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);
}


io lo provavo con un generatore di forme d'onda

altro non so, e' un codice oltre le mie misere conoscenze ;)

ps.: credo che per misurare 31kHz si debba incrementare il 10000, prova, come dicevo non ricordo e non so

Brunello

Ci sarebbe anche un'apposita libreria http://www.pjrc.com/teensy/td_libs_FreqCount.html ed ero pure curioso di provarla

Manukun


una volta qualcuno mi aveva dato questo sketch per misurare la frequenza, funzionava

Code: [Select]
//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);
}


io lo provavo con un generatore di forme d'onda

altro non so, e' un codice oltre le mie misere conoscenze ;)

ps.: credo che per misurare 31kHz si debba incrementare il 10000, prova, come dicevo non ricordo e non so


Reizel grazie mille questo codice fa il suo dovere, l'unica cosa è che per ottenere dei valori precisi (che oscillano di circa 6 Hz) devo incrementare il numero di cicli del for fino a 1000000, ma questo mi rallenta un pò il programma.

Manukun


Ci sarebbe anche un'apposita libreria http://www.pjrc.com/teensy/td_libs_FreqCount.html ed ero pure curioso di provarla


Ho già provato ad utilizzare questa libreria ma mi da un errore in fase di compilazione. Non capisco perchè! :0

Michele Menniti

#5
May 15, 2012, 11:01 am Last Edit: May 15, 2012, 11:07 am by Michele Menniti Reason: 1


Ci sarebbe anche un'apposita libreria http://www.pjrc.com/teensy/td_libs_FreqCount.html ed ero pure curioso di provarla


Ho già provato ad utilizzare questa libreria ma mi da un errore in fase di compilazione. Non capisco perchè! :0

Temo sia dovuto al fatto che quella libreria sia per il Teensyduino, che ha un core diverso dai modelli tipici degli Arduino. Magari se posti l'errore se ne può avere conferma.

EDIT: più in basso c'è scritto
Quote
FreqCount can be used on Arduino, Sanguino and probably other boards. See the file util/timers.h for details to port to other AVR-based boards.
quindi probabilmente bisogna cambiare i pin di riferimento per usarla con Arduino.
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

flz47655

#6
May 15, 2012, 11:22 am Last Edit: May 15, 2012, 11:25 am by flz47655 Reason: 1
Guarda, l'oscillazione potrebbe essere dovuta dagli interrupt, prova a disabilitarli se non gli usi (la funzione delay() dopo non funziona però), un ulteriore causa dell'oscillazione potrebbe essere il clock con resonatore ceramico del 328 su arduino che non è stabile come un cristallo, ciao

EDIT: non so se senza interrupt funziona PulseIn..

Brunello

Code: [Select]
Ho già provato ad utilizzare questa libreria ma mi da un errore in fase di compilazione. Non capisco perchè!

Strano che ti dia errore. Per scrupolo l'ho provata ora ora su un arduino UNo con IDE 1.0.
Scavola di qualche hertz ( circa lo 0,15 % ) ma e' molto stabile

Michele Menniti


Code: [Select]
Ho già provato ad utilizzare questa libreria ma mi da un errore in fase di compilazione. Non capisco perchè!

Strano che ti dia errore. Per scrupolo l'ho provata ora ora su un arduino UNo con IDE 1.0.
Scavola di qualche hertz ( circa lo 0,15 % ) ma e' molto stabile

Per curiosità, hai dovuto modificare i pin come credo di aver letto o l'hai provata così com'è?
Guida alla programmazione ISP e seriale dei micro ATMEL (Caricare bootloader e sketch):
http://www.michelemenniti.it/Arduino_burn_bootloader.php
Guida alla Programmazione ATmega328 noP:
http://www.michelemenniti.it/atmega328nop.html
Articoli su Elettronica In:
http://www.michelemenniti.it/elettronica_in.html

Brunello

Cosi' com'e'. Con l'input sul Pin 5

lesto

fondamentalmente puoi provare a sostituire pulseIn con
Code: [Select]

tempo = micros();
while (HIGH ==digitalRead(pin)){;}
tempo = micros()-tempo;


la cosa ideale è sostituire digitalRead con le macro molto più veloci. Su linux alcune versioni di compilatori danno grossi problemi con la pulseIn
sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Go Up