Plant Watering Robot with a Raspberry Pi
Building a useful robot doesn’t have to require complicated code or expensive equipment. With a Raspberry Pi and some cheap, basic hardware, you can keep your plants healthy and happy from anywhere in the world!
Follow this tutorial to learn how to set up an automatic plant watering system:
- Complete the physical assembly and wiring.
- Create and connect to the robot, and configure your robot’s components.
- Configure the ADC as a module from the registry.
- Write code utilizing the Viam Python SDK to control the plant watering robot.
You can also follow a simplified version of this tutorial in this video: it eliminates the need for the ADC and the breadboard, instead using the digital pin of the moisture sensor to get “high” and “low” readings and to turn a relay on and off. You can start with this simple version and then add the ADC to make your machine more accurate!
The tutorial uses the following hardware, but you can adjust it as needed:
- A Raspberry Pi 3B or 4B with SD card and 5V USB power supply
- A resistive soil moisture sensor
- A 5V mini water pump with clear vinyl tube
- A MCP3008 ADC
- A one channel relay switch
- A breadboard
- Assorted breadboard jumper wires, including two splicing connectors
- A planter box or flower pot
- A water container
- A screwdriver
Before starting this tutorial, follow the Raspberry Pi Setup Guide to prepare your machine to run viam-server
.
Connect your Pi to its power supply to power it on.
Make sure your Pi is flashed with a Viam-compatible operating system, and that you are able to SSH into it.
Set up your plant watering robot
Before programming the machine, you need to physically set up the plant watering robot by wiring the different components together. You will set up the robot to receive signals from the resistive soil moisture sensor and signal to the peristaltic pump when it is time to pump water from the water container to the plant container.
Full wiring diagram
Refer back to this diagram as you complete the steps to wire your hardware. Turn your Pi off while you are wiring the hardware.
Wire your ADC
The analog-to-digital converter (ADC) converts the resistive soil moisture sensor’s analog readings to digital signals that can be processed by your machine, which expects digital signals to come to it through its GPIO pins.
Start by wiring your ADC to your machine.
You can find a Raspberry Pi pinout diagram at pinout.xyz. Reference the following pinout diagram for your MCP3008 analog-to-digital converter:
Tip
The half circle shown in the pinout diagram above should be physically present on your ADC. Use this to orient the ADC to determine the location to insert your wires.
Insert the MCP3008 into your breadboard so that it bridges both sides of the divide. Now you can use the breadboard points next to the MCP3008 to connect pins on the MCP3008 to your Raspberry Pi and other peripherals using jumper wires. Begin by connecting MCP3008 pins to your Raspberry Pi:
MCP3008 ADC Pin | Raspberry Pi Pin |
---|---|
CLK | SCLK |
DOUT | MISO |
DIN | MOSI |
CS/SHDN | 24GPIO8 |
Next, connect MCP3008 pins to the ground and power rails on the breadboard:
MCP3008 ADC Pin | Breadboard |
---|---|
VDD | Any point on 5V power rail (red +) |
VREF | Any point on 5V power rail (red +) |
AGND | Any point on GND rail (blue -) |
DGND | Any point on GND rail (blue -) |
Finally, connect your breadboard rails to 5V power and ground on the Raspberry Pi:
Breadboard rail | Raspberry Pi pin |
---|---|
Any point on 5V power rail (red +) | Pin 4 (a 5 volt power pin) |
Any point on GND rail (blue -) | pin 34 (a ground pin) |
Wire your resistive soil moisture sensor
Next, wire your resistive soil moisture sensor to your Pi and ADC.
Reference this diagram of the blue module part of the sensor:
Start by connecting the female jumper wires at the end of the sensor prongs to the blue module where the diagram shown above is labeled “Connect with Probe.” Be careful of the positive and negative sides, and make sure to match them correctly.
Then, wire the rest of the pins on the module to the breadboard as follows:
Moisture Sensor Pin | Breadboard |
---|---|
A0 (Analog Signal Output) | CH0 |
VCC | Any point on 5V power rail (red +) |
GND | Any point on GND rail (blue -) |
Put the soil moisture sensor inside of the container holding your plant.
Wire your pump
Now, wire and power your pump and relay module to complete your hardware setup:
- Use a splicing connector to connect your 5V pump motor’s positive wire to a jumper wire, and connect it to the NO pin on the relay module. NO stands for normally open, which will keep the circuit open unless the pin is triggered.
- Use a splicing connector to connect your 5V pump motor’s negative wire to a jumper wire, and connect it to pin 39 (ground) on the Raspberry Pi.
- Connect the COM (common) pin on the relay to pin 2 (5V) on the Pi.
- Connect the DC+ pin on the relay to pin 1 (3.3V) on the Pi.
- Connect the DC- pin on the relay to pin 14 (ground) on the Pi.
- Connect the IN pin on the relay to the pin 8 (GPIO 14) on the Pi.
Tip
To complete the steps, insert the ends of the jumper wires into the pin gates on the relay module and tighten the screws on these gates with your screwdriver to close the wires inside.
Program your plant watering robot
Enable SPI on your machine
Now that you have wired your ADC and moisture sensor, make sure that the Serial Peripheral Interface (SPI) is enabled on your machine. This protocol allows your machine to communicate with the moisture sensor peripheral.
Turn your machine back on. SSH into your machine and run the following command:
sudo raspi-config
Once the raspi-config
interface is open, navigate to Interface Options:
Then, select SPI:
Now, select Yes to enable SPI:
Finally, select Finish.
Restart your machine using sudo reboot
to make these changes take effect.
Configure the components of your robot in the Viam app
Add a new machine in the Viam app.
On the machine’s page, follow the setup instructions to install viam-server
on the computer you’re using for your project.
Wait until your machine has successfully connected to the Viam app.
Then, navigate to the CONFIGURE tab of your new machine’s page in the app.
First, add your machine as a board component:
Click the + icon next to your machine part in the left-hand menu and select Component or service.
Select the board
type, then select the appropriate viam:raspberry-pi:pi
model (for example, viam:raspberry-pi:pi4
for Raspberry Pi 4).
Enter a name for your board and click Create.
This tutorial uses the name local
.
{
"components": [
{
"name": "local",
"model": "pi",
"api": "rdk:component:board",
"attributes": {},
"depends_on": []
}
]
}
Configure the ADC as a module from the registry
Resources refer to the different components and services Viam provides for robots to use.
Components refer to types of hardware, and each component’s built-in models
support the most common models of this hardware.
For example, the sensor component has an ultrasonic
model built in for the ubiquitous ultrasonic sensor.
However, there are many different types of sensors used for sensing different things across the Internet of Things. Although the resistive soil moisture sensor is not currently one of Viam’s built-in models, you can add an analog-to-digital-converter (ADC) as a module and use it to get readings from the moisture sensor.
A module provides one or more modular resources, which add resource types (components and services) or models that are not built into Viam. A module can be added to your robot from the Viam Registry.
The Viam Registry allows hardware and software engineers to collaborate on their robotics projects by writing and sharing custom modules with each other. You can add a module from the Viam Registry directly from your robot’s CONFIGURE tab in the Viam app, using the + (Create) button.
To add the mcp300x-adc-sensor module to your robot, follow these steps:
Go to your machine’s CONFIGURE tab. Click the + icon next to your machine part in the left-hand menu and select Component or service.
Search for
mcp300x
and selectsensor / mcp300x
. Click Add module.Give your module a name of your choice. We used the name
sensor
.Click Create to add this module to your machine.
Find your module’s card on the CONFIGURE page. Copy the following JSON object into the configuration field.
{ "channel_map": { "moisture": 0 }, "sensor_pin": 8 }
sensor_pin
is the GPIO pin number of the machine’s pin you connected to the MCP300x chip. If you followed the wiring in this tutorial, this will be8
which is pin 24, GPIO 8 (SPI Chip Select 0). Otherwise if you are using CS1, use7
.
Save your config by clicking Save in the top right corner of the page.
On the sensor configuration panel, click on the TEST area to confirm you can get readings from your sensor.
This module allows you to get multiple readings at the same time from different channels of the ADC sensor.
If you wire and configure another sensor, such as a temperature sensor on channel 1, you can add the sensor to the "channel_map"
and get a reading from it.
Info
If you would like to see how the module works, you can find its code on GitHub.
Now that you have set up your robot, you can put the suction tube of your pump into the water cup, and the output tube into the plant!
Install the Python SDK
Make sure any packages on your Pi are up to date, while connected to your Pi with SSH run:
sudo apt update
sudo apt upgrade
Then run the following command to create and activate the virtual environment: If you want to read more on virtual environments, check out the documentation.
python3 -m venv .venv
source .venv/bin/activate
Make sure you have pip
installed for Python 3:
pip --version
If not, run the following command:
sudo apt install python3-pip
Run the following command to install the SDK:
pip3 install viam-sdk
Add Python control code
Follow these instructions to start working on your Python control code:
Navigate to your machine’s page in the Viam app, and click on the CONNECT tab and the Code sample page.
Select Python as the language.
Follow the instructions shown under step 1 on that page to install the SDK.
Then, under step 2 on that page, click the copy icon to copy the generated code sample, which establishes a connection with your robot when run.
To show your machine’s API key in the sample code, toggle Include API key.
Caution: Keep your API key and machine address safe
We strongly recommend that you add your API key and machine address as an environment variable. Anyone with these secrets can access your machine, and the computer running your machine.
Paste this code sample into a new file on your machine.
Name the file
plant-watering-robot.py , and save it.
Run the following commands on your machine to create and open the file:
source .venv/bin/activate
touch plant-watering-robot.py
nano plant-watering-robot.py
Now, you can add code into
To start, add your system logic code into the main()
function of the program.
Use the Viam board and sensor API methods to read from the moisture sensor and control the pump’s voltage with PWM as a GPIO pin.
You can get your components from the robot like this:
# Note that this name, `sensor`, is defined when you add the mcp300x module
sensor = Sensor.from_robot(robot=robot, name='sensor')
# Note that this name, `local`, is defined when you add the board
local = Board.from_robot(machine, "local")
Then, add a control loop that runs continuously, similar to the following example:
while True:
# this level depends on your specific setup, replace after testing
is_not_moist = 600
# Get the moisture sensor's readings
readings = await sensor.get_readings()
soil_moisture = readings.get('moisture')
# Calculate the average moisture reading from the list of readings
# to account for outliers
avg_moisture = sum(soil_moisture) / len(soil_moisture)
# If the average moisture reading indicates moisture, trigger pump
# watering
if (avg_moisture > is_not_moist):
print('this plant is too thirsty! giving it more water')
# Get the GPIO pin with PWM output (pin number 8) the water pump is
# wired to on the board through the relay's IN wire
pwm_pin = await local.gpio_pin_by_name(name="8")
# Run the water pump
# Set the duty cycle to .8, meaning that this pin will be in the
# high state, powering the pump motor, for 80% of the duration of the
# PWM interval period
await pwm_pin.set_pwm(duty=0.8)
# Wait for 15 seconds
print('watering')
time.sleep(15)
# Stop the pump by setting the duty cycle to 0%
await pwm_pin.set_pwm(duty=0.0)
# Wait 60 seconds so that the water can soak into the soil a bit before
# trying to water again
print('waiting a little bit for the water to soak in')
time.sleep(60)
Tip
Make sure to import time
at the top of sleep()
!
Test motor
On your machine’s CONTROL page in the Viam app, expand the TEST card for your board component. You should see a panel that allows you to control individual GPIO pins.
Enter 8
as a GPIO number. Set a decimal value between 0 and 1, (for example 0.8), to activate the motor and begin pumping water. Set a value of 0 to turn the motor off and stop pumping water.
Test moisture sensor
On your machine’s CONTROL page in the Viam app, expand the TEST card for your sensor to see a live observed value from your moisture sensor.
Test your sensor by putting it in air, water, and soils containing different amounts of moisture.
Use these observed values to determine an appropriate is_not_moist
value for your setup.
Save control code
Save
sudo python3 plant-watering-robot.py
Next steps
Now that you have created your automatic plant watering system with a resistive soil moisture sensor, you can easily use Viam to automate other aspects of your garden. For example, you can use a light sensor or a temperature sensor, and get readings from other channels of the MCP3008!
You could set up data capture and graph your sensor data, or create your own custom Typescript dashboard to display your sensor data.
If you build something based on this please share it in our Community Discord - we’d love to see it.
Was this page helpful?
Glad to hear it! If you have any other feedback please let us know:
We're sorry about that. To help us improve, please tell us what we can do better:
Thank you!