Ở bài này, chúng ta dùng Tilt Switch (cảm biến nghiêng/đổ) để phát hiện thiết bị bị nghiêng hoặc lật. Đây là cảm biến rất đơn giản, giá rẻ, phù hợp cho các ứng dụng:
- Phát hiện đổ/nghiêng thiết bị
- Cảnh báo xê dịch, rung lắc mạnh
- Kết hợp với PIR/Reed/SW-420 để tăng độ tin cậy
Bài viết gồm 2 ví dụ code:
- Đọc trạng thái nghiêng local (Serial)
- Gửi trạng thái nghiêng lên IoTLabs Cloud MQTT để theo dõi realtime
1) Tilt Switch là gì?
- Tilt Switch là công tắc cơ học đóng/mở khi bị nghiêng
- Bên trong thường là bi kim loại hoặc viên bi dẫn điện
- Không đo góc chính xác → chỉ báo trạng thái
Nguyên lý
- Thẳng/đặt đúng → mạch mở (hoặc đóng tuỳ loại)
- Nghiêng/đổ → mạch đóng (hoặc mở)
📌 Lưu ý: có nhiều loại Tilt Switch logic ngược nhau → cần test thực tế.
2) Chuẩn bị
Phần cứng
- ESP32-C3 SuperMini (Tenstar Robot)
- Tilt Switch (KY-020, SW-200D, hoặc tương tự)
- Dây nối
Chân sử dụng
- TILT_PIN → GPIO0
- GND → GND
✅ Không cần cấp 5V/3.3V cho Tilt Switch (chỉ là công tắc)
3) Nối dây Tilt Switch với ESP32
Cách ổn định nhất là dùng pull-up nội bộ.
Tilt Switch ESP32-C3 SuperMini
-----------------------------------
1 chân ------------ GPIO0
1 chân ------------ GND
Trong code:
pinMode(GPIO0, INPUT_PULLUP);
Logic đọc (phổ biến)
| Trạng thái | GPIO đọc |
|---|---|
| Bình thường | HIGH |
| Nghiêng/đổ | LOW |
(Nếu bạn thấy ngược → chỉ cần đảo logic trong code)
4) Đặc điểm tín hiệu cần lưu ý
- Tilt Switch có thể bật/tắt liên tục khi rung nhẹ
- Cần:
- Phát hiện thay đổi trạng thái
- Có debounce/cooldown đơn giản
Ví dụ 1 — Code local đơn giản (phát hiện nghiêng)
Mục tiêu: in trạng thái Bình thường / Nghiêng ra Serial.
// ===== Tilt Switch Local Read =====
const int TILT_PIN = 0;
int lastState = HIGH;
void setup() {
Serial.begin(115200);
delay(200);
pinMode(TILT_PIN, INPUT_PULLUP);
Serial.println("Tilt switch monitor started...");
}
void loop() {
int state = digitalRead(TILT_PIN);
if (state != lastState) {
if (state == LOW) {
Serial.println("⚠️ Thiết bị BỊ NGHIÊNG / ĐỔ!");
} else {
Serial.println("🟢 Thiết bị trở lại BÌNH THƯỜNG");
}
lastState = state;
}
delay(50);
}
5) Chuẩn dữ liệu realtime cho IoTLabs Cloud
Topic
iotlabs/<orgId>/devices/<deviceId>/telemetry
Payload JSON
{
"ts": 1760000000,
"metrics": {
"tilt": 1
},
"status": {
"tilt": "tilted"
}
}
| tilt | Ý nghĩa |
|---|---|
| 0 | bình thường |
| 1 | nghiêng / đổ |
Ví dụ 2 — Gửi trạng thái nghiêng lên IoTLabs Cloud MQTT
Chiến lược:
- Chỉ gửi khi trạng thái thay đổi
- Có cooldown để tránh spam
#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";
// ===== TILT =====
const int TILT_PIN = 0;
int lastState = HIGH;
unsigned long lastEventMs = 0;
const unsigned long COOLDOWN_MS = 1000;
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-tilt", MQTT_USER, MQTT_PASS)) {
Serial.println("MQTT connected");
break;
}
delay(1000);
}
}
void setup() {
Serial.begin(115200);
pinMode(TILT_PIN, INPUT_PULLUP);
connectWiFi();
connectMQTT();
}
void loop() {
if (!mqtt.connected()) connectMQTT();
mqtt.loop();
int state = digitalRead(TILT_PIN);
unsigned long now = millis();
if (state != lastState && now - lastEventMs > COOLDOWN_MS) {
lastEventMs = now;
lastState = state;
long ts = millis() / 1000;
String payload = "{";
payload += "\"ts\":" + String(ts) + ",";
payload += "\"metrics\":{\"tilt\":" + String(state == LOW ? 1 : 0) + "},";
payload += "\"status\":{\"tilt\":\"";
payload += (state == LOW ? "tilted" : "normal");
payload += "\"}}";
mqtt.publish(MQTT_TOPIC, payload.c_str());
Serial.println(payload);
}
delay(50);
}
6) Lỗi thường gặp & kinh nghiệm
- Rung nhẹ cũng trigger
- Tăng cooldown (1–2s)
- Gắn tilt chắc chắn hơn
- Logic bị ngược
- Đảo điều kiện
LOW/HIGH
- Đảo điều kiện
- GPIO0 là chân boot
- Không kéo LOW lúc boot → đảm bảo tilt không ở trạng thái nghiêng khi khởi động
7) Ứng dụng thực tế
- Cảnh báo thiết bị bị đổ/nghiêng
- Kết hợp SW-420 để xác nhận va chạm + nghiêng
- Kết hợp PIR/Reed để tăng độ tin cậy
- Thiết bị pin + deep sleep (bài nâng cao)
Bài tiếp theo (Level 1)
👉 Bài 6: Hướng dẫn đọc cảm biến Hall A3144 bằng ESP32: phát hiện từ trường/nam châm & theo dõi realtime.


