Raspberry Pi Soil Moisture Sensor

141K33791

Intro: Raspberry Pi Soil Moisture Sensor

Agriculture consumes between 80 - 90% of all freshwater in the United States. An easy way to conserve water in the agricultural sector is to install a soil moisture sensor. Soil moisture sensors measure the amount of water in the soil to maintain consistent and ideal soil conditions for plants. In some cases, installing a soil moisture sensor reduces residential irrigation by as much as 50%.

The following is a simple capacitive soil moisture sensor using a Raspberry Pi and a co-planar capacitor from the Zero Characters Left blog.

Excluding the Pi, the system can be built for less than $25.

Here's a tutorial on how to control an outdoor irrigation valve to automatically water your plants when the soil is dry.

STEP 1: Materials

-- Raspberry Pi 2 Model B
This tutorial is based on a fully set-up Raspberry Pi, including GPIO libraries + GPIO cable w/ breadboard connector. I also recommend setting it up for wireless + SSH.

Other microcontrollers, like an Arduino, also work.

-- 1 MOhm Resistor (1/4 Watt)

This resistance was the best for my system, but a different resistor value might work better for your own setup. Experiment w/ different value resistors and see what happens!

-- Co-Planar Capacitor

Save the two EAGLE files (schematic and board file), then send to OSHPark. It costs ~ $10.00 for three.

-- 22 Gauge Wire (recommended to get stranded)

Recommended to get stranded wire b/c conducts better & is less likely to break.

-- GPIO Cable, GPIO cable adapter + breadboard

This is the bare minimum needed to build & test the system. If you want to install it outside after it has been tested and confirmed to work, coat everything in epoxy! ...Although a better way might be to replace the breadboard w/ a PCB Board . Molex 2-Pin Connectors are also a nice addition.

STEP 2: Tools

-- Soldering Iron, solder, & Solder Sucker (or desoldering wick)
A soldering iron is (almost) essential for this project, especially for attaching wire leads to the co-planar capacitor. You can purchase a soldering iron, solder and solder wick (removes solder) for ~ $20-30, or find a local makerspace/hackerspace that will let you come in and use an on-site soldering iron.

-- Wire Strippers

-- Epoxy

-- Optional (but highly recommended): Multimeter (for testing and debugging!)

STEP 3: Sensor & Circuit Design

An RC circuit provides a quick & simple way to measure changes in the sensor capacitance due to changes in soil water content.

Every RC circuit has an associated time constant, which is the time it takes the capacitor to reach ~ 63% of its maximum charge. The time constant equals the total circuit resistance times the circuit capacitance: τ = R * C

The time constant is used to measure changes in the sensor capacitance due to changes in soil water content. As the water content increases, the capacitance increases causing the associated circuit time constant to increase. The Raspberry Pi GPIO Pin 14 measures, or counts, the circuit time constant (how long it takes the capacitor to charge).

STEP 4: Build It: Hardware Pt 1.

Solder wire leads onto the co-planar capacitor (aka soil moisture sensor) pads. Test connection w/ multimeter. If the sensor is electrically connected, coat in epoxy & let dry before continuing.

If you're using stranded wire + a breadboard, you'll need to find a way to connect the stranded wire to the breadboard (b/c trying to shove it into the breadboard holes will make you want to pull your hair out). I stripped two breadboard wires and soldered them to the sensor leads. However, my connections were still a bit finicky and sensitive to touch and changes in light. Try different methods and see what works best. Use available materials and keep it simple!

STEP 5: Build It: Hardware Step 2.

  • Connect the RPi GPIO pins to the breadboard. Connect the 3.3 V output pin to the "+" column along the side of the breadboard.
  • Connect the GPIO ground pin to the "-" column.
  • Connect one resistor end to the 3.3 V output (any of the holes in the "+" column). Connect the other end to any of the breadboard rows. Orientation of the resistor leads doesn't matter.
  • Connect GPIO pin 14 to the same breadboard row as the resistor. You can use a different GPIO pin, but remember to change it in the software program.The GPIO probe MUST go between the resistor and the co-planar capacitor.
  • Connect one of the co-planar capacitor leads to the same breadboard row as the resistor + probe. Connect the other lead to ground (any of the holes along the "-" column). It doesn't matter which lead goes where.

STEP 6: Build It: Software

Write a code to measure the capacitance of the sensor! Use the fact that the time constant changes depending on the medium in which the sensor is installed (capacitance is much larger in water than in air).

Or you can just use mine :)

Keep in mind that this is a basic program and doesn't include a GUI. All commands are run on the Pi's terminal window (LXTerminal). The program prints the circuit time constant, correlated to soil water content, and a raw time stamp. If the reading is too low, the program also prints a reminder to water the plants. It stores the raw data in a text file. To end the program, use "Ctrl + Z" or "Ctrl + C". Modify and improve the program based on your own skills/needs.

Remember to change the watering threshold based on your own experimental discoveries!

STEP 7: Testing!

  • Test the software program and determine your ideal threshold.
    • Test the sensor in water and air first; this provides the upper and lower bounds on the sensor output. If you find that the sensor is not reading in either of these mediums, change the value of the resistor until you get a reasonable signal. Be sure to record the reading for at least 5 - 10 minutes. It is helpful to plot the results in a program like Excel or R.
    • Place the sensor in a cup of dry soil. Add a small amount of water and measure changes in sensor output over time (wait at least 5 - 10 minutes). Repeat this multiple times to get a better understanding of the reading and to improve the software/hardware as necessary.
    • If you are not getting a reading in either medium, try checking the electrical connections on the sensor.
  • Fix the program as necessary.
    • Your signal will likely be different than mine due to minor differences in your sensor and general setup. Use your findings from above to find an approximate value at which your soil is too dry.

STEP 8: Enjoy!

Install in a sunny spot and use it to maintain consistent watering of your beloved plants!

Note: In the system pictured above, the Raspberry Pi is also controlling a solenoid irrigation valve, so the entire watering system is automated! This is fairly easy to do and if there is sufficient interest I will include an overview of this process as well.

Happy hacking!

83 Comments

my partner and I could not get our program to work. It always said there was not enough water.

well foo! there are a lot of factors that could be causing this. are there any shorts? did you coat the electrical connections in epoxy? where did you connect the GPIO pin? Also, use a multimeter to check the capacitance of the soil moisture sensor directly in water and in air to be sure that you're getting different values. if that is working, then it's not the sensor and the issue is somewhere in the hardware or software. best of luck!

That definitely helps, Thanks for your follow-up! Please forgive my ignorance here (I'm new to basic circuitry, [and RPi and Python]), but to combine the two projects, is it safe to presume that I will use one of the 3.3v pins for the moisture sensor and the other for the solid state relay? (i.e., use 3.3v pin #1 and ground pin #6 for the moisture sensor project and 3.3v pin #17 and ground pin #20 for the irrigation controller) or will this damage my RPi?.

Happy to help! And hey, we're all beginners at some point! This was my first project so I totally know how it goes. Yes, you can use the same 3.3V pin for both the sensor and the relay. The relay won't pull too much current since it is mostly just looking for a change in voltage on the DC side -- that's why relays are super useful, you can use a small current and voltage to control a much larger current and voltage. Also, you can use the same ground pins for both.

Related aside: all ground points need to be connected to the same place, or you might get funny readings (since voltage is a potential difference it is measured between two points, like dropping a ball at arm's length while standing on the ground vs. on top of a building, the ball will bounce the same distance even though you're technically higher up in the second scenario).

Hi Jen,
Thanks for creating this tutorial. In the picture above with the integrated projects, I see the two waterproof boxes. Are you using two RPis for the integrated project, or does one of the boxes contain the RPi and moisture sensor pcb board, while the other contains the irrigation controller pcb board with the relay?

Just one Pi, like you guessed it's both projects combined (soil moisture sensor and irrigation controller) -- it was all one big project but I separated them in write-up to make it easier to follow. I split the soil moisture sensor PCB from the irrigation controller and Pi because I wanted to be able to install the sensor far from the spigot. In retrospect, I could have just added longer wires to the sensor and combined all the PCBs in one box. Hope that helps!

Why is the resistor important to this build?

Good question! The simple resistor-capacitor ("RC") circuit is used to measure changes in the capacitance of the soil moisture sensor. The RPi logs the time constant of the circuit (aka how long it takes to charge the capacitor) which changes depending on moisture and the resistor needs to be large enough to be able to see those small changes. Hope that helps!

Is that reliant to this particular soil moisture sensor?

I'm curious because I have a soil moisture sensor that puts out voltage. Up to 2.8V and each of those voltages is directly porpotionate to how wet the soil is.

Yes, this particular soil moisture sensor is a co-planar capacitor. If your soil moisture sensor is putting out voltage, it is not just the sensor but includes additional circuit components. If you're having trouble calibrating it or whatnot, I'd suggest doing a search in Google for the specific sensor you are using and then reading up on it.

You could also do what I did to try and calibrate my sensor -- bake some soil in the oven to get all the moisture out, then all small volumes of water and make readings over time. Takes a loooong time but it's not terribly difficult.

Hi Jen,

I know it's been a long time since you wrote this article but, I tried to reproduce it and got something weird. I always get the same message.. my plants need water, event when I got a bottle with water over the soil. I followed your instructions step by step, line by line. I am also using your code.

Any thoughts?

Hello! Based on your description, sounds like something is wrong with the sensor signal. Are you getting a sensor reading output? Does it change at all? Try checking your connections -- a multimeter can be super helpful with this if you have one on-hand.
If it's not the connections, output the sensor signal and see if it is changing at all. If it's not changing, it could be that the circuit is not sensitive enough (aka you'll need a larger resistance). LMK if these suggestions prove useful!

The same values with with both air, dry soil and wet soil..

Huh, that's odd. Did you coat the sensor in anything? Seems like it's not making direct contact with the dielectric.

Hey!!! Thanks for the response. Well I made a lot of measurements, resoldered a few times the sensor but still stuck into this hheh.

I made a few tests with different resistances.. and believe me.. the soil I am using has a lot of water

So the responses I got here were:

For 10M Resistor

1459726298.7 0.122217178345

1459726299.82 0.118407011032

1459726300.95 0.121515989304

1459726302.07 0.128042221069

1459726303.2 0.139445066452

1459726304.35 0.143229007721

When using 20M resistor

1459726352.18 0.16845202446

1459726353.35 0.174252033234

1459726354.53 0.177757978439

1459726355.71 0.171924114227

1459726356.88 0.17144203186

30 M

1459726387.79 0.214463949203

1459726389.01 0.213176965714

1459726390.23 0.21272110939

1459726391.45 0.219429016113

40 M

1459726421.87 0.233628988266

1459726423.11 0.231085062027

1459726424.34 0.246037006378

1459726425.59 0.234977006912

1459726426.83 0.23019695282

1459726428.07 0.237556934357

and finally 50 M

1459726442.36 0.272974967957

1459726443.63 0.280236005783

1459726444.92 0.282718896866

1459726446.2 0.277140855789

1459726447.48 0.281071186066

1459726448.77 0.279512166977

Well it seems there´s something related to either the my sensor or my RPI... not sure if the second option is possible... the weirdest thing is that I got good measurements using something like this https://www.arduino.cc/en/Tutorial/CapacitanceMeter and an Arduino Mega..

So the first thing that I notice is that the sensor reading increases with increasing resistance -- which means that the sensor is outputting some kind of signal. Are you getting different sensor readings in dry soil vs. wet soil with any of those resistance values?

Hey there, first of all thanks a lot for the Pro tip with the capacitor, I was about to buy a sensor for 60 bucks and this one saved my wallet! (and made me a bit smarter with electronics : >)

I've built it and it works like a dream, I am even able to control a little pump to water my plants. I have also noticed an increase and a decrease in the readings and wanted to share my thoughts with you guys, see what you think. I'm using the model b.

I also built a light module that, like the pump, is controlled over a 2 channel relay board. My program runs those as seperate instances in different threads. Since my plant is 2 weeks old, the roots aren't really developed enough to get the water so the soil is pretty stable. the readings are ok, I am doing 100 readings and taking the average of those, but from time to time it jumps about 10 counts.

I think, the change is due to the cpu timing that each thread occupies the cpu. If the light is on, there are more instructions to be processed which takes longer time, therefore I get less counts. Lights off means more counts because my water pump thread has more time or rather gets faster back onto the cpu. would that make sense? therefore you could increase the precision of the sensor if you could influence the cpu time but I wouldn't know how to do that in python... anyways I would appreciate your feedback!

Whoops, apologies for missing this! Based on your description, it sounds like you are the right track re: cpu timing. Yes, I would assume that if you add more stuff for the computer to do, it could affect the sensor reading.

The way to get around this is to use a separate function for the other stuff you want to have happen, then call that separately in a main function. Hopefully this helps if you haven't already figured it out!

Very interesting.
I do capacitive mositure metering as well, using just two virgin PCB pieces in plastic in the soil. Use that as the 'C' of an RC oscillator and measure the output with 'PulseIn' on an Arduino. Readings are pretty stable. Initially I just use the Arduino as capacitance meter but I found the RC oscillator to work more reliable

Thanks! Love your approach as well, very clever/creative!
More Comments