Ультразвуковой датчик расстояния (HC-SR04)

Летучие мыши и дельфины «видят» звуком. Тот же фокус — эхолокация — стоит пару сотен рублей и помещается на твоей макетке.

HC-SR04 пускает ультразвуковой щелчок и слушает эхо. Зная скорость звука и время полёта эха, мы вычисляем расстояние до препятствия. Это парктроник своими руками.

Сейчас соберём датчик расстояния и будем выводить в сантиметрах, как далеко предмет. На этом принципе работают парктроники, роботы-пылесосы и охранные системы.

Схема и принцип эхолокации

  HC-SR04        Arduino
  VCC  --------- 5V
  Trig --------- пин 9   (мы посылаем импульс "пищи!")
  Echo --------- пин 10  (датчик отвечает импульсом длиной = время эха)
  GND  --------- GND

  Trig -> ))) звук летит к стене -> ((( эхо назад -> Echo
  Время туда-обратно * скорость звука / 2 = расстояние

Код

const int TRIG = 9;
const int ECHO = 10;

void setup() {
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
  Serial.begin(9600);
}

void loop() {
  digitalWrite(TRIG, LOW);  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH); delayMicroseconds(10);  // щелчок 10 мкс
  digitalWrite(TRIG, LOW);

  long duration = pulseIn(ECHO, HIGH);  // время эха в микросекундах
  long cm = duration / 58;              // перевод в сантиметры

  Serial.print(cm); Serial.println(" см");
  delay(100);
}

Как работает под капотом

Звук летит со скоростью ~340 м/с = 0.034 см за микросекунду. Датчик измеряет время туда и обратно, поэтому делим пополам: расстояние = время · 0.034 / 2. Удобное приближение: см = микросекунды / 58 (потому что 2 / 0.034 ≈ 58). Функция pulseIn(ECHO, HIGH) измеряет, сколько микросекунд пин Echo держал HIGH — это и есть время полёта эха.

# Та же логика на Python: время эха -> сантиметры
SOUND_CM_PER_US = 0.0343   # скорость звука, см за микросекунду

def echo_to_cm(duration_us):
    # делим на 2: звук летит туда И обратно
    return round(duration_us * SOUND_CM_PER_US / 2, 1)

for us in (58, 580, 1740, 2900):
    print(us, "мкс эха ->", echo_to_cm(us), "см")
# сравни с быстрым приближением /58:
print("Приближение 580/58 =", 580 // 58, "см")

Запусти — увидишь, что деление на 58 даёт почти тот же ответ, что и честная формула. Вот откуда «магическое» число.

Частые ошибки

  • Слишком короткий импульс на Trig. Нужно ровно ~10 мкс HIGH, иначе датчик не «щёлкнет».
  • Подают Echo на пин 5В-логики без проверки. На Uno это норма, но на 3.3В-платах Echo нужно понижать делителем.
  • Меряют слишком быстро. Дай эху вернуться — ставь небольшой delay между замерами.

Best practices

  • Добавь таймаут к pulseIn (третий аргумент), чтобы программа не зависала, если эха нет вовсе.
  • Усредняй несколько замеров — ультразвук шумит, особенно у мягких поверхностей.
  • Помни про слепую зону: ближе ~2 см и дальше ~4 м датчик врёт.

Слепая зона, угол и материалы

Ультразвук — мощный, но не всемогущий инструмент, и его ограничения стоит знать заранее. У датчика есть слепая зона: ближе примерно 2 см эхо возвращается слишком быстро, и измерение врёт. Сверху диапазон ограничен где-то 4 метрами — дальше эхо слишком слабое. Ещё важен угол: звук распространяется конусом примерно 15 градусов, поэтому датчик «видит» не точку, а область перед собой, и наклонная поверхность может отразить эхо в сторону, мимо приёмника.

Сильно влияет и материал препятствия. Твёрдая ровная стена отражает звук отлично — измерения точные. А вот мягкие ткань, поролон, шторы поглощают ультразвук, и эха почти нет — датчик «не видит» мягкое препятствие. Поэтому в роботах ультразвук часто дополняют другими датчиками (инфракрасными, контактными). Понимание этих границ — часть инженерного мышления: любой датчик хорош в своей нише и слеп вне её, и задача мейкера — выбрать правильный инструмент под условия.

Итоги

HC-SR04 измеряет расстояние эхолокацией: пускаем щелчок, ловим эхо через pulseIn, делим время на 58 — получаем сантиметры. Деление на 2 — потому что звук летит туда и обратно. Датчики освоены. Теперь заставим Arduino не только чувствовать, но и двигать мир — моторами.

Проверьте себя
1. Почему время полёта эха делят на 2?
AДля красоты
BЗвук проходит путь туда и обратно
CЧтобы ускорить плату
DИз-за округления
2. Что измеряет функция pulseIn(ECHO, HIGH)?
AНапряжение
BСколько микросекунд пин держал уровень HIGH
CТемпературу
DНомер пина