Rain Sensor FC-37 (còn gọi là YL-83) là sensor phát hiện mưa bằng cách đo điện trở giữa các răng điện cực đồng song song trên tấm PCB. Khi có nước mưa → tạo cầu dẫn điện → điện trở giảm → MCU phát hiện. Bài này phân tích nguyên lý hoạt động, so sánh ngõ ra analog/digital, và hướng dẫn sử dụng đúng cách để tránh ăn mòn điện cực.
Nguyên Lý Hoạt Động
1. Tấm Cảm Biến — Cầu Điện Trở Nước Mưa
Tấm cảm biến (sensing pad) của FC-37 là một miếng PCB FR4 với các răng điện cực đồng song song, xen kẽ nhau:
Tấm cảm biến mưa (nhìn từ trên):
+───────┬───────┬───────┬───────+
│ (+) │ (-) │ (+) │ (-) │ ← Răng điện cực xen kẽ
│ ↕ 2mm │ ↕ 2mm │ ↕ 2mm │ ↕ 2mm │ khoảng cách nhỏ giữa các răng
+───────┴───────┴───────┴───────+
Bề mặt PCB trống (FR4, cách điện)
Khi không có mưa: khoảng cách giữa răng là không khí → cách điện → R = ∞
Khi có mưa: giọt nước bắc cầu qua khoảng cách → R giảm xuống kΩ
Độ dẫn điện của nước mưa:
- Nước mưa không phải nước cất — chứa CO₂ hòa tan (tạo axit cacbonic H₂CO₃), các khoáng nhỏ từ không khí
- Điện trở nước mưa thực tế: khoảng 10kΩ – 100kΩ tùy mật độ mưa và ô nhiễm không khí
- Mưa lớn (nhiều giọt) → nhiều cầu song song → điện trở tổng thấp hơn → dễ phát hiện hơn
2. Mạch Module — LM393 Comparator
Module FC-37 gồm 2 phần tách rời:
- Tấm cảm biến (sensing pad, thường 54mm × 40mm): cắm ra ngoài trời
- Board xử lý (control board): ở trong nhà/hộp, kết nối với MCU
Mạch trong board xử lý:
VCC
│
R (10kΩ, cố định)
│
├──── Chân AOUT (điện áp tỷ lệ với độ ẩm tấm)
│
R_sensor (thay đổi theo lượng nước trên tấm)
│
GND
Đồng thời:
AOUT ──→ LM393 (+IN)
LM393 (-IN) ──→ Triết áp (điều chỉnh ngưỡng)
LM393 OUT ──→ DOUT
AOUT (Analog Output):
- Khô: R_sensor = ∞ → AOUT ≈ VCC → ADC đọc cao (Arduino ~1023, ESP32 ~4095)
- Ướt: R_sensor giảm → AOUT giảm → ADC đọc thấp
DOUT (Digital Output) qua LM393:
- Khô: AOUT > ngưỡng (triết áp) → DOUT = HIGH (không mưa)
- Ướt: AOUT < ngưỡng → DOUT = LOW (có mưa, đèn LED trên module sáng)
LED indicator trên module: Sáng khi DOUT = LOW (phát hiện mưa). Hữu ích để debug nhanh mà không cần Serial Monitor.
3. Ăn Mòn Điện Cực — Cùng Vấn Đề Với Soil Moisture
Rain Sensor dùng cùng nguyên lý điện trở với Soil Moisture → cùng vấn đề điện phân. Dòng DC chạy qua nước → điện phân → ăn mòn điện cực đồng.
Biểu hiện:
- Điện cực đổi màu (xanh lục/đen): muối đồng tích tụ
- Tấm PCB có váng/mảng trắng: khoáng tủa
- Đọc sai ngay cả khi mưa lớn: bề mặt bị phủ lớp cách điện
Giải pháp thực tế:
- Cấp nguồn xung: GPIO cấp VCC cho module, chỉ bật khi cần kiểm tra
- Vệ sinh định kỳ: Dùng khăn mềm và isopropyl alcohol lau tấm cảm biến
- Không dùng module làm moisture meter liên tục — rain sensor chỉ phù hợp phát hiện mưa ngắt quãng, không đo liên tục như soil moisture
Thông Số Kỹ Thuật
| Thông số | Giá trị |
|---|---|
| Điện áp hoạt động | 3.3V – 5V |
| Dòng tiêu thụ | ~15–30mA |
| Kích thước tấm cảm biến | 54mm × 40mm (thông dụng) |
| Khoảng cách điện cực | 1–2mm |
| Ngõ ra analog | 0V – VCC (đảo: cao = khô, thấp = ướt) |
| Ngõ ra digital | 0V / VCC (điều chỉnh bằng triết áp) |
| Comparator | LM393 |
| Nhiệt độ hoạt động | 0°C – 50°C (tấm cảm biến) |
Lưu ý nhiệt độ: Dưới 0°C nước đóng băng → điện trở tăng rất cao → sensor báo “không mưa” dù tuyết hoặc băng. Rain sensor này không phân biệt được tuyết.
Sơ Đồ Chân (Pinout)
Board Xử Lý FC-37 (Control Module — 4 chân)
┌──────────────────────────┐
│ [LED] [Triết áp] │
│ ┌──────────────────┐ │
│ │ LM393 Comparator│ │
│ └──────────────────┘ │
│ │
│ [Kết nối tấm cảm biến] │
└──────────────────────────┘
VCC GND DOUT AOUT
| Chân | Tên | Chức năng |
|---|---|---|
| VCC | VCC | Nguồn 3.3V hoặc 5V |
| GND | GND | Đất |
| DOUT | D0 | Digital: LOW = có mưa, HIGH = khô |
| AOUT | A0 | Analog: điện áp thấp = nhiều nước, cao = khô |
Tấm Cảm Biến (Sensing Pad — 2 chân)
Chỉ có 2 chân (+) và (-). Nối với board xử lý qua 2 dây đi kèm. Không phân cực — 2 chân đối xứng.
Phân Biệt FC-37 Và Các Biến Thể
| Model | Kích thước tấm | Ghi chú |
|---|---|---|
| FC-37 | 54mm × 40mm | Phổ biến nhất, tấm nhỏ |
| YL-83 | 54mm × 40mm | Về cơ bản giống FC-37 |
| YL-38 | Tấm lớn hơn | Module khác, nguyên lý như nhau |
| Không tên | Nhiều size | Cùng nguyên lý — chỉ khác kích thước tấm |
Tất cả đều dùng cùng nguyên lý và cùng cách kết nối. Sự khác biệt chủ yếu là kích thước tấm cảm biến (lớn hơn = phát hiện mưa nhỏ hơn).
Kết Nối Phần Cứng
Kết Nối với ESP32 DevKit V1
ESP32 DevKit V1 Rain Sensor Module
───────────────────── ─────────────────────
GPIO26 (Output) ────────→ VCC ← Cấp nguồn xung qua GPIO
GND ───────────────────→ GND
GPIO34 (ADC1_CH6) ──────→ AOUT ← Đọc analog (chỉ input, GPIO34 không có OUTPUT)
GPIO25 (Input) ─────────→ DOUT ← Đọc digital
Tại sao GPIO34 cho AOUT: GPIO34 là input-only, chỉ ADC1 → không bị ảnh hưởng WiFi. Phù hợp để đọc analog. GPIO34, 35, 36, 39 là input-only trên ESP32.
GPIO26 cấp nguồn: Cùng kỹ thuật như soil moisture — bật để đo, tắt để tiết kiệm và giảm ăn mòn.
Kết Nối với Arduino Uno
Arduino Uno Rain Sensor Module
───────────────────── ─────────────────────
Pin 8 (Output) ─────────→ VCC ← Cấp nguồn xung
GND ───────────────────→ GND
A0 (Analog Input) ──────→ AOUT
Pin 7 (Input) ──────────→ DOUT
Code Arduino IDE
Code Phát Hiện Mưa — Arduino Uno
/*
* Rain Sensor FC-37/YL-83 — Phát hiện mưa analog + digital
* Board: Arduino Uno
* Kết nối: VCC→Pin8, GND→GND, AOUT→A0, DOUT→Pin7
*/
const int POWER_PIN = 8; // Cấp nguồn sensor qua GPIO
const int ANALOG_PIN = A0; // Đọc analog từ AOUT
const int DIGITAL_PIN = 7; // Đọc digital từ DOUT
// Ngưỡng phân loại độ mưa từ giá trị ADC analog (Arduino Uno, 10-bit)
// Cần hiệu chỉnh cho từng sensor — đây là ước tính ban đầu
const int THRESHOLD_DRY = 900; // ADC > 900: không có nước (khô)
const int THRESHOLD_LIGHT = 600; // ADC 600-900: mưa nhẹ
const int THRESHOLD_MEDIUM = 300; // ADC 300-600: mưa vừa
// ADC < 300: mưa nặng
void setup() {
Serial.begin(9600);
pinMode(POWER_PIN, OUTPUT);
pinMode(DIGITAL_PIN, INPUT);
digitalWrite(POWER_PIN, LOW); // Tắt nguồn ban đầu
Serial.println("=== Rain Sensor FC-37 - Arduino Uno ===");
}
// Phân loại mức độ mưa từ giá trị ADC
String getRainLevel(int analogValue) {
if (analogValue > THRESHOLD_DRY) return "Khô — Không mưa";
if (analogValue > THRESHOLD_LIGHT) return "Mưa nhỏ / Sương";
if (analogValue > THRESHOLD_MEDIUM) return "Mưa vừa";
return "Mưa lớn";
}
void loop() {
// Bật nguồn sensor trước khi đọc
digitalWrite(POWER_PIN, HIGH);
delay(100); // Chờ ổn định
// Đọc analog (5 lần lấy trung bình)
int total = 0;
for (int i = 0; i < 5; i++) {
total += analogRead(ANALOG_PIN);
delay(10);
}
int analogValue = total / 5;
// Đọc digital (từ LM393 comparator)
int digitalValue = digitalRead(DIGITAL_PIN);
// Tắt nguồn sau khi đọc xong
digitalWrite(POWER_PIN, LOW);
// Hiển thị kết quả
Serial.print("Analog raw: ");
Serial.print(analogValue);
Serial.print(" | Mức độ: ");
Serial.print(getRainLevel(analogValue));
Serial.print(" | Digital: ");
// DOUT LOW = phát hiện mưa (logic đảo!)
Serial.println(digitalValue == LOW ? "CÓ MƯA" : "KHÔNG MƯA");
delay(3000); // Kiểm tra mỗi 3 giây
}
Code Phát Hiện Mưa + Cảnh Báo — ESP32
/*
* Rain Sensor FC-37/YL-83 — Phát hiện mưa và cảnh báo qua Serial
* Board: ESP32 DevKit V1
* Kết nối:
* GPIO26 → VCC (cấp nguồn xung)
* GPIO34 → AOUT (analog, input-only pin)
* GPIO25 → DOUT (digital)
*
* ESP32 ADC 12-bit: 0-4095 (khác Arduino Uno 0-1023)
* Ngưỡng cần hiệu chỉnh thực tế cho sensor cụ thể
*/
const int POWER_PIN = 26; // Cấp nguồn qua GPIO
const int ANALOG_PIN = 34; // ADC1_CH6 — input-only, ổn với WiFi
const int DIGITAL_PIN = 25; // DOUT từ LM393
// Ngưỡng ADC 12-bit (0-4095) — ước tính ban đầu, cần calibrate thực tế
const int THRESHOLD_DRY = 3500; // ADC > 3500: khô
const int THRESHOLD_LIGHT = 2500; // ADC 2500-3500: ẩm / mưa nhỏ
const int THRESHOLD_MEDIUM = 1500; // ADC 1500-2500: mưa vừa
// ADC < 1500: mưa lớn
// Trạng thái mưa để phát hiện thay đổi (chỉ in khi thay đổi)
bool lastRainState = false;
unsigned long lastCheckTime = 0;
const unsigned long CHECK_INTERVAL = 3000; // Kiểm tra mỗi 3 giây
void setup() {
Serial.begin(115200);
pinMode(POWER_PIN, OUTPUT);
pinMode(DIGITAL_PIN, INPUT);
digitalWrite(POWER_PIN, LOW);
// Cấu hình ADC ESP32
analogSetAttenuation(ADC_11db); // Dải đọc 0-3.3V
analogReadResolution(12); // 12-bit: 0-4095
Serial.println("=== Rain Sensor FC-37 - ESP32 ===");
}
String getRainLevel(int raw) {
if (raw > THRESHOLD_DRY) return "Khô";
if (raw > THRESHOLD_LIGHT) return "Mưa nhỏ/Sương";
if (raw > THRESHOLD_MEDIUM) return "Mưa vừa";
return "Mưa lớn";
}
int readAnalogAvg() {
int total = 0;
for (int i = 0; i < 10; i++) {
total += analogRead(ANALOG_PIN);
delay(5);
}
return total / 10;
}
void loop() {
unsigned long now = millis();
if (now - lastCheckTime >= CHECK_INTERVAL) {
lastCheckTime = now;
// Bật sensor
digitalWrite(POWER_PIN, HIGH);
delay(200); // Ổn định ADC (ESP32 cần lâu hơn Arduino)
int analogValue = readAnalogAvg();
int digitalValue = digitalRead(DIGITAL_PIN);
// Tắt sensor ngay
digitalWrite(POWER_PIN, LOW);
bool isRaining = (digitalValue == LOW); // DOUT LOW = có mưa
// In kết quả chi tiết mỗi lần đo
Serial.printf("ADC: %4d | Mức: %-15s | Digital: %s\n",
analogValue,
getRainLevel(analogValue).c_str(),
isRaining ? "CÓ MƯA ☔" : "Không mưa"
);
// Phát hiện thay đổi trạng thái — in thông báo đặc biệt
if (isRaining != lastRainState) {
if (isRaining) {
Serial.println(">>> BẮT ĐẦU MƯA! <<<");
// Thêm: gửi MQTT, bật còi cảnh báo, đóng cửa mái nhà...
} else {
Serial.println(">>> MƯA ĐÃ TẠNHh <<<");
// Thêm: gửi MQTT, tắt còi...
}
lastRainState = isRaining;
}
}
// Loop không block — có thể thêm logic khác ở đây
}
Kết Quả Mong Đợi
=== Rain Sensor FC-37 - ESP32 ===
ADC: 3890 | Mức: Khô | Digital: Không mưa
ADC: 3870 | Mức: Khô | Digital: Không mưa
ADC: 2340 | Mức: Mưa nhỏ/Sương | Digital: CÓ MƯA ☔
>>> BẮT ĐẦU MƯA! <<<
ADC: 1150 | Mức: Mưa lớn | Digital: CÓ MƯA ☔
ADC: 3200 | Mức: Khô | Digital: Không mưa
>>> MƯA ĐÃ TẠNH <<<
Ứng Dụng Thực Tế
| Ứng dụng | Chi tiết |
|---|---|
| Tự động đóng cửa sổ / mái che | DOUT = LOW → đóng servo/motor |
| Tắt hệ thống tưới cây tự động | Phát hiện mưa → dừng máy bơm |
| Cảnh báo mưa qua điện thoại | ESP32 WiFi → push notification |
| Trạm thời tiết | Kết hợp BMP280 (áp suất) + DHT22 (độ ẩm) + rain sensor |
| Bãi đỗ xe thông minh | Cảnh báo thu dọn đồ khi mưa |
| Logger mưa | Ghi timestamp khi bắt đầu và kết thúc mưa |
Lưu Ý Khi Sử Dụng
1. Logic DOUT đảo ngược — dễ nhầm
DOUT LOW = có mưa (phát hiện nước), DOUT HIGH = không mưa. Đây là logic âm, ngược với cảm giác thông thường. LED trên module sáng khi DOUT LOW (có mưa) — dùng LED để kiểm tra logic trước khi viết code.
2. Điều chỉnh ngưỡng bằng triết áp
Vặn triết áp trên module để chọn ngưỡng “đủ ướt” cho DOUT chuyển LOW. Vặn theo chiều kim đồng hồ = tăng ngưỡng (cần nhiều nước hơn mới báo), ngược chiều = giảm ngưỡng (ít nước cũng báo). Dùng AOUT + Serial Monitor để hiệu chỉnh trực quan.
3. Cấp nguồn xung để giảm ăn mòn
Tấm cảm biến bị ăn mòn theo thời gian nếu cấp điện liên tục. Với rain sensor, thường chỉ cần check mỗi vài giây một lần — cấp nguồn qua GPIO, bật khi check, tắt ngay sau.
4. Bảo vệ chống bụi và côn trùng
Tấm cảm biến đặt ngoài trời: bụi khô tích tụ → không dẫn điện → báo “khô” sai. Bọ/kiến đôi khi bò qua → báo “ướt” sai. Đặt tấm nghiêng ~45° để nước mưa chảy đi và bụi ít tích tụ hơn.
5. Phân biệt sương và mưa
Sensor có thể phát hiện cả sương mù dày (hơi nước tụ thành giọt trên tấm). Nếu ứng dụng cần phân biệt sương và mưa thật: dùng ngưỡng analog cao hơn cho “mưa”, hoặc thêm logic thời gian (mưa thật kéo dài liên tục > 30 giây).
6. GPIO34 là Input-Only trên ESP32
GPIO34, 35, 36, 39 của ESP32 chỉ là input — không thể dùng pinMode(34, OUTPUT). Phù hợp để đọc AOUT (analog). Không nhầm cắm nguồn vào GPIO34.


