Projects Research & Design Hub

Measuring Soil Moisture with ADCs

Written by Jeff Bachiochi

Capacitors as Garden Tools

How does capacitance relate to gardening? Here, Jeff steps through the math and science of capacitance, with insights on how capacitor functionality plays a role in successive approximation ADCs. He then applies MCU-based ADC tech to measure the amount of moisture in his garden’s soil.

  • How to measure the amount moisture in soil using MCU-based ADCs

  • How to understand how SAR ADCs work

  • How to use Capacitive sensors to measure moisture

  • How to use an MCU’s Capacitive Voltage Divider module to do relative capacitance measurement

  • How to control a circuit using an I2C interface.

  • How to use the Microchip PICKit3 and MPLAB X IDE for debugging

  • Microchip PIC16LF1554 MCU

  • Successive approximation (SAR) ADCs

  • Capacitive sensors

  • Capacitive Voltage Divider

  • Microchip PICKit3 dev kit


When I hear the word capacity, I think of an ability to retain a quantity or quality of something. This might pertain to things as diverse as a thimble, a lake, a strength, empathy or productivity. In electronics, we use capacity to describe the ability to store energy in the form of an electric charge. Originally known as a condenser, the capacitor is an integral part of all electronic circuitry. While similar to a battery—in that it can hold a voltage potential and be discharged, sourcing a current flow—a battery produces its power from an internal electrochemical conversion. In contrast, a capacitor must be charged by an external potential.

A capacitor’s capacity to store a charge is based on its composition. A typical capacitor consists of two conductors separated by a non-conductive region. The size of these conductors or plates and the non-conductive region or dielectric between them establish the capacity (Figure 1). The conductors are usually made from thin metal foil or film. The insulation or dielectrics materials are typically glass, ceramic, plastic film, paper or mica. Unlike a resistor that passes current and produces heat, a capacitor only collects current and dissipates (essentially) no heat.

FIGURE 1 – A capacitor is a device that can store a charge. It is made up of two parallel plates separated by an insulator (dielectric). The dielectric (material and thickness) and area of the plates affect the capacitance of the device.

The capacity (C) of any capacitor—independent of the materials used in its construction—can be measured in farads. One farad is one coulomb (Q) of charge caused by one volt (V) across its plates. A coulomb is the electric charge produced by a constant 1A for 1 second. C = Q/V. Referring back to Figure 1, you can see that changing the plate size (A in square meters), distance between plates (d) or the dielectric material’s permittivity (ε) will affect the capacitance. C= ε (A/d). With a fixed plate area and distance between its plates, increasing the permittivity increases the capacitance. Hold onto this for a few minutes.

Microcontrollers (MCUs) are digital in nature. Let’s assume for this discussion that the MCU is running on 5V and can accept a 5V analog input. Digital inputs are seen as either 1 or 0. If an analog voltage is applied to a digital input, you get either a 1 or 0, depending on the analog voltage and the input’s characteristics. To measure an analog voltage, we need to convert it to a digital value so the MCU can handle it. Many MCUs contain an analog-to-digital converter (ADC) peripheral. There are many varieties of ADCs—flash, successive approximation (SAR), integrating, sigma-delta and others.

A popular ADC type that MCUs embed is the SAR ADC. Since this conversion requires a bit of time, and the analog voltage could be changing, we need to be able to take a sample of it and then hold it steady while the conversion is performed—otherwise the changing voltage will cause an invalid conversion value. This is done by connecting an internal capacitor to an analog input pin—allowing it time to charge to the external analog voltage—and then disconnecting it from the input and allowing the ADC to do its conversion.

The time it takes to convert depends on the number of bits of resolution you want. The number of bits is directly proportional to how close the digital representation is to the actual analog value. If we go back to the example of applying the analog input to a digital input pin, we find that the digital output could be a 1 or a 0. This is 1 bit of resolution. The digital representation of a 1-bit conversion is either 1 or 0. Assuming the digital input is referenced to 2.5V, any analog input below this will be interpreted as a 0, and any analog input equal to or above this will be interpreted as a 1. In this case, a 1-bit resolution has an accuracy of ±2.5V or 50% accuracy. To get better accuracy, we need to add more bits of resolution.

In reality, an infinite number of bits will never achieve 100% accuracy. But you probably don’t need 100%, so you can get by with fewer than an infinite number of bits. Just how few is up to you. Well…up to you and the manufacturer. 8-, 10- and 12-bit ADCs are fairly standard in today’s MCUs. The Microchip Technology PIC16LF1554 has twin 10-bit SAR ADCs in this 14-pin package. Ten bits of resolution will give you approximately 0.1%. Out of a possible 5V, that’s an accuracy of ±5mV.

The heart of the SAR ADC is the sampling capacitor. The perfect capacitor would be small enough to be internal but able to be charged (and discharged) quickly by the external impedance. For this device, less than 3kΩ is recommended, to allow acquisition in 5µs or less. Many of today’s ADCs offer several analog channels. While multiple analog inputs are available, only one can be connected to the ADC at a time. Note: While this device has twin ADCs and sampling capacitors and can convert two channels at the same time, we’ll only be using one. Once a channel is selected and has adequately charged its internal capacitor (acquisition time), it is disconnected from the source input and conversion can begin. As the name suggests, successive approximation requires multiple comparisons—one for each bit of resolution. In our case, 10 bits required 10 comparisons.

The SAR ADC basically comprises of a comparator and a digital-to-analog converter (DAC). A typical SAR ADC is shown in Figure 2 [1]. The DAC is initialized with Sample = 0V and bit N = 0. For each bit conversion, N is incremented and the DAC set to 1/2N × VCC, plus the previous sample voltage. For an input voltage of 3V, the first conversion will have the DAC set to 1/21 × 5V = 2.5V + 0V. The comparator will see 3V and with a reference 2.5V, output “1” (input is larger than 2.5V). The second conversion will have the DAC set to 1/22 × 5V = 1.25V + 2.5V. The comparator will see 3V and with a reference of 3.75V, output “0” (input is smaller than 3.75V). The 2-bit ADC value is therefore 10. This will continue for eight more conversions, concluding with a 10-bit conversion value. A cool animation [2] shows how the DAC voltage changes for each bit of a 10-bit conversion, based on the input voltage.


Advertise Here

FIGURE 2 – The SAR ADC creates a digital representation of the analog input voltage. The converter’s resolution is determined by its bit size: n-bits.

All living things require food and water to survive and reproduce. Plants use their root structure to retrieve water and the minerals dissolved in the soil, and move this to the rest of the plant via special tissue called xylem. Above the soil, a plant’s leaves manufacture food molecules using energy obtained from light through photosynthesis, and these are transported to the rest of the plant by special tissue called phloem. Water is used during the photosynthesis process, and must be must be replenished. If all the minerals in the soil are used up, plant development will suffer from a lack of food. If the soil becomes dried out, a plant will wither and die. This is what can happen to plants that are not properly watered (and fed). Unfortunately, neglect can happen, and—often before you even notice—it’s too late. If only plants could talk—or at least signal us somehow.

Mind you, it’s not that I want my foliage to suffer. It’s just that I get too wrapped up in other things. So how about giving your green friends a way of signaling when they need attention—in this case when their soil dries out to certain point—enabling an alarm of some kind?

Moisture probes can use conductivity or capacitive polymer sensing. Conductivity probes emit a small electrical charge from one point to another. The amount of resistance correlates to the amount of moisture in the material. Because moisture is a good conductor, higher moisture levels result in lower resistance (or higher conductivity) values, and can be quantified. The biggest disadvantage of the conductive sensor is its tendency to destroy itself. Electrodes must be exposed to moisture, and a potential across them creates electrolysis and oxidation.

Capacitive sensors operate on the electrical characteristics of a capacitor. Because a capacitor is made of two conductive plates isolated from one another by a dielectric, its capacitance varies with a change in the dielectric. Moisture, the soil, and any insulation on your contacts combine to act as a dielectric. This varies with the amount of moisture present. By measuring the capacitance, the moisture level can be quantified, because capacitance is proportional to the dielectric constant. A capacitive sensor does not need to expose its electrode surfaces directly to the environment, so it can be totally waterproofed and will not degrade.

Soil is made up of three kinds of mineral particles in various combinations: clay, silt and sand. Each influences the properties of the soil they make up. This is best demonstrated by Table 1. Whether you are planting in a pot or outside in a garden, you should use the type of soil that will be most beneficial to the flora you are planting.

TABLE 1 – The relative amounts of sand, silt and clay determine a soil’s characteristics, including the amount of water it can hold, drainage rate and ability to store plant nutrients. It is important to match the soil composition to the type of plant you wish to nurture.

A succulent such as a cactus requires a porous, sandy soil that provides plenty of aeration and excellent drainage. A good cactus potting mixture will also contain some organic material that makes moisture available to the plant roots when watered but then dries out quickly. In contrast, asters do not like sandy soil, because it tends to dry out the plants’ roots. They are happier with a greater percentage of clay, which holds moisture well.


Advertise Here

The point here is that a soil with higher proportions of clay will hold water longer, whereas a soil consisting mostly of sand will dry out quickly. These soils and the types of plants in them need different watering schedules. Paying attention to the moisture content and being able to determine when watering is necessary are requirements for those that want to keep their thumbs green.

Earlier I discussed how a capacitor could be affected by moisture content. Moisture directly affects the dielectric, which, if all else remains the same, affects the capacitance. Our MCU’s ADC module uses an internal capacitor to sample an external voltage and to convert the voltage to a digital value. How can this be used to measure capacitance?

Another module available to us in this MCU is the CVD or Capacitive Voltage Divider module. This module lets us perform a relative capacitance measurement, using an ADC channel with the internal ADC sample and hold capacitance as a reference. An external capacitor connected to an analog input forms a voltage divider with the internal capacitor, and this voltage is used to determine the relationship between the two capacitors. To do this, the CVD circuit uses three steps: pre-charge, acquisition and conversion.

Let’s assume for this discussion that the external capacitor is equal to the internal capacitor. We will be working with the relationship between the two capacitance values, and not specific values. The pre-charge action isolates the two capacitors and charges the internal capacitor (ICAP) to the reference voltages (5V). The external capacitor (ECAP) is discharged to 0V. The pre-charging time must be long enough to allow the capacitors to fully charge/discharge.

In the acquisition phase, the two capacitors are placed in parallel. The ICAP‘s voltage will be charging the ECAP. ECAP‘s voltage will rise as it gains a charge, while ICAP‘s voltage will drop as it loses its charge. At some point the charging/discharging will cease, as both capacitors will reach the same voltage. The acquisition time must be long enough to allow equilibrium. If ECAP were tiny compared to the ICAP, it would charge up close to 5V. And if ECAP were huge compared to ICAP, then ECAP would suck almost all of ICAP‘s charge down to almost to 0V. In our example, where ECAP = ICAP, we have a voltage divider made up of two capacitors of equal value. Therefore, the resultant charge is half of 5V, or 2.5V.


Advertise Here

In the conversion phase, the external capacitor is again isolated from the internal capacitor, which holds the sample charge for the ADC. After 10 comparisons, the voltage has been converted into a 10-bit value that equals the sample voltage (±5mV), when multiplied by 5mV (5V/2-10).

The circuitry allows this three-step process to be repeated a second time with opposite pre-charge characteristics. ECAP is charged, and ICAP is discharged. After acquisition and conversion, we have two (differential) results (Figure 3). For the best results, ECAP should be close in value to ICAP when ECAP is dry, which produces a differential voltage around half of VCC (5V/2 = 2.5V).

FIGURE 3 – The solid line shows the voltage on the external capacitor. The dotted line shows the voltage on the internal capacitor. The charges are reversed for the second sample time, essentially providing a differential conversion.

If we can match these when dry, we could have a low differential result. Adding capacitance (dielectric increase) will increase the capacitance value of ECAP and allow it to gain a higher charge from ICAP in phase 1 and lose less charge to ICAP in phase 2. This differential result will be greater than the dry result shown in Figure 4. We will normally have some fixed dry capacitance value for the sensor we choose. To help obtain a closer match to ICAP, this CVD module has additional internal capacitors (2-32pF) that can be programically connected to ICAP.

FIGURE 4 – In this voltage plot, you can see what happens to the conversions when the external capacitor changes value.

We know a capacitor is made up of two plates separated by a dielectric, and we can use two parallel traces that are separated by some nominal spacing. The plate spacing and the dielectric will determine the sensor’s dry capacitance. I have some prototyping board material that have parallel buses, which may make reasonable sensors (Figure 5). These buses measure about 10pF. After attaching a pair of twisted leads (additional parallel capacitance), the total is up to 50pF.

FIGURE 5 – My project prototype is in the center. To its left is a sensor made from a piece of PCB that has vertical buses. To the right is a sensor made from copper foil stuck to a plastic strip. Below is the sensor cut off a commercial moisture circuit (which provided an analog voltage out). Above are three cables I tested– a twisted pair, a shielded conductor and a coax.

I played with various ways to make a sensor, and the best approach by far was to apply a copper foil pattern to a substrate such as a strip of rigid plastic (acrylic or styrene). You can get a roll of adhesive copper in various widths for about $6. With over 50′, you can make plenty of sensors. You will also need some kind of conformal coating to make all of this waterproof. NOTE: If you choose to make some PCBs (etched copper instead of adding copper foil), you will still need to coat the PCB edges, because their exposed edges can allow moisture to wick internally.

Now let’s turn all of this into a useful project. The original idea was to create a project that would monitor the moisture content of soil and send a message when the moisture content fell below a proscribed amount. In essence, our little MCU would communicate alarm conditions to some other device. I wanted to use a serial protocol to keep the interconnections to a minimum. I wanted it to sleep between samples to reduce power consumption. I looked at what that other device might be—maybe the one in the project described in my two-part article “Texting and IoT Embedded Devices” [3]. But I saw that enabling this project’s MCU to sleep wouldn’t help consumption in external circuitry, so I opted for a stand-alone approach. I added a piezo device that can beep an alarm condition.

The circuit I ended up with is shown in Figure 6. Note that there are four moisture sensor channels. Each channel has its own alarm setpoint. Serial debug info is sent serially using TX. An I2C interface allows customizing all of the user registers, and the PWM output drives the piezo device. Let’s begin with a look at what the user can access. Table 2 shows the registers that can be set via the I2C interface.

FIGURE 6 – This project requires very few parts and supports four capacitive sensors. Serial debug data is provided via TX, while a piezo device is driven by the PWM output. Once the PICKit3 debugger is removed, I2C is accessible via those pins. The MCU runs on a single Li-Ion battery.

TABLE 2 – The set of registers that the user can access via I2C. Registers 12-15 reflect the data that is loaded into the CVD module’s control registers. In a perfect world, we would have a Dry conversion value of 0% and a Wet conversion value of 100%. These are conversion values that the user can set—they more closely relate to the actual test values for a Dry/Wet sensor. Writing to the mySave register makes any changes permanent.

Because this project is also the experimentation platform, all pertinent control registers have been duplicated, so they are dynamic. This means that changing any of registers 12-15 directly affects the pre-charge/acquisition/conversion process in real time. If a channel’s flag bit is enabled, the channel is activated. The debug mode gives you the individual conversion values for phase 1, 2 and the differential value, plus control register values. The data mode gives you Channel Moisture Percentage and/or Alarm (if less than the Alarm Percentage for that channel). Beep mode enables the piezo Alarm output for any enabled channel. The Alarm is a quick channel count for that alarm—the highest channel alarm takes precedent. It is repeated once every Sleep Time (second, minute, hour, day).

Early on, I used the Microchip PICKit3 to debug the program using the MPLAB X IDE. I could halt the program and view conversions at any step along the way. Debug data was streaming out the TX pin, but I still had to stop the program to change any registers. Then I remembered last month’s article (Circuit Cellar 358, May 2020) and how the I2C port gave me access to internal registers. In Table 1, I added the code to access the registers. Now I got debug data on the TX line (Figure 7), and with the help of an Arduino, I wrote some code to access the I2C registers in our project’s micro, as shown in Figure 8. Now any parameter could be updated dynamically, and I was ready to test some sensors.

FIGURE 7 – Screenshot showing the output from the Arduino program that displays the present values of register table (Table 1) and allows you to write to those registers. New settings can be permanently saved.

FIGURE 8 – Screenshot showing that channel 0 has been enabled and continually reports its converted and differential values. An alternate function can present either percent moisture or an alarm condition for each channel. The moisture value 0-100% is calculated on the Dry and Wet values as established in register table (Table 1). Each channel can have a separate Alarm value set in that register table.

In Figure 5, you can see many of the sensors and cables I used to connect the sensors to my MCU. The two guard ring resistors on both my project board and in the schematic can be used to set up guard rings around sensor that you would like to use as touch pads. They make the touch pad more sensitive to your finger by helping to cancel noise from around the pad. They were found to be detrimental to our cause here, and were not used. The connections necessary are just ground and sensor. I tried a twisted pair, a shielded conductor and a coax.

First, a few words on the connections. The shielded conductor had the highest capacitance, the coax the least conductance and the twisted pair somewhere in the middle. The coax and the shielded conductor were immune to capacitance loading around the cable, whereas the twisted pair would change capacitance from handling. This shouldn’t be an issue while in operation, since the cables shouldn’t be handled. The cable does add to the sensor (it’s in parallel), so you’re shooting for cable capacitance as low as possible.

I tested all sensor and cable combinations, and found reasonable results from all. With 3′ cables, I was able to see some Wet/Dry differences of over 4× by obtaining conversions where the sensor was either dunked in water or dry in the air. I treated all sensors to a conformal coating before submersing them. Sensors had connectors mounted on them, so I could try different cabling types. When I make a final batch of sensors, they won’t have connectors, so the waterproofing will include the attached cable.

I set the sleep timer to awaken in 1 second. Upon wake-up, the system checks register offset 0 to see how long it should sleep—a second, minute, an hour or a day. This routine will send it back to sleep unless its total wakes equals 1, 60, 3600 or 86400 seconds. Once the total has met its match, we go on to convert all enabled channels. The total ON time for a single enabled channel is 40ms (with the maximum timing register selections). Execution current is less than 10mA. Sleep current can be in the low microamps, if all peripherals are shut off before going to sleep.

I’m hoping that this project will save me from having to replace many of my house plants due to neglect. Once I have my final probes made and I have the best settings selected for the probes used, I’ll need to log some of this data, so I can see how the probes act in different soil types. I suspect I’ll need to set different alarm levels for each probe, depending on the soil type into which each sensor is inserted.

I’ve instituted touch sensors on a few projects now, but this is the first time I’ve used the mechanism for sensing something other than a finger’s touch. The CVD module in this MCU has a lot of flexibility. Creating tools that can dynamically change parameters might actually be more fun than the project itself. You just never know where the path will take you. Too much to do, too little time. 



[1] – White Flye, 2006. Successive Approximation ADC Block Diagram, CC BY-SA 2.5.
[3] Jeff Bachiochi, “Texting and IoT Embedded Devices- Part 1,” Circuit Cellar 332, March, 2018.
Jeff Bachiochi, “Texting and IoT Embedded Devices – Part 2,” Circuit Cellar 333, April, 2018.

Microchip Technology |


Keep up-to-date with our FREE Weekly Newsletter!

Don't miss out on upcoming issues of Circuit Cellar.

Note: We’ve made the Dec 2022 issue of Circuit Cellar available as a free sample issue. In it, you’ll find a rich variety of the kinds of articles and information that exemplify a typical issue of the current magazine.

Would you like to write for Circuit Cellar? We are always accepting articles/posts from the technical community. Get in touch with us and let's discuss your ideas.

Sponsor this Article
 | Website

Jeff Bachiochi (pronounced BAH-key-AH-key) has been writing for Circuit Cellar since 1988. His background includes product design and manufacturing. You can reach him at: or at:

Supporting Companies

Upcoming Events

Copyright © KCK Media Corp.
All Rights Reserved

Copyright © 2024 KCK Media Corp.

Measuring Soil Moisture with ADCs

by Jeff Bachiochi time to read: 16 min