Таймери Arduino UNO — Частина 5. Вимірювання тривалості імпульсів і частоти (Input Capture)

Теорія

Режим Input Capture (ICP1)

Режим Input Capture — це спеціальна функція Timer1 у мікроконтролері ATmega328P, яка дозволяє з високою точністю фіксувати моменти приходу фронтів сигналу (зростаючого або спадаючого) на піні ICP1 (Arduino UNO — пін D8).

Коли на вхід ICP1 надходить вибраний фронт сигналу, поточне значення лічильника TCNT1 автоматично копіюється в регістр ICR1. Це дозволяє точно зафіксувати момент події без затримок, які могли б виникнути під час опитування піна у звичайному коді.

Як виміряти частоту і тривалість

  • Частота розраховується за формулою: F = F_CPU / (Prescaler * ΔTCNT), де ΔTCNT — різниця між двома захватами, а Prescaler — вибраний дільник таймера.
  • Тривалість імпульсу можна визначити, вимірявши час між фронтами (зростаючим і спадаючим) одного імпульсу.

Input Capture корисний у завданнях, де потрібна висока точність вимірювань — наприклад, у тахометрах, аналізаторах сигналів, частотомірах.

Практика

Вимірювання частоти сигналу від датчика Холла

Приклад коду для вимірювання частоти обертання колеса з датчиком Холла:


volatile uint16_t lastCapture = 0;
volatile uint16_t period = 0;
float frequency = 0;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT);

  TCCR1A = 0; // Звичайний режим
  TCCR1B = 0;
  TCCR1B |= (1 << ICES1); // Захоплення за зростаючим фронтом
  TCCR1B |= (1 << CS11);  // Дільник 8
  TIMSK1 |= (1 << ICIE1); // Дозвіл переривання захоплення
}

ISR(TIMER1_CAPT_vect) {
  uint16_t capture = ICR1;
  period = capture - lastCapture;
  lastCapture = capture;
}

void loop() {
  if (period > 0) {
    frequency = 16000000.0 / (8.0 * period);
    Serial.print("Частота: ");
    Serial.print(frequency);
    Serial.println(" Гц");
    delay(500);
  }
}
  

Проєкт: Тахометр на Arduino UNO

У цьому проєкті ми використовуємо Input Capture для створення тахометра, що вимірює оберти на хвилину (RPM) двигуна.


volatile uint16_t lastCapture = 0;
volatile uint16_t period = 0;
float rpm = 0;

void setup() {
  Serial.begin(9600);
  pinMode(8, INPUT);

  TCCR1A = 0;
  TCCR1B = 0;
  TCCR1B |= (1 << ICES1); // Захоплення за зростаючим фронтом
  TCCR1B |= (1 << CS11);  // Дільник 8
  TIMSK1 |= (1 << ICIE1); // Переривання захоплення
}

ISR(TIMER1_CAPT_vect) {
  uint16_t capture = ICR1;
  period = capture - lastCapture;
  lastCapture = capture;
}

void loop() {
  if (period > 0) {
    float frequency = 16000000.0 / (8.0 * period);
    rpm = frequency * 60.0; // 1 імпульс на оберт
    Serial.print("RPM: ");
    Serial.println(rpm);
    delay(500);
  }
}
  

Такий тахометр можна застосувати у моделях автомобілів, мотоциклів, вентиляторах та інших механізмах, де потрібно вимірювати швидкість обертання.

<< Проекти << Усі товари >> Статті, уроки >>

Написати відгук

Примітка: HTML размітка не підтримується! Використовуйте звичайтий текст.
    Погано           Добре
Стабілізатор напруги 3,3 В 800 мА LM1117T-3.3

Стабілізатор напруги 3,3 В 800 мА LM1117T-3.3

Стабілізатор напруги у вигляді мікросхеми з трьома ногамиВикористовується для стабілізації нестабілі..

19.54грн.

Модуль розширення входів-виходів PCF8574A

Модуль розширення входів-виходів PCF8574A

Модуль розширення входів-виходів PCF8574A Розширювач портів на основі спеціалізованої мікросхеми ..

62.18грн.

Дискретний регулятор вологості повітря на Arduino

Дискретний регулятор вологості повітря на Arduino

Привіт, захопленим електронікою читачам. У цій статті і відео нам належить розробити, змонтувати і н..

Як не спалити Arduino та ESP32: GPIO, струми і напруги простими словами

Як не спалити Arduino та ESP32: GPIO, струми і напруги простими словами

Як не спалити Arduino та ESP32: GPIO, струми і напруги простими словами Arduino та ESP32 не «ніжн..

Конденсатор електролітичний алюмінієвий

Конденсатор електролітичний алюмінієвий

Використовується для згладжування пульсацій в джерелах живлення, в генераторах сигналів, в частотних..

3.10грн.