Anton Wilén - aw224be
This device measures the moisture in the soil of a pot, and when the moisture gets within a threshold, a pump is activated, watering the soil.
The time needed for this project will vary greatly depending on experience. With everything from research, buying hardware, assembling hardware, writing code and testing, a beginner might have to spend around 10-20 hours on the project.
---
I chose this project because I was going away on vacation and somehow had to make sure our plants wouldn't die. The device takes care of all watering needs of the plants, all I have to do occasionally is to refill the water supply bucket. Another benefit is that you can select exactly how moist the soil should be, which is difficult to do when watering manually.
By doing this project you will learn the basics of setting up sensors with a microcontroller. You will also learn some very basic electronics to be able to run the pump. The device could also help with better understanding your plants and their needs, as you will be able to see how often they need water, and a potentially lot more with the additions of more sensors.
---
## Hardware
### 5V DC Submersible Pump

---
The cheapest low voltage submersible pump that I could find. Runs on 5 volts and the pump flow is supposedly 1,2-1,6 l/min, which is much more than needed for this project.
### Capacitive Soil Moisture Sensor

---
An analog sensor that is used for measuring the moisture content in soil. Capacitive soil moisture sensors work by using two metal electrodes that are placed in the soil. They measure the moisture level by detecting how well the soil conducts electricity. The more moisture in the soil, the better it conducts electricity, and the sensor can determine the level of moisture based on this conductivity. Compared to its counterpart; the resistive sensor, capacitive sensors are praised for their higher accuracy and durability.
### Relay
---

A simple relay for controlling the pump from an external power supply. This is needed as we need a reliable 5 volt output to run the pump. Although it could technically be run from the Rasperry Pi Pico's VBUS pin, it might draw to much current, which could damage the Pico.
### Raspberry Pi Pico
---

The Raspberry Pi Pico is a microcontroller board developed by Raspberry Pi Foundation. It features the RP2040 microcontroller chip, which provides a powerful yet affordable platform for a wide range of embedded projects. With a dual-core ARM Cortex-M0+ processor, ample GPIO pins, and support for various programming languages, the Raspberry Pi Pico offers flexibility and versatility.
The Pico's small size, low power consumption and general ease of use makes it perfect for this project, although any microcontroller would work just fine.
### External Power Supply
---
For this I chopped up an old usb cable, which together with an old phone charger makes a very cheap (free) 5 volt power supply that can provide more than enough current to power the pump.
### Hose
---
Any hose that fits the pump will do. I bought a transparent hose at Biltema. If watering multiple plants - Attach one end to the pump and block the other end. Then make holes where you want the water to go.
---
### Total cost
| Product | Price in SEK |
| ----------- | --------- |
| [5V DC Submersible Pump ](https://www.amazon.se/dp/B07PNDTVS2?psc=1&ref=ppx_yo2ov_dt_b_product_details) (5 pumps - only one needed) | 114 |
| [Capacitive Soil Moisture Sensor](https://www.amazon.se/dp/B07HJ6N1S4/ref=twister_B08CF1TB9M?_encoding=UTF8&psc=1) | 68 |
| [Relay (Does not need to be 2 channel)](https://www.amazon.se/dp/B078Q326KT?ref=ppx_yo2ov_dt_b_product_details&th=1) | 63 |
| [Raspberry Pi Pico](https://www.electrokit.com/en/product/raspberry-pi-pico/)| 65 |
| Hose| ~30 |
| Breadboard| ~50 |
| External power supply| 0 |
| **Total estimated**| 390 |
## Computer setup
I used Visual Studio Code with the Pymakr extension.
**IDE Setup:**
1. Download and install Visual Studio Code - [Download Visual Studio Code](https://code.visualstudio.com/download)
2. Download and install NodeJS, if you're not sure which version to download, use the LTS version - [Download NodeJS](https://nodejs.org/en)
3. [Pymakr Setup](https://docs.pycom.io/gettingstarted/)
Upload code to the pico by navigating to the Pymakr tab in VS Code, select your device and hit the upload button after creating a new project.
**Flashing Pico Firmware**
Follow: [Part 1: Update Firmware on Raspberry Pi Pico W and run a test code](https://hackmd.io/@lnu-iot/rkFw7gao_)
## Putting everything together

Wiring is very straightforward for the most part. Make sure to connect the pump to the NO (normally open) terminal on the relay and not NC (normally closed) and the power supply to the COM (Common) terminal.
## Platform
I selected Adafruit IO because I only required the very basic functionality of uploading values to the cloud which Adafruit IO does just fine. I am using the free version and do not plan to use a paid subscription. However, any platform that lets you upload values will work just fine.
## The Code
The logic of the device involves two main aspects: moisture sensing and pump control.
### Setting up the moisture sensor
To get any usable information from the moisture sensor we first need to convert the output from voltage to moisture.
1. Note down the peak output voltage when the sensor is completely dry
2. Note down the peak output voltage when the sensor is submerged in water
We will then use these two values to convert from voltage to soil moisture.
This is done with the function mapValue():
```python
def mapValue(value, minIn, maxIn, minOut, maxOut):
return (value - minIn) * (maxOut - minOut) / (maxIn - minIn) + minOut
```
With this function we will have a readout, however, the sensor will not always be completely consistent and can sometimes show values over or below the previous noted down peaks. To avoid readouts below 0 and above 100 we can constrain the value:
```python
def constrain(value, minValue, maxValue):
return min(max(value, minValue), maxValue)
```
Using this looks like this:
```python
moistureLevel = constrain(mapValue(sensorOutput, dryValue, wetValue, 0, 100), 0, 100)
```
After this, it is only a matter of measuring, uploading and comparing the moisture value to a threshold.
### Setting up the pump logic
We need to enable the relay when the moisture hits a certain threshold. However, it is not a good idea to simply turn on the pump when the soil is dry and keep it on until the soil is moist again, simply because the water will probably not have enough time to spread out in the soil so that the sensor can get a proper readout. This can and will most likely result in a lot of water in places where it does not belong. To solve this, we enable the relay for a set amount of time. The time depends on a lot of different factors:
* Pump flow
* Amount of soil in plants
* Size of hose
* Etc.
*Experiment!*
For my particular setup 5 seconds works perfectly.
To control the pump duration, we store the activation time and continuously compare it with the current time. If the time difference exceeds 5 seconds, we deactivate the pump.
```python=
def turnPumpOn():
global pumpOn, lastPumpActivationTime
relayPin.on()
pumpOn = True
lastPumpActivationTime = time.time() # Save the activation time
print("Pump turned on")
def checkPumpDuration():
global pumpOn, lastPumpActivationTime, PUMP_ACTIVATION_DURATION
if pumpOn:
currentTime = time.time() # Compare current time to last activation time
if currentTime - lastPumpActivationTime >= PUMP_ACTIVATION_DURATION:
turnPumpOff()
```
To ensure proper water distribution, we implement a pump cooldown using the same timer logic, preventing immediate reactivation of the pump.
### Network setup
Simple function to connect to WiFi (from [Part 2: Using WiFi](https://hackmd.io/@lnu-iot/rJVQizwUh)):
```python=
def do_connect():
import network
from time import sleep
import machine
wlan = network.WLAN(network.STA_IF) # Put modem in station mode
if not wlan.isconnected(): # If not connected to wifi
print('connecting to network...')
wlan.active(True)
# set power mode to get WIfFi power saving off if needed
wlan.config(pm = 0xa11140)
wlan.connect(WIFI_SSID, WIFI_PASSWORD) # Connect to wifi
print("Connecting to " + WIFI_SSID)
# Check if connected to wifi otherwise wait
while not wlan.isconnected() and wlan.status() >= 0:
print(".", end="")
sleep(1)
# Print IP address
ip = wlan.ifconfig()[0]
print("/nConnected on {}".format(ip))
return ip
```
### Adafruit IO
After following [this](https://hackmd.io/@lnu-iot/r1yEtcs55) tutorial it should be pretty straight forward how to set up a simple dashboard and upload the moisture level to the Adafruit IO.
## Transmitting the data / connectivity
Data is sent every five minutes via MQTT over WiFi since the device is indoors with constant access to power and WiFi, eliminating the need to optimize power consumption.
## Presenting the data
The dashboard is very basic but functional, showing the soil moisture history the last seven days, as well as the current soil moisture. With the free version of Adafruit IO the data is saved for 30 days.

## Finalizing the design
The device fulfills its purpose of automatically watering plants based on the soil moisture. However, there is room for improvement:
* Sometimes the moisture values spikes, possibly causing the pump to turn on earlier than supposed. To solve this the device could measure the moisture level multiple times (for example once a minute for five minutes), then remove any value that differs by a large amount from the others, and then calculating the average value. This would give a much more accurate reading and also a less "spikey" graph.
* If the water runs out, the pump will run dry, likely causing damage to the pump.
* To better understand the water consumption of the plants, there should also be a temperature and humidity sensor as it would provide highly relevant data to compare too. However this is not necessary if the sole purpose is to water the plants automatically.
* There is no way to control anything remotely. Maybe being able to change the moisture threshold or controlling the pump manually would be a good idea?
Overall the project went well and I no longer need to worry about the plants not being watered as long as I make sure the water reservoir is filled.
---

The entire system
---

Everything "neatly" tucked away in a box
GitHub: https://github.com/antonwilen/IoT-SelfWateringDevice