Компонент · Датчик
Ультразвуковой датчик HC-SR04
HC-SR04 — ультразвуковой датчик расстояния для роботов. Как работает эхолокация, какова дальность и слепые зоны и как подключить датчик.
Что это такое
HC-SR04 — ультразвуковой датчик расстояния: небольшая плата с двумя серебристыми цилиндрами, похожими на глаза робота. Он измеряет расстояние так же, как летучая мышь или подводная лодка: излучает пакет слишком высокого для слуха звука, слушает эхо и измеряет время пути туда и обратно. За несколько долларов он даёт роботу представление о пространстве перед ним, поэтому является стандартным датчиком первого робота, объезжающего препятствия.
Два цилиндра — передатчик и приёмник. Один посылает сигнал, другой слушает. Всё остальное на плате — схема измерения времени, превращающая эхо в сигнал, который может измерить микроконтроллер.
Как это работает
Датчик использует простой протокол из двух проводов:
- Подайте на вывод Trigger высокий уровень на 10 микросекунд.
- Датчик посылает восемь ультразвуковых импульсов частотой 40 kHz и устанавливает высокий уровень на выводе Echo.
- Когда эхо вернётся, датчик снова переводит Echo на низкий уровень.
- Измерьте время, в течение которого Echo оставался высоким.
Ширина импульса и есть время пути туда и обратно. Звук распространяется в воздухе со скоростью около 343 m/s, поэтому distance = (echo_time × 343) / 2; деление на два нужно потому, что звук прошёл туда и обратно. Большинство программ Arduino реализуют это через pulseIn() и несколько арифметических операций.
Поскольку результат зависит от скорости звука, показания немного изменяются с температурой: в тёплом воздухе звук распространяется быстрее. Для робота, объезжающего стены, эта ошибка несущественна; при точном измерении её необходимо компенсировать.
Когда его следует использовать
Выбирайте HC-SR04, когда роботу нужно примерно понять, насколько далеко находится ближайший объект: для объезда препятствий, следования вдоль стены, защиты «не съехать со стола» или запуска поведения при приближении чего-либо. Широкий луч здесь даже полезен: препятствие трудно пропустить.
Выбирайте другое решение, когда требуется точное расстояние, узкий луч или быстрое обновление. Датчик времени пролёта использует свет вместо звука и даёт узкое, быстрое измерение с точностью до миллиметра; он лучше подходит для построения карты или оценки конкретного промежутка.
Подключение и важные нюансы
- Echo — вывод 5 V. На плате 5 V, например Arduino Uno, это допустимо. На плате 3.3 V, например ESP32, установите на Echo делитель напряжения, иначе можете повредить вывод.
- Учитывайте слепую зону и конус. Ничто ближе ~2 cm не регистрируется, а луч ~15° означает, что датчик сообщает о ближайшем объекте в конусе: боковая ножка стола может вызвать срабатывание.
- Мягкие и наклонные поверхности обманывают. Пена, ткань или стена под крутым углом рассеивают эхо в сторону от приёмника, поэтому датчик показывает «далеко» или ничего. Лучше всего он работает с ровными твёрдыми поверхностями, направленными к нему.
- Не опрашивайте слишком часто. Оставляйте ~60 ms между измерениями, чтобы предыдущее эхо затухло; при более частых запросах блуждающие отражения дают ложные показания. Фильтрация потока также помогает — см. подавление шума датчиков.
Расположение выводов
| Вывод | Название | Направление | Назначение |
|---|---|---|---|
| 1 | VCC | Вход | 5 V. Плата потребляет около 15 mA с выбросом во время импульса |
| 2 | Trig | Вход | Импульс HIGH длительностью 10 µs запускает измерение |
| 3 | Echo | Выход | HIGH при выходе пакета, LOW при возвращении. Выход 5 V |
| 4 | GND | — | Земля |
Четыре вывода всегда расположены в таком порядке, а модуль почти всегда ориентирован выводами от излучателя, поэтому при взгляде на «глаза» VCC находится слева.
Подключение к Arduino
| HC-SR04 | Arduino Uno | ESP32 |
|---|---|---|
| VCC | 5 V | 5 V (от VIN, не от шины 3.3 V) |
| Trig | Любой цифровой вывод | Любой GPIO |
| Echo | Любой цифровой вывод | Через делитель — см. ниже |
| GND | GND | GND |
Проблема 3.3 V
Вывод Echo выдаёт полные 5 V, а выводы GPIO ESP32 или Raspberry Pi рассчитаны на 3.3 V. Подача 5 V превышает абсолютный максимум и действительно повреждает вывод, хотя часто он какое-то время работает. Исправляют это два резистора:
Echo ──┬── 1 kΩ ──┬── to 3.3 V GPIO
│ │
│ 2 kΩ
│ │
└──────────┴── GND
Делитель даёт 5 V × 2/(1+2) = 3.33 V. Подойдёт любое отношение около 2:1 — 1 kΩ и 2 kΩ либо 10 kΩ и 20 kΩ. Не используйте значения выше примерно 20 kΩ, иначе входная ёмкость вывода настолько замедлит фронт, что исказит измеряемое время.
Расчёт расстояния и источники ошибок
distance = (echo_microseconds x speed_of_sound) / 2
При 20 °C звук распространяется со скоростью 343 m/s, то есть 0.0343 cm/µs. Отсюда получается постоянная, которую используют все: разделите время эхо на 58.2, чтобы получить сантиметры.
Скорость звука зависит от температуры, примерно:
speed (m/s) = 331.3 + 0.606 x temperature_celsius
| Температура | Скорость звука | Ошибка при допущении 20 °C |
|---|---|---|
| 0 °C | 331 m/s | Показывает на 3.5% дальше |
| 20 °C | 343 m/s | — |
| 40 °C | 356 m/s | Показывает на 3.7% ближе |
На расстоянии 2 m зимой в гараже это около 7 cm по сравнению с тёплой комнатой. Для объезда препятствий ошибка несущественна. При измерении промежутка её следует компенсировать; если на роботе есть MPU-6050 или почти любой датчик I²C, показание температуры у вас уже есть.
Минимальный рабочий код
const int TRIG = 9, ECHO = 10;
const unsigned long TIMEOUT_US = 25000UL; // ~4.3 m, past the sensor's range
void setup() {
Serial.begin(115200);
pinMode(TRIG, OUTPUT);
pinMode(ECHO, INPUT);
}
// Returns centimetres, or -1 when nothing came back.
float pingCm() {
digitalWrite(TRIG, LOW); delayMicroseconds(2);
digitalWrite(TRIG, HIGH); delayMicroseconds(10);
digitalWrite(TRIG, LOW);
unsigned long us = pulseIn(ECHO, HIGH, TIMEOUT_US);
if (us == 0) return -1.0f; // timeout: no echo, NOT "zero distance"
return us / 58.2f;
}
// Median of three kills the occasional wild reading.
float pingMedianCm() {
float a = pingCm(); delay(60);
float b = pingCm(); delay(60);
float c = pingCm();
if (a > b) { float t = a; a = b; b = t; }
if (b > c) { float t = b; b = c; c = t; }
if (a > b) { float t = a; a = b; b = t; }
return b;
}
void loop() {
float cm = pingMedianCm();
if (cm < 0) Serial.println("no echo");
else Serial.println(cm);
delay(60);
}
Три детали отличают работающий датчик от неработающего.
Тайм-аут обязателен. pulseIn без тайм-аута блокирует выполнение до прихода эхо, которого от мягкой или наклонной поверхности может не быть. Робот выглядит произвольно зависшим, и причина кажется не связанной с датчиком.
Ноль — не расстояние. Тайм-аут означает «ничего не вернулось», то есть ближайший объект обычно далеко или невидим, а не имеет нулевого значения. Если считать тайм-аут равным 0 cm, робот включит аварийную остановку в пустой комнате.
Медиана трёх измерений отбрасывает единичное аномальное значение, которое такие датчики регулярно выдают. Одно ложное значение 20 cm в открытом пространстве способно заставить робота резко свернуть в стену.
Честная оценка диаграммы направленности
В характеристиках указано 15°, что звучит как узкий луч фонаря, но это не так: это полуугол основного лепестка, и практическое следствие состоит в том, что на расстоянии 1 m датчик слушает конус шириной примерно 50 cm.
| Расстояние | Примерная ширина конуса |
|---|---|
| 20 cm | ~10 cm |
| 50 cm | ~26 cm |
| 1 m | ~53 cm |
| 2 m | ~105 cm |
Датчик сообщает о ближайшем объекте в любом месте конуса и никак не указывает, где именно внутри он находится. Поэтому HC-SR04 может обнаружить дверной проём, но не определить его положение, а ножка стола сбоку вызывает остановку.
При перемещении по комнате это преимущество: очень трудно пропустить препятствие. Для измерения расстояния до конкретного объекта это неприемлемо, и нужен VL53L0X.
Чего он не может видеть
Это физические ограничения, а не дефекты, и проектирование с их учётом — часть работы:
| Поверхность | Что происходит | Почему |
|---|---|---|
| Стена под углом более ~45° | Показывает далеко или ничего | Звук отражается в сторону от приёмника, как свет от зеркала |
| Подушки, шторы, пена | Ничего не показывает | Материал поглощает импульс вместо отражения |
| Очень близкие объекты | Ничего не показывает ближе ~2 cm | Приёмник ещё не восстановился после излучающего пакета |
| Тонкие объекты (ребро ножки стула сбоку) | Обнаруживаются, но положение неверно | Конус широкий; отражение реально, но азимут определён неверно |
| Поблизости другой HC-SR04 | Случайные аномальные показания | Датчики слышат сигналы друг друга — разнесите моменты срабатывания |
Робот, полагающийся только на ультразвуковую дальномерию, рано или поздно будет толкать штору, пока что-нибудь не поддастся. Именно поэтому бамперный переключатель является самой дешёвой мерой надёжности на всём роботе.
Диагностика
| Симптом | Вероятная причина | Исправление |
|---|---|---|
| Всегда показывает 0 | Тайм-аут трактуется как расстояние | Возвращать специальное значение и явно обрабатывать отсутствие эхо |
| Робот произвольно зависает | pulseIn без тайм-аута |
Передать тайм-аут — 25000 µs покрывает всю дальность |
| Показания скачут | Опрос чаще ~60 ms | Дождаться затухания предыдущего эхо |
| Постоянная ошибка в несколько процентов | Температура | Компенсировать по формуле скорости звука |
| Работает на стенде, но не на роботе | Шум двигателей на шине 5 V | Разделить питание датчика; удалить провода от проводов двигателей |
| Два датчика мешают друг другу | Слышат взаимные сигналы | Запускать их по очереди, никогда одновременно |
| Вывод ESP32 перестал реагировать | 5 V от Echo на GPIO 3.3 V | Добавить делитель и проверить работоспособность вывода |
| Обнаруживает то, что не находится впереди | Конус 15° | Так и ожидается; механически сузить полезный угол или использовать лазерный датчик |
HC-SR04 или VL53L0X?
| HC-SR04 | VL53L0X | |
|---|---|---|
| Метод | Звук 40 kHz | Лазер 940 nm по времени пролёта |
| Дальность | 2 cm – 4 m | 3 cm – 2 m (до 4 m в лучшем случае) |
| Луч | Полуугол ~15° — широкий конус | Поле зрения ~25°, но фактически узкое пятно |
| Частота обновления | ~16 Hz (цикл 60 ms) | До 50 Hz |
| Не видит | Мягкие и круто наклонённые поверхности | Тёмные матовые и зеркальные поверхности, яркий солнечный свет |
| Интерфейс | Два вывода, библиотека не нужна | I²C |
| Стоимость | ~$2 | ~$5 |
Они отказывают на противоположных материалах, поэтому выбор становится простым, если известно помещение. Сонар видит чёрную коробку под тканью, которую не видит лазер; лазер видит стеклянную дверь под углом, которую не видит сонар. Для надёжного робота честный ответ часто звучит так: использовать оба, а когда оба ошибаются — ещё и бамперный переключатель.
Исследуйте граф
Используется в этих сборках
Проекты, учебные пути и симуляторы, в которых используется Ультразвуковой датчик HC-SR04.
Сравнение
Альтернативы
Вопросы
Ультразвуковой датчик HC-SR04: частые вопросы
Что такое ультразвуковой датчик HC-SR04?
HC-SR04 — недорогой датчик расстояния, который измеряет удалённость объекта по отражённому пакету ультразвука, по тому же принципу, что используют летучие мыши и сонары. Это датчик, который большинство первых роботов использует для обнаружения и объезда препятствий.
Как работает HC-SR04?
Подайте короткий импульс на вывод Trigger. Датчик излучает восемь ультразвуковых пакетов частотой 40 kHz и устанавливает высокий уровень на выводе Echo до возвращения отражения. Измерьте время, в течение которого Echo остаётся высоким; поскольку скорость звука составляет около 343 m/s, расстояние равно времени, умноженному на скорость звука и делённому на два из-за пути туда и обратно.
Какова максимальная дальность HC-SR04?
HC-SR04 измеряет примерно от 2 cm до 4 m. Наиболее точен в диапазоне от 5 cm до 2 m; около предела 4 m показания становятся ненадёжными, а объекты ближе примерно 2 cm попадают в слепую зону и не могут быть измерены.
Насколько HC-SR04 точен и надёжен?
Для объезда препятствий его точности достаточно: примерно 3 mm на ровной твёрдой поверхности, перпендикулярной лучу. Он хуже работает с мягкими и наклонными поверхностями, рассеивающими эхо, зависит от температуры и имеет широкий луч ~15°, поэтому воспринимает конус, а не точку.
Как подключить HC-SR04 к Arduino?
Подключите VCC к 5 V, GND к земле, Trigger к любому цифровому выходу, а Echo к цифровому входу. Важно: Echo выдаёт 5 V, поэтому при использовании платы 3.3 V, например ESP32, понизьте напряжение делителем перед считыванием.
HC-SR04 или US-100 — что лучше?
US-100 — близкий аналог с температурной компенсацией, вариантом последовательного интерфейса и питанием 3.3–5 V, поэтому он точнее и удобнее для плат 3.3 V. HC-SR04 дешевле и по нему больше руководств. Для обучения HC-SR04 подходит; для точности преимущество у US-100.
Как проверить работоспособность ультразвукового датчика?
Выводите измеренное расстояние в последовательный монитор и приближайте или удаляйте руку от датчика: показания должны изменяться плавно. Если они зависли на нуле или максимальном значении, проверьте подключение Trigger и Echo, убедитесь в надёжном питании 5 V и выберите достаточно большой тайм-аут для полной дальности 4 m.
Дополнительные материалы