Подсчёт частоты импульсов

ajdivotf
Offline
Зарегистрирован: 15.06.2022

Как с помощью кода на ардуино uno реализовать подсчёт частоты импульсов в районе 300 кГц? На меньшей частоте считает по готовым скетчам, а выше нет.

b707
Offline
Зарегистрирован: 26.05.2017

взять более быструю "ардуину", например stm32F103

 

А на Уно это сложно... 300 КГц на МК с частотой 16 МГц - это всего 25 тактов на каждую полуволну... маловато для входа-выхода из прерывания, поэтому и не считает, видимо...

rkit
Offline
Зарегистрирован: 23.11.2016

Настраиваешь таймер на тактование от внешнего источника, через равные интервалы времени считываешь состояние счетчика и высчитываешь частоту.

Morroc
Offline
Зарегистрирован: 24.10.2016

Можно какую нибудь библиотеку поковырять или поюзать как есть https://www.pjrc.com/teensy/td_libs_FreqCount.html

ajdivotf
Offline
Зарегистрирован: 15.06.2022

b707, рассмотрим этот вариант, но пока не уверены. спасибо за ответ!

Morroc, только что попробовали, и это не работает - пример на первой странице сайта выдаёт совсем не то, что нужно. мы переделали его под вывод на LED-дисплей, но не думаю, что это имеет значение.

rkit, что должно являться внешним источником?

b707
Offline
Зарегистрирован: 26.05.2017

ajdivotf пишет:

мы переделали его под вывод на LED-дисплей, но не думаю, что это имеет значение.

а нахрена, спрашивается?

там же написано в описании, что любые иные прерывания мешают измерению частоты! А в вашем случае, когда контроллер и так работает близко к пределу - это может быть критично.

Неужели не пришло в голову сначала проверить как есть. а потом уже переделывать?

rkit
Offline
Зарегистрирован: 23.11.2016

ajdivotf пишет:

что должно являться внешним источником?

Может ты прочитаешь даташит?

ajdivotf
Offline
Зарегистрирован: 15.06.2022

b707 пишет:

ajdivotf пишет:

мы переделали его под вывод на LED-дисплей, но не думаю, что это имеет значение.

а нахрена, спрашивается?

там же написано в описании, что любые иные прерывания мешают измерению частоты! А в вашем случае, когда контроллер и так работает близко к пределу - это может быть критично.

Неужели не пришло в голову сначала проверить как есть. а потом уже переделывать?

попробовали с выводом на монитор компьютера, но всё то же самое. при стабильном результате отклоняется приблизительно на 100кГц, но при изменении вообще никак не соотносится. код прям с сайта этой библиотеки.

Morroc
Offline
Зарегистрирован: 24.10.2016

Что на вход подается ?

ajdivotf пишет:

rkit, что должно являться внешним источником?

Примерно как тут про внешний тактовый http://microsin.net/programming/avr/atmega-ct1-pulse-counting.html

Morroc
Offline
Зарегистрирован: 24.10.2016

Если подаете не прямоугольник >3В, то можно(нужно?) добавить схему-формирователь как в статье про библиотеку.

b707
Offline
Зарегистрирован: 26.05.2017

Morroc пишет:

Если подаете не прямоугольник >3В, то можно(нужно?) добавить схему-формирователь как в статье про библиотеку.

нужно

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

ajdivotf пишет:

Как с помощью кода на ардуино uno реализовать подсчёт частоты импульсов в районе 300 кГц? На меньшей частоте считает по готовым скетчам, а выше нет.

легко, у меня в катушке Мишина это делает кусок кода позаимствованный у Dimax

SLKH
Offline
Зарегистрирован: 17.08.2015

ajdivotf пишет:

b707, рассмотрим этот вариант, но пока не уверены. спасибо за ответ!

Morroc, только что попробовали, и это не работает - пример на первой странице сайта выдаёт совсем не то, что нужно. мы переделали его под вывод на LED-дисплей, но не думаю, что это имеет значение.

rkit, что должно являться внешним источником?

для реального результата (а не для учебного программирования) добавь 1 корпус счетчика-делителя на чём-нибудь CD40??/561 серии. 

ajdivotf
Offline
Зарегистрирован: 15.06.2022

ua6em пишет:

ajdivotf пишет:

Как с помощью кода на ардуино uno реализовать подсчёт частоты импульсов в районе 300 кГц? На меньшей частоте считает по готовым скетчам, а выше нет.

легко, у меня в катушке Мишина это делает кусок кода позаимствованный у Dimax

а можно этот код? 

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

ajdivotf пишет:

rkit, что должно являться внешним источником?

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

b707
Offline
Зарегистрирован: 26.05.2017

ajdivotf пишет:

а можно этот код? 

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

 

то. что у вас код библиотеки из #3 не работает - наводит на размышления, что у вас какой-то сигнал нестандартный.

ну или руки кривые... сорри

b707
Offline
Зарегистрирован: 26.05.2017

ajdivotf пишет:

попробовали с выводом на монитор компьютера, но всё то же самое. при стабильном результате отклоняется приблизительно на 100кГц, но при изменении вообще никак не соотносится. код прям с сайта этой библиотеки.

какой пример пробовали. вот этот?

#include <FreqCount.h>

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();
    Serial.println(count);
  }
}

Возможно в библиотеке нет контроля переполнения, тогда этот код будет работать только для частот менее 65 КГц. Для измерения частот порядка 300 КГц в 5 строчке интервал надо ставить например 100 или типа того. И полученное значение потом умножать на 10.

Попробуйте так:

#include <FreqCount.h>

void setup() {
  Serial.begin(57600);
  FreqCount.begin(100);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();
    Serial.print("Freq: ");
    Serial.println(count*10);
  }
}

 

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

ajdivotf пишет:

ua6em пишет:

ajdivotf пишет:

Как с помощью кода на ардуино uno реализовать подсчёт частоты импульсов в районе 300 кГц? На меньшей частоте считает по готовым скетчам, а выше нет.

легко, у меня в катушке Мишина это делает кусок кода позаимствованный у Dimax

а можно этот код? 

прям под рукой нету, но брал с этой ветки форума

void freq_meter(){
   lcd.clrScr();
   lcd.setFont(SmallFont);
   lcd.print("Freq.counter",LEFT, 0);
  int_on();//включить прерывание PCINT1
  TIMSK1 = 1<<TOIE1;// подключить прерывание
  uint32_t freqm=0;// Переменная измерения частоты
  int_tic=0; TCNT1=0; TIFR1=0;//всё обнулить
while(1){
   TCCR1B=7;//тактировани от входа Т1
   delay(2000); TCCR1B=0;
   freqm= (((uint32_t)int_tic<<16) | TCNT1)/2; //сложить что натикало
   int_tic=0; TCNT1 = 0; 
   lcd.clrScr(); lcd.setFont(SmallFont);
   lcd.print("Freq.counter",LEFT, 0);
   lcd.setFont(MediumNumbers);
   if (freqm <10000) { lcd.printNumI(freqm, CENTER, 8); lcd.setFont(SmallFont); lcd.print("Herz",CENTER, 32 ); }
   if (freqm >=10000u && freqm < 1000000ul ) { lcd.printNumF( ((float)freqm/1000),3 ,CENTER, 8);lcd.setFont(SmallFont);  lcd.print("KiloHerz",CENTER, 32 ); }
   if (freqm >=1000000ul ) { lcd.printNumF( ((float)freqm/1000000ul),3 ,CENTER, 8); lcd.setFont(SmallFont); lcd.print("MegaHerz",CENTER, 32 ); }    
   }  
 }

 

b707
Offline
Зарегистрирован: 26.05.2017

Для определенности решил попробовал потестить библиотеку FreqCount.h

Взял две стандартные Нано атмега328 16 МГц

На одной Нано собрал генератор с частотой примерно 300 КГц, как у ТС:

void setup() {
  pinMode(9,OUTPUT);
  noInterrupts();
  TCCR1A =0;
  TCCR1B=0;
  TCNT1 =0;
  TCCR1A = 0b01000000;          
  OCR1A   = 26;          // 16 MHz / (2* (26+1)) = 296296 hz
  TCCR1B =0b00001001;
  interrupts();
}
void loop() {  
}

на другую зашил пример из библиотеки

#include <FreqCount.h>

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();
    Serial.println(count);
  }
}

Получил результат 296 150 Гц.  Как оказалось, библиотека отлично отслеживает переполнение счетчика, моя правка скетча, предложенная в #16, не нужна.

В описании заявлено, что на атмеге328 можно мерить частоты до 8 Мгц. Попробовал повысить

Реальное      Измеренное

296.3 КГц       296.15 КГц
500 Кгц         499.75 КГц
4 МГц           3.997 МГц

Меряет! И точность очень неплохая.

 

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

ajdivotf
Offline
Зарегистрирован: 15.06.2022

b707 пишет:

ajdivotf пишет:

попробовали с выводом на монитор компьютера, но всё то же самое. при стабильном результате отклоняется приблизительно на 100кГц, но при изменении вообще никак не соотносится. код прям с сайта этой библиотеки.

какой пример пробовали. вот этот?

#include <FreqCount.h>

void setup() {
  Serial.begin(57600);
  FreqCount.begin(1000);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();
    Serial.println(count);
  }
}

Возможно в библиотеке нет контроля переполнения, тогда этот код будет работать только для частот менее 65 КГц. Для измерения частот порядка 300 КГц в 5 строчке интервал надо ставить например 100 или типа того. И полученное значение потом умножать на 10.

Попробуйте так:

#include <FreqCount.h>

void setup() {
  Serial.begin(57600);
  FreqCount.begin(100);
}

void loop() {
  if (FreqCount.available()) {
    unsigned long count = FreqCount.read();
    Serial.print("Freq: ");
    Serial.println(count*10);
  }
}

 


как раз-таки это и заработало. на частотах от ~260 до 310 всё хорошо. спасибо!

b707
Offline
Зарегистрирован: 26.05.2017

ajdivotf пишет:

как раз-таки это и заработало. на частотах от ~260 до 310 всё хорошо. спасибо!

пример из библиотеки тоже рабочий, я проверил.
Может вы в своем коде переменную count описывали как int? - тогда будет считать неправильно

PS спасибо что написали о результате, а то новички обычно пропадают после получения ответа.

Green
Offline
Зарегистрирован: 01.10.2015

b707 пишет:

PS спасибо что написали о результате, а то новички обычно пропадают после получения ответа.


Это да. И не только новички. Сетевая этика, называется.

BOOM
BOOM аватар
Offline
Зарегистрирован: 14.11.2018

И 99% стем с вопросами на форуме заканчиваются: "Ок. Попробую и обязательно отпишусь!" ))))