Простой частотомер

Buldakov
Offline
Зарегистрирован: 17.01.2016

Предлагаю вашему вниманию вариант частотомера выполненный на плате Arduino Nano v3.0.

Напряжение питания 5 в. Тактовая частота 16 мгц.

Данный частотомер предназначен для измерения частоты входного сигнала подаваемый на вывод 5 платы.

Диапазон измеряемых частот от 100 Гц. до 4000000 Гц.

Точность вызванная работой программы составляет 1*10 Е-06.

//Пин 5 вход измерителя частоты. 
//---------------------------------------------------------------------------------------------------------------------------------//
#include <Wire.h>                                                                                                                  //
#include <LiquidCrystal_I2C.h>                                                                                                     //
//---------------------------------------------------------------------------------------------------------------------------------//
LiquidCrystal_I2C lcd(0x27, 16, 2); // Для экрана 16х2 (двухстрочный)                                                              //
//---------------------------------------------------------------------------------------------------------------------------------//
unsigned long interval_izm     =  1000;  //Время счета входной частоты в миллисекундах                                             //
unsigned long interval_LCD     =  1000;  //Интервал смены показаний на LCD в миллисекундах                                         //
unsigned long lastTime_LCD     =     0;  //Время последнего изменения состояния для LCD в миллисекундах                            //
unsigned long DeltaTime_LCD    =     0;  //Время с момента последнего вывода на LCD в миллисекундах                                //
unsigned long currentTime      =     0;  //Текущее время в милисекундах                                                            //
unsigned long F_min            =   100;  //Минимальная измеряемая частота Гц                                                       //
unsigned long korr_timer       =    67;  //Коррекция времени запроса после вызова таймера в тактах процессора                      //
//---------------------------------------------------------------------------------------------------------------------------------//
unsigned long ovf_tic_timer_1,out_ovf_tic_timer_1,tik_timer_1;                                                                     //
unsigned long ovf_tic_timer_2,out_ovf_tic_timer_2,tik_timer_2;                                                                     //
unsigned long interval_timer_2;                                                                                                    //
unsigned int  out_TCNT2,out_TCNT1;                                                                                                 //
boolean       stop_for_timer_1,start_for_timer_1,flag_LED;                                                                         //
float f,t1;                                                                                                                        //
//---------------------------------------------------------------------------------------------------------------------------------//
void setup() {                                                                                                                     //
Serial.begin(9600);                                                                                                                //
pinMode(5, INPUT);                     //Назначим вывод 5 на ввод сигналов                                                         //
digitalWrite(5, HIGH);                 //Включаем подтягивающий резистор                                                           //
lcd.init();                             //Задаем размерность LCD дисплея                                                           //
lcd.backlight();                        //Включаем подсветку экрана                                                                //
lcd.clear();                            //Очистка экрана                                                                           //
//---Настройка таймера 1-----------------------------------------------------------------------------------------------------------//
TCCR1A=0;                                                                                                                          //
TIMSK1 = 1 << OCIE1A; //прерывание по совпадению с OCR1A                                                                           //
OCR1A = (F_min-1);    //Минимальная измеряемая частота Гц                                                                          //
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << WGM12); //СТС делитель 1                                                  //
TCNT1=0;                                                                                                                           //
//---Настройка таймера 2-----------------------------------------------------------------------------------------------------------//
TCCR2A=0;                                                                                                                          //
TIMSK2 = 1<<TOIE2;//прерывание по переполнению таймера2                                                                            //
TCCR2B = 1 << CS20; // делитель 1                                                                                                  //
//---------------------------------------------------------------------------------------------------------------------------------//
interval_timer_2=(unsigned long)interval_izm*62.5;                                                                                 //
//---------------------------------------------------------------------------------------------------------------------------------//
}                                                                                                                                  //
//---Прерывание по таймеру 1-------------------------------------------------------------------------------------------------------//
ISR (TIMER1_COMPA_vect){                                                                                                           //
if (start_for_timer_1==1  && flag_LED==0)                                                                                          //
{                                                                                                                                  //
TCNT2=0;TCNT1=0;TCCR2B = 1 << CS20;                                                                                                //
start_for_timer_1=0;ovf_tic_timer_2=0;ovf_tic_timer_1=0;                                                                           //
}                                                                                                                                  //
if (stop_for_timer_1==1  && flag_LED==0){                                                                                          //
TCCR2B=0;TCCR1B=0;                                                                                                                 //
out_TCNT2=TCNT2;                                                                                                                   //
out_TCNT1=TCNT1;                                                                                                                   //
TCNT2=0; TCNT1=0; //сброс счётных регистров                                                                                        //
ovf_tic_timer_1=ovf_tic_timer_1+1;                                                                                                 //
out_ovf_tic_timer_1=ovf_tic_timer_1;ovf_tic_timer_1=0;                                                                             //
out_ovf_tic_timer_2=ovf_tic_timer_2;ovf_tic_timer_2=0;                                                                             //
flag_LED=1;stop_for_timer_1=0;                                                                                                     //
}                                                                                                                                  //
if (start_for_timer_1==0 && stop_for_timer_1==0 && flag_LED==0){ovf_tic_timer_1=ovf_tic_timer_1+1;}                                //
}                                                                                                                                  //
//---Прерывание по таймеру 2-------------------------------------------------------------------------------------------------------//
ISR (TIMER2_OVF_vect){                                                                                                             //
ovf_tic_timer_2=ovf_tic_timer_2+1; //считать количество переполнений таймера 2                                                     //
if (ovf_tic_timer_2>=interval_timer_2){stop_for_timer_1=1;}                                                                        //
}                                                                                                                                  //
//---------------------------------------------------------------------------------------------------------------------------------//
void loop()                                                                                                                        //
{                                                                                                                                  //
//---Условия для вывода показаний на LCD-------------------------------------------------------------------------------------------//
currentTime=millis();                                                                                                              //
DeltaTime_LCD  =abs(currentTime - lastTime_LCD);      //Время с момента последнего вывода на LCD                                   //
if (DeltaTime_LCD >= interval_LCD && flag_LED==1)     //Условия вывода на LCD                                                      //
{                                                                                                                                  //
//---------------------------------------------------------------------------------------------------------------------------------//
tik_timer_2=out_ovf_tic_timer_2*256+out_TCNT2-korr_timer;                                                                          //
tik_timer_1=out_ovf_tic_timer_1*F_min+out_TCNT1;                                                                                   //
t1=(float)tik_timer_2/tik_timer_1;                                                                                                 //
f=1000000.0/(t1*0.0625);                                                                                                           //
//---------------------------------------------------------------------------------------------------------------------------------//
Serial.print("ovf_tic2=");Serial.print(out_ovf_tic_timer_2);Serial.print(" ,");                                                    //
Serial.print(" TCNT2 =") ;Serial.print(out_TCNT2)          ;Serial.print(" ,");                                                    //
Serial.print("  tik2 =") ;Serial.print(tik_timer_2)        ;Serial.print(" n.    ");                                               //
Serial.print("ovf_tic1=");Serial.print(out_ovf_tic_timer_1);Serial.print(" ,");                                                    //
Serial.print(" TCNT1 =") ;Serial.print(out_TCNT1)          ;Serial.print(" ,");                                                    //
Serial.print("  tik1 =") ;Serial.print(tik_timer_1)        ;Serial.print(" n.");                                                   //
Serial.print("  f  =") ;Serial.print(f,3)        ;Serial.println(" Hz");                                                           //
lcd.clear();                            //Очистка экрана                                                                           //
lcd.setCursor(0, 0);lcd.print(tik_timer_2);                                                                                        //
lcd.setCursor(9 ,0);lcd.print(tik_timer_1);                                                                                        //
lcd.setCursor(0 ,1);lcd.print(f,3);                                                                                                //
//---------------------------------------------------------------------------------------------------------------------------------//
lastTime_LCD = currentTime;                                                                                                        //
flag_LED=0;                                                                                                                        //
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << WGM12); //СТС делитель 1                                                  //
start_for_timer_1=1;                                                                                                               //
}                                                                                                                                  //
//---------------------------------------------------------------------------------------------------------------------------------//
}                                                                                                                                  //
//---------------------------------------------------------------------------------------------------------------------------------//

 

Buldakov
Offline
Зарегистрирован: 17.01.2016

Нашел 1 ошибку. Строку 56 надо убрать.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Buldakov пишет:

Нашел 1 ошибку. Строку 56 надо убрать.

Отлично! Ищите следующую, ибо закон Брукса никто не отменял. :)

(Если вдруг не знаете, закон гласит: "every last bug you found is actually the penultimate" ("всякая найденная последняя ошибка на самом деле является предпоследней")

Buldakov
Offline
Зарегистрирован: 17.01.2016

Версия частотомера от 06 февраля 2016.

Диапазон частот от 100 до 4500000 Гц.

//Пин 5 вход измерителя частоты. 
//06_02_2016
//------------------------------
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C lcd(0x27, 16, 2); // Для экрана 16х2 (двухстрочный)
//----
unsigned long interval_izm= 1000;//Время счета входной частоты в миллисекундах
unsigned long interval_LCD= 1000;//Интервал смены показаний на LCD в миллисекундах
unsigned long F_min       =   99;//Минимальная измеряемая частота Гц
unsigned long korr_timer  =   67;//Время запроса после вызова таймера в тактах
//----
unsigned long currentTime;  //Текущее время в милисекундах
unsigned long lastTime_LCD; //Время последнего изменения LCD
unsigned long DeltaTime_LCD;//Время с момента вывода на LCD
unsigned long ovf_tic_timer_1,out_ovf_tic_timer_1;
unsigned long ovf_tic_timer_2,out_ovf_tic_timer_2;
unsigned long tik_timer_1,tik_timer_2;
unsigned long interval_timer_2;
unsigned int  out_TCNT2,out_TCNT1;
boolean       stop_for_timer_1,start_for_timer_1,flag_LED;
float f,t1;
//----
void setup() {
pinMode(5, INPUT);              //Назначим вывод 5 на ввод сигналов
digitalWrite(5, HIGH);          //Включаем подтягивающий резистор
lcd.init();                     //Задаем размерность LCD дисплея
lcd.backlight();                //Включаем подсветку экрана
lcd.clear();                    //Очистка экрана
//---Настройка таймера 1
TCCR1A=0;
TIMSK1 = 1 << OCIE1A; //прерывание по совпадению с OCR1A
OCR1A = (F_min-1);    //Минимальная измеряемая частота Гц
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << WGM12);
TCNT1=0;
//---Настройка таймера 2
TCCR2A=0;
TIMSK2 = 1<<TOIE2;//прерывание по переполнению таймера2
TCCR2B = 1 << CS20; // делитель 1
//----
interval_timer_2=(unsigned long)interval_izm*62.5;
//----
}
//---Прерывание по таймеру 1
ISR (TIMER1_COMPA_vect){
if (start_for_timer_1==1  && flag_LED==0)
{
TCNT2=0;TCCR2B = 1 << CS20;TCNT1=0;TCNT1=0;
start_for_timer_1=0;ovf_tic_timer_2=0;ovf_tic_timer_1=0;
}
if (stop_for_timer_1==1  && flag_LED==0){
TCCR2B=0;TCCR1B=0;
out_TCNT2=TCNT2;
out_TCNT1=TCNT1;
TCNT1=0;TCNT2=0;  //сброс счётных регистров
out_ovf_tic_timer_1=ovf_tic_timer_1;ovf_tic_timer_1=0;
out_ovf_tic_timer_2=ovf_tic_timer_2;ovf_tic_timer_2=0;
flag_LED=1;stop_for_timer_1=0;
}
if (start_for_timer_1==0 && stop_for_timer_1==0 && flag_LED==0)
{ovf_tic_timer_1=ovf_tic_timer_1+1;}
}
//---Прерывание по таймеру 2
ISR (TIMER2_OVF_vect){
ovf_tic_timer_2=ovf_tic_timer_2+1; //количество переполнений таймера 2
if (ovf_tic_timer_2>=interval_timer_2 && flag_LED==0)stop_for_timer_1=1;
}
//----
void loop()
{
//---Условия для вывода показаний на LCD
currentTime=millis();
DeltaTime_LCD  =abs(currentTime - lastTime_LCD);
if (DeltaTime_LCD >= interval_LCD && flag_LED==1)//вывод на LCD
{
//----
tik_timer_2=(unsigned long)out_ovf_tic_timer_2*256+out_TCNT2;
tik_timer_1=(unsigned long)out_ovf_tic_timer_1*F_min+out_TCNT1;
t1=(float)(tik_timer_2-korr_timer)/tik_timer_1;
f=1000000.0/(t1*0.0625);
//----
lcd.clear();                            //Очистка экрана
lcd.setCursor(0 ,0);lcd.print(f,3);lcd.print(" Hz");
//----
lastTime_LCD = currentTime;
flag_LED=0;             //Сигнал об окончании вывода на индикатор
TCCR1B = (1 << CS10) | (1 << CS11) | (1 << CS12) | (1 << WGM12);
start_for_timer_1=1;
}
}

 

Vitos-Vitos
Offline
Зарегистрирован: 05.05.2016

Я полный чайник в этих вопросах. Если не сложно, подскажите    -----  можно ли Вашим способом замерить частоту около 800-5000Гц и амплитудой 15В

Buldakov
Offline
Зарегистрирован: 17.01.2016

Частоту можно замерить если ваше устройство выдает частотный сигнал по напряжению от нуля до 15 вольт. Для этого надо между вашим устройством и выводом 5 Arduino повесить резистор номиналом от 2 до 10 Ком.

Частоту нельзя померить простым способом если вы берете сигнал от минус 7.5 до плюс 7.5 вольт. (например если в цепи сигнала стоит конденсатор, или это выход усилителя звука). В этом случае необходим будет как минимум еще 1 диод.

Ссылка на схему подключения

http://radiolubitel.net/index.php/elektronika/301-ogranichiteli-urovnya

смотри рис:28.10 или

рис:28.14 а. Только стабилитрон надо на 4.7 вольта.

SPIREX
SPIREX аватар
Offline
Зарегистрирован: 05.05.2016

  

Buldakov
Offline
Зарегистрирован: 17.01.2016

Просьба помочь.

Делаю частотомер на нулевом прерывании и таймере 1.

Если на вход пин 2 подается частота частоту показывает правильно.

Если на вход подается нулевая частота тоже показывает правильно 0.

Если сначала на входе небыло частоты, а потом ее подали - то показания меняются и частота показывается правильно.

Если частота уже была, а мы прекратили подавать на вход частоту - то на индикаторе высвечивается последнее значение измеренной частоты на ноль она не сбрасывается и индикатор больше не обновляется.

//Максимальная измеряемая частота 160000 Гц.                                                               //
//Пин 2 вход измерителя частоты.                                                                           //
//Пин 11 выход генератора частоты.                                                                         //
//---------------------------------------------------------------------------------------------------------//
#include <LiquidCrystal.h>                                                                                 //
//---------------------------------------------------------------------------------------------------------//
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);                                                                       //
unsigned int  interval_izm  =     1000;        //Время счета входной частоты в миллисекундах.              //
unsigned long freq_gen      = 16000000;        //Тактовая частота кварцевого генератора в Гц               //
unsigned long Timer_gen     =    80000;        //Тактовая частота max=160000 Гц min=31250 Гц.              //
//---------------------------------------------------------------------------------------------------------//
boolean       start_timer_1,stop_timer_1,flag_LED,sig,sig_Lcd;                                             //
int           n_timer_2;                                                                                   //
unsigned int  ovf_tik_timer_1;                                                                             //
unsigned long ovf_tik_int_0;                                                                               //
unsigned long tik_int_0,tik_timer_1;                                                                       //
float         f,t1;                                                                                        //
//---------------------------------------------------------------------------------------------------------//
void setup() {                                                                                             //
lcd.begin(16, 2);                              //Задание размерности экрана                                //
lcd.clear();                                   //Очистка экрана                                            //
pinMode     (2, INPUT);                        //Вывод 2 в режим ввода                                     //
digitalWrite(2, HIGH);                         //Включаем подтягивающий резистор                           //
//---------------------------------------------------------------------------------------------------------//
delay(1000);                                   //Ждем 1 секунду                                            //
lcd.setCursor( 0, 0);                                                                                      //
lcd.print("Ver 30.09.2016");                                                                               //
delay(1000);                                   //Ждем 1 секунду                                            //
interval_izm=interval_izm/4;                                                                               //
sig_Lcd=1;                                                                                                 //
//---Настройка прерывания int 0----------------------------------------------------------------------------//
EIMSK   =  (1<<INT0);                          //разрешение прерываний INT0                                //
EICRA   =  (1<<ISC01) | (1<<ISC00);            //настройка INT0 по фронту                                  //
//---Настройка таймера 0-----------------------------------------------------------------------------------//
TCCR0B=0;TIMSK0=0;                             //Отключить системный таймер                                //
//---Настройка таймера 1-----------------------------------------------------------------------------------//
TCCR1A  = 0;                                                                                               //
TCCR1B  = 0;                                                                                               //
TCNT1   = 0;                                                                                               //
OCR1A   = 63999;                               //отсчитать 64 000 входных импульсов до прерывания          //
TIMSK1 |= (1 << OCIE1A);                       //enable timer compare interrupt                            //
//---Настройка таймера 2-----------------------------------------------------------------------------------//
n_timer_2=freq_gen/Timer_gen;                                                                              //
n_timer_2=(n_timer_2/2)-1;                                                                                 //
pinMode(11, OUTPUT);                           //Назначим вывод 11 на вывод сигналов                       //
TCCR2A = (0<<COM2A1)|(1<<COM2A0)|(1<<WGM21)|(0<<WGM20); //CTC mode                                         //
TCCR2B = (0 << CS22)|(0 << CS21)|(1 << CS20);  //Коэффициент предделителя 1                                //  
OCR2A =n_timer_2;                              //Регистр сравнения.Сюда записываем то, с чем надо сравнить.//  
//---------------------------------------------------------------------------------------------------------//
}                                                                                                          //
//---Прерывание по int 0-----------------------------------------------------------------------------------//
ISR (INT0_vect){                                                                                           //
if (start_timer_1==1                    && flag_LED==0){TCNT1=0;ovf_tik_timer_1=0;start_timer_1=0;}        //
if ( stop_timer_1==1                    && flag_LED==0){TCCR1B=0;stop_timer_1=0;flag_LED=1;}               //
if (start_timer_1==0 && stop_timer_1==0 && flag_LED==0){ovf_tik_int_0=ovf_tik_int_0+1;}                    //
}                                                                                                          //
//---Прерывание по таймеру 1-------------------------------------------------------------------------------//
ISR(TIMER1_COMPA_vect) {                       // timer compare interrupt service routine                  //
ovf_tik_timer_1=ovf_tik_timer_1+1;             //считать количество переполнений таймера 1                 //
if (ovf_tik_timer_1>=interval_izm)sig=1;                                                                   //
if (sig==1 && flag_LED==0)stop_timer_1=1;                                                                  //
}                                                                                                          //
void loop()                                                                                                //
{                                                                                                          //
Label_a:                                                                                                   //
//---Блок вывода показаний на LCD--------------------------------------------------------------------------//
if (sig==1 && flag_LED==1) sig_Lcd=1;                                                                      //
if (sig==1 && flag_LED==0 && ovf_tik_int_0==0) {sig_Lcd=1;TCCR1B=0;stop_timer_1=0;}                        //
if (sig_Lcd==1)                                //Условия вывода на LCD                                     //
{                                                                                                          //
//---------------------------------------------------------------------------------------------------------//
tik_timer_1=ovf_tik_timer_1*64000+TCNT1-4;                                                                 //
tik_int_0  =ovf_tik_int_0;                                                                                 //
t1         =(float)tik_int_0/tik_timer_1;                                                                  //
f          =(float)freq_gen*t1;                                                                            //
//---Вывод показаний на экран------------------------------------------------------------------------------//
lcd.clear();                                   //Очистка экрана                                            //
lcd.setCursor( 0,0);lcd.print(tik_int_0);                                                                  //
lcd.setCursor( 7,0);lcd.print(tik_timer_1);                                                                //
lcd.setCursor( 0,1);lcd.print(f,2);lcd.print(" Hz");                                                       //
//---------------------------------------------------------------------------------------------------------//
TCNT1=0;ovf_tik_timer_1=0;start_timer_1=1;ovf_tik_int_0=0;sig=0;sig_Lcd=0;                                 //
flag_LED=0;                                    //Сигнал об окончании вывода на индикатор                   //
TCCR1B=(1<<CS10)|(1<<WGM12);                   //Запускаем Таймер 1                                        //
goto Label_a;                                                                                              //
}                                                                                                          //
//---------------------------------------------------------------------------------------------------------//
}                                                                                                          //
//---------------------------------------------------------------------------------------------------------//

 

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

Смотрим на мой пост №2 :)

Buldakov
Offline
Зарегистрирован: 17.01.2016

Спасибо за помощь. Ошибку нашел. Оказалось значение одной переменной записал 1 вместо 0. Во 2 посте правильный код. А по всем вопросам по программе буду отсылать лично к вам. Вы тоже им подскажете.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Buldakov, кстати на будущее -форматируйте текст программы. В том виде что вы вставили -совершенно не читабельно, в основном из-за гигантских отступов в комментариях. Может у вас в редакторе смотрится красиво, но при вставлении на форум становится ужастно.

 

Buldakov
Offline
Зарегистрирован: 17.01.2016

Согласен, что не читается. А что делать если форум разбивает длинные строки на две строки. Есть конечно вариант сократить длинну строк для форума, а потом вернуть обратно. Попробую так и сделать.

Buldakov
Offline
Зарегистрирован: 17.01.2016

Вот этот вариант должен быть лучше.

//Максимальная измеряемая частота 160000 Гц.
//Пин 2 вход измерителя частоты.
//Пин 11 выход генератора частоты.
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
unsigned int  interval_izm  =     1000;//Время счета входной частоты в миллисекундах.
unsigned long freq_gen      = 16000000;//Тактовая частота кварцевого генератора в Гц.
unsigned long Timer_gen     =    80000;//Тактовая частота max=160000 Гц min=31250 Гц.
boolean       start_timer_1,stop_timer_1,flag_LED,sig,sig_Lcd;
int           n_timer_2;
unsigned int  ovf_tik_timer_1;
unsigned long ovf_tik_int_0;
unsigned long tik_int_0,tik_timer_1;
float         f,t1;
void setup() {
lcd.begin(16, 2);        //Задание размерности экрана.
lcd.clear();             //Очистка экрана.
pinMode     (2, INPUT);  //Вывод 2 в режим ввода.
digitalWrite(2, HIGH);   //Включаем подтягивающий резистор.
delay(1000);             //Ждем 1 секунду.
lcd.setCursor( 0, 0);
lcd.print("Ver 30.09.2016");
delay(1000);             //Ждем 1 секунду.
interval_izm=interval_izm/4;
sig_Lcd=1;
//Настройка прерывания int 0.
EIMSK   =  (1<<INT0);    //разрешение прерываний INT0
EICRA   =  (1<<ISC01) | (1<<ISC00);//настройка INT0 по фронту
//Настройка таймера 0.
TCCR0B=0;TIMSK0=0;       //Отключить системный таймер
//Настройка таймера 1
TCCR1A  = 0;
TCCR1B  = 0;
TCNT1   = 0;
OCR1A   = 63999;        //отсчитать 64 000 входных импульсов
TIMSK1 |= (1 << OCIE1A);//enable timer compare interrupt
//Настройка таймера 2
n_timer_2=freq_gen/Timer_gen;
n_timer_2=(n_timer_2/2)-1;
pinMode(11, OUTPUT);   //Назначим вывод 11 на вывод сигналов
TCCR2A = (0<<COM2A1)|(1<<COM2A0)|(1<<WGM21)|(0<<WGM20);//CTC mode
TCCR2B = (0 << CS22)|(0 << CS21)|(1 << CS20);//Коэффициент предделителя =1  
OCR2A =n_timer_2;//Регистр сравнения.Сюда записываем то, с чем надо сравнить.  
}
//Прерывание по int 0
ISR (INT0_vect){
if (start_timer_1==1 && flag_LED==0){TCNT1=0;ovf_tik_timer_1=0;start_timer_1=0;}
if ( stop_timer_1==1 && flag_LED==0){TCCR1B=0;stop_timer_1=0;flag_LED=1;}
if (start_timer_1==0 && stop_timer_1==0 && flag_LED==0){ovf_tik_int_0=ovf_tik_int_0+1;}
}
//Прерывание по таймеру 1
ISR(TIMER1_COMPA_vect) {           // timer compare interrupt service routine
ovf_tik_timer_1=ovf_tik_timer_1+1; //считать количество переполнений таймера 1
if (ovf_tik_timer_1>=interval_izm)sig=1;
if (sig==1 && flag_LED==0)stop_timer_1=1;
}
void loop()
{
Label_a:
//Блок вывода показаний на LCD
if (sig==1 && flag_LED==1) sig_Lcd=1;
if (sig==1 && flag_LED==0 && ovf_tik_int_0==0) {sig_Lcd=1;TCCR1B=0;stop_timer_1=0;}
if (sig_Lcd==1)    //Условия вывода на LCD
{
tik_timer_1=ovf_tik_timer_1*64000+TCNT1-4;
tik_int_0  =ovf_tik_int_0;
t1         =(float)tik_int_0/tik_timer_1;
f          =(float)freq_gen*t1;
//Вывод показаний на экран
lcd.clear();    //Очистка экрана
lcd.setCursor( 0,0);lcd.print(tik_int_0);
lcd.setCursor( 7,0);lcd.print(tik_timer_1);
lcd.setCursor( 0,1);lcd.print(f,2);lcd.print(" Hz");
TCNT1=0;ovf_tik_timer_1=0;start_timer_1=1;ovf_tik_int_0=0;sig=0;sig_Lcd=0;
flag_LED=0;                //Сигнал об окончании вывода на индикатор
TCCR1B=(1<<CS10)|(1<<WGM12);//Запускаем Таймер 1
goto Label_a;
}
}

 

Buldakov
Offline
Зарегистрирован: 17.01.2016

Вопрос решился положительно.

Просто частотомер имеет 4 режима счета частоты. 3 режима я запрограммировал, а про четвертый забыл. Запрограммировал 4 режим и все заработало. Всем спасибо.

И особенно лично ЕвгенийП.

ЕвгенийП
ЕвгенийП аватар
Онлайн
Зарегистрирован: 25.05.2015

да, не за что! Ещё увидимся, т.к. "закон Брукса никто не отменял" :)

Buldakov
Offline
Зарегистрирован: 17.01.2016

Теперь другой вопрос. Как лучше сделать вывод измеренной частоты?

С фиксированной точкой. Или равнение по левому разряду. И надо ли делать различное число знаков после запятой в зависимости от частоты?

Пока сделал так:

   888.888 Hz

 8888.88  Hz

88888.8   Hz

Клапауций 232
Offline
Зарегистрирован: 05.04.2016

ЕвгенийП пишет:

да, не за что! Ещё увидимся, т.к. "закон Брукса никто не отменял" :)

прекрасно. Закон Брукса моим высочайшим указом отменён с момента публикации этого поста.

di_mot
Offline
Зарегистрирован: 12.08.2016

Buldakov пишет:
Как лучше сделать вывод измеренной частоты?

А с какой точностью ва-аще измерят твой частотомер?

Какая точность на нижнем пределе измерения (100Гц) и верхнем (4,5мГц)?

Ответ с "точностью кварца" - ниачом. Бо тут же будет встречный вопрос на засыпку: - А какая у данного кварца точность? Абсолютная и относительная.

Где и что измерять собрался частотомером?

Сама постановка вопроса показывает, что нет понимания "что и как".

Радиолюбители бьются за точность и стабильность частоты опорного генератора в приёмо-передатчиках до... Значит прибор, которым измерют, должет быть в 10 раз точнее. :-) Ведь +/- еденица в младшем разряде - автоматически возникающая погрешность при цифровой обработке. Ее отбрасываем, штобы не морщила нам мозг своей "квази-мега-точностью."

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

диодов по входу никаких не надо  резюк   на  входо  на 10ком и 50 вольт можно смело подать

каждый вход защищён диодами внутри микросхемы

 меньше  нуля не будет выше   напряжения питания тоже.

Автор молодец, пиши ещё, занимайся   творчеством, на нудил внимания не обращай  )))

Ксти  хорошобы   нижний предел от 0.1 Гц

Автоопределение   частоты ,если  большая  то   быстрый счёт если маленькая  на  длинный  отсчёт.

А  точность,её всегда можно улучшить, когда будет надо.

Buldakov
Offline
Зарегистрирован: 17.01.2016

Вообще то тут 2 разных частотомера. Первый измеряет частоту от 100 до 4500000 Гц. Второй от 1 до 160000 Гц. Частоту можно измерять от 0.1 Гц если время счета сделать 10 сек.

Точность измерения на 100 Гц и на 4500000 Гц одинаковая и составляет 4/16000000 - это программная точность. Лучше вы не получите. А точность кварца такая - какой вы поставите кварц. Эсли вы поставите Рубидиевый будет самая лучшая.

Количество знаков зависит от частоты: При времени измерения 1 сек.

от 100000 Гц и выше 0.1 Гц

от 10000 до 100000 Гц - 0.01 Гц

от 1000 до 10000 Гц - 0.001 Гц

от 100 до 1000 Гц - 0.0001 Гц

Частотомер делал для измерения температурной нестабильности LC генератора на частоту 700 Гц.

А вы не думаете, что единица в младшем разряде уже отброшена? И можно верить единице младшего разряда при частоте измерения 400 Гц Четвертому знаку после запятой.

И кстати радиолюбители бьются за точность частоты опорного генератора на частоты от 1800000 Гц. Там достаточно единиц Гц.

А если частоты до 10000 Тут вы точнее 0.01 процента не померите обычным частотомером.

di_mot
Offline
Зарегистрирован: 12.08.2016

Buldakov, после 80-й строчки из последнего кода:

f=1000000.0/(t1*0.0625);

спорить откровенно лень....

Buldakov
Offline
Зарегистрирован: 17.01.2016

 

 

А о чем вы хотели поспорить? Сначала заинтригуете, а потом ничего не говорите.

 

selevo
selevo аватар
Offline
Зарегистрирован: 21.12.2013

низкую частоту (0.1-100гц )можно   считать   заполнением  счётчика от кварца

например  0.1 Гц заполнить импульсами 1\4   генератора, затем посчитать сколь набежало за 0.1 секунду

И не адо  ждать 10 секунд

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

selevo, как изволите вас понимать вашу методику ? О том что входящая частота =0,1Гц можно узнать только спустя полный её период, т.е. через 10 секунд.

di_mot
Offline
Зарегистрирован: 12.08.2016

Buldakov, для примера твоей безграмотности приведу:

1. Радиолюбительский диапазон начинается с "160 метров", 1810 - 2000 кГц. Следующий "80 метров" лежит между 3500-3800 кГц.

2. Зарытое во внутрь 73-й строки скетча: lcd.print(f,2); где f=(float)freq_gen*t1; определенное в строке №68 того же скетча. Какую математическую погрешность на 700гц и 3,5мГц дает сей код?

 

Buldakov
Offline
Зарегистрирован: 17.01.2016

Я про это и написал. Что начинается диапазон со 160м или 1800000 Гц. или пусть будет оф. диапазон от 1810 кГц. Хорошо давайте к примеру приведем обычную однополосную модуляцию. (Телеграфом уже мало кто пользуется) Возьмем телефон. Если взять какой нибудь фильтр типа ЭМФ 500-3В он режет ПЧ с полосой пропускания 3.3 кГц. В итоге получим диапазон частот для одной станции в диапазоне от 1900 до 1903 кГц. Изменение частоты ЗГ на десятки Гц. никак не отразится на сигнале. Поэтому НЧ диапазоны и предназначены для начинающих. Таким образом точность может составлять около 1/200000.

Теперь по поводу моего кода. Погрешность частотомера не зависит от частоты и составляет 4/16000000.

Т.е. Он измерит частоту на диапазоне 80 Метров с точностью до одного герца. Если надо мерить большую частоту на вход надо поставить делитель типа 555ие2.

А по поводу того что там стоит 2 знака после запятой - то это для измерения низких частот. На диапазон 80 м. можно эти 2 знака выкинуть.

di_mot
Offline
Зарегистрирован: 12.08.2016

Buldakov пишет:

Теперь по поводу моего кода. Погрешность частотомера не зависит от частоты и составляет 4/16000000.

Т.е. Он измерит частоту на диапазоне 80 Метров с точностью до одного герца. Если надо мерить большую частоту на вход надо поставить делитель типа 555ие2.

А по поводу того что там стоит 2 знака после запятой - то это для измерения низких частот. На диапазон 80 м. можно эти 2 знака выкинуть.

- Брехня! (Не из кины про Неуловимых)

1. Ибо при t1>1 появляется погрешность усреднения. Для случая не стабильной частоты источника. Где и как ты это обрабатываешь в коде?

2. Долговременную стабильность "опорного" генераторы, кварца 16 мГц на плате Nano - тебе НИ КТО НЕ ГАРАНТИРУЕТ. Или тащи сюды даташит на ентот кварц. И его порвёрм. :-)

В соседнем топике порвали нафех термо- и вольто- стабилизированный генератор DS3231 с его ±2ppm, который имеет выбег, указанный в ТЕКСТЕ даташита, но совершенно не применимый для измерений. Кста, рекомендую разобраться что такое эти PPM и какой у них физический смысл. Будешь не прияно удивлен. ;-)

3. В твоем вдювайсе нет даже элементарного узла, но без которого все твои расчёты и утверждения о точности - ниачом. Но который есть в готовых дешевых китайских модулях-частотомерах или DIY-китах.

Buldakov
Offline
Зарегистрирован: 17.01.2016

А какого элементарного узла у меня в приборе нет? Только не говорите, что это подстроечный конденсатор.

ssss
Offline
Зарегистрирован: 01.07.2016

di_mot пишет:

2. Долговременную стабильность "опорного" генераторы, кварца 16 мГц на плате Nano - тебе НИ КТО НЕ ГАРАНТИРУЕТ. Или тащи сюды даташит на ентот кварц. И его порвёрм. :-)

Ваш мысленный гейзер убил остатки ваших мыслей. )))))))))))))))

Какая ещё долговременная стабильность? Где аффтар о ней упоминал? Где он сказал что это крутой частотомер? Да ещё и на Меге! ))))))))))))))))

Даже для крутых частотомеров существует такое действо как поверка. У многих есть доступ к эталону частоты? Не смешите уже своим бредом!

Цитата:

3. В твоем вдювайсе нет даже элементарного узла, но без которого все твои расчёты и утверждения о точности - ниачом. Но который есть в готовых дешевых китайских модулях-частотомерах или DIY-китах.

Для домашнего показометра и этого хватит. И дешёвые китайские модули так и останутся дешёвкой, ничем не отличающимися от этого показаметра. Если вы не в теме, то и не надо другим лапшу на уши вешать.

di_mot
Offline
Зарегистрирован: 12.08.2016

ssss пишет:

Где он сказал что это крутой частотомер? Да ещё и на Меге! ))))))))))))))))

См. пост №1 и №15 автора. Если ни чего не видишь - то это уже не мои заморочки.

ssss пишет:
Даже для крутых частотомеров существует такое действо как поверка. У многих есть доступ к эталону частоты? Не смешите уже своим бредом!

Гос.поверка такой техники производится раз в год.

Долговременная - это скока в днях по твоему?

Если не вкурил суть спора, то объясняю, что автор НЕ МОЖЕТ сказать какая погрешность получается через 1 час непрерывной работы, но точноть пишет заоблачную для токой поделки. Откуда он ее взял - догадываюсь. А что такое час поковырять в деталюшках? - Ниачом. ;-)

Промолчал бы про точность или написал боле-мене нормальную и спору бы не было. Ни кто его за язык не тянул. :-)

 

Buldakov пишет:
А какого элементарного узла у меня в приборе нет?

Ты ответь для начала на первые 2 вопроса, а потом и за другое разберем. А пока - учи матчасть.

 

 

ssss
Offline
Зарегистрирован: 01.07.2016

di_mot пишет:

См. пост №1 и №15 автора. Если ни чего не видишь - то это уже не мои заморочки.

А как можно видеть то, чего нет? Там только зачатки проги и больше ничего! ))))))))))))))

Тема зовётся "Простой частотомер", что в общем == показометр, коих валом в сети на разных МК. Хотите толкнуть ТС на ратный подвиг? )))))))))))))

Цитата:

Долговременная - это скока в днях по твоему?

Да мне пофигу! Это к данной теме вообще никак не относится.

Цитата:

Если не вкурил суть спора, то объясняю, что автор НЕ МОЖЕТ сказать какая погрешность получается через 1 час непрерывной работы, но точноть пишет заоблачную для токой поделки. Откуда он ее взял - догадываюсь. А что такое час поковырять в деталюшках? - Ниачом. ;-)

Да там вообще всё под вопросом. Ну показометр, ну простой, ну на ардуине, ну что получилось, то и получилось. Кого-то устраивает, ну и ладно.

Даже если повесить ТСХО, что изменится? Да ничего, в общем! Если делать это на СТМ8 СТМ32 или как у ЛИ, там может это всё и имеет смысл. А на голой меге смысла ну просто никакого, тем более на ардуино.

Buldakov
Offline
Зарегистрирован: 17.01.2016

"Ты ответь для начала на первые 2 вопроса, а потом и за другое разберем. А пока - учи матчасть."

Первое. Мы с тобой на Брудершафт не пили и поэтому не надо мне тыкать.

Второе. Если просят ответить на 2 вопроса, хотябы пронумеруйте эти вопросы.

di_mot
Offline
Зарегистрирован: 12.08.2016

Buldakov пишет:

Первое. Мы с тобой на Брудершафт не пили и поэтому не надо мне тыкать.

Второе. Если просят ответить на 2 вопроса, хотябы пронумеруйте эти вопросы.

1. Ага, нуда, канешна... Да трищаза. ;-)

/Кто такой тебе Брудершафт, да еще с заглавной буквы, даже спрашивать неб буду./

2. Да лехко! Тынц. Или цифирок не видишь?

 

ssss пишет:
А как можно видеть то, чего нет? Там только зачатки проги и больше ничего! ))))))))))))))

... но таки про точность автор не забыл. С нее и начал...

 

ssss пишет:
Тема зовётся "Простой частотомер", что в общем == показометр, коих валом в сети на разных МК.

Прощее и правильнее, чем сваял dimax и которые есть в 3-х вариантах на форуме - пока не встречал. Его код, конечно, сложнее к пониманию. Но результат - лучше. За что ему респект! И как показала практика, его проект повторили не раз

 

ssss пишет:
Даже если повесить ТСХО, что изменится? Да ничего, в общем!

Это зависит от квалификации. Кому-то поделка бест_палезная, а кому и свет в окошке.

Так я про последних. Сам морду побил об косячные и не продуманные "трахо_мётры". :-)))

И если рассматривать не "ва-апче", то в частных случаях, хороший и правильный проект, свет ведущий на правильную дорогу. :-)

А гуанамо-прожехтов в Инете таки да, выше всяческой меры..

ssss
Offline
Зарегистрирован: 01.07.2016

di_mot пишет:

Прощее и правильнее, чем сваял dimax и которые есть в 3-х вариантах на форуме - пока не встречал. Его код, конечно, сложнее к пониманию. Но результат - лучше. За что ему респект! И как показала практика, его проект повторили не раз

Прощее и правильнее... и сложнее к пониманию - просто когнитивный диссонанс. ))))))))))))))))))))))

Но результат - лучше... чем что? Если оно всё убогое? Что-то у вас всё перепуталось. )))))))))))))))

di_mot
Offline
Зарегистрирован: 12.08.2016

ssss пишет:

Прощее и правильнее... и сложнее к пониманию - просто когнитивный диссонанс. ))))))))))))))))))))))

А чё-нить свое - слабо придумать, чем повторять чужую и затасканную банальность? ;-)

Если тебе невкурить три условия в IF вряд - перепиши в столбик и не вешай на других свой диягноз. :-)

- Иди-иди, дружище, не флуди... :-)

ssss
Offline
Зарегистрирован: 01.07.2016

di_mot пишет:

- Иди-иди, дружище, не флуди... :-)

Я? Не! Может у автора и получится то, что у других на меге ещё никогда не получалось. Хотя... "Всё придумано до нас!"(с).

vb
Offline
Зарегистрирован: 15.09.2016

уже есть U-speed модуль на Arduino. Схему подключения можно найти здесь http://ngin.pro/arduino/143-u-speed-modul-na-arduino.html

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

dimax пишет:

selevo, как изволите вас понимать вашу методику ? О том что входящая частота =0,1Гц можно узнать только спустя полный её период, т.е. через 10 секунд.

т.е. через 20 секунд.

ssss
Offline
Зарегистрирован: 01.07.2016

andriano пишет:

dimax пишет:

selevo, как изволите вас понимать вашу методику ? О том что входящая частота =0,1Гц можно узнать только спустя полный её период, т.е. через 10 секунд.

т.е. через 20 секунд.

т.е. через 10 секунд.

Werewolf
Offline
Зарегистрирован: 06.01.2016

А можно заменить 5-й вывод для измерений частоты на другой, например 3-й?

Хочу применить LCD shield, а там 5-й вывод задейстован для управления дисплеем.

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

Werewolf,  нельзя, но вариант решения есть Тыц

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

ssss пишет:

andriano пишет:

dimax пишет:

selevo, как изволите вас понимать вашу методику ? О том что входящая частота =0,1Гц можно узнать только спустя полный её период, т.е. через 10 секунд.

т.е. через 20 секунд.

т.е. через 10 секунд.

Напишите, пожалуйста, методику измерения частоты порядка 0.1 Гц, которая гарантированно укладывается в примерно 10 сек.

demyan2
Offline
Зарегистрирован: 10.12.2014

А куда  LCD  подключить ,  к каким  пинам ?

Buldakov
Offline
Зарегистрирован: 17.01.2016

LCD подключать по ссылке ниже:

https://lesson.iarduino.ru/page/urok-4-podklyuchenie-lcd1602-po-i2c-k-ar...

 

Lexxx_HU
Offline
Зарегистрирован: 14.04.2017

Buldakov пишет:
unsigned long korr_timer = 67; //коррекция времени запроса после вызова таймера в тактах процессора

Извиняюсь за нескромный вопрос, но откуда взялась цифра 67?

и почему сравнение идет с

Buldakov пишет:
OCR1A = (F_min-1);    //Минимальная измеряемая частота 

заранее спасибо за ответы

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014

Lexxx_HU пишет:

и почему сравнение идет с

OCR1A = (F_min-1);    //Минимальная измеряемая частота

Это не сравнение, а присвоение.

Lexxx_HU
Offline
Зарегистрирован: 14.04.2017

имелось ввиду сравнение в таймере с частотой, на 1 меньше заданной, почему отнимается единица?

Yarik.Yar
Offline
Зарегистрирован: 07.09.2014

Потому что счёт в микроконтроллере начинается с нуля.

Lexxx_HU
Offline
Зарегистрирован: 14.04.2017

Спасибо за ответ

еще вопрос, если позволите

что за такой коэффициент 67?

unsigned long korr_timer = 67; //коррекция времени запроса после вызова таймера в тактах процессора

 

Buldakov
Offline
Зарегистрирован: 17.01.2016

Я конечно уже всех тонкостей уже не помню, но 67 это сколько машинных тактов выполняются операции при вызове таймера (которое произошло после окончании времени измерения). Типа интервал измерения окончился, затем пришел последний счетный импульс, но надо его еще обработать. Вот это время обработки по моему и равно 67 тактов.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

а если мне надо мерить от 200Кгц до 400Кгц что изменить в коде