Ультразвуковой датчик расстояния HC-SR04 на ESP32
Ультразвуковой датчик HC-SR04 вычисляет расстояние по времени, за которое испущенная им звуковая волна отражается от предмета и возвращается (Time of Flight). В этом проекте ESP32 подаёт импульс 10 микросекунд на пин TRIG датчика, а длительность эха читает с пина ECHO через pulseIn(). Вычисленное расстояние в сантиметрах выводится на I2C LCD 16x2. HC-SR04 работает от 5V, поэтому на пине ECHO нужен делитель напряжения.

Видео
Схема

Исходный код
1// ─────────────────────────────────────────
2// BlueGrays · bluegrays.com
3// Ультразвуковой датчик расстояния HC-SR04 на ESP32
4// ─────────────────────────────────────────
5// Запускает HC-SR04 импульсом TRIG, вычисляет расстояние (см) по времени
6// ECHO и каждые 0,2 с показывает его на I2C LCD 16x2. Если эхо не
7// вернулось, на экране "Menzil disinda" (вне диапазона).
8//
9// Пины:
10// GPIO 5 -> HC-SR04 TRIG
11// GPIO 18 -> HC-SR04 ECHO (через делитель напряжения)
12// Делитель: ECHO -> 1k -> GPIO 18 -> 2k -> GND
13// GPIO 21 -> LCD SDA, GPIO 22 -> LCD SCL
14// HC-SR04 and LCD VCC -> 5V (VIN), GND -> GND
15
16#include <Wire.h>
17#include <LiquidCrystal_I2C.h>
18
19// Определения пинов
20const int TRIG_PIN = 5;
21const int ECHO_PIN = 18; // Нужен делитель напряжения 1k + 2k
22
23// Адрес LCD 0x27 или 0x3F
24LiquidCrystal_I2C lcd(0x27, 16, 2);
25
26const float SOUND_SPEED_CM_PER_US = 0.0343f; // Скорость звука (см/мкс)
27const unsigned long PULSE_TIMEOUT_US = 30000UL; // Тайм-аут эха (~5 м)
28
29void setup() {
30 pinMode(TRIG_PIN, OUTPUT);
31 pinMode(ECHO_PIN, INPUT);
32 digitalWrite(TRIG_PIN, LOW);
33
34 // Пины I2C DevKit V1 по умолчанию
35 Wire.begin(21, 22);
36
37 lcd.init();
38 lcd.backlight();
39
40 // Заставка 3 с
41 lcd.setCursor(3, 0);
42 lcd.print("BlueGrays");
43 lcd.setCursor(1, 1);
44 lcd.print("HC-SR04 v1.0");
45 delay(3000);
46
47 // Главный экран
48 lcd.clear();
49 lcd.setCursor(0, 0);
50 lcd.print("Mesafe:");
51}
52
53// Читает расстояние в см, при ошибке -1
54float readDistanceCm() {
55 // Импульс TRIG 10 мкс запускает измерение
56 digitalWrite(TRIG_PIN, LOW);
57 delayMicroseconds(2);
58 digitalWrite(TRIG_PIN, HIGH);
59 delayMicroseconds(10);
60 digitalWrite(TRIG_PIN, LOW);
61
62 unsigned long duration = pulseIn(ECHO_PIN, HIGH, PULSE_TIMEOUT_US);
63 if (duration == 0) return -1.0f;
64 // Путь туда и обратно, поэтому делим на 2
65 return (duration * SOUND_SPEED_CM_PER_US) / 2.0f;
66}
67
68void loop() {
69 float distance = readDistanceCm();
70
71 // Очистить нижнюю строку
72 lcd.setCursor(0, 1);
73 lcd.print(" ");
74 lcd.setCursor(0, 1);
75
76 if (distance < 0) {
77 lcd.print("Menzil disinda");
78 } else {
79 lcd.print(distance, 1); // 1 знак после запятой
80 lcd.print(" cm");
81 }
82
83 delay(200);
84}
85
Частые вопросы
Зачем на линии ECHO ставят делитель напряжения?
HC-SR04 работает от 5 V, и пин ECHO выдаёт 5 V; входы ESP32 принимают максимум 3,3 V. Делитель напряжения из резисторов 1 kΩ и 2 kΩ понижает 5 V примерно до 3,3 V и тем самым защищает ESP32.
Нужен ли делитель и на пине TRIG?
Нет. TRIG — это сигнал от ESP32 к датчику; уровень HIGH 3,3 V у ESP32 обычно надёжно распознаётся HC-SR04.
Нужен ли делитель с HC-SR04P?
Модели вроде HC-SR04P и RCWL-1601 можно питать от 3,3 V; в этом случае выход ECHO тоже 3,3 V, и делитель не нужен.
Как сделать измерение расстояния точнее?
Скорость звука зависит от температуры (около 343 м/с при 20 °C). Поправка скорости звука по датчику температуры и медиана нескольких измерений повышают точность.
