How to Use a Soil Moisture Sensor to Keep Your Plants Alive
Every good plant mom (or dad) knows there are two important things to keep your indoor plants alive: light and water. The balance of getting the right amount of these two things is like walking a tight rope. As the type of millennial who accidentally kills succulents on the regular, I needed to find a way to keep my plants alive.
I like to add technology to all aspects of my life, so I thought how can I monitor my plants so I stop killing them? I’ve written tutorials about monitoring temperature before so why not try light and moisture. After a quick Adafruit search, the sensors I needed were in the mail. The next thing I had to do was get more information about how to take care of the plants I own.
Each plant requires different amounts of light and water. You can easily find information about how much light is required for your specific plant online. Indoor plants can range from low light to bright light. My house only gets low to medium light at best. It’s important to know what lighting your home has and to pick plants that will fit your lighting situation.
You now should know your plant and know how much sun it needs. How can you determine whether it is getting enough light? If your plant’s leaves are dark, have bleached patches, or are dried out, your plant may be getting too much sun. You need to move it to a shadier location. If your plant has small pale leaves or weak stems, it may be getting too little sun. You’ll need to move it to a sunnier location. Seems simple enough.
Now on to water. If your plant’s leaves are yellow and softening, you may be watering it too much. In this case, you should water it less. If your plant has brown, crispy leaves or the leaves falling off, your plant is too dry. The good rule of thumb I’ve been told is to check the soil with your finger. If the soil is wet or damp, you don’t need to water it. If the soil is dry it needs to be watered. The amount of water you need varies for each plant. The soil type shouldn’t matter that much.
This all seems very simple, yet somehow my plants keep dying. This project has fixed that! I found a way to measure soil moisture and ambient light. I’ll detail how I put this project together, how I remotely monitor my plants, and how this simple solution gave me a green thumb.
What You’ll Need
This is a list of what I used for this project:
- (2) Raspberry Pi Zero WH ($14 each) with power chargers ($7.50 each)
- (2) SD Card with NOOBS ($14.95 each)
- Adafruit STEMMA Soil Sensor — I2C Capacitive Moisture Sensor ($7.50)
- Adafruit BH1750 Ambient Light SensorLight sensor, soil moisture sensor ($4.50)
- STEMMA QT / Qwiic JST SH 4-pin Cable with Female Sockets ($0.95)
- JST PH 4-Pin to Female Socket Cable — I2C STEMMA Cable ($1.50)
- Initial State — or any data visualization platform ($9.99/mo)
For this design, I am using Raspberry Pi Zero WH, because they are inexpensive and the header is pre-soldered. A Raspberry Pi 3 or 4 could be used, it would just be overkill. The only issue with the Raspberry Pi Zero WH is it can sometimes be hard to find and there is usually a purchasing limit of 1 per order due to manufacturing limitations.
This design doesn’t make sense to replicate for all my indoor plants. That would be too costly and repetitive. The plan would be to monitor a single plant for 1–2 months until I got the right balance of sun and light and then move the setup to the next plant.
You’ll want a keyboard and monitor to be able to easily get your Pi’s up and running. I have some that I use to get every Pi I buy started. Some of my Pi’s are actually connected to monitors always and others I just connect to set them up and reuse the keyboard and monitors when needed.
I used a Raspberry Pi 3 as one of the Pi’s because I have one constantly connected to a monitor. This lets me put my dashboard on the monitor for a constant view of my data. This setup is a little over the top for what we are doing, but I really love the dashboard view on the Pi monitor.
Hardware
You’ll need to connect your Raspberry Pi’s to their respective sensors. This is easily done if you purchased the two cables in the material list or using female to female jumper wires.
To connect your Pi to the soil sensor, you’ll need to connect the following pins:
- Pi GND to sensor GND (black wire)
- Pi 3V3 to sensor VIN (red wire)
- Pi SDA to sensor SDA (white wire)
- Pi SCL to sensor SCL (green wire)
To connect your Pi to the light sensor, you need to connect the following:
- Pi GND to sensor GND (black wire)
- Pi 3V to sensor VCC (red wire)
- Pi SDA to sensor SDA (blue wire)
- Pi SCL to sensor SCL (yellow wire)
The connections will be slightly different for the BH1750 if you are using jumper wires and a soldered header versus the female socket cable pictured above. If you are using this alternative setup, your connection is as follows:
- Pi 3V to sensor VCC (red wire)
- Pi GND to sensor GND (black wire)
- Pi SCL to sensor SCL (yellow wire)
- Pi SDA to sensor SDA (blue wire)
My preference is to always use cables vs having to solder a header. Soldering the header onto these small devices can be hard if you aren’t well-practiced with soldering. They say practice makes perfect so maybe give it a try.
Test Your Sensors
For this project, I am using Python 3. You’ll need to have that downloaded and set as your default Python version on your Raspberry Pi. I followed these instructions to install Python 3 on my Pi’s and it went really well (just took a while to download it all).
Both sensors require I2C to be enabled on your Pi’s. You can do this one of two ways. One way is to go to your Raspberry Pi Configuration on your monitor, enable I2C, and reboot your Pi.
The other way is to type this into the command prompt:
sudo raspi-config
Select 5 Interfacing Options
, P5 I2C
, and select <YES>
to enable i2c. Select <Finish>
to save and exit. You can test out the connection to the sensor. On your Pi type the following in the command prompt:
sudo i2cdetect -y 1
You should see something like the following:
The sensor is detected on a Pi at address 0x76. This should show your sensor at address 0x76 (possibly address 0x77). If you don’t see either, check your wiring, make sure i2c is enabled in raspi-config
, and reboot.
*You may need to install pip if your Python version does not have it preinstalled.
sudo apt install python-pip
Next, you’ll need to add three Adafruit libraries & the Initial State Streamer Module to get the sensors working and stream our data. The first is the Blinka library. This provides CircuitPython support in Python.
$ pip3 install adafruit-blinka
The second is the library for the soil sensor
$ sudo pip3 install adafruit-circuitpython-seesaw
The third is the library for the light sensor
$ sudo pip3 install adafruit-circuitpython-bh1750
The last one is the Initial State Streamer Module
$ sudo pip3 install ISStreamer
Once those are installed we can test each sensor accordingly.
To test the soil sensor, created a python script called soil_simpletest.py. Copy and paste the code below (from Adafruit’s tutorial) into the script, save, and exit the text editor.
To run the script type:
$ python3 soil_simpletest.py
You will see soil moisture (amount of water in the soil) values and temperature values if it is connected properly.
On your other Pi, you can test the BH1750 sensor. Create a script called bh1750_simpletest.py. Copy and paste the code below (from Adafruit’s BH1750 tutorial) into the script, save, and exit the text editor.
To run the test script type:
$ python3 bh1750_simpletest.py
You will see lux values if the sensor is connected properly.
Initial State
We have data but now we want to monitor that data. I think Initial State is a great solution for that, but you can choose to use any data visualization platform. This tutorial will show you how to use Initial State but you can modify the code to send data to any platform of your choosing.
Initial State is a data visualization software that can be used for real-time data monitoring and historical data evaluation. It offers a free tier for students with an active Edu email address, an individual tier for hobbyists and prototypers for $9.99/month, and an enterprise tier for businesses starting at $20/month. Every account is given a 14-day free trial to test out all features and functions on the platform.
Once you register for an account, you can go to your settings and view your access keys. An access key allows you to send data into your account. You’ll use your access key in the Python script later in the article.
Stream Data with Python
You’ve connected your hardware, tested your sensors, and chosen your data platform. Now we can stream data from your Pi’s and sensors to Initial State and create dashboards from that data.
For your Pi connected to the soil sensor, you will use the code below. Create a python script called is_soil.py and copy and paste the code below. You’ll need to make a few changes that I have detailed below before it is ready to be run.
For the Pi connected to the light sensor, you will use the code below. Create a python script called is_ambientlight.py and copy and paste the code below. You’ll need to make a few changes that I have detailed below before it is ready to be run.
In both code scripts, you can modify the lines in the User Settings area.
- SENSOR_LOCATION_NAME — This helps you identify which sensor you are streaming data from.
- BUCKET_NAME — This names your bucket and should be the same for both scripts.
- BUCKET_KEY — This is an identifier telling Initial State what data bucket you want to send data to. This should be the same for both scripts.
- ACCESS_KEY — You can find your Initial State access key by going to the settings page on your account. This should be the same for both scripts.
- MINUTES_BETWEEN_READS — This is how long you want to script to wait until it reads from the sensor again.
By making your access key and bucket key the same for each script, you will be streaming both sensors’ data in the same bucket.
To run the soil sensor code type:
$ python3 is_soil.py
To run the ambient light sensor code type:
$ python3 is_ambientlight.py
IP Address
I will always recommend sending the IP address of your Pi to your dashboard. This makes life easier so that if something goes awry, you can easily SSH into your Pi and get it resolved. No additional hardware is required, just another Python script to run in the background. You can stream the IP address to the same bucket as your plant data.
Auto-Run on Reboot
This is an important step in the process. If you set your Pi sensor code to run on reboot then if you lose power and it comes back, your code will start to automatically run when the Pi restarts. This can save you some time and heartache. Trust me.
In the Pi terminal type:
crontab -e
If this is the first time you have run crontab, it may ask you which text editor you want to use (I selected nano). Add the following line to the bottom of the crontab text file then save and exit:
@reboot nohup python3 /home/pi/plantmonitor/is_soil.py &
or:
@reboot nohup python3 /home/pi/plantmonitor/is_ambient.py &
You will need to specify the exact path of your script. Mine is kept in a folder called “plantmonitor.”
The nohup
command is important. This stands for “no hangup” and allows you to create a process that runs in the background without stopping, even if your terminal window is closed. If you run your script from an SSH prompt without the nohup
command, the script will exit as soon as your SSH connection is broken.
Plant Dashboard
You’ve got everything connected and your code is running, now it’s time to play with the data!
Soil Moisture Values
The soil sensor uses a capacitive touch measurement system to determine soil moisture. The soil moisture level can range from 200 (very dry) to 2000 (very wet). You can set the min and max on your gauge tile to these values.
Temperature Values
The soil sensor also has an internal temperature sensor that gives you ambient temperature readings. It is not highly accurate but can give you readings with +/- 2 degrees accuracy. It is a nice addition to be able to add this data to your dashboard.
Ambient Light (Lux) Values
The ambient light sensor measurements are in units of Lux (the SI unit of measurement for light. The sensor can measure from 0.0001 lux (moonless, overcast night) to 65,000 lux (direct sunlight). Plants that need low light can survive on the lower level of this range and plants that need direct light need the upper level.
Tiles
You have three data streams in your dashboard: temperature, ambient light, and moisture. I made three rows for each of the signals and made a pattern: summary tile, gauge tile, and line graph. For temperature I use the thermometer gauge tile, for moisture I use the liquid level gauge tile, and for ambient light, I use the arc gauge tile.
I specifically designed this dashboard to fit well on my Raspberry Pi monitor. I created duplicated views for my desktop and mobile with a different arrangement of tiles and additional tiles included.
Background Image
Initial State allows you to choose a background image from Unsplash, specify a background color, or upload a custom background image. This gives you limitless possibilities for dashboard creation. I searched for an indoor plant and choose an Unsplash image for mine.
Mobile
Another good view to create for your dashboards is a mobile view. It’s easy to duplicate your dashboard and create a specific design that looks good on your phone and shows you all the necessary information in one small window.
All you need to do is stack your three signals in tiles in a column and set the tiles to the gauge types you want. This will make it so when you open your phone to view the dashboard you will have a compact view like the one you see here.
Weatherstack Weather
Not only can you have light, temperature, and plant moisture data in your dashboard, you can also stream in local weather data through the Weatherstack Integration in the Initial State Integration Marketplace. All you have to do is set up the integration with your zip code or coordinates and you can stream temperature, cloud cover, and current forecast. All these things will affect how much ambient light your plant is getting.
Bucket Watchdog
If you have your Pi processes set up to run on reboot, you are good to go if your Pi restarts. But what happens if your Pi has an issue and shuts off completely? You’ll want to know if your dashboard stops receiving data so you can get it fixed quickly. The Bucket Watchdog Integration in the Initial State Integration Marketplace can monitor the signals sent to your bucket and alert you if it receives fewer signals than anticipated.
This project is slowly helping me with my plant mom skills. My goal is to kill slightly fewer plants this year now that I can monitor how much light and water they are getting. I encourage you to give this project a try and let me know how it goes!