Cảm biến độ ẩm đất điện dung v1.2: khác loại điện trở, lỗi hay gặp, hiệu chuẩn bằng mẫu đất

Cảm biến độ ẩm đất điện dung v1.2: so với loại điện trở LM393, lỗi phần cứng hay gặp, vì sao hiệu chuẩn không khí và nước cho số sai, hiệu chuẩn bằng mẫu đất; code ESP32 bảng nhiều điểm.

Cảm biến độ ẩm đất điện dung (capacitive soil moisture sensor, bản v1.2 màu đen phổ biến) thay cho loại hai que kim loại vì không bị ăn mòn. Nhưng nhiều người dùng xong vẫn thắc mắc: cảm biến báo 60 % mà đất nhìn khá khô, hay số đọc không đổi khi tưới. Bài này giải thích cảm biến điện dung khác loại điện trở (module LM393) thế nào, các lỗi phần cứng hay gặp của bản v1.2, vì sao cách hiệu chuẩn "để ngoài không khí là 0 %, nhúng nước là 100 %" không cho ra lượng nước thật trong đất, và cách hiệu chuẩn bằng mẫu đất theo phương pháp cân. Có chương trình ESP32 dùng bảng hiệu chuẩn nhiều điểm lưu trong flash và script Python so sánh hai cách hiệu chuẩn.

1. Cảm biến điện dung và điện trở khác nhau thế nào

Sơ đồ khối cảm biến độ ẩm đất: loại điện dung v1.2 gồm mạch dao động 555 CMOS, tụ là hai bản mạch phủ kín với đất làm điện môi, mạch lọc RC, AOUT giảm khi đất ướt; loại điện trở gồm hai que kim loại hở, điện trở đất, LM393 so ngưỡng
Loại điện dung không có kim loại chạm đất.
  • Loại điện dung: hai dải đồng trong bo mạch, phủ kín bằng lớp sơn, tạo thành một tụ điện. Nước có hằng số điện môi khoảng 80, đất khô chỉ vài đơn vị, nên đất càng ướt điện dung càng lớn. Mạch dao động và mạch lọc trên bo đổi điện dung thành điện áp: đất ướt cho điện áp thấp, đất khô cho điện áp cao.
  • Loại điện trở: dòng điện một chiều chạy qua đất giữa hai que. Que bị điện phân, ăn mòn sau vài tuần cắm liên tục; số đọc còn phụ thuộc mạnh vào lượng phân bón (muối) trong đất. Module LM393 có thêm ngõ ra số DO theo ngưỡng chỉnh bằng biến trở.

Nguyên lý các loại cảm biến độ ẩm có ở bài cảm biến độ ẩm: điện dung, điện trở.

2. Lỗi phần cứng hay gặp của bản v1.2

Bảng lỗi hay gặp của cảm biến độ ẩm đất điện dung v1.2: chip 555 lưỡng cực không chạy ở 3,3 V, điện trở xả không nối GND làm ra chậm, mép bo hở thấm nước, cắm quá vạch giới hạn, dây dài chung nguồn bơm
Thử ngay khi mua: đo điện áp ngoài không khí và trong cốc nước.

Cảm biến v1.2 được nhiều xưởng sản xuất với linh kiện khác nhau. Bản dùng chip 555 loại CMOS chạy được ở 3,3 V; bản dùng chip 555 lưỡng cực (NE555) cần khoảng 4,5 V trở lên. Một số bản nối thiếu điện trở xả của mạch lọc, điện áp ra không giảm kịp khi khô lại. Cách thử nhanh: cấp nguồn bằng đúng điện áp sẽ dùng, đo AOUT khi để ngoài không khí (khoảng 2,5–2,8 V) và khi nhúng vào cốc nước tới vạch (khoảng 1,1–1,4 V); rút ra khỏi nước, điện áp phải tăng lại trong vài giây.

3. Vì sao hiệu chuẩn "không khí và nước" cho số sai

Cách thường thấy: ghi điện áp khi để ngoài không khí làm 0 %, khi nhúng nước làm 100 %, rồi đổi tuyến tính. Số ra là một chỉ số tương đối, không phải lượng nước trong đất, vì hai lý do: đất khô không phải không khí (đất có điện môi riêng), và quan hệ điện áp với lượng nước là đường cong, thay đổi nhanh khi đất khô và chậm dần khi đất ướt. Đại lượng nông nghiệp dùng là độ ẩm thể tích θv: phần trăm thể tích nước trong một thể tích đất. Đất vườn thường từ vài phần trăm (khô) tới 40–50 % (bão hòa), không bao giờ 100 %.

# PYWORLD.VN - Hiệu chuẩn cảm biến độ ẩm đất điện dung bằng mẫu đất: độ ẩm thể tích (θv) tính từ cân mẫu, so với điện áp cảm biến
# PYWORLD.VN - So sánh cách đổi "không khí = 0 %, nước = 100 %" với bảng hiệu chuẩn nhiều điểm (nội suy tuyến tính từng đoạn)
# PYWORLD.VN - Số liệu mẫu là giả lập theo dạng đường cong thường gặp; thay bằng số đo với đất của mình
"""θv = (khối lượng ướt − khối lượng khô) / thể tích mẫu (nước 1 g/cm³), nhân 100 ra %."""
from __future__ import annotations

V_KHONG_KHI, V_NUOC = 2650, 1180          # mV đo được khi để ngoài không khí và nhúng vào cốc nước


def mv_that(theta: float) -> float:
    """Dạng đường cong giả lập của cảm biến trong đất: điện áp giảm nhanh lúc đất khô, chậm dần khi đất ướt."""
    return 1180 + 1290 / (1 + theta / 9.0)


# Mẫu hiệu chuẩn: (khối lượng khô g, khối lượng ướt g, thể tích mẫu cm³); số đo mV lấy từ mv_that() thay cho đo thật
MAU = [(130.0, 130.0, 100), (130.0, 136.5, 100), (130.0, 143.0, 100), (130.0, 152.0, 100), (130.0, 161.0, 100),
       (130.0, 170.0, 100), (130.0, 177.0, 100)]


def theta_tu_can(kho: float, uot: float, the_tich: float) -> float:
    return (uot - kho) / the_tich * 100


def bang_hieu_chuan() -> list[tuple[float, float]]:
    """(mV, θv %) sắp theo mV tăng dần để nội suy."""
    return sorted((round(mv_that(theta_tu_can(*m))), theta_tu_can(*m)) for m in MAU)


def noi_suy(bang: list[tuple[float, float]], mv: float) -> float:
    if mv <= bang[0][0]:
        return bang[0][1]
    if mv >= bang[-1][0]:
        return bang[-1][1]
    for (x0, y0), (x1, y1) in zip(bang, bang[1:]):
        if x0 <= mv <= x1:
            return y0 + (mv - x0) / (x1 - x0) * (y1 - y0)
    return bang[-1][1]


def hai_diem(mv: float) -> float:
    return (V_KHONG_KHI - mv) / (V_KHONG_KHI - V_NUOC) * 100


def main() -> None:
    bang = bang_hieu_chuan()
    print("Bang hieu chuan (mV -> theta_v %):", ", ".join(f"{mv:.0f}->{t:.1f}" for mv, t in bang))
    print(" theta that   mV    2 diem (khong khi/nuoc)   bang nhieu diem")
    for theta in (8, 15, 25, 35, 45):
        mv = mv_that(theta)
        print(f"   {theta:5.1f} %  {mv:5.0f}   {hai_diem(mv):7.1f} %                 {noi_suy(bang, mv):6.1f} %")


if __name__ == "__main__":
    main()
Đồ thị so sánh giá trị báo ra theo độ ẩm thể tích thật: cách đổi 2 điểm không khí và nước báo trên 50 phần trăm khi đất chỉ có 8 phần trăm nước; bảng hiệu chuẩn bằng 7 mẫu đất bám sát đường báo đúng
Đường cong cảm biến giả lập theo dạng thường gặp.

Với đường cong giả lập trong script, đất có 8 % nước thì cách 2 điểm báo khoảng 54 %, bảng 7 điểm báo 8,4 %. Dùng chỉ số tương đối vẫn tưới được (chọn ngưỡng bằng cách quan sát cây), nhưng không so sánh được giữa hai loại đất, và không đối chiếu được với số liệu khuyến cáo cho cây trồng.

4. Hiệu chuẩn bằng mẫu đất

Bảng các bước hiệu chuẩn bằng mẫu đất theo phương pháp cân: sấy khô đất, cho vào cốc thể tích biết trước rồi cân, cắm cảm biến ghi mV, thêm nước trộn đều cân lại tính độ ẩm thể tích, lặp 5 đến 7 lần
Mỗi gam nước thêm vào cốc 100 cm³ là 1 % độ ẩm thể tích.

Cần một cân nhà bếp (0,1 g hoặc 1 g), một cốc nhựa có thể tích biết trước, đất lấy đúng nơi sẽ trồng. Mỗi lần thêm nước thì trộn đều, nén đất vào cốc chặt như ngoài vườn, cắm cảm biến tới vạch, đo, rồi gõ lệnh vào chương trình ở mục 5. Năm đến bảy điểm từ khô tới sũng là đủ; chương trình nội suy tuyến tính giữa các điểm.

5. Chương trình ESP32 dùng bảng hiệu chuẩn

Nối AOUT vào GPIO34, VCC vào GPIO25, GND chung với ESP32 DevKit V1. ESP32 chỉ cấp nguồn cho cảm biến lúc đo (cảm biến ăn khoảng 5 mA), đỡ tốn pin và tránh làm ấm đất quanh cảm biến.

// PYWORLD.VN - Cảm biến độ ẩm đất điện dung v1.2 với ESP32: đổi mV ra độ ẩm thể tích theo bảng hiệu chuẩn nhiều điểm (nội suy)
// PYWORLD.VN - Lệnh Serial "c 25" ghi mV hiện tại ứng với 25 % (đo bằng cân mẫu đất); "x" xóa bảng; bảng lưu trong flash
// PYWORLD.VN - AOUT -> GPIO34; VCC lấy từ GPIO25 (chỉ cấp khi đo, cảm biến ăn khoảng 5 mA), GND chung

#include <Preferences.h>

const int CHAN_AO = 34, CHAN_NGUON = 25;
const int TOI_DA_DIEM = 10;

Preferences luu;
int soDiem = 0;
float bangMv[TOI_DA_DIEM], bangPt[TOI_DA_DIEM];   // sắp theo mV tăng dần

float docMv() {
  digitalWrite(CHAN_NGUON, HIGH);
  delay(150);                                        // chờ mạch dao động và lọc trên cảm biến ổn định
  uint32_t tong = 0;
  for (int i = 0; i < 32; i++) tong += analogReadMilliVolts(CHAN_AO);
  digitalWrite(CHAN_NGUON, LOW);
  return tong / 32.0f;
}

float doiRaPhanTram(float mv) {
  if (soDiem < 2) return NAN;                        // chưa đủ hai điểm hiệu chuẩn
  if (mv <= bangMv[0]) return bangPt[0];
  if (mv >= bangMv[soDiem - 1]) return bangPt[soDiem - 1];
  for (int i = 1; i < soDiem; i++) {
    if (mv <= bangMv[i]) {
      float t = (mv - bangMv[i - 1]) / (bangMv[i] - bangMv[i - 1]);
      return bangPt[i - 1] + t * (bangPt[i] - bangPt[i - 1]);
    }
  }
  return NAN;
}

void luuBang() {
  luu.putInt("n", soDiem);
  luu.putBytes("mv", bangMv, sizeof(bangMv));
  luu.putBytes("pt", bangPt, sizeof(bangPt));
}

void themDiem(float mv, float pt) {
  if (soDiem >= TOI_DA_DIEM) return;
  int i = soDiem++;
  while (i > 0 && bangMv[i - 1] > mv) {              // chèn giữ thứ tự mV tăng dần
    bangMv[i] = bangMv[i - 1];
    bangPt[i] = bangPt[i - 1];
    i--;
  }
  bangMv[i] = mv;
  bangPt[i] = pt;
  luuBang();
  Serial.printf("Them diem %.0f mV = %.1f %%, bang co %d diem\n", mv, pt, soDiem);
}

void setup() {
  Serial.begin(115200);
  pinMode(CHAN_NGUON, OUTPUT);
  digitalWrite(CHAN_NGUON, LOW);
  analogSetPinAttenuation(CHAN_AO, ADC_11db);        // thang đo tới khoảng 3,1 V
  luu.begin("do_am_dat", false);
  soDiem = luu.getInt("n", 0);
  luu.getBytes("mv", bangMv, sizeof(bangMv));
  luu.getBytes("pt", bangPt, sizeof(bangPt));
  Serial.printf("Bang hieu chuan: %d diem. Lenh: c <phan tram>, x\n", soDiem);
}

void loop() {
  if (Serial.available()) {
    String lenh = Serial.readStringUntil('\n');
    lenh.trim();
    if (lenh.startsWith("c ")) themDiem(docMv(), lenh.substring(2).toFloat());
    else if (lenh == "x") {
      soDiem = 0;
      luuBang();
      Serial.println("Da xoa bang");
    }
  }
  static uint32_t lan = 0;
  if (millis() - lan < 5000) return;
  lan = millis();
  float mv = docMv();
  float pt = doiRaPhanTram(mv);
  if (isnan(pt)) Serial.printf("%.0f mV (chua hieu chuan)\n", mv);
  else Serial.printf("%.0f mV -> do am the tich %.1f %%\n", mv, pt);
}
  • Gõ c 0 khi cảm biến trong đất khô, c 12.5 khi đất có 12,5 % nước…; bảng tự sắp theo mV và lưu vào flash, mất điện không mất.
  • Gõ x để xóa bảng, làm lại từ đầu.
  • Chưa đủ hai điểm thì chương trình chỉ in mV.
  • Bảng hiệu chuẩn chỉ đúng cho loại đất đã dùng để hiệu chuẩn; đổi đất, đổi giá thể thì hiệu chuẩn lại.

6. Lắp đặt ngoài vườn

  • Phủ keo epoxy hoặc keo nến lên mép bo và phần linh kiện phía trên vạch; mép bo cắt hở là chỗ nước thấm vào lớp mạch.
  • Cắm thẳng đứng, ép đất sát hai mặt cảm biến; khe hở không khí làm số đọc thấp hẳn.
  • Đặt ở độ sâu vùng rễ, cách gốc cây và vòi tưới một khoảng để không đo đúng chỗ nước vừa chảy xuống.
  • Bón phân, tưới nước có muối làm số đọc lệch; định kỳ đối chiếu bằng cách lấy mẫu đất cân.

Dùng cảm biến để tự tưới có ở bài tưới cây tự động với ESP32 và nhà kính mini với ESP32.

7. Lỗi hay gặp

Hiện tượngNguyên nhânCách xử lý
Số đọc không đổi khi tướiChip 555 không chạy ở 3,3 V, cảm biến hỏngThử cấp 5 V (AOUT vẫn dưới 3,3 V), đổi cảm biến
Rút khỏi nước mà số giảm rất chậmThiếu điện trở xả mạch lọcKiểm tra mạch, chọn bản khác
Số trôi dần sau vài tuầnNước thấm vào mép boPhủ keo, thay cảm biến
Hai cảm biến cùng loại báo khác nhauLinh kiện khác nhau giữa các bảnHiệu chuẩn riêng từng cái
Số % lớn bất thườngDùng cách đổi 2 điểm không khí, nướcHiệu chuẩn bằng mẫu đất

Bài cùng cụm chủ đề: tưới vườn nhiều vùng bằng van điện từ; bơm và van điện từ điều khiển bằng MOSFET; hiệu chuẩn cảm biến bằng hồi quy.


Tin tức liên quan

Cảm biến độ dẫn điện (EC, TDS): cấu tạo, nguyên lý, chế tạo và tự làm đầu đo với ESP32
Cảm biến độ dẫn điện (EC, TDS): cấu tạo, nguyên lý, chế tạo và tự làm đầu đo với ESP32

Cảm biến độ dẫn điện hoạt động thế nào: EC và TDS, hằng số bình đo, vì sao phải đo bằng dòng xoay chiều, loại hai điện cực, bốn điện cực, cảm ứng, cách chế tạo và tự làm đầu đo với ESP32.

Động cơ bước cho máy CNC: NEMA 17, NEMA 23, mô-men giữ, vi bước, vì sao rung và mất bước
Động cơ bước cho máy CNC: NEMA 17, NEMA 23, mô-men giữ, vi bước, vì sao rung và mất bước

Động cơ bước quay thế nào, cỡ NEMA 17, NEMA 23 khác nhau ra sao, vi bước, vì sao mô-men giảm khi quay nhanh, cách tìm cặp dây cuộn và cách xử lý khi động cơ rung, mất bước.

Chọn mạch ESP32 nào: DevKit 30 hay 38 chân, CH340 hay CP2102, bản có OLED, có pin 18650
Chọn mạch ESP32 nào: DevKit 30 hay 38 chân, CH340 hay CP2102, bản có OLED, có pin 18650

Mạch ESP32 là gì, dùng để làm gì và cách chọn bản phù hợp: 30 hay 38 chân, CH340 hay CP2102, Type-C hay Micro USB, anten rời, bản có OLED, có pin 18650, ESP32 Lite.

Bắt đầu với STM32: chọn Blue Pill, Black Pill hay Nucleo, ST-Link, STM32CubeIDE, nháy LED đầu tiên
Bắt đầu với STM32: chọn Blue Pill, Black Pill hay Nucleo, ST-Link, STM32CubeIDE, nháy LED đầu tiên

Bắt đầu với STM32: các dòng theo nhân Cortex-M, chọn Blue Pill, Black Pill hay Nucleo, nối ST-Link qua SWD, tạo dự án STM32CubeIDE nháy LED PC13 bằng HAL, nạp không cần ST-Link và lỗi hay gặp.

Cấu tạo máy CNC mini và máy khắc laser: khung, ray trượt, truyền động, đầu công cụ, bộ điều khiển
Cấu tạo máy CNC mini và máy khắc laser: khung, ray trượt, truyền động, đầu công cụ, bộ điều khiển

Cấu tạo máy CNC kiểu cổng và máy khắc laser khung hở: khung nhôm định hình, ray dẫn hướng, vít me và dây đai, động cơ bước, spindle, module laser, phần điện và ba kiểu kết cấu.

Để học lập trình phát triển tư duy toàn diện cho trẻ: 7 điều kiện và bảng theo dõi cho phụ huynh
Để học lập trình phát triển tư duy toàn diện cho trẻ: 7 điều kiện và bảng theo dõi cho phụ huynh

Bảy điều kiện từ các nghiên cứu giúp việc học lập trình phát triển tư duy toàn diện cho trẻ, kèm bảng theo dõi tiến bộ, mẫu buổi học 45 phút và câu hỏi khi chọn lớp học.

Arduino IDE 2: tự gợi ý code, quản lý board và thư viện, gỡ lỗi từng bước, log khi không có JTAG
Arduino IDE 2: tự gợi ý code, quản lý board và thư viện, gỡ lỗi từng bước, log khi không có JTAG

Dùng Arduino IDE 2 hiệu quả: tự gợi ý code, nhảy tới định nghĩa, quản lý board và thư viện, thư mục của IDE, gỡ lỗi từng bước, macro log có mức cho ESP32.

CAN bus (phần 2): bộ lọc nhận, tốc độ bit và xử lý lỗi bus-off trên ESP32
CAN bus (phần 2): bộ lọc nhận, tốc độ bit và xử lý lỗi bus-off trên ESP32

Phần 2 về CAN bus với ESP32: đặt bộ lọc nhận theo mã lọc và mặt nạ, chọn tốc độ bit theo chiều dài dây, hiểu ba trạng thái lỗi của nút và viết chương trình theo dõi bộ đếm lỗi, tự hồi phục sau bus-off.


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