Plant monitor on an Arduino Uno
A soil moisture sensor, a rain sensor and a water level sensor on three analog pins. Two read lower when wetter and one reads higher. The whole build, an Arduino Uno and 5 more parts, runs here in your browser on the firmware below; open it in the editor to change the wiring or the code and run it again.
IntermediateRuns in your browser. Free, and no account needed.
The code
The firmware exactly as the editor opens it. Change a line there and press Run: it compiles in the browser.
// Plant monitor: the soil, the rain and the water butt, once a second.
//
// A0 the soil sensor's AOUT A1 the rain sensor's AO
// A2 the water level's S pin 7 the rain sensor's DO
// pin 8 the "water me" lamp, through 220 ohm to GND
// every sensor's VCC -> 5 V and GND -> GND
//
// Three sensors that all look like "an analog pin that means water", and they
// disagree about which way is up. That is the thing to take away.
//
// # The soil sensor reads lower when it is wetter
//
// The capacitive stake gives about 520 counts held in the air and about 260
// with its tip in water, and the soil is somewhere between. So the percentage
// is map(reading, 520, 260, 0, 100): the two ends swapped. Those two numbers
// are this sensor's; a real one is calibrated in dry and soaked soil first.
//
// # The rain sensor reads lower too, and has a comparator
//
// Dry, the plate is open and A1 reads the full 1023. Wet, it falls. Its board
// also compares that with its trimmer and pulls DO low when it is wet enough,
// so pin 7 is a plain "is it raining" without any arithmetic.
//
// # The water level reads higher, and not in millimetres
//
// Its transistor turns on as soon as the tip is wet and then creeps up as the
// water rises: most of the reading is in the first few millimetres. It is a
// level indicator, not a gauge.
//
// # The lamp
//
// Pin 8 lights when the soil is under 30% and it is not raining: the plant
// wants water and the sky is not going to give it any.
const int SOIL = A0;
const int RAIN_AO = A1;
const int WATER = A2;
const int RAIN_DO = 7;
const int LAMP = 8;
// This sensor's two ends, in counts on a 5 V board.
const int SOIL_AIR = 520;
const int SOIL_WATER = 260;
void setup() {
pinMode(RAIN_DO, INPUT);
pinMode(LAMP, OUTPUT);
Serial.begin(115200);
Serial.println("Mokxi Arduino Uno: plant monitor");
}
void loop() {
int soil = analogRead(SOIL);
int percent = constrain(map(soil, SOIL_AIR, SOIL_WATER, 0, 100), 0, 100);
int rain = analogRead(RAIN_AO);
bool raining = digitalRead(RAIN_DO) == LOW;
int water = analogRead(WATER);
Serial.print("soil ");
Serial.print(percent);
Serial.print("% (");
Serial.print(soil);
Serial.print(") rain ");
Serial.print(rain);
Serial.print(raining ? " raining" : " dry");
Serial.print(" water ");
Serial.println(water);
digitalWrite(LAMP, percent < 30 && !raining ? HIGH : LOW);
delay(1000);
}
Parts list
7 parts, plus the jumper wires. Every one is in the editor's parts bin.
How it is wired
8 connections, pin by pin, read from the circuit itself. Each line is one set of pins joined together, by a jumper wire or a breadboard strip.
- Arduino Uno R3 pin 8; Resistor, 220 Ω pin 1
- Arduino Uno R3 pin 7; Rain sensor pin DO
- Arduino Uno R3 pin 5V; Soil moisture sensor, capacitive pin VCC; Rain sensor pin VCC; Water level sensor pin VCC
- Ground: Arduino Uno R3 pin GND; Soil moisture sensor, capacitive pin GND; Rain sensor pin GND; Water level sensor pin GND; LED, green pin C
- Arduino Uno R3 pin A0; Soil moisture sensor, capacitive pin AOUT
- Arduino Uno R3 pin A1; Rain sensor pin AO
- Arduino Uno R3 pin A2; Water level sensor pin S
- Resistor, 220 Ω pin 2; LED, green pin A
Change it and keep it
Open it in the editor, change the circuit or the code, and keep your version in a free account.