Skip navigation

Raspberry Pi Projects - How does your IoT garden grow?

Join Les Pounder as he works on his IoT Garden! Watch him integrate technology into his garden and maintain the health of his favorite plants.

Check out our other Raspberry Pi Projects on the projects homepage

Previous Part
All Raspberry Pi Projects
Next Part

Can our garden water itself?

In this project we continue our search to keep our garden well watered, but this time we start fresh with a new project...A self watering garden!


Re-using some of the kit from Project 1, in this project we introduce relays, 12V circuits and peristaltic pumps that will water our garden based on the soil moisture sensor from Project 1. All we need to do is keep a water butt full of water, either through rain or grey water collection!




For this project you will need


Building the hardware

Aside from our Pi Zero W, the main player in this project is the Rasp.IO Analog Zero board, which provides us with an analog to digital converter, the MCP3008. Yes you can buy the chip on its own for only a few dollars / pounds, but the Analog Zero board is a convenient form factor that offers a “less wires” alternative.

The main sensor we are using is a simple soil moisture sensor from Velleman. The moisture sensor is a simple analog sensor which connects to the 3V and GND pins on the Analog Zero and the output of the sensor is connected to A0. The output from the sensor is in the form of a voltage from 0V to 3.3V (as we are using the 3.3V power from the Pi Zero GPIO) if there is no conductivity, i.e the soil is dry then no voltage is conducted, if the soil is wet then the soil will most likely conduct all of the voltage.


The other part of the project is a relay, used to control the 12V circuit for our peristaltic pump which will pump water from a water butt to our plants using a rotating motion to “squeeze” the water through the connected plastic hose. The relay is controlled from the GPIO of our Pi. In this case we connect the relay to 3V, GND and the Input of the relay to GPIO17.


The Analog Zero will take a little time to solder, and we shall also need to solder the pins for I2C and solder the 3V and GND pins for later. Once soldered, attach the Analog Zero to all 40 pins of the GPIO and then connect the sensor and relay board as per the diagram. You will also need to provide the 12V power supply to the peristaltic pump. The + connection from the 12V supply goes to the relay, via the normally open connection, the icon looks like an open switch.




Build the project so that the wiring is as follows.




Now connect up your keyboard, mouse, HDMI, micro SD card, and finally power up the Pi Zero W to the desktop. You will need to setup WiFi on your Pi Zero W, and make a note of the IP address for future use. Now open a terminal and enter the following command to configure SPI connection.




sudo raspi-config



Yes we can use the GUI “Raspberry Pi Configuration” tool found in the Preferences menu, but having raspi-config available to us over an SSH connection is rather handy should we need it.



Once inside raspi-config, we need to navigate to “Interfacing Options” then once inside this new menu go to the SPI option and press Enter, then select “Yes” to enable SPI. While not strictly necessary, now would be a great time to reboot to ensure that the changes have been made correctly. Then return to the Raspbian desktop. With the hardware installed and configured, we can now move on to writing the code for this project.


Writing the code

To write the code for this project we have used the latest Python editor, Thonny. Of course you are free to use whatever editor you see fit. You will find Thonny in the Main Menu, under the Programming sub-menu.


We start the code for this project by importing two libraries. The first is the GPIO Zero library, used for simple connections to electronic components. In this case we import the MCP3008 class for our Analog Zero board and then we import DigitalOutputDevice, a generic class to create our own output device.


from gpiozero import MCP3008, DigitalOutputDeviceimport time



Now lets create two objects, the first, soil is used to connect our code to the Velleman soil moisture sensor, connected to A0 on the Analog Zero board, which is channel 0 on the MCP3008 ADC. Our second object is a connection to the relay, which is triggered by an output device, on GPIO17.



soil = MCP3008(channel=0)relay = DigitalOutputDevice(17)



Moving on to the main part of the code we create a loop that will constantly run the code within it. Inside the loop the first line of code creates a variable, soil_check. This variable will store the value passed to it by the MCP3008, which is handled via the soil object. As this value is extremely precise we use the round function to round the returned value to two decimal places.



 while True:    soil_check = round(soil.value,2)



Next we print the value stored in the variable to advise the user on the soil moisture level, handy for debugging the code! Then the code waits for one second.



   print('The wetness of the soil is',soil_check)    time.sleep(1)



To check the soil moisture level we use an if conditional test. This will test the value stored in the soil_check variable against a hard coded value. In this case 0.1 was found to be very dry soil, but of course you are free to tinker and find the value right for your soil. If the soil is too dry then the condition is passed and the code is executed.



   if soil_check <= 0.1:




So what is the code that will be run if the condition is met? Well remember the relay object that we created earlier? We are going to use that object to turn on the relay, effectively closing the open switch and enabling the 12V circuit to be completed. This will trigger the peristaltic pump to life and pump water into the plants. Now for testing we set the time to two seconds, but in reality this will be much longer, depending on the length of hose that the water needs to pass through.  So when enough water has been passed  we need to turn off the relay, cutting the 12V circuit. The code then waits for 10 seconds before the loop repeats. Again these times are in seconds for test purposes, but in reality they would be in minutes.


       relay.on()        time.sleep(2)        time.sleep(10)


So that’s it, we have now built and coded the project and it is ready to be tested. To test the code in Thonny, click on the “play” button located in the menu, or press F5. Now as there is no conductivity between the prongs of the soil moisture sensor the code will trigger and start to water the plants, obviously be careful with this!

Once checked, place something conductive between the two prongs and you will see that the output is just printed to the Python shell and no watering is triggered. When you are finished press the red stop button to halt the code.


So now that we have code, how can we make it executable? In order to do this there are two steps to take. First we need to add a line to the top of our Python code which instructs Python where to find the interpreter.








With that complete, we now need to go back to the terminal, and we need to issue a command to make the Python file executable from the terminal. The command is.




sudo chmod +x 




Now in the same terminal, launch the project by typing







Now the project will run in the terminal, checking our soil moisture levels and watering as necessary!


So how can we have the code run on boot? Well this is quite easy really. In the terminal we need to issue a command to edit our crontab, a file that contains a list of applications to be run at a specific time/date/occasion. To edit the crontab, issue the following command in the terminal.



sudo crontab -e



If this is the first time that you have used the crontab, then it will ask you to select a text editor, for this tutorial we used nano, but everyone has their favourite editor!


With crontab open, navigate to the bottom of the file and add the following line.



@reboot /home/pi/



Then press Ctrl + X to exit, you will be asked to save the file, select Yes.


Now reboot the Pi Zero W and for now ensure the soil moisture sensor has no connection between the prongs. After a about a minute, the project should be running, and your pump should start pumping water into the plants.


Power down the Pi Zero W, place it in a waterproof container along with a USB battery power source, ensure the soil sensor is out of the box. Place the project in your garden, and make sure the soil moisture sensor is firmly in the ground. Power up the Pi Zero W, and now your garden can now water itself!

You may have seen my blog post about creating a small portable media center that I can easily take on holiday to hook up to the hotel TV. If not, you can find it here;


Raspberry Pi powered media center to take on holiday


To reduce the amount space it took up, I used a cheap USB keypad which could be used to control the media center. It worked really well & having something hard-wired meant I didn't have to worry about a Bluetooth-paired device needing re-pairing.


However, what I then realised was it would be good to be able to use a spare remote control instead. I was using the OpenElec distribution and looked through their documentation for how to do this, but only found references to version 3 of the software (it's on version 7) and how to get LIRC working with it. There were plenty of blog posts on hooking up IR support, but a lot of them were written 2-3 years ago, and the software has moved on somewhat.


Hardware Setup


What I did first was buy a suitable IR receiver. I chose the Vishay TSOP4838TSOP4838 (which costs less than £1) because of the voltage range (2.5-5.5v) and receiver frequency (38KHz). If you look at the datasheet for the product, you'll see which pins should get wired up to the Pi;



Simply wire pin 1 to GPIO 18, pin 2 to GND, and pin 3 to a 3.3v power pin, e.g.



By using some short F-F jumper wires and a small cut in the side of the case, I was able to position the reciever neatly(ish) on the side.. it's still easily removable, but you could integrate it into the case a bit more seamlessly than this





Software Setup


Before this project I was using OpenElec, but had limited success getting the IR support working properly. I switched to OSMC which I'd read had better IR support through the main UI. I think I was actually on the right track with OpenElec, but I realised later that the old vintage Xbox remote I was trying to use wasn't 100% working.


If you're going to use a remote control that's officially recognised, then you can jump this part about learning IR remote control codes.


Learning IR remote commands


The remote I found in the loft was an old DVD player remote which (unsurprisingly) wasn't in the list of pre-recognised remotes in the OSMC installation. I needed to get the Pi to learn the IR pulses being sent out by the remote and map them to the Kodi functions.


1. First off, you need to telnet to the Pi. Username: osmc, Password: osmc.


2. Next you need to stop the LIRC service which is being locked/used by Kodi


sudo systemctl stop lircd_helper@lirc0


3. Now you can run the IR learn mode.. this will record what it finds to the config file you specify;


irrecord -d /dev/lirc0 /home/osmc/lircd.conf


4. Follow the on-screen instructions which will recognise your remote.


One observation I had was that this only worked properly if I stopped after the first prompt to press lots of keys on the remote.. if I completed the second stage, the key mapping didn't work, e.g.


If I ignored the second phase & let it abort, the learn process worked



When it's working, you'll be able to enter the Kodi function (like KEY_UP, KEY_DOWN, etc)  & map it to a key press on your remote;


Once you've mapped all the functions you want, we then need to move back to OSMC and tell it to use that config file we've just written.


OSMC Settings


In OSMC you need to do the following;


1. Disable the CEC service (via System Settings > Input > Peripherals > CEC Adapter), which seems to be needed for LIRC to work.

2. Now go into OSMC settings and pick the Raspberry Pi icon



2. Go into Hardware Support and enabled LIRC GPIO Support. You shouldn't need to change anything if you connected the sensor to GPIO 18.



3. Now go back and select the Remote Control option;



4. Ignore the list of pre-installed remotes and select Browse;



5. Navigate to the folder where LIRC wrote your config file;



6. Confirm the change & reboot the box;



That should be it.. your remote should be able to control everything in Kodi.

Here is my  Raspberry Pi Wireless project to display daily Flickr  explore photos on a used Apple Cinema Display:

Filter Blog

By date: By tag: