Introduction: Soil Moisture Sensing With the Maker Pi Pico

This project demonstrates using two common hobbyist soil moisture sensors with the Cytron Maker Pi Pico and an optional small OLED screen. One sensor measures the resistance of the soil with a probe using a DC voltage, the other sensor measures the capacitance across two broad PCB traces - these two properties vary with the water content of the soil. The program to output the values from these analogue sensors is written in CircuitPython.

The Maker Pi Pico is a board designed for beginners based on the new, low-cost Raspberry Pi Pico, the first microcontroller from the Raspberry Pi Foundation. The Maker Pi Pico has blue LEDs for all of the GPIO, a small speaker, 3.5mm stereo output, a micro SD card slot, a reset button, three buttons, one RGB LED, a socket for an ESP-01 and six 3.3V Seeed Studio Grove connectors. Advanced users may find the board's Grove connectors and headers useful for rapid prototyping and experimentation.

The board in this article is a sample Cytron kindly sent to me to evaluate. The only difference to the production version is the addition of passive components to debounce the three buttons.

Supplies

Step 1: Connecting Soil Sensors and Optional Screen

The resistive soil moisture sensor has a small control board which connects to the probe. The analogue output voltage is the voltage across the soil from a simple potential divider with the other resistor being 10kohm. This board features a digital output based on a threshold set by the potentiometer which is not used here. The maximum power consumption for this board was measured at 3.03mA with both LEDs on and the probe shorted. This low current allows this particular sensor to be powered by a GPIO pin. The current limit for each output on the RP2040-based Pi Pico are not clear but 10mA is a reasonable conservative guess at a maximum.

If you are using a different sensor check its data sheet or measure the current with the two electrodes shorted to ensure it's below 10mA before using GPIO to power it.

Three female to female jumper wires are needed to connect the control board to the Maker Pi Pico:

  • VCC - GP16 (red) or use 3V3 for higher current sensors,
  • GND - GND (black),
  • D0 - not needed, leave unconnected,
  • A0 - GP26 (blue).

The capacitive soil moisture sensor plugs into the Maker Pi Pico's GROVE 6 connector which provides the following connectivity:

  • SIG - GP27 (yellow),
  • NC (not connected) - GP26 (white),
  • VCC - 3V3 (red),
  • GND - GND (black).

It's important to verify the capacitive sensor does not use the white wire since GP26 is already in use for the resistive sensor.

The Pi Pico only has a relatively low number of ADC capable pins for a microcontroller: GP26, GP27 and GP28. The Maker Pi Pico has the data input for the WS2812B RGB LED connected to GP28. The GP28 pin can still be used as an analogue input but not at the same time as the RGB LED.

If you have the optional i2c-based screen then connect this to the Maker Pi Pico's GROVE 1 connector or connect with four wires:

  • SCL - GP0 (white),
  • SDA - GP1 (yellow),
  • VCC - 3V3 (red),
  • GND - GND (black).

The order of pins on the screen is not standard and may vary from the one in photographs. These screens appear to have onboard 10k pull-up resistors for the i2c bus lines which is likely to be sufficient. The GP0 and GP1 LEDs should both illuminate if the i2c bus is healthy. An idle i2c bus has both lines high and data transfers will show up as small fluctuations of brightness.

Step 2: Installing CircuitPython and Soil Moisture Measurement Example Program

If you are not familiar with CircuitPython then it's worth reading the Welcome to CircuitPython guide first.

  1. Install the latest version of CircuitPython (6.2.0-beta.3 on March 2021) from https://circuitpython.org/ - this process is described in Getting Started with Raspberry Pi Pico and CircuitPython. The access to the bootloader mode is slightly different on the RP2040-based Pi Pico compared to other boards running CircuitPython, the BOOTSEL button must be held down as it's connected to USB - the RPI-RP2 drive will then appear.
  2. Verify the installation by connecting to the serial console over USB. The REPL prompt shows the version number. The version can also be checked by inspecting the boot_out.txt file on the CIRCUITPY drive.
  3. Install these libraries from a recent bundle from https://circuitpython.org/libraries into the lib directory on CIRCUITPY:
    1. adafruit_bus_device
    2. adafruit_display_shapes
    3. adafruit_display_text
    4. adafruit_displayio_ssd1306.mpy (not adafruit_ssd1306.py)
    5. neopixel.mpy
  4. Download the example program to CIRCUITPY by clicking Save link as... on soil-moisture.py
  5. Rename or delete any existing code.py file on CIRCUITPY, then rename the soil-moisture.py to code.py. This file is run when the CircuitPython interpreter starts or reloads.

The versions used for this article were:

  • CircuitPython: 6.2.0-beta.3
  • CircuitPython library bundle: adafruit-circuitpython-bundle-6.x-mpy-20210225.zip

Step 3: Example Program

The example program can drive an SSD1306 compatible screen. The one shown above is a split monochrome display, the top quarter has yellow LEDs, the rest are cyan.

The buttons on the Maker Pi Pico have the following functions:

  • left - toggles between linear and data fit model for percentage calculation;
  • middle - toggles Mu plotter compatible output to serial console;
  • right - toggles showing the raw ADC values between 0 and 65535 (the photograph above shows these).

The capacitive value is updated approximately every half second, the resistive value is only updated on every twentieth loop to reduce electrolytic effects.

The linear model uses the following values:

  • resistive 65535 (dry) to 10000 (wet);
  • capacitive 38000 (dry) to 22000 (wet).

These can easily be adjusted in the Moisture class for your sensors and soil. The origin and usefulness of the data fit model is described on next page.

The RGB LED on the Maker Pi Pico is used to indicate the moisture level. It takes the more extreme of the two values and uses the following colour scheme:

  • flashing red - 20% or less;
  • red - 21-35%;
  • orange - 36-45%;
  • green - 46%-79%;
  • magenta - 80% or more.

For a real application those values would need to be tailored to the plants and soil.

Step 4: An Attempt at Soil Moisture Calibration

Some garden compost was dried in a low oven for a few hours and then placed into a dry pot with a volume around 780ml (26.5 fl. oz.). The two soil sensors were inserted into the soil 75mm (3in.) apart. The room-temperature tap water was added in 10ml (1/3 fl oz.) increments every ten minutes by dripping it onto the surface of soil with most in the middle of the pot but some around the edges too. The graphs shown above were created from manual recording of the ADC values shown on the small screen. The resistive graph uses error bars to indicate how the value dramatically dropped as the water was added and then quickly climbed back up to a stable value as the soil became sodden. Water seeped out of the drainage holes in the pot at 290ml.

Observations and thoughts:

  • Soil is very unlikely to get as dry as the starting point particularly for house plants. This probably made the soil overly dense too.
  • The values for 0-40ml would probably be lower if more time was allowed for the water to spread evenly into the soil, although very dry soil is likely to be hygroscopic to some extent further complicating things.
  • The seating of the sensors in the soil makes has a large effect on the output value, more so on the resistive sensor. Nudging them or re-inserting them can radically change the value.
  • The resistance value drops slightly if the polarity of the resistive sensor is reversed and then it climbs back to original value over a few minutes. This suggests a small degree of electrolysis is taking place in the nearby soil.
  • The sensors do not appear to affect each other at this separation distance.
  • Soil type has a significant effect on the output value. This was noted later with the soil which came with the rosemary plant.
  • The presence and activity of roots would change the output value.
  • Plants in pots might use perlite and vermiculite to regulate moisture. Bark, mulch and straw might be used for outside plants. These must have some effect on the output value.
  • Capacitive sensors tend to have pcb tracks on one side only. This is likely to cause them to be more sensitive on that side. They are best inserted facing the bulk of the soil and not close-up, facing the side of the pot.

Water has the the following conductivity in microsiemens per centimetre (resistivity in megaohm-centimetres) at 25 degrees Celsius from Hanna Instruments: Conductivity/TDS Meters Introduction:

  • Pure water: 0.055 (18.18)
  • Typical deionised water 0.1 (10)
  • Distilled water 0.5 (2)
  • Rain water 50-100 (0.02 - 0.01)
  • Drinking water 500-800 (2-1.25 kohm-cm)
  • Potable water (max) 1.055 (0.95 kohm-cm)

The presence of electrolytes in water affects its conductivity, the minerals in tap water cause a noticeable increase compared to rain water. Fertiliser (plant food) will have a further effect on this.

This attempt at calibration is less useful than it may appear in terms of trying to provide calibration curves for the sensors. However, it does suggest the capacitive sensor is more likely to produce reliable values. This is confirmed by the Meter Group's (previously UMS and Decagon Devices) Soil moisture sensors - How they work. Why some are not research-grade. article.

Step 5: Resistive Sensor Electrode Corrosion

The voltage used by a resistive sensor causes some degree of electrolysis over time which hastens corrosion shortening the life of the electrodes, particularly the anode. The photographs above of a matching probe from a Raspberry Pi Stack Exchange question and different model from http://homecontrols.ch/gardening.php. This is undesirable in terms of:

  • sensor lifetime,
  • deterioration in the quality of measurements and
  • the transfer of unknown metals of unknown purity into the soil where they may end up in the (edible) plants.

This can be minimised by only powering the sensor for short periods. If the polarity on the two-pronged sensor can be swapped over periodically this would help a little to extend the life of the sensor. The sensors with ENIG gold-plating will last a little longer but as can be seen this plating process is still not good enough to prevent corrosion of the electrodes.

The capacitive sensors appear far superior in terms of corrosion because their design does not require exposed metal allowing the solder mask layer to protect the top and bottom surfaces. Seeed Studio mentions this on the page for their resistive sensor (operating current 35mA):

This sensor is not hardened against contamination or exposure of the control circuitry to water and may be prone to electrolytic corrosion across the probes, please use it for PROTOTYPING ONLY. We also offer Grove - Capacitive Moisture Sensor with corrosion resistance.

Step 6: Sensor Reaction Time to Watering

The time-lapse video above shows how the two soil moisture sensors react to watering. The capacitive sensor reacts at about 14 minutes after watering, the resistive sensor takes 34 minutes.

This is the second attempt using watering from the bottom of the plant pot to give more even absorption across the soil. The resistive sensor's probe is shorter than the capacitive one making the comparison a little unfair. However, the resistive sensor in the first attempt took over an hour to register a difference with slow, gradual watering from the top so the length is not the only factor.

Step 7: Going Further

Here are some ideas for areas to explore once you're setup to measure your soil moisture.

Further reading.