Частотомер на Arduino UNO и LCD KeyPad Shield

shtep
Offline
Зарегистрирован: 16.06.2017

dimax пишет:

shtep, нужна плата с тремя 16-битными таймерами + что бы были выведены три их тактовых входа.   Есть вариации плат мега2560 со всеми распаяными  пинами, вот например. Думаю это для вас самый оптимальный вариант.

Спасибо за ответ. Пришла здравая мысль воткнуть схему переключения и считывать по показания очереди.

Водолаз
Offline
Зарегистрирован: 24.08.2017

Сначала собрал частотомер с подсчетом тиков в нуле и единице (не хотелось разбираться с прерываниями :). На низких частотах хорошо измеряет, но уже на килогерцах показания начинают скакать. Хотя сам сигнал ТТЛ, близкий к меандру, с хорошими фронтами (с триггера Шмитта). Обработка усреднением (а тем более сортировка) сильно замедляют процесс измерения. Тогда использовал схему и скетч, предложенный dimax. Понравилась краткость программы. Только не понял, зачем обязательно использовать 5-ый пин и для дисплея. Оставил его на чистый вход, дисплей подцепил на 8,9, 10, 11,12,13. Спасибо автору, все замечательно работает.

facset
Offline
Зарегистрирован: 10.08.2016

Один из участников данной темы использует ЛСД Шилд, и чтобы не курочить Шилд чисто под этот проект, было решено программно переключать 5 пин между частотомером и дисплеем. Всё-таки не все хотят намертво привязывать железо, которое завтра может пригодиться где-то ещё

Водолаз
Offline
Зарегистрирован: 24.08.2017

Спасибо за разъяснение!

Greyter
Offline
Зарегистрирован: 15.11.2017

Здравствуйте, использовал схему предложеную dimax с расшарингом пинов, подключил arduino и LCD, через резистор подключил сигнал, но после заливки программы на дисплее показывает иероглифы и при измерении также показывает иероглифы, хотел спросить почему так может происходить? 

sera.brat
Offline
Зарегистрирован: 31.01.2018

Здравствуйте, хочу поинтересоваться, как можно измерить длительность положительного импульса (секунды, или милисекунды). который подается  на микроконтроллер (программирую в ардуино).

пробовал pulsein(), но увыб ничего толкового не получается

 

arduinec
Offline
Зарегистрирован: 01.09.2015

sera.brat пишет:

Здравствуйте, хочу поинтересоваться, как можно измерить длительность положительного импульса (секунды, или милисекунды). который подается  на микроконтроллер (программирую в ардуино).

Примерно так:

unsigned long time1 = millis();
delay(500);
unsigned long time2 = millis();
long dlit = time2 - time1;

 

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Планируется ли под ОЛЕД или жк  экран модификация?

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

fly245 пишет:

Планируется ли под ОЛЕД или жк  экран модификация?

 а почему нет?

vlad3156
Offline
Зарегистрирован: 28.12.2019

Уважаемый dimax

ваш код измерения частоты оказался самым работоспособным... в области частот интересующих меня(20Гц.....250 кгц)...я скопировал ваш код и внес некоторые изменения, но что-то не так отображается на дисплее(2004А). Почему то Гц отображаются как Hzz...мне нужно отображать частоту входного сигнала с двумя знаками после запятой. Я еще не очень разбираюсь в программировании.

 

volatile unsigned int int_tic=0;
volatile unsigned long tic;
 
#include <Wire.h>                   
#include <LiquidCrystal_I2C.h>        
LiquidCrystal_I2C lcd(0x27,16,2);
 
void setup() {
lcd.init();
lcd.setCursor(0, 0);
lcd.print("  Signal Frequecy");
 
TCCR1A=0; TIMSK1 = 1<<TOIE1;
}
 
ISR (TIMER1_OVF_vect){ int_tic++; }
 
void loop() {
pinMode (5,INPUT);
 
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);
 
delay(1000);
TCCR1B=0;
float tic= ((uint32_t)int_tic<<16) | TCNT1;
int_tic=0; TCNT1 = 0;
lcd.setCursor(3, 1);
if (tic < 1000){
      lcd.print(tic);
      lcd.print(" Hz");
      };
      lcd.setCursor(3, 1);
      if (tic > 1000){
      float freq = tic / 1000;
      lcd.print(freq);
      lcd.print(" KHz");
      };
}

 

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

вот так исправь

 int_tic=0; TCNT1 = 0;
lcd.setCursor(3, 1);
  lcd.print("                    ");
lcd.setCursor(3, 1);
if (tic < 1000){
      lcd.print(tic);
      lcd.print(" Hz");
// и далее без изменения

 

vlad3156
Offline
Зарегистрирован: 28.12.2019

       uabem

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

sadman41
Offline
Зарегистрирован: 19.10.2016

Достаточно lcd.print(" Hz ");

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

sadman41 пишет:

Достаточно lcd.print(" Hz ");

...не был уверен, что затрёт полностью...и, существует 99 способов...сто профессор...сто... )))

надо затирать знакоместо при уменьшении выводимого количества знакомест... в вашем случае при переходе с Khz к Hz

sadman41
Offline
Зарегистрирован: 19.10.2016

Ну, ещё к KHz пробел добавить тогда. 

Конечно, если товарищ резко уменьшит строку на два и более символов, то не поможет. А по одному ежели скидывать, то нормально - последний знак затрёт.

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

sadman41 пишет:

Ну, ещё к KHz пробел добавить тогда. 

Конечно, если товарищ резко уменьшит строку на два и более символов, то не поможет. А по одному ежели скидывать, то нормально - последний знак затрёт.

я жеж не настоящий сталевар, не могу как вы - скользящим взглядом на код...метод кардинального костыля наше фсё )))

Electrobit
Offline
Зарегистрирован: 19.09.2021

Можно ли ещё раз уточнить, какая плата Mega имеет все распаянные пины таймеров/счетчиков и как их можно использовать одновременно.

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

Electrobit пишет:

Можно ли ещё раз уточнить, какая плата Mega имеет все распаянные пины таймеров/счетчиков и как их можно использовать одновременно.

любая видимо

Electrobit
Offline
Зарегистрирован: 19.09.2021

Допустим. Но если речь идет о измерении частоты, то насколько я понимаю, для того чтоб измерить количество тактов за один период, нужно два аппаратных канала: один для измерения "положительного"  полупериода, а другой для измерения "отрицательного" полупериода.  

fly245
fly245 аватар
Offline
Зарегистрирован: 25.08.2013

Немного обновлю тему,вот добавил вывод на OLED i2c  дисплей .

volatile unsigned int int_tic=0; 
volatile unsigned long tic; 
//#include <LiquidCrystal.h>
//LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#define I2C_ADDRESS 0x3C
SSD1306AsciiWire oled;

void setup() {
//lcd.begin(16, 2);
 Wire.begin();
  Wire.setClock(400000L);
  oled.begin(&Adafruit128x32, I2C_ADDRESS);
  oled.setFont(font5x7);
  oled.clear();
  oled.set2X();
  
TCCR1A=0; TIMSK1 = 1<<TOIE1; //прерывание по переполнению
}
ISR (TIMER1_OVF_vect){ int_tic++; }

void loop() {

pinMode (5,INPUT); // вход сигнала T1 (only для atmega328)
TCCR1B = (1<<CS10)|(1<<CS11)|(1<<CS12);//тактировани от входа Т1
delay(1000);
TCCR1B=0;
tic= ((uint32_t)int_tic<<16) | TCNT1; //сложить что натикало
int_tic=0; TCNT1 = 0; 
//lcd.setCursor(0, 0);
//lcd.print(tic);
//lcd.print(" Hz  ");
oled.clear();
 oled.print (tic);
  oled.print ( " Hz " ) ; 
 
  


}

 

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

Electrobit пишет:

Допустим. Но если речь идет о измерении частоты, то насколько я понимаю, для того чтоб измерить количество тактов за один период, нужно два аппаратных канала: один для измерения "положительного"  полупериода, а другой для измерения "отрицательного" полупериода.  

Нет. Нужно просто измерить интервал между двумя соседними фронтами одинаковой полярности, и пересчитать.