Ультразвуковой датчик HC-SR04: подключение к Arduino и код
HC-SR04 это дальномер, который меряет расстояние ультразвуком и стоит 100–150 рублей на любом маркетплейсе. С ним собирают парктроники, роботов, объезжающих препятствия, датчики уровня воды в баке и ночники, включающиеся при подходе человека. Для начинающего это первый настоящий прибор после светодиодов и кнопок: результат ощутимый, живая цифра в сантиметрах.
Ниже всё для запуска за полчаса: схема на 4 провода, скетч с pulseIn без единой библиотеки, таблица характеристик и разбор граблей, на которые наступает почти каждый, вечные «0 см» и зависший pulseIn. Потренироваться можно заранее в симуляторе, а полный обзор других сенсоров в справочнике датчиков.
Отдельные разделы ниже отвечают на вопросы, которые возникают после первой сборки: почему вместо расстояния ноль, почему робот видит собственную раму, как устроена слепая зона и какой датчик вообще стоит брать под задачу.
Как работает HC-SR04: эхолокация за 300 рублей
Принцип тот же, что у летучей мыши: Arduino шлёт триг-импульс длиной 10 микросекунд на пин Trig, модуль отвечает пачкой ультразвука на 40 кГц и поднимает пин Echo на время полёта звука до препятствия и обратно. Осталось измерить длительность высокого уровня и поделить: 58 микросекунд эха это 1 сантиметр. Скорость звука 343 м/с при 20 °C, на морозе при −20 °C она падает примерно до 318 м/с, и показания уплывают на несколько процентов. Парктронику это не мешает, а точным замерам нужна температурная компенсация, например по DHT11.
Важно понимать, что Echo это не «уровень», а длительность импульса. Именно поэтому в коде стоит pulseIn, который меряет, сколько микросекунд вывод был в состоянии HIGH. Само название Echo и есть отсылка к эху: модуль не возвращает «расстояние», он возвращает задержку, а перевод в сантиметры это уже арифметика в вашем скетче. Отсюда и таймаут: если эха не будет, вывод Echo останется в нуле, и pulseIn без третьего аргумента будет ждать полную секунду.
Распиновка и схема подключения
- VCC на 5 В Arduino: от 3.3 В обычный HC-SR04 не стартует, нюанс описан ниже
- Trig на D9: выход Arduino, запускает измерение
- Echo на D10: вход Arduino, приходит ответ
- GND на GND
- Соединять удобно dupont-проводами male–female, воткнув модуль в макетную плату. Как пользоваться макеткой, разобрано в отдельном гайде: breadboard с нуля
| Параметр | Значение | Комментарий |
|---|---|---|
| Питание | 5 В | Ток 15 мА в работе, меньше 2 мА в покое |
| Диапазон | 2–400 см | Ближе 2 см слепая зона, дальше примерно 3 м эхо глохнет |
| Точность | ±3 мм | На ровных твёрдых поверхностях |
| Угол обзора | 15° | Узкий конус: поверхность держите перпендикулярно |
| Частота | 40 кГц | На слух не воспринимается, но мешает соседнему HC-SR04 |
const int TRIG = 9; // Trig HC-SR04const int ECHO = 10; // Echo HC-SR04 void setup() { Serial.begin(9600); pinMode(TRIG, OUTPUT); pinMode(ECHO, INPUT);} void loop() { // Стартовый импульс 10 мкс — команда «мерь» digitalWrite(TRIG, LOW); delayMicroseconds(2); digitalWrite(TRIG, HIGH); delayMicroseconds(10); digitalWrite(TRIG, LOW); // Таймаут 30000 мкс = 5 м: дальше эха не ждём, pulseIn вернёт 0 long duration = pulseIn(ECHO, HIGH, 30000); int distance = duration / 58; // 58 мкс эха = 1 см Serial.print(distance); Serial.println(" sm"); delay(200);}Разберём код по шагам. Импульс на Trig длиной 10 микросекунд запускает измерение, и после его окончания вывод переводится в LOW, иначе датчик будет «думать», что вы ещё держите команду. Дальше pulseIn с таймаутом в 30 миллисекунд ждёт фронт на Echo и возвращает его длительность в микросекундах, а деление на 58 даёт сантиметры. Ноль в результате означает, что эха не дождались, и это надо обрабатывать отдельно: иначе в Serial будет строка «0 sm», которая читается как «расстояние ноль» и в реальном роботе приведёт к ложному срабатыванию.
Типовые ошибки и грабли
Тупик: вместо расстояния всегда ноль
Первый наш дальномер показывал ноль при любом расстоянии и при любом положении платы. Мы переставили провода, переткнули модуль в другую сторону макетки, проверили питание мультиметром и в какой-то момент решили, что модуль сгорел при первом же включении.
Модуль был цел, а дело было в том, что мы не дождались его готовности. У HC-SR04 после подачи питания есть короткий период, когда приёмник ещё не разошёлся, и первый замер после включения может не вернуться. Мы добавили задержку в setup(), и датчик заработал сразу. Второй похожий случай: у нас на руках оказался клон с переставленными выводами, и если смотреть на плату снизу, а не сверху, подписи читаются наоборот. Третий случай мы даже не сразу признали: мы забыли про общую землю, датчик питался, но не видел обратного сигнала, и тоже показывал ноль.
Личный опыт: робот видит свою раму
Когда мы поставили HC-SR04 на робота-обходчика, он вёл себя странно: вместо нормальной дистанции до стены он стабильно показывал меньше десяти сантиметров и постоянно пытался повернуть на месте. Мы решили, что датчик неисправен, и проверили его отдельно на столе, где он показывал честные метры.
Дело было в том, что робот измерял расстояние до самого себя. Корпус, кронштейн и провода оказались в конусе обзора, и блик от них возвращался раньше, чем сигнал доходил до стены. Лечится это установкой датчика так, чтобы в поле зрения не было ничего, что отражает: вынести его вперёд на кронштейне, вывести провода вниз и в сторону, а сам датчик развернуть чуть вверх. Второе наблюдение из той же серии: два HC-SR04 на одной машине мешают друг другу, потому что один слышит ультразвук другого. Лечится разнесением по времени: сначала меряет один датчик, потом, после паузы, второй.
Авторская позиция: какой дальномер взять
Мы советуем начинать с HC-SR04: он стоит как пара булок, подключается четырьмя проводами, работает без библиотек и под него написано подавляющее большинство примеров. Для первого парктроника или ночника этого более чем достаточно.
Но если вам нужна стабильная цифра, стоит посмотреть в сторону лазерных ToF-датчиков, например VL53L0X или VL53L1X. Они меряют дальность лазером, не зависят от угла поверхности, не слепят вблизи и дают миллиметровую точность на расстоянии до метра-двух. Минус у них один: цена в несколько раз выше и нужна отдельная библиотека. А для бака с водой мы берём JSN-SR04T в металлической колбе: он не боится влаги, а слепая зона у него больше, поэтому опускать его в воду нельзя. Выбор мы делаем по трём вопросам: что за поверхность, какая нужна точность и не будет ли воды.
Проверь датчик без пайки
Модуль ещё в пути, а помемигать дальномером хочется сегодня? Запустите скетч выше в симуляторе HC-SR04: виртуальный датчик отрабатывает код так же, как настоящий, пододвигайте препятствие и смотрите цифры в Serial Monitor. Дальше по маршруту уроки основ Arduino: от мигания светодиодом шаг за шагом дойдёте до парктроника со звуковой сигнализацией.
Где применяется
- Парктроник: дальномер и пьезоизлучатель, частота писка растёт по мере сближения с препятствием
- Уровень воды в баке: модуль сверху смотрит на поверхность, не ржавеет в отличие от контактных датчиков
- Робот-обходчик: HC-SR04 на серво поворачивается влево и вправо и выбирает свободное направление
- Счётчик посетителей у двери: проходящий человек пересекает конус эха, считаем срабатывания
- Ночник: свет включается, когда рука ближе 50 см, без кнопок и хлопков