Here’s a simple, reliable way to use a soil-moisture [sensor](https://www.ampheo.com/c/sensors) so each plant gets the amount of water it actually needs. ![F2H363LLXLUF7N6](https://hackmd.io/_uploads/HJs6HHC6gx.jpg) **1) Pick the right sensor** * Capacitive soil-moisture sensor (analog or I²C) → best for hobby/DIY (less corrosion than resistive “forks”). * Tensiometer / matric-potential sensor (kPa) → most agronomy-correct, but pricier. * Tip: Whatever you choose, plan to calibrate per soil mix (potting soil vs cactus mix) because raw numbers aren’t universal. **2) Calibrate your sensor (5–10 min per soil)** 1. Stick the sensor in air-dry soil → note reading = DRY. 2. Fully saturate the soil, let it drain to field capacity (30–60 min) → note reading = WET. 3. Convert later readings to a %: `moisture_% = 100 * (reading - DRY) / (WET - DRY) // clamp 0…100` For capacitive probes: wetter soil usually = higher reading; confirm on your unit (some are inverted). **3) Choose setpoints per plant (as % of your calibrated scale)** ![企业微信截图_20251016180211](https://hackmd.io/_uploads/Hkc3Mr0agg.png) Add hysteresis (two thresholds) so pumps don’t chatter. **4) Hardware sketch (per pot)** * MCU: [Arduino](https://www.ampheo.com/c/development-board-arduino)/ESP32. * Sensor: Capacitive probe → analog pin (use 3.3–5 V as specified). * Pump/valve: 5–12 V peristaltic pump or [solenoid](https://www.onzuu.com/category/solenoids). * Driver: N-[MOSFET](https://www.onzuu.com/category/fets-mosfets) or [relay](https://www.onzuu.com/category/relays) + flyback [diode](https://www.onzuu.com/category/diodes) ([1N5819](https://www.onzuu.com/search/1N5819)/[1N4007](https://www.onzuu.com/search/1N4007)) across the load. * Power: Separate supply for pumps; common ground with MCU. * Scaling up: Use an [ADS1115](https://www.onzuu.com/search/ADS1115) (I²C ADC) or analog multiplexer to read many pots. **5) Minimal Arduino example (multi-plant, hysteresis)** ``` struct Zone { uint8_t ain, pumpPin; int DRY, WET; // from your calibration float lowPct, highPct; // plant setpoints unsigned long maxMs; // safety cutoff per cycle bool pumping; unsigned long tStart; }; Zone z[] = { // ain, pump, DRY, WET, low%, high%, max pump time {A0, 5, 1780, 2650, 25, 35, 20UL*1000}, // succulent {A1, 6, 1820, 2700, 45, 60, 25UL*1000}, // tomato }; float pct(int raw, int DRY, int WET){ float p = 100.0f * (raw - DRY) / float(WET - DRY); if (p < 0) p = 0; if (p > 100) p = 100; return p; } void setup(){ Serial.begin(115200); for (auto &q : z){ pinMode(q.pumpPin, OUTPUT); digitalWrite(q.pumpPin, LOW); } } void loop(){ static unsigned long last = 0; if (millis() - last < 1000) return; // ~1 Hz control loop last = millis(); for (auto &q : z){ // simple median of 5 reads to reduce noise int rmin=4096,rmax=0,sum=0; for(int i=0;i<5;i++){ int v=analogRead(q.ain); rmin=min(rmin,v); rmax=max(rmax,v); sum+=v; delay(5); } int raw = (sum - rmin - rmax)/3; float m = pct(raw, q.DRY, q.WET); if (!q.pumping && m <= q.lowPct) { q.pumping = true; q.tStart = millis(); digitalWrite(q.pumpPin, HIGH); } if (q.pumping && (m >= q.highPct || millis() - q.tStart > q.maxMs)) { q.pumping = false; digitalWrite(q.pumpPin, LOW); } Serial.print("zone:"); Serial.print(&q - z); Serial.print(",moist:"); Serial.print(m,1); Serial.print(",pumping:"); Serial.println(q.pumping); } } ``` * Replace DRY/WET with your measured values. * Tune lowPct/highPct to plant needs. * maxMs prevents over-watering if a tube pops off. **6) Practical tips** * Depth matters: place the probe near the root zone, not just the top 2 cm. * Avoid fertilizer spikes: EC/salinity affects capacitive reads; re-calibrate after heavy feeding or use distilled water for calibration. * Temperature drift: readings shift with temp; take measurements at a similar time of day or add a temp sensor and compensate. * Filter & average: small median/EMA filtering smooths noise; don’t over-filter—water decisions should lag by minutes, not hours. * Watering window: restrict pumps to daytime to avoid fungus (unless urgent). * Maintenance: wipe probes monthly; recalibrate each season or when repotting. **7) Scaling to many plants** * One sensor per pot = best. * Or rotate one [sensor](https://www.ampheoelec.de/c/sensors) across zones to learn thresholds, then water by time/weight (load cells under pots work great) and re-check weekly.