Read an FC-28 soil moisture sensor with an Arduino
Beginner
Or see every lesson.
- 503parts on the bench
- 44boards running now
- 1.00xreal time, on every board
The FC-28 is the soil moisture sensor with the two-pronged fork, sold as the YL-69 too. You push the fork into a plant pot, and a small blue board on its lead gives the Arduino a reading that falls as the soil gets wetter, plus a pin that switches when the soil is wet enough.
The circuit above is an Uno with an FC-28, powered from pin 7, and a 16x2 I2C LCD. Press Run and drag the slider from the air to a glass of water: the screen goes from "Dry, water me" through "Just right" to "Wet". It runs in your browser on the sketch below.
What you need
- An Arduino Uno
- An FC-28 or YL-69 soil moisture sensor with its LM393 board
- A 16x2 LCD with an I2C backpack
- A half-size breadboard and jumper wires
- A plant pot to try it in
Wiring
| Part and pin | Goes to | Note |
|---|---|---|
| Board VCC | Pin 7 | Powered only while reading, so the fork lasts |
| Board GND | GND | |
| Board AO | A0 | Lower means wetter |
| Board DO | Pin 2 | LOW when wetter than the trimmer |
| Fork | The two pins on the board’s other end | Either way around |
| LCD SDA and SCL | A4 and A5 | Backpack address 0x27 |
The soil is a resistor
The two prongs are bare metal with nothing joining them but the soil. Dry soil barely conducts. Wet soil, with salts dissolved in its water, conducts well. The board puts the fork under a 10 kohm pull-up to VCC, so the reading on AO is 1023 with the fork in the air and falls as the soil gets wetter.
In the circuit above it starts in dry soil and reads 955: "Dry, water me". Slide it to 10% and it reads 992. At 50%, damp soil, it reads 570, "Just right". At 70% it reads 400 and at 80% 337, the 300s and 400s tutorials show for wet soil. In a glass of water it reads 245.
Those numbers are a shape, not a promise. Mokxi makes the fork’s resistance fall as the square of the moisture, the rule soil scientists use for wet ground, but a real fork reads different numbers in different soils, and fertilized potting mix reads far wetter than sand. Measure your own dry and wet readings and use those.
Power it from a pin, or it corrodes
A steady current through wet soil is electrolysis: one prong slowly plates away, and in a few weeks the readings drift. That is why the sketch powers the board from pin 7. It sets the pin HIGH, waits 10 ms, reads AO and DO, and sets it LOW again, once a second. Pin 7 can easily supply the few milliamps the board takes.
If your plant project has to run for months, the capacitive soil sensor has no metal in the soil and does not corrode.
void loop() {
digitalWrite(POWER, HIGH);
delay(10);
int moisture = analogRead(AO);
bool wet = digitalRead(DO) == LOW;
digitalWrite(POWER, LOW);
const char *verdict;
if (moisture > 750) verdict = "Dry, water me";
else if (moisture >= 500) verdict = "Just right";
else verdict = "Wet";
Serial.print("Moisture: ");
Serial.print(moisture);
Serial.print(" DO: ");
Serial.print(wet ? "LOW" : "HIGH");
Serial.print(" ");
Serial.println(verdict);
delay(1000);
}AO or DO?
AO is the number, so a sketch can choose its own bands. DO is the board’s own answer: its LM393 compares AO with the blue trimmer and pulls DO LOW, lighting the second lamp, when the soil is wetter than the trimmer is set. Turn the trimmer and you move the point where it switches, with no code at all. In the circuit above DO reads HIGH at 570 and LOW at 400.
Try it in the editor
Add a relay and a pump that run for three seconds when the reading goes over 750. Or change the bands in the sketch to suit a cactus, which likes its soil much drier.
Common mistakes
Powering it from 5 V all the time. The fork corrodes. Power it from a pin only while you read it.
Expecting higher numbers for wetter soil. It is the other way around: wetter is lower.
Reading straight after switching it on. Wait a few milliseconds for the board to settle first.
Using someone else’s numbers. Calibrate in your own soil, dry and just watered.
Questions
How do I connect an FC-28 soil moisture sensor to an Arduino?
The fork plugs into the two pins on one end of the board. On the other end, VCC goes to an Arduino pin (or 5 V), GND to GND, AO to an analog pin such as A0 and DO to another pin if you want the board’s own wet or dry answer.
What readings does the FC-28 give?
On a 5 V Arduino it reads 1023 in the air, around 900 to 1000 in dry soil, in the 300s and 400s in wet soil and lower again in water. The exact numbers depend on your soil.
Why does my soil moisture sensor stop working after a few weeks?
The fork corrodes when current runs through it all the time. Power the board from an Arduino pin and switch it on only while you take a reading.
What does Mokxi not model on the FC-28?
The fork corroding, the soil’s salts, temperature and how long soil takes to dry. The curve from moisture to reading is a shape, not a measurement of one real fork.
Build this for real
Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.