IoTLabs

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

Series ESP32 & Cảm biến: Bài 3 – Hướng dẫn đọc cảm biến Reed Switch (công tắc từ cửa): phát hiện đóng/mở cửa & theo dõi realtime

Trong bài này, chúng ta sử dụng Reed Switch (công tắc từ) để phát hiện trạng thái đóng/mở cửa. Đây là cảm biến rất đơn giản, bền, ít lỗi, thường dùng trong các hệ thống:

  • Báo mở cửa / cửa sổ
  • An ninh cơ bản
  • Giám sát trạng thái phòng, tủ, kho

Bài viết gồm 2 ví dụ code:

  1. Đọc trạng thái cửa local (Serial)
  2. Gửi trạng thái cửa lên IoTLabs Cloud MQTT để theo dõi realtime

1) Reed Switch là gì? (hiểu nhanh)

  • Reed Switch là công tắc đóng/mở bằng từ trường
  • Gồm 2 phần:
    • Công tắc reed (gắn trên khung cửa)
    • Nam châm (gắn trên cánh cửa)

Nguyên lý

  • Khi nam châm ở gần → reed đóng mạch
  • Khi nam châm rời xa → reed hở mạch

👉 Reed không cần cấp nguồn, chỉ là công tắc cơ học.

2) Chuẩn bị

Phần cứng

  • ESP32-C3 SuperMini (Tenstar Robot)
  • 1x Reed Switch (loại thường dùng cho cửa)
  • 1x nam châm đi kèm
  • Dây nối

Chân sử dụng

  • REED_PIN → GPIO3
  • GND → GND

✅ Không cần 5V / 3.3V cho Reed Switch

3) Nối dây Reed Switch với ESP32

Cách đơn giản và ổn định nhất là dùng pull-up nội bộ của ESP32.

Reed Switch        ESP32-C3 SuperMini
-----------------------------------
1 chân ------------ GPIO3
1 chân ------------ GND

Trong code ta dùng:

pinMode(GPIO3, INPUT_PULLUP);

Logic đọc

Trạng thái cửaReedGPIO đọc được
Đóng cửaĐóng mạchLOW (0)
Mở cửaHở mạchHIGH (1)

4) Lưu ý thực tế

  • Reed rất nhạy → không cần debounce phức tạp
  • Nhưng khi cửa rung nhẹ, vẫn nên:
    • Kiểm tra thay đổi trạng thái
    • Không gửi MQTT liên tục

Ví dụ 1 — Code local đơn giản (đọc đóng/mở cửa)

Mục tiêu: phát hiện khi cửa đóng hoặc mở và in ra Serial.

// ===== Reed Switch Local Read =====
const int REED_PIN = 3;

int lastState = HIGH;

void setup() {
  Serial.begin(115200);
  delay(200);

  pinMode(REED_PIN, INPUT_PULLUP);
  Serial.println("Reed switch local monitor started...");
}

void loop() {
  int state = digitalRead(REED_PIN);

  if (state != lastState) {
    if (state == LOW) {
      Serial.println("Cửa ĐÃ ĐÓNG");
    } else {
      Serial.println("Cửa ĐÃ MỞ");
    }
    lastState = state;
  }

  delay(100);
}

✅ Kết quả:

  • Đóng cửa → "Cửa ĐÃ ĐÓNG"
  • Mở cửa → "Cửa ĐÃ MỞ"

5) Chuẩn dữ liệu realtime cho IoTLabs Cloud

Topic

iotlabs/<orgId>/devices/<deviceId>/telemetry

Payload JSON

{
  "ts": 1760000000,
  "metrics": {
    "door": 1
  },
  "status": {
    "door": "open"
  }
}
Giá trị doorÝ nghĩa
0đóng
1mở

Ví dụ 2 — Gửi trạng thái cửa lên IoTLabs Cloud MQTT

Chiến lược:

  • Chỉ gửi khi trạng thái thay đổi
  • Phù hợp cho pin / mạng yếu
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>

// ===== CONFIG =====
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";

// ===== REED =====
const int REED_PIN = 3;
int lastState = HIGH;

WiFiClientSecure net;
PubSubClient mqtt(net);

void connectWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  while (WiFi.status() != WL_CONNECTED) {
    delay(400);
    Serial.print(".");
  }
  Serial.println("\nWiFi connected");
}

void connectMQTT() {
  net.setInsecure(); // demo nhanh
  mqtt.setServer(MQTT_HOST, MQTT_PORT);

  while (!mqtt.connected()) {
    if (mqtt.connect("esp32c3-reed", MQTT_USER, MQTT_PASS)) {
      Serial.println("MQTT connected");
      break;
    }
    delay(1000);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(REED_PIN, INPUT_PULLUP);

  connectWiFi();
  connectMQTT();
}

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

  int state = digitalRead(REED_PIN);

  if (state != lastState) {
    lastState = state;

    long ts = millis() / 1000;

    String payload = "{";
    payload += "\"ts\":" + String(ts) + ",";
    payload += "\"metrics\":{\"door\":" + String(state == HIGH ? 1 : 0) + "},";
    payload += "\"status\":{\"door\":\"";
    payload += (state == HIGH ? "open" : "closed");
    payload += "\"}}";

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

  delay(100);
}

6) Lỗi thường gặp & kinh nghiệm

  • Cửa rung nhẹ → spam sự kiện
    • Gắn reed chắc hơn
    • Hoặc thêm delay 300–500ms xác nhận lại
  • Đọc ngược trạng thái
    • Kiểm tra lại logic INPUT_PULLUP
  • Dây dài bị nhiễu
    • Dùng dây xoắn / rút ngắn dây

7) Ứng dụng thực tế

  • Báo mở cửa trái phép
  • Kết hợp PIR để xác nhận có người
  • Ghi log thời gian mở/đóng cửa
  • Dùng pin + deep sleep (bài nâng cao sau)

Bài tiếp theo (Level 1)

👉 Bài 4: Hướng dẫn đọc cảm biến SW-420 bằng ESP32: phát hiện rung/va chạm & theo dõi realtime.