Таймеры 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 разметка не поддерживается! Используйте обычный текст.
    Плохо           Хорошо
LM317 линейный регулятор напряжения

LM317 линейный регулятор напряжения

Популярная микросхема - регулируемый регулятор напряженияВыходное напряжение 1,25 ... 37 ВВыходной т..

14.47грн.

ESP32 DevKit

ESP32 DevKit

Плата WiFi и Bluetooth контроллера ESP-32 с программатором CP2102 На плате уже установлен..

268.52грн.

Канифоль 10г

Канифоль 10г

Твердая канифоль для пайкиПрименяется как флюс при пайке свинцово-оловяным припоем..

41.95грн.

Двигатель 12В с редуктором 150RPM

Двигатель 12В с редуктором 150RPM

Коллекторный двигатель постоянного тока с сильным редуктором для использования в различной робототех..

575.28грн.

Умный дом #4: Умная розетка на ESP32

Умный дом #4: Умная розетка на ESP32

Умный дом #4: Умная розетка на ESP32 Умная розетка — один из наиболее востребованных элемен..