Главная chevron_right Функции chevron_right Расширенный ввод/вывод chevron_right pulseInLong()

pulseInLong()

pulseInLong() измеряет длительность импульса в микросекундах через micros() и лучше подходит для длинных сигналов, чем обычный pulseIn().

Полная статья

Описание

pulseInLong() решает ту же задачу, что и pulseIn(): измеряет, сколько времени вывод находится в заданном состоянии. Разница в том, что эта функция опирается на micros() вместо прямого подсчёта тактов процессора, поэтому она точнее работает на длинных импульсах и не теряет счёт, когда в программе активно срабатывают прерывания.

Принцип работы прост. Допустим, вы вызвали функцию с параметром value равным HIGH. Функция сначала ждёт, пока вывод окажется в состоянии LOW (то есть дожидается конца предыдущего импульса, если он ещё идёт), затем фиксирует момент перехода в LOW и замеряет, сколько времени вывод остаётся в этом состоянии. Как только вывод возвращается в LOW, измерение заканчивается и функция возвращает длительность в микросекундах. Если за отведённое время полный импульс так и не пришёл — возвращается 0.

Функция уверенно работает с импульсами длительностью от 10 микросекунд до 3 минут. На очень коротких импульсах точность ниже: временны́е характеристики определены экспериментально, и небольшая погрешность там неизбежна. Ключевое условие работы — прерывания должны быть включены, поскольку именно на них опирается micros().

Синтаксис

  • pulseInLong(pin, value)
  • pulseInLong(pin, value, timeout)

Параметры

  • pin — номер вывода Arduino, на котором нужно измерить импульс. Тип данных: int.
  • value — ожидаемый тип импульса: HIGH или LOW. Тип данных: int.
  • timeout — необязательный параметр: максимальное время ожидания начала импульса в микросекундах. По умолчанию равно одной секунде. Тип данных: unsigned long.

Возвращает

Длительность импульса в микросекундах в виде unsigned long, или 0, если за время timeout импульс так и не начался.

Пример кода

Пример выводит в Serial Monitor длительность импульса на выводе 7.

int pin = D1;
unsigned long duration;

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

void loop() {
  duration = pulseInLong(pin, HIGH);
  Serial.println(duration);
}

Практические замечания

  • pulseInLong() нельзя вызывать внутри обработчика прерывания (noInterrupts()): функция зависит от micros(), а тот внутри прерываний не обновляется.
  • Если вам нужно измерять короткие импульсы (единицы микросекунд) и прерывания в коде не используются, pulseIn() может оказаться точнее — он считает такты напрямую.
  • Параметр timeout удобно уменьшать, если датчик должен отвечать быстро: по умолчанию функция может «висеть» до секунды в ожидании импульса, что заметно тормозит цикл.
  • Перед вызовом убедитесь, что вывод настроен как вход (pinMode(pin, INPUT) или INPUT_PULLUP), иначе результат будет непредсказуемым.

Примечания и предупреждения

Функция использует micros(), поэтому её нельзя вызывать в контексте noInterrupts().

Полезные материалы