Skip to main content

HC-SR04 Сонар

HC-SR04: Классический сонар

HC-SR04 — это “Hello World” в мире датчиков расстояния. Он состоит из двух пьезоизлучателей: один работает как динамик (T), другой как микрофон (R).

HC-SR04

1. Sensing: Характеристики

  • Диапазон: 2 см – 400 см (реально стабильно до 2-3 метров).
  • Точность: ~3 мм.
  • Угол обзора: ~15 градусов.
  • Питание: 5V (есть версии на 3.3V, например HC-SR04P, но классический требует 5V).
  • Частота: 40 кГц.

Протокол работы

  1. Подаем импульс HIGH длительностью 10 мкс на пин Trig.
  2. Датчик сам посылает пачку из 8 импульсов по 40 кГц.
  3. Пин Echo становится HIGH в момент отправки и переходит в LOW, когда вернулось эхо.
  4. Длительность импульса на Echo пропорциональна расстоянию.

2. Подключение

PinНазначениеArduino
VCCПитание5V
TrigЗапуск (Trigger)Любой цифровой (напр. D9)
EchoЭхо (Output)Любой цифровой (напр. D10)
GNDЗемляGND

Внимание: Если вы используете ESP32 или Raspberry Pi (3.3V логика), пин Echo выдает 5V! Нужно использовать делитель напряжения (резисторы 1кОм и 2кОм), чтобы не сжечь вход контроллера.

3. Thinking: Программная реализация

Способ 1: Ручное управление (функция pulseIn)

#define TRIG_PIN 9
#define ECHO_PIN 10

void setup() {
  Serial.begin(9600);
  pinMode(TRIG_PIN, OUTPUT);
  pinMode(ECHO_PIN, INPUT);
}

void loop() {
  // 1. Сброс Trig
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  
  // 2. Импульс 10 мкс
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);
  
  // 3. Измерение длительности Echo (в микросекундах)
  // pulseIn ждет, пока пин станет HIGH, считает время, пока он HIGH
  long duration = pulseIn(ECHO_PIN, HIGH);
  
  // 4. Расчет дистанции
  // Скорость звука = 343 м/с = 0.0343 см/мкс
  // Путь туда-обратно, поэтому делим на 2
  int distance = duration * 0.0343 / 2;
  
  Serial.print("Distance: ");
  Serial.print(distance);
  Serial.println(" cm");
  
  delay(100); // Не опрашивайте чаще 60мс, чтобы эхо затухло!
}

Способ 2: Библиотека NewPing

Библиотека NewPing (автор Tim Eckel) работает быстрее, точнее и не блокирует код так сильно, как pulseIn.

Установка: Sketch -> Include Library -> Manage Libraries -> NewPing.

#include <NewPing.h>

#define TRIG_PIN 9
#define ECHO_PIN 10
#define MAX_DISTANCE 200 // Максимальная дистанция (см)

NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE);

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(50); // Задержка между пингами (минимум 29мс)
  
  unsigned int uS = sonar.ping(); // Время в микросекундах
  
  Serial.print("Ping: ");
  Serial.print(uS / US_ROUNDTRIP_CM); // Конвертация в см
  Serial.println(" cm");
}

4. Acting: Применение

  1. Робот-пылесос: Обнаружение стен и мебели.
  2. Парктроник: Звуковая индикация приближения к препятствию.
  3. Уровень жидкости: Измерение уровня воды в баке (датчик в крышке, смотрит вниз).
  4. Охранная система: Если расстояние изменилось (кто-то прошел), поднять тревогу.

Фильтрация

Показания могут “скакать”. Используйте медианный фильтр (в NewPing есть метод ping_median(iterations)).

// Получить медиану из 5 измерений (отсекает случайные выбросы)
unsigned int uS = sonar.ping_median(5);
int cm = sonar.convert_cm(uS);