Как собрать схему измерения расстояния с HC-SR04 и вывести результат на LCD

Если ты хочешь измерять расстояние с помощью ультразвукового датчика HC-SR04 и видеть результат на дисплее — например, для робота-исследователя, парктроника или просто ради интересного проекта — эта задача решается за один вечер. Главное правильно собрать схему и не наделать ошибок в коде, из-за которых датчик будет показывать ерунду.

Ниже — пошаговое руководство: от подключения проводов до рабочего скетча. Всё проверено на практике.

Что понадобится

Минимальный набор деталей:

  • Arduino (Uno, Nano или любая совместимая плата)
  • Ультразвуковой датчик HC-SR04
  • LCD-дисплей 16×2 с интерфейсом I2C (именно I2C — об этом ниже)
  • Соединительные провода (мама-мама или мама-папа — зависит от платы)
  • Макетная плата — опционально, но удобно

Почему LCD именно с I2C: обычный 16×2 без адаптера требует 6 пинов Arduino. С I2C-модулем — только 2 пина (SDA и SCL) плюс питание. Разница критическая, особенно если пинов мало.

Как устроен HC-SR04 и почему он работает

Датчик посылает ультразвуковой импульс на частоте 40 кГц, затем слушает отражённый сигнал. Время между отправкой и приёмом — это время прохождения звука туда и обратно. Зная скорость звука (~343 м/с при комнатной температуре), можно вычислить расстояние.

Формула простая: расстояние = (время × скорость звука) / 2. Делим на два, потому что звук проходит путь до объекта и обратно.

У HC-SR04 четыре вывода:

  • VCC — питание 5 В
  • GND — земля
  • Trig — вход, на него подаём короткий импульс для запуска измерения
  • Echo — выход, датчик выдаёт на него импульс, длительность которого равна времени прохождения звука

Схема подключения

Вот как всё соединять. Начну с датчика, затем дисплей.

Подключение HC-SR04 к Arduino

HC-SR04 Arduino
VCC 5V
GND GND
Trig Пин 9
Echo Пин 10

Пины Trig и Echo можно менять в коде, но для первого запуска оставь так — будет проверять.

Подключение LCD 16×2 I2C к Arduino

LCD I2C Arduino Uno / Nano
VCC 5V
GND GND
SDA A4
SCL A5

На Arduino Mega пины другие: SDA — 20, SCL — 21. На Leonardo: SDA — 2, SCL — 3. Проверь свою плату, если результат не появляется на дисплее — первая причина не тот пин.

Библиотеки, которые нужны

В Arduino IDE через менеджер библиотек установи:

  1. LiquidCrystal_I2C — самая распространённая, автор — Frank de Brabander. Ищи по названию в Library Manager.
  2. Для HC-SR04 отдельная библиотека не обязательна — работаем напрямую с пинами. Но если хочешь готовую обёртку, подойдёт NewPing — она корректно обрабатывает таймауты.

Рабочий скетч

Вот полный код. Скопируй, загрузи в Arduino, открой монитор порта на 9600 бод — там тоже будут показываться значения.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>

// Адрес дисплея обычно 0x27 или 0x3F. Если не работает — запусти I2C Scanner и проверь.
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int trigPin = 9;
const int echoPin = 10;

void setup() {
  Serial.begin(9600);
  lcd.init();
  lcd.backlight();
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  lcd.setCursor(0, 0);
  lcd.print("HC-SR04 Ready");
  delay(1500);
  lcd.clear();
}

void loop() {
  long duration;
  float distance;

  // Отправляем 10-микросекундный импульс на Trig
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);

  // Считываем длительность с Echo
  duration = pulseIn(echoPin, HIGH, 30000); // Таймаут 30 мс (~5 м)

  // Если таймаут — duration будет 0
  if (duration == 0) {
    lcd.setCursor(0, 0);
    lcd.print("Out of range    ");
    lcd.setCursor(0, 1);
    lcd.print("                ");
  } else {
    // Расчёт расстояния в сантиметрах
    distance = duration * 0.0343 / 2.0;

    lcd.setCursor(0, 0);
    lcd.print("Dist: ");
    lcd.print(distance, 1);
    lcd.print(" cm  ");

    // Дополнительно — строка состояния
    lcd.setCursor(0, 1);
    if (distance < 10) {
      lcd.print("! CLOSE OBJECT !");
    } else if (distance > 400) {
      lcd.print("Beyond 400cm   ");
    } else {
      lcd.print("Range OK       ");
    }
  }

  delay(200); // Не опрашиваем слишком часто
}

Обрати внимание на таймаут в pulseIn — 30 миллисекунд. Без него скетч зависнет, если датчик ничего не обнаружил (например, объект слишком далеко или сигнал ушёл в пустоту). Это одна из самых частых причин «зависающих» проектов.

Что делать, если на дисплее пусто

Порядок проверки:

  1. Подстроечный потенциометр на I2C-модуле. Крути его медленно — пока не появятся чёрные квадратики. Если их нет — контраст выставлен в крайнее положение.
  2. Адрес дисплея. Загрузь скетч I2C Scanner (File → Examples → Wire → scanner) и посмотри, какой адрес показывает монитор порта. Подставь его в LiquidCrystal_I2C lcd(0x27, 16, 2); вместо 0x27.
  3. Питание. Если дисплей подключён к 3.3V вместо 5V — он может не запуститься. Проверь напряжение мультиметром.
  4. Провода. Переткни SDA и SCL. Если провода длинные больше 20 см — могут быть помехи, укороти для теста.

Частые ошибки, из-за которых ничего не работает

  • Перепутаны Trig и Echo. Датчик не запускает измерение, на Echo тишина. Проверь пины по схеме.
  • Нет делителя напряжения на Echo. У HC-SR04 выход Echo — 5 В. У Arduino это обычно не проблема, но если у тебя 3.3В-плата (ESP32, Due) — без делителя напряжения пин может сгореть. Делитель: 1 кОм от Echo к пину, 2 кОм от пина к GND.
  • Слишком близкий объект. HC-SR04 не измеряет расстояние ближе ~2 см. Ближе — эхо возвращается быстрее, чем датчик успевает переключиться из режима передачи в режим приёма.
  • Мягкие или наклонные поверхности. Велосипедная шина, шторы, поролон — звук поглощается или отражается в сторону. Датчик выдаёт 0 или случайные значения. Это не поломка, это физика.
  • Забыли подсветку. lcd.backlight() без вызова — дисплей выглядит пустым, хотя данные на нём есть. Посмотри под углом — увидишь символы.

Какой LCD выбрать

Если только начинаешь — бери 16×2 с I2C-модулем на базе PCF8574. Это самый распространённый и дешёвый вариант. Вот что стоит учитывать:

Параметр LCD 16×2 I2C LCD 20×4 I2C OLED 0.96″ I2C
Символов 16 × 2 20 × 4 16 × 2 (или 21 × зависит от шрифта)
Интерфейс I2C I2C I2C
Подсветка LED, синяя/зелёная LED Сам экран — LED матрица
Читаемость при ярком свете Средняя Средняя Хорошая
Потребление ~20 мА с подсветкой ~30 мА ~15 мА
Удобство для проекта Достаточно для расстояния + статус Можно вывести больше данных Компактный, но дороже

Для задачи «показать расстояние» 16×2 хватает за глаза. 20×4 берут, когда нужно одновременно показывать минимальное/максимальное расстояние, статус системы или единицы измерения с переключением.

Сценарии выбора под свою задачу

Делаешь простой дальномер для мастерской. Бери 16×2 I2C, код выше — и работает. Минимум проводов, всё понятно.

Делаешь робот с объездом препятствий. Датчик на сервоприводе, сканирует влево-вправо. На LCD выводи расстояние + направление. Тут удобнее 20×4 — помещается больше информации.

Делаешь парктроник для гаража. LCD вообще не нужен — достаточно светодиодов и бипера. Но если хочешь именно дисплей — бери OLED, он читается при любом освещении.

Работаешь с ESP32 вместо Arduino. Схема та же, но учти: на ESP32 SDA — GPIO 21, SCL — GPIO 22. И обязательно делитель напряжения на Echo (5В → 3.3В).

Как улучшить точность

HC-SR04 из коробки даёт точность ±3 мм при идеальных условиях. На практике разброс больше. Вот что реально помогает:

  • Не опрашивай датчик слишком часто. Между измерениями нужно минимум 50–60 мс, иначе предыдущее эхо накладывается на новое.
  • Усредняй показания. Сделай 3–5 измерений, отбрось максимальное и минимальное, остальные усреднь. Разброс уйдёт.
  • Учитывай температуру. Скорость звука меняется: при 0°C это ~331 м/с, при 20°C — ~343 м/с, при 30°C — ~349 м/с. Для домашних условий разница незаметна, но если работаешь на улице зимой — добавь датчик температуры и корректируй расчёт.
  • Фиксируй датчик жёстко. Висящий на проводах, болтающийся на макетке — он сам себе создаёт помехи.

Итог

Собрать дальномер на HC-SR04 с выводом на LCD — задача на 30 минут, если знаешь порядок действий. Ключевые моменты:

  • Подключай LCD через I2C — экономишь пины и провода.
  • Всегда ставь таймаут в pulseIn — иначе скетч зависнет при потере сигнала.
  • Если дисплей пустой — сначала проверь контраст и адрес I2C, потом всё остальное.
  • Для мягких и наклонных поверхностей датчик врёт — это не баг, это особенность ультразвука.

Начни с приведённого выше кода — он рабочий. Когда заработает — добавляй свои фильтры, усреднение, переключение единиц измерения. Это уже детали.

Radio-Blog.ru