Tưới cây tự động với ESP32: cảm biến độ ẩm đất, relay và bơm mini, ngưỡng có trễ

Làm hệ thống tưới cây tự động với ESP32: cảm biến độ ẩm đất điện dung, hiệu chỉnh khô ướt, relay điều khiển bơm mini, ngưỡng có trễ, giới hạn thời gian bơm và thí nghiệm STEM.

Hệ thống tưới cây tự động là đề tài STEM gần gũi với học sinh Việt Nam: chậu rau trên ban công, vườn trường, mô hình nông nghiệp thông minh trong các cuộc thi khoa học kỹ thuật. ESP32 đọc cảm biến độ ẩm đất; khi đất khô thì bật relay cho bơm mini tưới, đủ ẩm thì tắt.

Bài viết hướng dẫn chọn cảm biến, hiệu chỉnh mức khô và ướt, nối dây qua relay, chương trình có ngưỡng trễ, giới hạn thời gian bơm, thời gian chờ nước thấm, và gợi ý thí nghiệm STEM.

1. Cảm biến độ ẩm đất kiểu điện dung

  • Cảm biến loại điện dung (thường ghi "Capacitive Soil Moisture Sensor v1.2") đo theo điện dung của đất quanh hai bản cực đã được phủ kín. Đất càng ẩm, điện dung càng lớn, điện áp ra ở chân AOUT càng thấp.
  • Loại hai chân kim loại trần (kiểu điện trở) rẻ hơn nhưng có dòng điện chạy trong đất nên bị ăn mòn sau vài tuần. Loại điện dung bền hơn nhiều.
  • Cấp cho cảm biến 3,3 V từ ESP32 để điện áp ra không vượt quá 3,3 V.
  • Giá trị đọc được phụ thuộc loại đất, độ nén và từng cảm biến, nên phải hiệu chỉnh: đo một lần khi đất khô, một lần khi nhúng vào nước.
Hình minh họa đổi giá trị ADC của cảm biến độ ẩm đất ra phần trăm: 2800 khi khô là 0 phần trăm, 1300 khi ướt là 100 phần trăm, ví dụ 2300 là 33 phần trăm; thang ngưỡng bật bơm dưới 35 phần trăm, tắt ở 60 phần trăm
Hình minh họa: đổi giá trị ADC ra phần trăm và ngưỡng bật, tắt bơm.

2. Linh kiện cần chuẩn bị

3. Sơ đồ nối dây

Sơ đồ khối hệ thống tưới cây: cảm biến độ ẩm đất AOUT vào D34, cấp 3V3; relay IN vào D26, cấp 5 V; nguồn 5 V qua tiếp điểm COM NO của relay tới bơm mini; GND chung
Hình minh họa: sơ đồ khối và bảng nối dây.
  • Bơm chạy bằng nguồn 5 V qua tiếp điểm COM–NO của relay. ESP32 chỉ điều khiển cuộn relay, không cấp dòng cho bơm.
  • Module relay có loại kích mức thấp và loại kích mức cao. Đặt hằng số RELAY_ACTIVE_LOW cho đúng, như trong bài ESP32 điều khiển relay.
  • Bơm là tải cảm. Hàn thêm một diode 1N4007 song song ngược với bơm (vạch của diode về phía cực +) để giảm xung điện áp khi ngắt.
  • Đặt mạch điện cao hơn chậu và bể nước, che kín khỏi nước. Phần cảm biến trên vạch giới hạn và mạch điện của cảm biến không được ngập nước.

4. Chương trình

/*
  PYWORLD.VN - Tưới cây tự động: cảm biến độ ẩm đất điện dung + relay + bơm mini (ESP32)
  Cảm biến: AOUT -> GPIO34, VCC -> 3V3, GND. Relay 1 kênh: IN -> GPIO26, VCC 5 V, GND. Bơm 5 V qua tiếp điểm COM-NO
  Lệnh (115200, New Line): kho = lưu mức khô (cắm cảm biến vào đất khô), uot = lưu mức ướt (nhúng vào nước), n = tưới ngay
*/

#include <Preferences.h>

#define CAM_BIEN_PIN 34
#define RELAY_PIN    26

// true: module kích mức thấp (IN = LOW thì relay đóng); false: module kích mức cao
const bool RELAY_ACTIVE_LOW = true;

const int NGUONG_BAT = 35;            // % độ ẩm: thấp hơn thì bắt đầu tưới
const int NGUONG_TAT = 60;            // % độ ẩm: đạt mức này thì ngừng tưới
const unsigned long BOM_TOI_DA_MS = 10000;   // mỗi lần tưới không quá 10 giây
const unsigned long CHO_THAM_MS = 60000;     // sau mỗi lần tưới chờ 60 giây cho nước thấm

int kho = 2800, uot = 1300;           // giá trị ADC khi khô và khi ướt, sửa bằng lệnh kho, uot
bool dangBom = false;
unsigned long tBatBom = 0, tTatBom = 0;
Preferences boNho;

void bom(bool bat) {
  bool muc = RELAY_ACTIVE_LOW ? !bat : bat;
  digitalWrite(RELAY_PIN, muc ? HIGH : LOW);
  if (bat && !dangBom) tBatBom = millis();
  if (!bat && dangBom) tTatBom = millis();
  dangBom = bat;
}

int docTho() {
  long tong = 0;
  for (int i = 0; i < 16; i++) { tong += analogRead(CAM_BIEN_PIN); delay(2); }
  return tong / 16;
}

// Cảm biến điện dung: đất càng khô, giá trị ADC càng lớn
int doAm(int raw) {
  if (kho == uot) return 0;
  return constrain((long)(kho - raw) * 100 / (kho - uot), 0, 100);
}

void xuLyLenh() {
  String s = Serial.readStringUntil('\n');
  s.trim();
  s.toLowerCase();
  if (s == "kho") { kho = docTho(); boNho.putInt("kho", kho); Serial.printf("Da luu muc kho = %d\n", kho); }
  else if (s == "uot") { uot = docTho(); boNho.putInt("uot", uot); Serial.printf("Da luu muc uot = %d\n", uot); }
  else if (s == "n") { bom(true); Serial.println("Tuoi ngay"); }
}

void setup() {
  Serial.begin(115200);
  pinMode(RELAY_PIN, OUTPUT);
  bom(false);
  tTatBom = millis() - CHO_THAM_MS;               // cho phép tưới ngay khi vừa bật nguồn
  boNho.begin("tuoicay", false);
  kho = boNho.getInt("kho", kho);
  uot = boNho.getInt("uot", uot);
  Serial.printf("Muc kho %d, muc uot %d. Lenh: kho, uot, n\n", kho, uot);
}

void loop() {
  if (Serial.available()) xuLyLenh();

  static unsigned long tDoTruoc = 0;
  if (millis() - tDoTruoc < 2000 && !dangBom) return;   // khi đang bơm thì đo liên tục
  tDoTruoc = millis();

  int raw = docTho();
  int pt = doAm(raw);

  if (dangBom) {
    if (pt >= NGUONG_TAT || millis() - tBatBom >= BOM_TOI_DA_MS) {
      bom(false);
      Serial.printf("Do am %d %% -> tat bom, cho %lu giay cho nuoc tham\n", pt, CHO_THAM_MS / 1000);
    }
  } else if (pt < NGUONG_BAT && millis() - tTatBom >= CHO_THAM_MS) {
    bom(true);
    Serial.printf("Do am %d %% (raw %d) -> bat bom\n", pt, raw);
  } else {
    Serial.printf("Do am %d %% (raw %d)\n", pt, raw);
  }
}

Hiệu chỉnh lần đầu (Serial Monitor, 115200 baud, kiểu xuống dòng "New Line"):

  1. Cắm cảm biến vào đất đã khô, gõ kho.
  2. Nhúng phần cảm biến (dưới vạch giới hạn) vào cốc nước, gõ uot.
  3. Cắm lại cảm biến vào chậu. Hai giá trị được lưu vào flash, lần sau bật nguồn không phải làm lại.

Gõ n để bơm thử ngay một lần.

5. Giải thích cách điều khiển

Hình mô phỏng độ ẩm đất theo thời gian: độ ẩm giảm dần, xuống dưới 35 phần trăm thì bơm chạy 10 giây làm độ ẩm tăng lên, sau đó chờ nước thấm và lặp lại
Hình mô phỏng đơn giản: diễn biến độ ẩm và các lần bơm.
  • Ngưỡng có khoảng trễ: dưới 35 % thì bật bơm, đạt 60 % mới tắt. Nếu bật và tắt cùng một ngưỡng, bơm sẽ bật tắt liên tục khi độ ẩm dao động quanh ngưỡng đó.
  • Giới hạn 10 giây mỗi lần bơm: nếu cảm biến tuột khỏi chậu hay hỏng, bơm cũng không chạy mãi làm ngập chậu.
  • Chờ 60 giây: nước cần thời gian thấm xuống tới chỗ cảm biến. Không chờ thì chương trình tưới tiếp khi đất ở dưới còn chưa kịp ẩm.
  • Đọc 16 lần lấy trung bình để số đo ổn định. Mỗi 2 giây đo một lần; khi đang bơm thì đo liên tục để tắt đúng lúc.

6. Gợi ý dùng trong giờ học STEM

Mục tiêu: học sinh biết dùng cảm biến để ra quyết định, hiểu vì sao cần hiệu chỉnh và khoảng trễ, và gắn kiến thức điện tử với sinh học, nông nghiệp.

  1. Hiệu chỉnh nhiều loại đất. Đo giá trị khô và ướt với đất thịt, đất cát, đất trộn xơ dừa. Lập bảng và nhận xét: vì sao mỗi loại đất cần hiệu chỉnh riêng?
  2. Đo tốc độ khô của đất. Ghi độ ẩm mỗi 30 phút trong một ngày, ở trong nhà và ngoài nắng. Vẽ đồ thị, tìm thời điểm đất khô nhanh nhất.
  3. Chọn ngưỡng theo loại cây. Tìm hiểu cây xương rồng, rau muống, cây cảnh cần đất ẩm bao nhiêu, rồi chỉnh NGUONG_BAT, NGUONG_TAT cho phù hợp.
  4. Tiết kiệm nước. Đo lượng nước bơm ra mỗi giây (hứng vào cốc có vạch chia), tính lượng nước dùng mỗi ngày. So sánh với tưới bằng tay.
  5. Mở rộng IoT. Gửi độ ẩm lên điện thoại qua Wi-Fi hoặc MQTT, như các bài web server và MQTT với ESP32 trên pyworld.vn.

7. Xử lý lỗi thường gặp

Lỗi thường gặp
Hiện tượngNguyên nhân thường gặpCách xử lý
Độ ẩm luôn 0 % hoặc 100 %Chưa hiệu chỉnh; nhầm thứ tự khô, ướtGõ lại kho khi đất khô, uot khi nhúng nước
Relay kêu nhưng bơm không chạyDây bơm nối COM–NC thay vì COM–NO; nguồn bơm yếuChuyển sang NO; kiểm tra nguồn 5 V
Vừa bật nguồn bơm đã chạy, lệnh ngượcSai loại relay kích mức cao hay thấpĐổi RELAY_ACTIVE_LOW
ESP32 khởi động lại khi bơm chạyBơm và ESP32 dùng chung nguồn yếu, nhiễuNguồn từ 1 A; diode song song với bơm; tụ 470 µF ở nguồn 5 V
Số đo nhảy nhiềuDây cảm biến dài, gần dây bơm; đất chưa nénDây ngắn, tách xa dây bơm; cắm cảm biến chặt vào đất

8. Xem thêm


Tin tức liên quan

Hướng dẫn dùng mạch tạo trễ NE555 có relay: đấu dây và chỉnh thời gian trễ
Hướng dẫn dùng mạch tạo trễ NE555 có relay: đấu dây và chỉnh thời gian trễ

Hướng dẫn dùng mạch tạo trễ NE555 có relay bản 5 V và 12 V: nguyên lý tạo trễ, ý nghĩa các cọc VCC, GND, COM, CK, CB, cách chỉnh thời gian trễ, sơ đồ đấu dây và xử lý lỗi thường gặp.

Hướng dẫn dùng Deep Sleep trên ESP32: tiết kiệm pin, đánh thức bằng timer và nút nhấn
Hướng dẫn dùng Deep Sleep trên ESP32: tiết kiệm pin, đánh thức bằng timer và nút nhấn

Hướng dẫn đưa ESP32 vào Deep Sleep trên Arduino IDE để tiết kiệm pin: các chế độ nguồn, đánh thức bằng timer và nút nhấn, giữ biến trong bộ nhớ RTC và ước tính thời lượng pin.

Hướng dẫn dùng PWM trên ESP32: điều chỉnh độ sáng LED bằng analogWrite và LEDC
Hướng dẫn dùng PWM trên ESP32: điều chỉnh độ sáng LED bằng analogWrite và LEDC

Hướng dẫn tạo PWM trên ESP32 bằng Arduino IDE: analogWrite, ledcAttach và ledcWrite của gói esp32 3.x, chỉnh độ sáng LED bằng biến trở, chọn tần số và độ phân giải.

Xe robot ESP32 điều khiển bằng điện thoại qua Wi-Fi: không cần router, không cần cài ứng dụng
Xe robot ESP32 điều khiển bằng điện thoại qua Wi-Fi: không cần router, không cần cài ứng dụng

Làm xe robot hai bánh với ESP32 và L298N, điều khiển bằng trình duyệt điện thoại qua Wi-Fi do ESP32 phát ra: bố trí, nối dây, code web, tự dừng khi mất sóng, lái vi sai, STEM.

Xe tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 trên servo quét, tự chọn đường
Xe tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 trên servo quét, tự chọn đường

Làm xe robot tự tránh vật cản với ESP32: cảm biến siêu âm HC-SR04 gắn trên servo quét trái phải, cầu phân áp cho chân ECHO, thuật toán chọn đường, lưu đồ và thí nghiệm STEM.

ESP32 điều khiển động cơ DC với driver L298N: đảo chiều, chỉnh tốc độ bằng PWM
ESP32 điều khiển động cơ DC với driver L298N: đảo chiều, chỉnh tốc độ bằng PWM

Hướng dẫn nối ESP32 với driver L298N và động cơ DC giảm tốc: cầu H, đảo chiều, phanh, chỉnh tốc độ bằng PWM, điều khiển bằng lệnh trên Serial Monitor và thí nghiệm STEM.

ESP32 điều khiển động cơ bước NEMA 17 với A4988: vi bước, chỉnh dòng VREF, tăng tốc mượt
ESP32 điều khiển động cơ bước NEMA 17 với A4988: vi bước, chỉnh dòng VREF, tăng tốc mượt

Hướng dẫn điều khiển động cơ bước NEMA 17 bằng ESP32 qua driver A4988: nối dây, chỉnh dòng VREF, chọn vi bước 1/16, tăng tốc giảm tốc hình thang và thí nghiệm STEM.

Mạch hạ áp LM2596 và MP1584: cách chọn, chỉnh điện áp và cấp nguồn ESP32
Mạch hạ áp LM2596 và MP1584: cách chọn, chỉnh điện áp và cấp nguồn ESP32

So sánh mạch hạ áp LM2596 và MP1584, cách chỉnh điện áp ra bằng đồng hồ vạn năng trước khi nối tải, cấp nguồn 5 V cho ESP32 DevKit V1 từ nguồn 12 V và xử lý lỗi thường gặp.


Bình luận
Đã thêm vào giỏ hàng