Making plants water themselves.

Using an Arduino, a few sensors, a water pump, and a Raspberry Pi to make my silly plants stop dying on me.

20th Mar 2020

How better to spend the extra time while locked in than building something from scratch? The fun thing about building for myself is that I don't have to worry about product viability, market match, or even whether I've designed something that could easily be manufactured. Nope - just hacking together something fun that solves a problem. This post will be Article 01 in a series of posts on household inventions!

The Problem

Before this zombie plague took over the globe, I traveled for work. A lot. Whether off on a UN trip to South America, or one of my monthly trips to the office in New York, I never seemed to be at home. And one of the frequent casualties of this lifestyle was my plants, suffering the neglect and mistreatment of my absence. What's more, I have a love of ferns - a plant that needs high humidity and waterings on a very often basis, as they would have in the wild in their natural habitats of temperate rainforests. I needed something that could monitor the sunlight they're getting (not too much, they like shade), monitor their temperature and humidity (moderately high for both), and the soil moisture (high), relay me that information anywhere on earth, and, if possible, do all the work needed to keep the plant in the optimal range for all.

Real-Time data from my fern, the first plant I've hooked up to the system (all times in GMT):

The Solution

Building an Arduino sensor that monitors soil moisture, air temperature, relative humidity, air pressure, and light is relatively simple. However Arduinos are local solutions, not something I could use to monitor remotely. Ultimately I landed on the following hardware platform:

  • An ELEGOO For Arduino Nano V3.0, Nano board CH340/ATmega328P with the following sensors:
    • GY-BME280 High Precision Digital Sensor Barometric Pressure, Temperature, & Humidity Module Sensor
    • 5mm Photoresistor GL5528 Light sensor
    • Analog Capacitive Soil Moisture Sensor V1.2
    • SX1278 433MHz LoRa Module (for sending data)
    • 433MHz LoRa antenna (for sending data)
    • And in the future, hook up a relay to a pump that can water the plant if the soil moisture drops below a specific value.
  • A Raspberry Pi 3B (an old one I had sitting around) with the following components:
    • SX1278 433MHz LoRa Module (for recieving data)
    • 433MHz LoRa antenna (for recieving data)

On the Arduino every 10 minutes data is collected from all attached sensors. Because we're doing multiple things at once, millis() is key here.

Some variables can be sent as-is, including temperature/barometric pressure/humidity, and some variables need to be mapped to human-understandable values, including light values. This was created by taking a brightness reading in bright sunlight (hard to find here in the UK, so I held the sensor next to a bright lightbulb), and a dark room (in my case, a closet).

After 10 minutes, the individual data variables are stored in a char buffer, and then sent as an integer measured value C-string, as an 80-byte packet:

char buf[80] = {0};
sprintf(buf, "%d|%d|%d|%d|%d|%d", soilMoisturePercent, airTemperature, airPressure, altitude, airHumidity, lightPercent);
rf95.send((uint8_t *)buf, 80);

The information is sent over LoRA rather than Bluetooth or WiFi because I wanted to have a system that could work anywhere in my house (or given the distances that LoRa signals function over - from the other side of the city). I'm also working on a project at work right now that uses LoRa, and I wanted to test how big my data packets could be before hitting issues. Either way, this isn't LoRAWAN, it's just a P2P radio connection using 433 MHz LoRA and the Rspreal/Radio Head library. For this project I'm using an SX1278 433MHz LoRa Module and a 433MHz LoRa antenna.

The Raspberry Pi functions as a local server for all data that is sent. It has it's own SX1278 433MHz LoRa Module and 433MHz LoRa antenna and is listening for any radio transmissions on the same frequency and spectrum as we're broadcasting from our Arduino(s). There is a python3 script that I wrote which will convert the string into an array, and write the individual array variables into our InfluxDB database. Both scripts are available on GitHub links below.

Finally the database is accessible on the front-end via Grafana, where there are some nice custom visuals to clearly show me how the plants are doing.

To-do in the future is to use a relay on the Arduino to turn on a water pump which will water/mist the plants when soil moisture or humidity drops too low. So far I've had some problems with interference causing the system to microcontroller and reboot - something that I'll have to put my electrical engineering hat on for and tackle in the near future! Read about that challenge here. I'd also like to build a shell for the sensor package out of wood, so that it fits in with the plants!

Project Stack:

Project Code:


Raspberry Pi Code: