A fertilizer doser automation system using a peristaltic pump with Arduino delivers precise nutrient dosing for hydroponics, greenhouse fertigation, and drip irrigation — eliminating manual mixing errors and reducing fertilizer waste by 30–50%. This guide walks through building a complete automated fertilizer dosing system with peristaltic pumps, EC/TDS feedback, and timed injection cycles.
Table of Contents
- Why Automate Fertilizer Dosing
- Understanding Peristaltic Pumps
- Components Required
- Circuit and Wiring
- Arduino Dosing Code
- Pump Calibration
- EC Sensor Feedback Loop
- Indian Agriculture Applications
- Frequently Asked Questions
Why Automate Fertilizer Dosing
Manual fertilizer mixing leads to inconsistent nutrient concentrations, over- or under-feeding plants, and significant labour costs. In Indian agriculture, fertilizer represents 15–25% of crop production costs. Automated dosing provides:
- Precision: Dose accuracy within ±2% vs ±20% for manual mixing
- Labour savings: Reduces fertigation labour from 2–3 hours/day to 15 minutes
- Yield increase: Consistent nutrient delivery improves yields by 15–30% in greenhouse crops
- Fertilizer savings: Up to 35% reduction via EC-feedback dosing vs fixed-rate application
- Scalability: One controller can manage 4–8 separate nutrient channels (N, P, K, micronutrients, pH up/down)
Understanding Peristaltic Pumps
Peristaltic pumps use rotating rollers to squeeze flexible tubing, pushing fluid forward without the fluid touching any pump mechanism. Key advantages for fertigation:
- Self-priming — works with concentrated fertilizer solutions
- No contamination between channels — each channel has dedicated tubing
- Accurate volumetric dosing — calibrate once, repeatable forever
- Handles viscous fertilizer concentrates (up to 500 cP)
- Easy to sanitise — replace tubing annually
Common flow rates: 100 mL/min (small greenhouse) to 1000 mL/min (commercial scale). For hobby and small farms, 100–300 mL/min DC peristaltic pumps at 12V are widely available in India for ₹500–1,500 each.
Components Required
Pumps and Control Modules from Zbotic
- 12V DC Mini Submersible Water Pump — ₹199 (for main irrigation water supply)
- 5V/12V Relay Control Module — ₹89 (for controlling pumps)
- Capacitive Soil Moisture Sensor — ₹129 (substrate monitoring for pot/bag culture)
Full parts list:
- Arduino Uno or Mega (Mega recommended for 4+ channels)
- 4× Peristaltic dosing pumps (12V, 100 mL/min)
- 4-channel relay module (5V)
- TDS/EC sensor module (analog output)
- pH sensor module (optional, for pH correction channel)
- 16×2 LCD with I2C adapter
- DS3231 RTC module
- Push buttons (3×) for menu navigation
- 12V 5A power supply
- Silicone peristaltic tubing (6mm ID)
Circuit and Wiring
Relay connections (active LOW relays):
- Relay IN1 → Arduino D4 (Nutrient A pump)
- Relay IN2 → Arduino D5 (Nutrient B pump)
- Relay IN3 → Arduino D6 (Micronutrient pump)
- Relay IN4 → Arduino D7 (pH adjustor pump)
- TDS sensor AOUT → Arduino A0
- pH sensor AOUT → Arduino A1
- LCD SDA → Arduino A4, SCL → A5
- DS3231 SDA → A4, SCL → A5 (same I2C bus)
Power all relay pump loads from a separate 12V supply. Use snubber diodes (1N4007) across pump terminals to protect relay contacts from back-EMF.
Arduino Dosing Code
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
RTC_DS3231 rtc;
// Relay pins (active LOW)
#define PUMP_A 4 // Nutrient A (Nitrogen base)
#define PUMP_B 5 // Nutrient B (Phosphate + Potassium)
#define PUMP_MICRO 6 // Micronutrients
#define PUMP_PH 7 // pH adjustment
// Sensor pins
#define TDS_PIN A0
#define PH_PIN A1
// Target parameters
const float TARGET_EC = 1.8; // mS/cm (adjust per crop)
const float TARGET_PH = 6.0; // pH (adjust per crop)
const float EC_TOLERANCE = 0.2;
const float PH_TOLERANCE = 0.3;
// Pump calibration (mL per second)
const float PUMP_RATE = 1.67; // 100 mL/min = 1.67 mL/s
// Dose schedule: dose every 4 hours during day
int doseHours[] = {6, 10, 14, 18};
bool dosedThisHour[24] = {false};
void setup() {
Serial.begin(9600);
Wire.begin();
lcd.init();
lcd.backlight();
rtc.begin();
// Set relay pins HIGH (relay off)
for (int p = 4; p <= 7; p++) {
pinMode(p, OUTPUT);
digitalWrite(p, HIGH);
}
lcd.setCursor(0, 0);
lcd.print("FertiDoser v1.0");
delay(2000);
}
float readTDS() {
int raw = analogRead(TDS_PIN);
float voltage = raw * (5.0 / 1023.0);
// TDS sensor EC calculation (simplified)
float ec = (133.42 * voltage * voltage * voltage
- 255.86 * voltage * voltage
+ 857.39 * voltage) * 0.5 / 1000.0; // Convert to mS/cm
return ec;
}
float readPH() {
int raw = analogRead(PH_PIN);
float voltage = raw * (5.0 / 1023.0);
float ph = -5.70 * voltage + 21.34; // Calibration: adjust these values
return ph;
}
void doseSeconds(int pumpPin, float seconds) {
if (seconds <= 0) return;
int ms = (int)(seconds * 1000);
digitalWrite(pumpPin, LOW); // Pump ON
delay(ms);
digitalWrite(pumpPin, HIGH); // Pump OFF
delay(500); // Brief pause between pumps
}
void runDoseCycle() {
float currentEC = readTDS();
float currentPH = readPH();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("EC:");
lcd.print(currentEC, 1);
lcd.print(" pH:");
lcd.print(currentPH, 1);
// Dose nutrients if EC is low
if (currentEC < TARGET_EC - EC_TOLERANCE) {
float ecDeficit = TARGET_EC - currentEC;
// Dose A and B in equal parts for 3 seconds minimum, up to 30s
float doseTime = constrain(ecDeficit * 10.0, 3.0, 30.0);
lcd.setCursor(0, 1);
lcd.print("Dosing A+B ");
lcd.print((int)doseTime);
lcd.print("s");
doseSeconds(PUMP_A, doseTime);
doseSeconds(PUMP_B, doseTime);
doseSeconds(PUMP_MICRO, doseTime * 0.1); // Micro = 10% of A/B
}
// Adjust pH if needed
if (currentPH > TARGET_PH + PH_TOLERANCE) {
// Dose pH down (phosphoric acid) - 2 seconds
doseSeconds(PUMP_PH, 2.0);
lcd.setCursor(0, 1);
lcd.print("pH Down dosed ");
}
}
void loop() {
DateTime now = rtc.now();
int hr = now.hour();
// Check if this is a scheduled dose hour
for (int i = 0; i < 4; i++) {
if (hr == doseHours[i] && now.minute() == 0 && !dosedThisHour[hr]) {
runDoseCycle();
dosedThisHour[hr] = true;
}
}
// Reset daily dose flags at midnight
if (hr == 0 && now.minute() == 0) {
memset(dosedThisHour, false, sizeof(dosedThisHour));
}
// Display current readings every minute
if (now.second() == 0) {
float ec = readTDS();
float ph = readPH();
lcd.setCursor(0, 0);
lcd.print("EC:");
lcd.print(ec, 2);
lcd.print(" mS/cm ");
lcd.setCursor(0, 1);
lcd.print("pH:");
lcd.print(ph, 2);
lcd.print(" ");
}
delay(1000);
}
Pump Calibration
Accurate dosing requires calibrating each pump individually:
- Place pump inlet in water, outlet into a measuring cylinder
- Run pump for exactly 60 seconds
- Measure volume dispensed
- Calculate: mL per second = volume / 60
- Update
PUMP_RATEconstant in code
Re-calibrate monthly as peristaltic tubing stretches slightly over time. Mark tubing with installation date — replace every 6–12 months.
EC Sensor Feedback Loop
The EC (electrical conductivity) feedback loop ensures precise dosing without over-fertilisation:
- Measure current EC before each dose cycle
- Calculate deficit from target EC
- Dose proportionally — larger deficit = longer pump run time
- Wait 5 minutes and remeasure before second dose (mixing time)
- Log all doses to EEPROM for agronomist review
Indian Agriculture Applications
This system is widely applicable across Indian horticulture:
- Polyhouse/net house tomato (Nasik, Pune): 4-channel dosing with EC targets 2.5–3.5 mS/cm for fruiting stage
- Hydroponic leafy greens (urban farms, Bangalore, Mumbai): EC target 1.2–1.8 mS/cm for lettuce, spinach
- Capsicum/bell pepper (AP, Telangana): pH 5.8–6.2 critical for nutrient availability
- Strawberry (Mahabaleshwar): Low EC (0.8–1.2) with precise pH control improves Brix
Frequently Asked Questions
Can I use a relay module to directly control peristaltic pumps?
Yes, for DC 12V pumps drawing under 3A per channel. Most relay modules handle up to 10A/30VDC. Always add flyback diodes across motor terminals and use separate power supply for pumps (do not power from Arduino’s 5V rail).
What is the minimum dose volume I can achieve?
With a 100 mL/min pump, a 100ms pulse delivers ~0.17 mL. This is precise enough for hobbyist systems. For commercial precision dosing below 1 mL, use slower pumps (10–50 mL/min) or PWM speed control.
How often should I calibrate the TDS sensor?
Calibrate at installation with a reference EC solution, then verify monthly. Clean the sensor probe weekly in diluted hydrochloric acid (1:10) to remove mineral deposits that cause drift.
Can I add WiFi and remote monitoring?
Yes — replace Arduino Uno with ESP32. Add a web dashboard or ThingSpeak channel to log EC, pH, and dosing events remotely. Set up Telegram alerts when EC drifts more than 0.5 mS/cm from target.
Add comment