Частотомер на Arduino
Данная статья является второй в серии статей про измерение с помощью Arduino параметров различных компонентов и физических величин, используемых в радиоэлектронике. Рассмотрим измерение частоты сигнала с помощью Arduino.
Почти каждый радиолюбитель должен столкнуться со сценарием, в котором ему необходимо измерить частоту сигнала, генерируемого тактовым генератором или счетчиком или таймером. Для выполнения этой задачи мы можем использовать осциллограф, но не все из нас могут его себе позволить. Мы можем купить оборудование для измерения частоты, но эти устройства стоят дорого. Учитывая это, мы собираемся разработать с помощью Arduino и триггера Шмитта простой, но эффективный частотомер.
Этот частотомер является экономически эффективным и может быть легко изготовлен. Для измерения частоты сигнала мы будем использовать Arduino Uno – сердце проекта.
Чтобы протестировать частотомер, мы собираемся создать простейший генератор сигнала. Этот простейший генератор сигнала будет изготовлен с использованием микросхемы таймера 555. Схема на таймере генерирует прямоугольный сигнал, который будет для тестирования подаваться на Arduino Uno.
В итоге у нас будет частотомер и генератор прямоугольного сигнала.
Необходимые компоненты
- микросхема таймера 555;
- микросхема триггеров Шмитта 74LS14 или элементов НЕ;
- плата Arduino Uno;
- LCD дисплей 16x2;
- конденсаторы 100 нФ (2 шт.) и 1000 мкФ (1 шт.);
- резисторы 100 Ом (1 шт.), 220 Ом (1 шт.) и 1 кОм (1 шт.);
- потенциометр 47 кОм;
- макетная плата;
- перемычки.
Принципиальная схема
Принципиальная схема частотомера на Arduino показана ниже. Схема проста, LCD дисплей подключен к Arduino для отображения измеренной частоты сигнала. Со схемы генератора сигналов мы подаем сигнал на Arduino через «сигнальный вход». Триггер Шмитта (микросхема 74LS14) используется для обеспечения подачи на Arduino только прямоугольного сигнала. Для фильтрации шума мы добавили на шину питания пару конденсаторов. Данный частотомер может измерять частоты до 1 МГц.
Генератор сигналов на микросхеме таймера 555
Прежде всего, мы поговорим о генераторе прямоугольного сигнала на микросхеме 555, или, я бы сказал, о нестабильном (астабильном, автоколебательном) мультивибраторе на 555. Эта схема необходима, потому что для проверки частотомера нам необходим сигнал, частота которого известна. Без этого сигнала мы не сможем рассказать о работе частотомера. Если у нас есть прямоугольный сигнал с известной частотой, мы можем использовать его для проверки частотомера на Arduino и для подстройки точности в случае любых отклонений. Макет генератора сигнала на микросхеме таймера 555 показан ниже.
Ниже показана типовая схема таймера 555 в нестабильном режиме, из которой мы получили вышеприведенную схему генератора сигналов.
Частота выходного сигнала зависит от резисторов RA и RB и конденсатора C. Формула будет следующей:
\[Частота (F) = {1 \over \text{длительность периода}} = {1,44 \over (RA + 2RB) \cdot C}\]
Здесь RA и RB – значения сопротивлений, а C – значение емкости. Подставляя значения сопротивлений и емкости в приведенную выше формулу, мы получаем частоту выходного прямоугольного сигнала.
Можно увидеть, что RB на схеме выше заменен в нашей схеме генератора сигналов потенциометром; это сделано для того, чтобы для лучшего тестирования мы могли получить на выходе прямоугольный сигнал переменной частоты. Для простоты можно заменить этот потенциометр простым резистором.
Триггер Шмитта
Мы знаем, что не все тестовые сигналы являются прямоугольными. У нас есть сигналы треугольные, пилообразные, синусоидальные и так далее. Поскольку Arduino Uno может детектировать только прямоугольные сигналы, нам необходимо устройство, которое могло бы преобразовывать любые сигналы в прямоугольные. Поэтому мы используем триггер Шмитта. Триггер Шмитта представляет собой цифровой логический элемент, предназначенный для арифметических и логических операций.
Этот элемент обеспечивает выходной сигнал (OUTPUT) на основе уровня напряжения входного сигнала (INPUT). Триггер Шмитта имеет пороговый уровень напряжения (THERSHOLD): когда уровень входного сигнала выше порогового уровня элемента, уровень сигнала на выходе будет равен высокому логическому уровню. Если уровень входного сигнала ниже порога, на выходе будет низкий логический уровень. Обычно у нас нет отдельного триггера Шмитта, за ним всегда следует элемент НЕ.
Мы собираемся использовать микросхему 74LS14, которая содержит 6 триггеров Шмитта. Эти шесть элементов внутри подключены, как показано на рисунке ниже.
Таблица истинности инвертированного триггера Шмитта показана ниже, в соответствии с ней мы должны запрограммировать Arduino Uno для инвертирования положительных и отрицательных периодов времени на ее выводах.
\(Y = \bar{A}\)
Вход | Выход |
---|---|
A | Y |
L | H |
H | L |
- H – высокий логический уровень;
- L – низкий логический уровень.
Теперь, когда мы подадим сигнал любого типа на элемент триггера Шмитта, у нас на выходе будет прямоугольный сигнал с инвертированными временными периодами, и этот сигнал мы подадим на Arduino Uno.
Как Arduino измеряет частоту
Arduinio Uno имеет специальную функцию pulseIn
, которая позволяет нам определять длительность положительного или отрицательного состояния конкретного прямоугольного сигнала:
Htime = pulseIn(8,HIGH);
Ltime = pulseIn(8, LOW);
Данная функция измеряет время, в течение которого высокий или низкий логический уровень присутствует на выводе 8 Arduino Uno. Таким образом, в одном периоде сигнала у нас будут продолжительности положительного и отрицательного уровней в микросекундах. Функция pulseIn
измеряет время в микросекундах. В заданном сигнале мы имеем время высокого логического уровня = 10 мс и время низкого логического уровня = 30 мс (частота 25 Гц). Таким образом, в Ltime
будет сохранено целое число 30000, а в Htime
– 10000. Если мы сложим эти два значения, то получим длительность периода, а инвертировав её, мы получим частоту.
Код
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
int Htime; // целочисленная переменная для хранения времени высокого логического уровня
int Ltime; // целочисленная переменная для хранения времени низкого логического уровня
float Ttime; // переменная для хранения общей длительности периода
float frequency; // переменная для хранения частоты
void setup()
{
pinMode(8,INPUT);
lcd.begin(16, 2);
}
void loop()
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Frequency of signal");
Htime=pulseIn(8,HIGH); // прочитать время высокого логического уровня
Ltime=pulseIn(8,LOW); // прочитать время низкого логического уровня
Ttime = Htime+Ltime;
frequency=1000000/Ttime; // получение частоты из Ttime в микросекундах
lcd.setCursor(0,1);
lcd.print(frequency);
lcd.print(" Hz");
delay(500);
}