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

Датчик вращения енкодер KY-040

Енкодер вращения KY-040 - это поворотный датчик, который индицирует степень поворота оси и в каком н..

37.93грн.

Arduino SIM800 исходящий звонок ATD

Arduino SIM800 исходящий звонок ATD

Привет друзья! Это продолжение серии статей о работе с SIM800. Всех их можно найти на этом канале.&n..

Микрофон со специализированным усилителем MAX9814

Микрофон со специализированным усилителем MAX9814

Микрофонный усилитель на специализированной микросхеме MAX9814 Коэффициент усиления выбирается..

189.28грн.

LED драйвер 330/660мА с PWM управлением

LED драйвер 330/660мА с PWM управлением

LED драйвер 330/660 мА с ШИМ LED драйвер на базе микросхемы AL8805 предназначен для управления мощн..

121.15грн.

SIM800 Arduino автоматические команды

SIM800 Arduino автоматические команды

Привет друзья! В прошлом видео мы разобрали ручное управление GSM-модулем набирая команды в мониторе..