Pe site-ul lablll (interface.khm.de) am gasit articolul Arduino Frequency Counter Library scris de Martin Nawrath, care prezinta un frecvenmetru care face masuratori pana la 8MHz folosind o librarie proprie (pe care o puteti se descarca de la http://interface.khm.de/wp-content/uploads/2009/01/FreqCounter_1_12.zip).
Atentie: intrarea semnalului se face doar pe pinul digital 5 al placii Arduino...
Schema de conectare este foarte simpla constand dintr-un un preamplificator sau un inversor pentru a avea la intrare semnal logic compatibil cu microcontrolerul ATmega depe placa Arduino:
Sketch-ul propus in acel articol e unul foarte simplu, afisarea frecventei facandu-se pe ecranul calculatorului (monitorizare seriala):
#include <FreqCounter.h>
void setup() {
Serial.begin(57600); // connect to the serial port
Serial.println("Frequency Counter");
}
long int frq;
Void loop() {
FreqCounter::f_comp= 8; // Set compensation to 12
FreqCounter::start(1000); // Start counting with gatetime of 1000ms
while (FreqCounter::f_ready == 0) // wait until counter ready
frq=FreqCounter::f_freq; // read result
Serial.println(frq); // print result
delay(20);
}
Aceeasi librarie este folosita si in articolul Arduino Frequency Counter, de data asta afisarea facandu-se pe un ecran LCD cu 16 coloane si 2 randuri (cel care foloseste driver-ul DS44780 si notat, uneori, 1602):
Schema de conectare este urmatoarea:
iar sketch-ul este:
#include <FreqCounter.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 6, 7, 8, 9); //Delcares LCD display pins
unsigned long frq; //Declares an extended size variable for the measured frequency
int cnt;
void setup() {
lcd.begin(16, 2); //LCD display columns and rows
lcd.print("FrequencyCounter"); //Prints a splash screen for 2 seconds
lcd.setCursor(0, 1);
lcd.print(" Version 2.1 ");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Frequency /Hz :"); //Prints "Frequency /Hz :"
}
void loop() {
FreqCounter::f_comp=10;
FreqCounter::start(1000);
while (FreqCounter::f_ready == 0)
frq=FreqCounter::f_freq; //Sets the 'frq' variable as the measured frequency
lcd.setCursor(0, 1);
lcd.print(frq); //Prints this measured frequency
lcd.print(" ");
}
Un alt articol, care foloseste aceasta librarie, facand si comparati intre masuratori cu acest frecventmetru si unul profesional, se numeste http://www.toddfun.com/2013/02/07/arduino-frequency-display-for-kenwood-ts-520s-hf-ham-radio-part-1/
Ulterior am gasit un site frantuzesc, http://f5mna.free.fr/, care are publicat articolul Fréquencemètre VHF UHF Arduino Exploitation de la librairie "FreqCount"
Acest frecventmetru masoara pana la 600MHz cu o rezolutie de 100Hz folosindu-se de un divizor dedicat, MB506 (datasheet-ul s epoate descarca de la http://www.qsl.net/n9zia/900/mb506.pdf, pus la intrarea placii Arduino sa divizeze cu 64.
Partea de conectare si programele aferente se gasesc la adresa http://f5mna.free.fr/arduino/Freq_Arduino.zip, schema dedivizare fiind:
Partea de afisare se poate adapta pentru domenii de Hz, kHz, MHz, inclusiv o autoscalare, prin conectarea divizorului si selectarea domeniului de divizare 64 sau 256, dar asta intr-un articol viitor...
Pana una alta, prezint sketch-ul din articolul frantuzesc, cu explicatii ale liniilor din program:
/*
//////////////// Fréquencemètre///////////////////
* Utilise le prédiviseur MB506 FUJITSU
* Les limites de la fréquence d'entrée Arduino et le division par 64
* autorisent un comptage jusqu'à environ 600 Mhz pour cette version.
* Pour mesurer une fréquence supérieure, le facteur de division sera
* de 128 ou 256 (Cf Datasheet).
* la ligne " unsigned long count = FreqCount.read() * 0.64001422;"
* sera modifiée en conséquence: 1.28 ou 2.56
* La valeur 001422 ci-dessus est une valeur d'ajustement.
*
* Mon site : http://f5mna.free.fr
*
*
* Entrée comptage PIN 5 dig.
*/
// comentarii in romaneste de Nicu FLORICA aka niq_ro
#include <FreqCount.h> // foloseste libraria dedicata pentru a masura frecventa
#include <LiquidCrystal.h> // foloseste libraria dedicata pentru afisaj LCD gen 1602
LiquidCrystal lcd(8, 9, 4, 3, 6, 7); // indica modul de conectare al pinior afisajului la placa Arduino
// LiquidCrystal lcd(RS, E, D4, D5, D6, D7); //se definesc pinii utilizati la afisajul LCD
unsigned long count0, count1, count2, count3, count4, count5; // se definesc variabile de lungime mare de la 0 la 4.294.967.295 (2^32-1)
void setup() {
lcd.begin(16, 2); // definire LCD ca 16x2
lcd.setCursor(0, 0); // pozitionare cursor in colt stanga sus
lcd.print (" FREQUENCEMETRE "); // scrie textul
lcd.setCursor(0, 1); // muta cursorul in colj stanga jos
lcd.print ("F5MNA Version 1"); // scrie alt text
delay(2000); // asteapta 2 secunde (2000ms)
lcd.clear (); // sterge ecranul
lcd.setCursor(3, 0); // muta cursorul pe colaone 3 de pe randul 0 (randul de sus)
lcd.print("Frequence"); // scrie frecventa
FreqCount.begin(1000); // citeste frecventa timp de 1 secunda (1000ms)
}
void loop() { // aici incepe progrsmul care ruleaza in blucla infinita
if (FreqCount.available()) // daca la intrare este semnal
{
unsigned long count = FreqCount.read() * 0.64007324; // valoare citita la pinul 5 este inmultita cu 0,64. deoarece a fost divizata anterior cu 64
// ATENTIE: face asta deoarece nu-i ajung numarul de cifre.. deci "count" e valoarea frecventei impartita la 100
//unsigned long count = FreqCount.read() * 1.28; // GHz // daca divizarea ar fi cu 128
// era asa: if (count < 10000) { (count = 0);} // signaux parasites ! / daca valaorea citita e mai mica de 10000x100=1MHz, insemna ca e zgomot si considera frecventa zero
// eu zic, deoare nu ar masura sub 1MHz
if (count < 100) { (count = 0);} // signaux parasites ! / daca valaorea citita e mai mica de 100x100=10000Hz=10kHz, insemna ca e zgomot si considera frecventa zero
/* Calcul du facteur de division.(1.0000222 ci-dessus)
Le quartz de 16 Mhz pilotant Arduino n'est pas précis ni identique pour toutes les platines.
Une correction peut être nécessaire au niveau logiciel. Pour ce faire,
mesurer la fréquence avec un fréquencemetre étalonné.
Puis faire le rapport entre féquence étalon mesurée et fréquence mesurée avec
ce fréquencemetre. Exemple 145000200/145000000 = 1.0000014
Multiplier le facteur de division (exemple 64) par cette valeur
vous obtenez 64.000088. Le facteur de correction devient 0.64000088
donc (count = count * 0.64000088)
*/
/*
// Affichage GHz si nécessaire
/////////////////////////////
// e asa ca nu e bine gandit..
if (count > 999999999) {
count1= (count/100000);
count2 = (count - (count1*100000));
count3 = (count2/10);
count4 = ((count2) - count3*10 );
}
*/
// Mhz
///////////////////
// original: if ((count > 999999) and (count < 1000000000)) (count1 = (count /10000));
// eu zic ca:
if ((count > 9999) and (count < 10000000)) (count1 = (count /10000));
{
count1 = (count /10000); // afla partea intreaga a milioanelor, care reprezinta si numarul milioanelor din numar
count2 = (count - (count1*10000)); // afla valoarea numarului de la mii in jos
count3 = (count2/10); // afla cifrele de mii
count4 = ((count2) - count3*10 ); // afla valoarea ultimei cifre din variabila "count", care reprezinta cifra sutelor din frecventa masurata
}
// < 1 MHz
////////////////////
// nu prea trebuie asta ca e acelasi lucru ca mai sus... deoarece count1=0
// original: if (count < 1000000)
// eu zic asa:
if (count < 10000) // faca frecventa citita e mai mica decat 1MHz (deci valoarea lui "count" < 10000
{
count2 = (count - (count1*1000)); // valoarea numarului de la mii in jos
count3 = (count2/10); // afla cifrele de la mii
count4 = ((count2) - count3*10 ); // afla valoarea ultimei cifre din variabila "count"
}
lcd.setCursor(3, 1); // pune cursorul pe randul 1, de jos, si a 3-a coloana
lcd.print (count1); // afiseaza cifrele din milioane
lcd.print ("."); // pune punct
if ((count3 < 100)and (count3 > 9)) (lcd.print ("0")); // daca cifrele din mii sunt de 2 cifre scrie un zero
if (count3 < 10) (lcd.print ("00")); // daca e doar o cifra la mii pune 2 de zero
lcd.print (count3); // afiseaza cifrele din mii
lcd.print ("."); // pune un punct
lcd.print (count4); // afiseaza cifra sutelor din frecventa
lcd.print ("00"); // rotunjeste cu 2 zerouri
lcd.print ("Hz "); // pusa de niq_ro si unitatea de masura
delay (100); // asteapta 0,1secunde si incepe iar masurarea si calculele
}
}
PS: divizorul cu MB506 modificat pentru 256 in loc de 64 arata asa:
23.09.2013
Pe ecran sunt afisate urmatoare variante:
Eu m-am gandit sa afisez frecventa, dar am doua variante:
- in Hz cu puncte intre multiplii
- in GHz cu virgula dupa cifra GHz-ilor, respectiv puncte intre ceilalti multiplii
Trebuie sa am si un aranjament al afisarii, asa ca m-am gandit la urmatoarele situatii:
- frecventa sub 1kHz
- frecventa peste 1kHz si sub 1MHz
- frecventa peste 1MHz si sub 1GHz
- frecventa peste 1GHz
24.09.2013
Situatiile ar fi:
31.12.2014
Am realizat un montaj de testare pentru un generator de semnal cu AD9850 dupa indicatiile din articolul de la http://www.ad7c.com/projects/ad9850-dds-vfo/ obtinand:
Apoi am incarcat intr-o alta placa Arduino primul sketch, pentru a vedea cum se comporta frecventmetrul (legare directa fara preamplificator, deoarece am semnal cu nivel suficient):
Rezultatul este foarte bun, eroare de 0,165%:
Exista frecventmetre de la Agilent care masoara pana la 350 de MHz
RăspundețiȘtergerePana la ce frecventa pot masura cu ajutorul placutei Arduino.ma refer la primul proiect.Multumesc frumos
RăspundețiȘtergereHi everyone,
RăspundețiȘtergereI have an idea about this sketch,
how about to make a menu for manual corrections for prescaler value?
begin from this code line:
unsigned long count = FreqCount.read() * 0.64000088
in reality to get correct reading on 145.000.000 Hz compared with my standard frequency source, i need to change the value if the prescaler 0.64000088 to 0.64007234.
If anyone can help:, how to make a changeable values between 0.64000000 to 0.64010000,
that mean 0.00000001 to 0.00009999 as a value setting that accessible from set menu using a rotary encoder?
Simple words,
There is a one button to access prescaler:
SET Prescaler code : 0.6400000000, 1.28, and 2.56
SET correction 0.00000001 to 0.00009999 (save it in EEPROM after exit this set menu)
a apreciate to anyone who understand my idea and help me to resolve this.