IoTLabs

Nghiên cứu, Sáng tạo và Thử nghiệm

Series ESP32 & Cảm biến: Bài 24 – Đọc cảm biến HC-SR04: đo khoảng cách siêu âm & theo dõi realtime

Cảm biến HC-SR04 là một trong những cảm biến đo khoảng cách phổ biến nhất trong thế giới DIY/Maker.
Với ESP32, HC-SR04 giúp bạn đo khoảng cách không tiếp xúc, rất phù hợp cho:

  • Tránh vật cản (robot, xe tự hành)
  • Đo mức nước/thùng chứa (phiên bản đơn giản)
  • Phát hiện có người/vật đi qua
  • Làm trigger cho cảnh báo, automation

Trong bài này, chúng ta sẽ:

  1. Đo khoảng cách HC-SR04 local
  2. Gửi dữ liệu realtime lên IoTLabs Cloud MQTT

1. HC-SR04 là gì?

HC-SR04 là cảm biến siêu âm, hoạt động theo nguyên lý:

  • Phát sóng siêu âm (Trigger)
  • Nhận sóng phản xạ (Echo)
  • Tính thời gian → suy ra khoảng cách

Thông số cơ bản

  • Điện áp: 5V
  • Khoảng đo: ~2cm → 400cm
  • Độ chính xác: ~±3mm
  • Giao tiếp: Trigger / Echo (Digital)

📌 Lưu ý: Echo trả về xung 5V → cần cẩn thận với ESP32 (3.3V).

2. Chuẩn bị phần cứng & nối dây

Thiết bị

  • ESP32-C3 SuperMini
  • HC-SR04
  • (Khuyến nghị) chia áp cho chân Echo

Kết nối cơ bản

HC-SR04ESP32-C3
VCC5V
GNDGND
TRIGGPIO4
ECHOGPIO5 (qua chia áp)

📌 Có thể dùng chia áp: 1kΩ + 2kΩ để hạ 5V → ~3.3V.

3. Nguyên lý đo khoảng cách

Công thức chuẩn:

distance_cm = (duration_us × 0.034) / 2
  • duration_us: thời gian Echo HIGH (microseconds)
  • 0.034 cm/µs: vận tốc âm thanh trong không khí

4. Ví dụ 1: Đọc HC-SR04 local (Serial)

#define TRIG_PIN 4
#define ECHO_PIN 5

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

float readDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000); // timeout 30ms
  if (duration == 0) return -1;

  return (duration * 0.034) / 2.0;
}

void loop() {
  float distance = readDistanceCM();
  if (distance > 0) {
    Serial.print("Distance: ");
    Serial.print(distance);
    Serial.println(" cm");
  } else {
    Serial.println("Out of range");
  }
  delay(500);
}

📌 pulseIn có timeout giúp tránh treo chương trình.

5. Đặc trưng dữ liệu HC-SR04 (IoT mindset)

HC-SR04 sinh ra telemetry liên tục, không phải event.

Dữ liệu phù hợp:

{
  "ts": 1760000000,
  "metrics": {
    "distance_cm": 42.5
  }
}

👉 Rất phù hợp cho:

  • Chart realtime
  • Trigger rule (nếu < X cm → cảnh báo)

6. Ví dụ 2: Gửi khoảng cách realtime lên IoTLabs Cloud MQTT

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

#define TRIG_PIN 4
#define ECHO_PIN 5

const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASS = "YOUR_PASS";

const char* MQTT_HOST = "mqtt.iotlabs.vn";
const int MQTT_PORT = 8883;
const char* MQTT_USER = "YOUR_MQTT_USER";
const char* MQTT_PASS = "YOUR_MQTT_PASS";

const char* MQTT_TOPIC =
  "iotlabs/<orgId>/devices/<deviceId>/telemetry";

WiFiClientSecure net;
PubSubClient mqtt(net);

float readDistanceCM() {
  digitalWrite(TRIG_PIN, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG_PIN, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG_PIN, LOW);

  long duration = pulseIn(ECHO_PIN, HIGH, 30000);
  if (duration == 0) return -1;
  return (duration * 0.034) / 2.0;
}

void connectWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) delay(500);
}

void connectMQTT() {
  net.setInsecure();
  mqtt.setServer(MQTT_HOST, MQTT_PORT);
  while (!mqtt.connected()) {
    mqtt.connect("esp32c3-hcsr04", MQTT_USER, MQTT_PASS);
    delay(1000);
  }
}

unsigned long lastSend = 0;

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

  connectWiFi();
  connectMQTT();
}

void loop() {
  if (!mqtt.connected()) connectMQTT();
  mqtt.loop();

  if (millis() - lastSend > 1000) {
    lastSend = millis();

    float d = readDistanceCM();
    if (d < 0) return;

    long ts = millis() / 1000;
    String payload = "{";
    payload += "\"ts\":" + String(ts) + ",";
    payload += "\"metrics\":{";
    payload += "\"distance_cm\":" + String(d, 1);
    payload += "}}";

    mqtt.publish(MQTT_TOPIC, payload.c_str());
    Serial.println(payload);
  }
}

7. Kinh nghiệm thực tế khi dùng HC-SR04

  • Không đo tốt với bề mặt mềm (vải, mút)
  • Góc phản xạ ảnh hưởng kết quả
  • Tránh đặt gần quạt, gió mạnh
  • Với môi trường ẩm → sai số tăng

📌 Nếu cần ổn định hơn:

  • Lấy trung bình 3–5 lần đo
  • Bỏ các giá trị outlier

8. Ứng dụng thực tế

Sau bài này, bạn có thể làm:

  • Cảnh báo vật cản
  • Đếm người (kết hợp logic)
  • Đo mức nước (demo)
  • Trigger relay khi khoảng cách < ngưỡng

9. Tổng kết Bài 24

Bạn đã:

  • Hiểu nguyên lý đo khoảng cách siêu âm
  • Đọc HC-SR04 bằng ESP32
  • Gửi dữ liệu realtime lên IoTLabs Cloud
  • Áp dụng tư duy telemetry + rule