Частотомер 6.5 МГц (Arduino)

Библиотека FreqCount, позволяет на своей основе создать довольно точный частотомер, с разными интервалами времени измерения. Так же небольшая коррекция файла библиотеки позволяет откалибровать частотомер.

На рисунке показана схема частотомера, помимо платы Arduino и одной кнопки, частотомер содержит усилитель-формирователь, который позволяет измерять частоту как импульсного, так и синусоидального сигнала. Максимальная частота которую может измерять частотомер 6,5 МГц, так же доступно три интервала времени измерения — 0.1, 1 и 10  секунд.

#include <FreqCount.h>//https://github.com/PaulStoffregen/FreqCount/archive/master.zip
#include <LiquidCrystal.h>
// вход частотомера 5 
LiquidCrystal lcd(7, 8, 9, 10, 11, 12);// RS,E,D4,D5,D6,D7
void setup() {
  lcd.begin(16, 2);// LCD 16X2
  pinMode(3,INPUT);
  FreqCount.begin(1000);
}
unsigned long f;float f0;
int x,n=3,r;

void loop() {
  
  if(digitalRead(3)==HIGH){n++;x=0;delay(100);}
    lcd.setCursor(0,1);
  if(n==1){x++;if(x==1){FreqCount.begin(100);}r=-1;lcd.print("T = 0.1 s ");}
  if(n==2){x++;if(x==1){FreqCount.begin(10000);}r=1;lcd.print("T = 10 s ");}
  if(n==3){x++;if(x==1){FreqCount.begin(1000);}r=0;lcd.print("T = 1 s  ");}
  if(n>3){n=1;} 
    lcd.setCursor(0,0);
    lcd.print("F = ");
  if(f>=1000000 && n==3){f0=f/1000000.0;lcd.print(f0,6+r);lcd.print(" MHz");}
  if(f<1000000 && n==3){f0=f/1000.0;lcd.print(f0,3+r);lcd.print(" kHz");}
  if(f>=100000 && n==1){f0=f/100000.0;lcd.print(f0,6+r);lcd.print(" MHz");}
  if(f<100000 && n==1){f0=f/100.0;lcd.print(f0,3+r);lcd.print(" kHz");}
  if(f>=10000000 && n==2){f0=f/10000000.0;lcd.print(f0,6+r);lcd.print("MHz");}
  if(f<10000000 && n==2){f0=f/10000.0;lcd.print(f0,3+r);lcd.print(" kHz");}

  if (FreqCount.available()) { 
   
    f = FreqCount.read(); 
    
   lcd.setCursor(10,1);lcd.print("***");
  }
   delay(200);
   lcd.clear();
}

/*
Корректировка частотомера 
***************************************************************
В папке библиотек Arduino найти библиотеку FreqCount, 
в файле FreqCount.cpp найдите строки:
#if defined(TIMER_USE_TIMER2) && F_CPU == 12000000L
    float correct = count_output * 0.996155;
и заменить их на:
#if defined(TIMER_USE_TIMER2) && F_CPU == 16000000L
    float correct = count_output * 1.000000; 
где 1.000000 - Ваш поправочный коэффициент
корректировку нужно проводить подав на вход частотомера 1 МГц
После изминений файла загрузите по новой скетч в плату Arduino
***************************************************************
*/

 

Во второй версии частотомера используется восьми разрядный семисегментный индикатор на базе драйвера MAX7219.

#include <LedControl.h>//https://github.com/wayoda/LedControl/archive/master.zip
#include <FreqCount.h>//https://github.com/PaulStoffregen/FreqCount/archive/master.zip
LedControl lc = LedControl(12,11,10,1);// DIN(12), CLK(11), CS(10)
 
void setup() {
  lc.shutdown(0, false);
  FreqCount.begin(1000);
  lc.clearDisplay(0); 
  lc.setIntensity(0,8); // яркость 0-15
 
unsigned long f;
byte fq[8],pd=false;
 
void loop() {
 
  if (FreqCount.available()) {f = FreqCount.read(); }
  lc.setRow(0,7,0x47);
  fq[6]= f/1000000%10;
  fq[5]= f/100000%10;
  fq[4]= f/10000%10;
  fq[3]= f/1000%10;
  fq[2]= f/100%10;
  fq[1]= f/10%10;
  fq[0]= f%10%10;
  for(int i = 0;i < 7;i++){
  lc.setDigit(0,i,fq[i],pd);
  }
}

Comments

  1. Подскажите, пожалуйста, как при такте таймера 16МГц вы ловите импульсы 6,5МГц. 2 такта таймера это 8МГц, 3 так та 5,33333(3)МГц, 4 такта 4 МГц. Вся ваша статья обман. Выше 10000кГц измерение частоты тыкание пальцем в небо.

      1. Я таких фотографий могу много сделать. Это ничего не доказвает. А то что 6.5 МГц не кратно тактам таймера говорит о многом. И для подсчета времени между импульсами необходимо формировать прерывание по фронту, физическое! Это прерывание при вызове скидывает в стек как минимум десяток регистров, а потом их восстанавливает. Это порядка 50 тактов, еще нужно закинуть какой то код. Т.е. будет порядка 60 тактов. 16000000Гц / 60 = ~270кГц!!!!. И при этом из прерываний не вылазим, а нужно еще и основную программу обрабатывать. Так что 6,5кГц с вменяемой точностью это может быть.

        1. Можно использовать таймер с внешним тактированием, например 16 битный таймер, вход Т1
          TCCR1B = (1 < < CS12)|(1 << CS11)|(1 << CS10); //Внешний тактовый источник на выводе T1. Тактирование по фронту
          TIMSK1 |= (1 < < TOIE1); // бит TOIE1 в регистре TIMSK1 взывает прерывание когда таймер переполняется

          Дальше считать импульсы
          ISR (TIMER1_OVF_vect){x++;}

          Таймер переполняется через каждые 65535 импульсов на счетном входе,
          Далее считаем частоту:
          f = x * 65535 + TCNT1; // подсчет частоты
          счетный регистр TCNT1 содержит остатки счета импульсов до переполнения

          Считаем ровно 1 секунду:
          x=0; // обнуляем счетчик прерывания
          TCNT1 = 0; // обнулить счетный регистр
          TCCR1B = (1 < < CS12)|(1 << CS11)|(1 << CS10); // разрешить прерывания
          delay(1000); // ждем 1 секунду пока таймер считает импульсы
          TCCR1B &= ~(1 < < CS12)|(1 << CS11)|(1 << CS10); // запретить прерывания
          Для более точного отсчета 1 секунды можно задействовать таймер 2

          1. Продолжим… 3 вход в ардуино это вход INT1, физическое прерывание. Теперь о тактирование таймера, при 6,5 Мгц мы имеем прерывание каждые 100 тактов, значит 1 такт нам добавляет 65кГц…Это точность. Вызванное прерывание это 60 тактов. Для точной фиксации нужно делать прерывания по времени, это еще обработчик. При пересчете нам нужно останавливать прерывания. Показания будут скакать не имоверно. Идея интересная, но одними корректировками не обойтимь, нужно учесть все задержки обработчиков. Завтра попробую набросать код, 6,5МГц это сказка, но более низкие частоты может быть. У меня задача до 10кГц иметь стабильные показания онлайн.

  2. Это все на словах. В реалиях прерывания не вызываются мгновенно, везде нужно делать условия, которые меняют время исполнения. Не будет никогда 328p измерять выходную частоту выше 10кГц с приемлемой точностью. Только как индикатор +-1мГц.

Добавить комментарий

Войти с помощью: