Off-Grid Garden Watering System

Solar powered watering system controlled with a Raspberry Pi to deliver an exact metered water volume to your garden plot, on schedule

Public Chat
Similar projects worth following
Solar powered watering system controlled with a Raspberry Pi to deliver an exact metered water volume to your garden plot, on schedule.

In communities where water is limited, due to usage restrictions or availability, every drop counts.  This project is a watering system that delivers an exact volume of water to a garden plot, scheduled and configured by a gardener with a cell phone.  Dispensing water in exact volumes and using efficient delivery mechanisms such as drip irrigation maximizes community water resources.

California USA has these restrictions right now.

Click on the picture below to run a Demo of the system.

The system is off-grid, using a solar panel/battery combination for 12v power.  A 12v diaphragm pump pumps water on-demand when a ball valve opens.  A hall-effect flow meter measures the volume of water pumped to the garden.

Off-grid power is easy enough to supply with the solar/panel combination, but what about off-grid communication to monitor and control the watering system?  We solve this problem by configuring the Raspberry Pi to run as a standalone WiFi access point, allowing anyone with a cell phone or other device to connect to the WiFi access point and browse to

Electrical/Mechanical Diagram

The ball valve is opened and closed using a relay controlled by GPIO pin 37 on the Raspberry Pi.  The Raspberry Pi samples the flow meter on GPIO pin 7.

A DC/DC converter supplies the 5v power to the Raspberry Pi.

User Interface

The Raspberry Pi is configured as a Wifi access point (AP), allowing the gardener to connect with their cell phone over Wifi and configure/control the system.   Once connected, browsing to will show the user interface:

The gardener can set the days/time to start watering, as well as the goal gallons.

When the set day/time strikes, the system will open the ball valve and continuously sample the flow rate to calculate a running volume.  Once the goal volume is reached, the ball valve will close, and the system is armed for the next day/time.

Manual override buttons are available to turn on/off the pump.  This is useful when setting up the system to verify system functionality or to troubleshoot issues.


The system software is written in Go programming language and is built with the Merle IoT framework and the Gobot framework.

The software is open source and is licensed under the BSD-3-Clause license.  The source code is here.

The compiled software runs on the Raspberry Pi.  In addition to controlling the ball valve and reading the flow meter, the software also runs as a web server, serving up the user interface shown above.  The user interface lets the user change settings and observe progress.

User Interface Software

The HTML for the user interface is here.  Pretty simple, just a bunch of nested divs with standard HTML5 elements.

The JavaScript for the user interface is here.  (Not my favorite language to program in, and I'm constantly searching the web for JavaScript-isms).  The main code opens a Websocket and listens for messages from the core code.  Basically it's a state machine, where it uses the HTML elements to store state.

The CSS for the user interface is here.  Bunch of flex boxes to layout the divs.

Core Go Code

The Go code that controls the ball valve and samples the flow meter is here.  Look for the Subscribers() function at the bottom of the code.  This looks very similar to the websocket loop in the JavaScript.  Same messages are handled on both sides to maintain a notion of "state".

This code leverages the GoBot framework to read/write the GPIO pins on the Raspberry Pi.

The code is built with the Merle framework.  The Merle framework provides the web server for the UI and handles all the messages passing on the websocket connecting the JavaScript UI front-end to the Go core back-end.

Sampling Flow Meter

Here's some facts:

  • Flow meter sensor reads 450 pulses/Liter
  • There are 3.78541...
Read more »

  • 1 × Raspberry Pi Any model except pico
  • 1 × Relay 4 Zero 3V 4 Channel Relay Shield for Raspberry Pi Relay hat to turn on/off ball valve (only one relay used)
  • 1 × Motorized Ball Valve- 1/2" Brass Ball Valve 9-24V AC/DC and 2 Wire Auto Return Setup, sold by U.S. Solid
  • 1 × Flow Meter Hall Effect Sensor Plastic 1/2" NPS Threaded, sold by Uniquers Liquid
  • 1 × Water Pressure Diaphragm Pump, 12v SEAFLO 42-Series, sold by SEAFLO

View all 8 components

  • Bumper Crop

    Scott Feldman09/27/2022 at 22:55 0 comments

    Bumper crop this year, thanks to the water system.

  • No RTC?

    Scott Feldman09/03/2022 at 18:59 1 comment

    The Raspberry Pi does a great job keeping time as long as there is power.  After a power failure, the Raspberry Pi's time will not be correct.  Knowing the correct day/time is important for this project as the schedule determines when to turn on/off the system, so not having the correct time is a problem.

    Two solutions come to mind:

    1. Add a $10 RTC (real time clock) hardware module to the Raspberry Pi to keep time in the event of a power failure.
    2. Use the first contact with a cell phone to set the time, from the cell phone's time.

    The first option is easy but adds $10 to the system costs.

    The second option works this way: After install, the Raspberry Pi comes up with some random day/time.  On first connection by a cell phone, push down the current day/time (from the cell phone) to the Raspberry PI.  As long as there is power, the Raspberry Pi will have the correct day/time.  The assumption here is the cell phone has the correct time, which is a reasonable assumption since most phones should have the correct time due to NTP.  In the event of a power failure (not likely since the system is off-grid and the battery/solar setup should keep the Raspberry Pi powered on 24/7), the Raspberry Pi's time will be messed up.  This means the watering schedule is messed up.  The system may water on the wrong day/times.  But, it will still water.  Once a cell phone reconnects to the system, the time will be corrected.

  • Zones?

    Scott Feldman09/03/2022 at 18:36 0 comments

    The Raspberry Pi relay hat I used for this project has four relays, each tied to a GPIO pin.  I'm only using one relay to control a single ball valve.  The project could be extended with zones, each zone on a relay, for up to four zones.  Each zone would have its own schedule.  We'd also need to have a flow meter for each zone, so we need to use additional GPIO pins for each flow meter.

    Design changes:

    • Modify UI with zone selector, 1-4.  Each zone would have a start day/time schedule and a target gallons of water.  
    • Modify the core code to add the four zones to the state using an array.  So turn this structure:
      type garden struct {
          // omitted fields
          StartTime   string
          StartDays   [7]bool
          Gallons     float64
          GallonsGoal uint
          Running     bool

     into this structure:

    type zone struct {
        StartTime   string
        StartDays   [7]bool
        Gallons     float64
        GallonsGoal uint
        Running     bool
    type garden struct {
        // omitted fields
        Zones [4]zone

    There would be other modifications to pass the zone number (0-3 for zero-based math) in the JSON messages that are passed around.  For example, the start time message would go from:

    type msgStartTime struct {
        Msg   string
        Time  string


    type msgStartTime struct {
        Msg   string
        Zone  int
        Time  string

  • Hall of Mirrors

    Scott Feldman09/03/2022 at 02:47 0 comments

    Something interesting about this project is the UI view is shared by all who view it. For example, imagine two people (two gardeners :) both pull out their cell phones and connect to the WiFi access point and browse to  Both users will see the same UI state.  The real state is stored on the Raspberry Pi; the UI is just a view of the state of the system, so it makes sense both would see the same view.  It's true for user input.  If one user clicks a checkbox, both users see the update.

    If you want to try this out without building the whole system, open the demo in multiple browser windows.  You can do this from multiple systems, if you want.  Now start pushing buttons and notice all views are synchronized.

  • Have Cell Coverage at Garden Location?​

    Scott Feldman09/03/2022 at 02:34 0 comments

    Connecting to the garden watering system with your phone over a private WiFi works wherever you are on the planet, even if there is no local cell phone coverage (LTE, 5G, etc).  You can even use a tablet to interact with the system; just need a device that can connect over WiFi and present the UI in a browser.

    But what if you do have a cell phone signal at your garden location?  And you want to monitor/control the system remotely?

    With a little bit more work we can use a cell modem hat with the Raspberry Pi to connect our watering system to the Internet via the cell modem.  Cell modems (LTE/4G) for Raspberry Pis are available for the $125 price range.  A SIM card is included for $2/month + data.  In our case, the data is minimal.  Network traffic is only generated when watering, or when the user makes some UI change.  Other than that, the network traffic is quiet.  So basically $2/month because data is negligible.

    If we add a cell modem to our solution, then we can access the UI over the Internet, from anywhere.  We see the same UI as before when we connected with the local WiFi connection.

    How does this work?

    The same software we're running on the Raspberry Pi can also be run on another system on the Internet as a proxy for the real device.  In fact, the other system can be a hub, allowing multiple watering systems to connect to the hub, giving you one place to control multiple systems.

    As I have time, I'll update this log entry with the steps to pull this off.  The trick is we're using the Merle framework to write our application.  Merle automatically provides support for this remote proxy model.  Securely, I might add, since connecting anything to the Internet requires a strong security model.  (Don't want Elves in Elveville hacking our watering system).

  • Custom OS image to make install/setup easier?

    Scott Feldman08/31/2022 at 22:53 5 comments

    Thinking about building a custom Raspberry Pi OS image with the garden system software already installed and configured.  Once installed, the Raspberry Pi would boot up as an access point and the garden system will be running.  This would make the installation of the system much quicker and easier.

    Need to figure out how to pass configuration of system in the install image.  Kind of like how other files like wpa_supplicant.conf are placed in the /boot dir of the image to connect to WiFi.

    Things that need to be configured:

    • SSid of access point
    • (optional) Password of access point
    • System locale and timezone
    • SSH or not?
    • ???

  • Pump or no Pump?

    Scott Feldman08/30/2022 at 23:43 0 comments

    My version of this project uses a 12v diaphragm pump to pressurize the water.  It's an on-demand pump, which means it automatically turns on when there is a demand (ball valve opens), and turns off when there is no demand (ball valve closes).

    If a pressurized water source is available, the pump is not needed.  Just hook the ball valve directly to the water source.

View all 7 project logs

  • 1
    Prepare the Raspberry Pi with Raspberry Pi OS

    Flash a copy of Raspberry Pi OS onto an SD card. The 32-bit Raspberry Pi OS Lite version is sufficient.

    At this stage, it is convenient to configure for WiFi headless access to the Raspberry Pi over the local WiFi network. To do so, in the /boot directory of the SD card, manually add the following files:

    Boot the Raspberry Pi on the SD card. If headless access was configured, and WiFi connected, you can SSH into the Raspberry Pi with user "gardener" and proceed to the next step.

  • 2
    Deploy the Software

    On the Raspberry Pi, download the deploy script:

    $ wget -O deploy

    Run the deploy script:

    $ chmod +x deploy
    $ ./deploy

    There are some prompts to answer.  Enter the project name "garden".  Answer "y" to the y/n prompts.  Enter a SSID, or choose the default "garden" SSID.  Disabling SSH after reboot is to close a security hole.

    Project: garden
    Auto-start (y/[N])? y
    Configure as access point (AP) (y/[N])? y
    AP Country Code: US
    SSID: garden
    Disable SSH access (after reboot) (y/[N]? y 

    The deploy script will

    • install the required build tools
    • build the garden system
    • install the garden system to run on startup
    • setup the access point software

    Once the deploy script is done, shutdown the Raspberry Pi and continue with the next step of setting up the hardware.

    $ sudo init 0
  • 3
    Setup Hardware

    Wire the hardware according to:

    The relay shown in the diagram is one of four relays on the relay hat.  I've broken it out in the diagram from the Raspberry Pi but it really sits on top of the Raspberry Pi so it's already wired to GPIO pin 37.  Connect the ball valve to the relay's normally open (NO) terminal and the 12v supply to the common (COM) terminal.

    The ball valve is a two-wire auto-return valve.  When power is supplied, the valve opens.  As long as power is supplied, the valve remains open.  Once the open state, the valve consumes very little current.  When the power is cut, the valve closes.  Closing on power failure is a helpful feature in shutting off the water.

    The flow meter is a hall-effect sensor switch which counts pulses.  For this particular flow meter, there are 450 pulses per liter of water.  We'll run the sensor off of the Raspberry Pi's 3v.  GPIO pin 7 will be used to sample the pulses, so wire the signal wire to GPIO pin 7.

    Vcc       1
    Gnd       9
    Signal    7

View all 4 instructions

Enjoy this project?



Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates