Hướng dẫn lập trình ESP32 đọc cảm biến siêu âm HC-SR04, đo khoảng cách vật thể theo thời gian thực. Bài viết giải thích nguyên lý hoạt động, sơ đồ kết nối, và cung cấp code ví dụ in kết quả ra Serial và OLED SSD1306.
Mục lục
- Giới thiệu cảm biến HC-SR04
- Nguyên lý hoạt động
- Chuẩn bị phần cứng
- Sơ đồ kết nối
- Code ví dụ 1 – Đọc cảm biến hiển thị qua Serial
- Code ví dụ 2 – Đọc cảm biến & hiển thị lên OLED
- Giải thích mã nguồn
- Gợi ý mở rộng
- Lỗi thường gặp
1) Giới thiệu cảm biến HC-SR04
Cảm biến HC-SR04 là loại siêu âm (ultrasonic) phổ biến dùng để đo khoảng cách bằng cách phát xung âm thanh và đo thời gian phản hồi khi sóng âm dội lại từ vật thể.
- Khoảng đo: 2cm – 400cm
- Điện áp hoạt động: 5V
- Tín hiệu: Trig (phát xung), Echo (nhận phản hồi)
- Giao tiếp: digital pulse (không cần giao thức đặc biệt)
2) Nguyên lý hoạt động
- Gửi xung HIGH 10µs vào chân Trig
- Module phát sóng âm tần số 40kHz
- Khi gặp vật cản, sóng phản xạ trở lại và được cảm biến thu qua chân Echo
- ESP32 đo thời gian xung HIGH tại Echo
- Khoảng cách được tính theo công thức:

3) Chuẩn bị phần cứng
| Linh kiện | Số lượng | Ghi chú |
|---|---|---|
| ESP32 DevKit V1 | 1 | Board chính |
| HC-SR04 Ultrasonic | 1 | Module đo khoảng cách |
| OLED SSD1306 I2C | 1 | Tùy chọn hiển thị |
| Dây nối | — | 4–6 dây dupont |
4) Sơ đồ kết nối

| HC-SR04 Pin | ESP32 Pin | Mô tả |
|---|---|---|
| VCC | 5V | Nguồn 5V |
| GND | GND | Chung mass |
| Trig | GPIO5 | Chân phát xung |
| Echo | GPIO18 | Chân nhận phản hồi |
OLED (tùy chọn):
- SDA → GPIO21
- SCL → GPIO22
- VCC → 3.3V
- GND → GND
Lưu ý: Echo xuất mức 5V, nên dùng chia áp 10kΩ/20kΩ hoặc logic-level shifter để bảo vệ chân ESP32.
5) Code ví dụ 1 – Đọc cảm biến và in Serial
#define TRIG_PIN 5
#define ECHO_PIN 18
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop() {
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration / 58.2;
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
delay(500);
}
6) Code ví dụ 2 – Hiển thị lên OLED SSD1306
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define TRIG_PIN 5
#define ECHO_PIN 18
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
void setup() {
Serial.begin(115200);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("OLED failed!"));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
}
void loop() {
// Phát xung đo
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
float distance = duration / 58.2;
display.clearDisplay();
display.setCursor(0, 0);
display.println("ESP32 - HC-SR04");
display.setTextSize(2);
display.setCursor(10, 30);
display.print(distance, 1);
display.print(" cm");
display.display();
Serial.printf("Distance: %.1f cm\n", distance);
delay(500);
}
7) Giải thích mã
pulseIn(ECHO_PIN, HIGH)đo thời gian phản hồi (µs).- Công thức chia 58.2 quy đổi sang cm (tốc độ âm thanh 343m/s).
- OLED hiển thị giá trị đo dạng chữ lớn, cập nhật mỗi 0.5s.
8) Gợi ý mở rộng
- Thêm buzzer cảnh báo khi vật ở gần (< 20 cm).
- Gửi dữ liệu MQTT / WebSocket lên dashboard.
- Hiển thị biểu đồ realtime trên web UI.
- Kết hợp servo hoặc motor để tạo hệ thống tránh vật cản tự động.
9) Lỗi thường gặp
| Lỗi | Nguyên nhân | Cách xử lý |
|---|---|---|
| Luôn hiển thị 0 | Sai chân Trig/Echo | Kiểm tra dây hoặc delayMicroseconds |
| Kết quả sai lệch | Echo 5V chưa giảm áp | Thêm chia áp 10k/20k |
| OLED không hiển thị | Địa chỉ I2C sai (0x3C/0x3D) | Kiểm tra SDA/SCL |


Để lại một bình luận