Learn

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
Arduino Uno: FC-28 soil moisture meterlive0.000 s 0.00x
Click to open it in the editor
An FC-28 resistive soil sensor powered from pin 7, with AO on A0, DO on pin 2 and an I2C LCD, on a simulated ATmega328P. Drag the slider to water the soil.

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 pinGoes toNote
Board VCCPin 7Powered only while reading, so the fork lasts
Board GNDGND
Board AOA0Lower means wetter
Board DOPin 2LOW when wetter than the trimmer
ForkThe two pins on the board’s other endEither way around
LCD SDA and SCLA4 and A5Backpack 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.

The loop, from the soil moisture meter
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.