This project results in a plant watering robot connected to the internet of things. It costs as low as $40 if you scavenge components or as much as $150 if you purchase everything new from Amazon. Photos of project: https://drive.google.com/drive/folders/15Lo0dJZWEtEklvmKzovByCo_7SCllino?usp=sharing
Running Linux or you must use the Arduino-IDE to compile and flash the code. This isn’t covered here but it is on https://github.com/xoseperez/espurna/wiki/ArduinoIDE. Have pio, esptool, gcc installed.
Estimated cost to make one is between $70 and $150 at the time of making this guide, depending on what you have already. See the Excel or Google sheet for more info on specific parts. https://docs.google.com/spreadsheets/d/1ye8_F2U_gymXYMMUUAUZvnKoF8kuvBFObCXN0axRH-A/edit?usp=sharing
Some kind of container you can put the float sensor and a tube into. The robot will pull water from there to water plants with the other tube. I used a 4L jug of water.
Something sorta water resistant (don’t want to spill water on it and wreck it) to put your electronics and pump into. You also have to be able to get the hoses out and power into the box. I would just use a small cardboard box to start. Once everything is assembled you can pick out a proper plastic box to order on Amazon depending on what you want it to look like and the size you would like. I purchased two of these, one for the motor and one for the electronics in case of leaks.
An ESP8266 device, I used the NodeMCU-12E board available on Amazon and elsewhere. This board should be capable of running at 5V to switch a 5V relay. The NodeMCU-12E is rated for 3.3V but can usually run at 5V without issue.
A 5V relay that can switch 8-12 volts DC. You connect the motor power through this, and the ESP8266 can tell it to turn the motor on and off.
Just a push button from an arduino kit.
Something to tell you when the water level is low so your plant doesn’t die.
Just some extra wire to conenct things with.
A small parastolic pump. 5 Watts is what I purchased. It should run at a decent speed when powered by whatever power supply you selected.
Sized that it can be connected to the parastolic pump. If the pump says it works with 6mm OD, 4mm ID then buy that. More than a meter worth but depends on the reseviour and plants you intend to water.
>= 5 watts, 8-12V. Nice to have a switch on it. The end cut off so its just two wires; mark the positive and negative with a volt meter if it isn’t marked. I grabbed an old LED light power supply. This should be the right voltage for the parastalic pump you selected with maybe an amp more than the motor requires.
Optional but makes a nicer final product than just connecting wires to each other. The one I linked also comes with nice little screw terminals to allow disconnecting wires easily.
To make initial connections and debug issues without soldering and in a more organized manner than twisting wires.
Can take the output of your power supply as input to create 5V.
Very useful for other projects, variable output voltage (just set it to 5V with a volt meter). You can also use these if you have a higher voltage power supply, just also regulate the motor voltage with another one.
Or electrical tape to cover wire connections and prevent shorting.
Optional but recommended to connect wires together and use the prototype board.
To check polarity and voltages and such.
If a pin is specified without telling you what its on, its on the ESP8266 WiFi board. All the pins on the ESP8266 board we will be dealing with are on the same side, the ones labeled D1, D2…
Make two connections come off of both wires (4 total, two negative/black and two positive/red). Connect one pair of positive/red and negative/black to the correct inputs of the 5V regulator.
Connect the positive/red output from the 5V regulator to one of the 3V3 pins. Note: We are connecting 5V to the 3.3V pins and Not the 5V input pin. The relay requires 5V so we have to run the ESP8266 over voltage at 5V so the data pins can switch the relay. This may shorten the life of the ESP8266 depending on which one you buy. Connect the negative/black output from the 5V regulator to one of the GND pins.
Connect one side to a GND pin and label it negative/black. The other side goes to D6 and label it positive/red.
Connect one side to a GND pin. The other side goes to D5.
For different relays this is different but the instructions for the relay I had follow. Generally, you want the relay coil going to GND and D7, one side of the switch going to the power supply GND and the other side going to the motor GND. Also I am using a normally closed relay. If you have a normally open relay you need to change RELAY1_TYPE from RELAY_TYPE_NORMAL to RELAY_TYPE_INVERSE. See https://github.com/xoseperez/espurna/wiki/Buttons-and-switches.
We will label the relay pins as such:
+------+ |* *| | | | | | | |* *| |* *| +------+
- top left as R1
- top right as R2
- middle left as R3
- middle right as R4
- bottom left as R5
- bottom right as R6
To figure out which side of the relay is normally open, use your multimeter to test for continuity between R6 to R2, then R5 to R1. Which ever pair is not connected is the normally open pair. Use that pair for below.
- One of R3 or R4 goes to D7, the other goes to GND.
- Connect either R1 or R2 (the normally open one) to the power supply negative/black.
- Connect eitther R5 or R6 (the normally open one) to the motor’s negative/black.
Connect the positive/red to the power supply positive/red. The negative/black should be connected to the relay.
I installed the float sensor using a length of plastic SharkBite pipe hot glued to threaded end. Then I dipped the float sensor down to the bottom of the container. This allows me to use different containers.
You could also probably just drop the float sensor in and tape the wires to the lid of the bottle. I think its heavy enough to sink.
The only thing of importance is the float sensor is currently configured such that it is switched on when the water level drops, and off when the water level is higher. If you flip the switch around or buy a different one, you might have to reconfigure it in HomeAssistant.
Make sure the water inlet tube from the robot is nearish the bottom of the container and it can’t fall out. The peristaltic pump makes the tubing vibrate a reasonable amount. If the tube falls out the pump is more than happy to pump air, but your plant doesn’t drink air.
When you turn on the pump you might notice that the tubing shakes a lot. If you want to prevent this, make a loop filled with air using two T connectors in between the pump and plant. The air will compress and absorb the vibration.
<- this side filled with air | |
---|---|
<- this one filled with water |
Clone/download this repo and its submodules to your computer. Use `git clone –recurse-submodules https://github.com/eightys3v3n/plant_water.git`.
If you just download a zip of the repository, you must also go download a zip of the latest espurna repository and put it in the espurna folder inside plant_water. Download it from https://github.com/eightys3v3n/espurna/tree/plant_water. The directory tree should look like this when you’re ready.
plant_water/ espurna/ code/ firmware/ ... information.org
Naviage to plant_water/.
Only the credentials.h file is required to be edited. The other two are just things you can edit if need be. The code included is an example of the file contents, see the actual files for up to date contents.
`code/espurna/config/credentials.h`
You have to make this file, but you don’t have to have anything in it. You can set this up once you flash the ESP8266 by connecting to its WiFi network, it just takes longer than setting them in this file. If you plan on using HomeAssistant you’ll probably have to set up MQTT after you setup Home Assistant’s built in broker. You can comment out the MQTT stuff to just not set it until later.
#define WEB_USERNAME "Username for ESPurna web interface" #define ADMIN_PASS "Password for ESPurna web interface" #define WIFI1_SSID "SSID for 2.4Ghz WiFi" #define WIFI1_PASS "Password for WiFi" #define MQTT_AUTOCONNECT 1 #define MQTT_USER "MQTT server username" #define MQTT_PASS "MQTT server password" #define MQTT_PORT 1883 #define MQTT_SERVER "MQTT server IP address" #define MQTT_QOS 2
`code/platformio_override.ini`
`-4m-` is the megabytes of memory on the selected ESP8266 device. You may need to change this to 1m if you have a board with less memory.
[env:plant_water] extends = env:esp8266-4m-base src_build_flags = -DUSE_CUSTOM_H
`code/espurna/config/custom.h`
Converting pin numbers from D0, D1… to code compatible https://randomnerdtutorials.com/esp8266-pinout-reference-gpios/. LED1_PIN 2 means the LED is connected to GPIO2, which is correct for NodeMCU 1.0 devices but changes for other ESP8266 devices. If not sure comment this whole section out. RELAY1_PIN 13 means we connect the relay switch to pin D7. BUTTON2_PIN 14 means we connect the button to D5. DIGITAL1_PIN 12 means we connect the float sensor to D6. The button2 stuff lets you use your extra button to turn on and off the sensor. Information about how to customize it is on the wiki. The other configuration options have details at https://github.com/xoseperez/espurna/wiki.
// Prevents checking of default options for this board. #define MANUFACTURER "NODEMCU" #define DEVICE "LOLIN" // Features #define ALEXA_SUPPORT 0 #define API_SUPPORT 1 #define BUTTON_SUPPORT 0 #define DEBUG_SERIAL_SUPPORT 1 #define DEBUG_TELNET_SUPPORT 0 #define DEBUG_UDP_SUPPORT 0 #define DEBUG_WEB_SUPPORT 1 #define DOMOTICZ_SUPPORT 0 #define ENCODER_SUPPORT 1 #define HOMEASSISTANT_SUPPORT 1 #define I2C_SUPPORT 0 #define INFLUXDB_SUPPORT 0 #define IR_SUPPORT 0 #define LED_SUPPORT 1 #define LLMNR_SUPPORT 0 #define MDNS_SERVER_SUPPORT 0 #define MQTT_SUPPORT 1 #define NETBIOS_SUPPORT 0 #define NOFUSS_SUPPORT 1 #define NTP_SUPPORT 1 #define OTA_ARDUINOOTA_SUPPORT 0 #define RFM69_SUPPORT 0 #define RFB_SUPPORT 0 #define RPN_RULES_SUPPORT 0 #define SCHEDULER_SUPPORT 1 #define SPIFFS_SUPPORT 0 #define SSDP_SUPPORT 0 #define TELNET_SUPPORT 0 #define TERMINAL_SUPPORT 1 #define TERMINAL_MQTT_SUPPORT 0 #define TERMINAL_WEB_API_SUPPORT 0 #define THINGSPEAK_SUPPORT 0 #define TUYA_SUPPORT 0 #define UART_MQTT_SUPPORT 0 #define WEB_SUPPORT 1 // Sensors #define ADE7953_SUPPORT 0 #define AM2320_SUPPORT 0 #define ANALOG_SUPPORT 0 #define BH1750_SUPPORT 0 #define BMP180_SUPPORT 0 #define BMX280_SUPPORT 0 #define BME680_SUPPORT 0 #define CSE7766_SUPPORT 0 #define DALLAS_SUPPORT 0 #define DHT_SUPPORT 0 #define DIGITAL_SUPPORT 1 #define ECH1560_SUPPORT 0 #define EMON_ADC121_SUPPORT 0 #define EMON_ADS1X15_SUPPORT 0 #define EMON_ANALOG_SUPPORT 0 #define EVENTS_SUPPORT 0 #define EZOPH_SUPPORT 0 #define GEIGER_SUPPORT 0 #define GUVAS12SD_SUPPORT 0 #define HLW8012_SUPPORT 0 #define LDR_SUPPORT 0 #define MAX6675_SUPPORT 0 #define MHZ19_SUPPORT 0 #define MICS2710_SUPPORT 0 #define MICS5525_SUPPORT 0 #define NTC_SUPPORT 0 #define PMSX003_SUPPORT 0 #define PULSEMETER_SUPPORT 0 #define PZEM004T_SUPPORT 0 #define SDS011_SUPPORT 0 #define SENSEAIR_SUPPORT 0 #define SHT3X_I2C_SUPPORT 0 #define SI7021_SUPPORT 0 #define SONAR_SUPPORT 0 #define T6613_SUPPORT 0 #define THERMOSTAT_SUPPORT 0 #define TMP3X_SUPPORT 0 #define V9261F_SUPPORT 0 #define VEML6075_SUPPORT 0 #define VL53L1X_SUPPORT 0 #define HDC1080_SUPPORT 0 // Configuration #define LIGHT_SAVE_ENABLED 0 #define BUTTON_MQTT_SEND_ALL_EVENTS 1 #define MQTT_RETAIN 0 #define MQTT_ENABLED 1 #define HOMEASSISTANT_ENABLED 1 // Make the built in LED flash on WiFi activity #define LED1_PIN 2 #define LED1_PIN_INVERSE 1 #define LED1_MODE LED_MODE_WIFI // For the motor relay #define RELAY1_PIN 13 #define RELAY1_TYPE RELAY_TYPE_NORMAL #define RELAY1_PULSE_MODE RELAY_PULSE_OFF // defaults to being off (not watering) #define RELAY1_PULSE_TIME 30 // number of seconds the relay can stay on for // Built-in flash button #define BUTTON1_PIN 0 #define BUTTON1_CONFIG BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON1_LNGCLICK BUTTON_ACTION_NONE // Extra external button #define BUTTON2_PIN 14 #define BUTTON2_CONFIG BUTTON_PUSHBUTTON | BUTTON_SET_PULLUP | BUTTON_DEFAULT_HIGH #define BUTTON2_PRESS BUTTON_ACTION_PULSE #define BUTTON2_CLICK BUTTON_ACTION_NONE #define BUTTON2_RELEASE BUTTON_ACTION_OFF #define BUTTON2_DBLCLICK BUTTON_ACTION_TOGGLE #define BUTTON2_RELAY 1 // Float sensor #define DIGITAL1_PIN 12 // Secret Configuration #include "credentials.h"
Plug in the ESP8266 board via USB.
Some times you may need to reflash the entire ESP8266 memory to avoid issues, Use `esptool.py erase_flash` to do that before running the above commands if you encounter random crashes.
From plant_water/ run `./build.sh` to compile the project and flash it to a connected deivce.
You also have to decide now if you want to run HomeAssistant to manage the watering device (more features and stuff) or just use the device its self (easier). Now that ESPurna is flashed, we have a few options we can change on the following tabs. Make sure to hit save on every page.
Set the host name to something that makes sense like “PlantWater”.
- Enable discovery.
- Leave the prefix as homeassistant if you don’t know what this does. Its default.
- Retain to yes. This means Home Assistant sees if the device has ever existed and adds it rather than waiting for it to say “Hello”.
Enable if it isn’t already. Some times you have to disable, save, then enable, save the first flash. Also enter your HomeAssistant broker details here if you aren’t using your own broker. This needs to be done after HomeAssistant is setup.
Set your timezone by finding it in the list at https://github.com/esp8266/Arduino/blob/master/cores/esp8266/TZ.h. Then copy the bit between the quotes and paste it into the Time Zone field.
If you don’t want to use HomeAssistant to control plant watering, just add a watering schedule here. With Pulse Mode on you should only have to set a turn on schedule, the switch will turn off after the pulse time.
- Read interval is how often to check whether the water is empty or not. Set it accordingly to something like 1 minute.
- Change “Report every” to 1.
Setting first, the value after the colons.
- Boot mode
- Always Off
- Pulse mode
- Normally Off
- Pulse time
- The maximum time we should be able to water the plant. It auto-stops watering after this many seconds if you don’t turn it off.
- On MQTT disconnect
- Turn off
Here you can add more WiFi networks and change the WiFi password. If you only have one WiFi network, turn off Scan. This results in better performance when the WiFi signal is low.
This just lists what the device is doing. You can also use it to turn things on and off, see for details https://github.com/xoseperez/espurna/wiki/Terminal.
Go through the Getting Started guide at https://www.home-assistant.io/getting-started/.
Once you have HomeAssistant up and running, if you have a dedicated MQTT server: https://www.home-assistant.io/docs/mqtt/broker/.
If you don’t have a dedicated MQTT server: https://github.com/home-assistant/addons/blob/master/mosquitto/DOCS.md
Install the File Editor Addon: https://www.home-assistant.io/getting-started/configuration/
Configure the broker URL information to use your dedicated server or the MQTT Server Addon. You should see your Plant Water device in Configuration > Devices.
Use the File Editor addon to edit the configuration.yaml file. Add the following in and make changes. The PlantWater should be changed to the Hostname of your device. After making changes, go to Configuration > Server Controls > Restart. If there are any errors they will show up in Configuration > Logs. On the Overview page you should now have a switch that when toggled, waters the plant, then toggles its self off again (thanksto pulse mode on ESPurna).
switch: - platform: mqtt unique_id: watering_plant name: Watering Plant state_topic: "PlantWater/relay/0" command_topic: "PlantWater/relay/0/set" payload_on: 1 payload_off: 0 optimistic: false qos: 2 retain: false
A water level of 0 or 1 is fine and all, but “Not Empty” and “Empty” is nicer. This does that. Do the same as configuring the water button but with the below stuff now a new sensor will show up on Overview.
sensor: - platform: template sensors: plant_water_level: friendly_name: Plant Water Level unique_id: sensor.plantwater_level_nice value_template: > {% if is_state('sensor.plantwater_level', '0') %} Not Empty {% else %} Empty {% endif %} icon_template: > {% if is_state('sensor.plantwater_level', '0') %} mdi:flask-full {% else %} mdi:flask-empty {% endif %}
The command_topic is set to the the MQTT topic subscription value on your ESPurna. HomeAssistant posts to this topic to tell the ESP8266 to water or not to water the plants.
The state_topic is your hostname /relay/0. It should have the state of the ESP8266 relay every time it changes, or the state of the plant watering.
Save your changes and go to the Overview page. Click on the Plant Water device with a 0 or 1 next to it (or what ever you called it). Click the gear (settings) icon. Change the Entity ID to sensor.plantwater_level.
Check whether it has made a post at homeassistant/# by using a MQTT client to subscript to that. If there is one, the problem is with HomeAssistant.
If you can’t subscribe, the problem is with the MQTT broker (try starting it in HomeAssistant if you used the addon).
If there is nothing there, the problem is your ESP8266. You might have to setup MQTT on the ESP8266 with a host, username, password, and such so it can connect to the MQTT broker.
Also make sure your firewall allows the port that your MQTT broker is using.
Identified by looking at the serial output, basically it says it restarted or that it crashed. It may also say its in Fail Safe mode. Use the RST button once its connected to see all the serial output, and make sure the Arduino IDE serial monitor is set to 115200 baud rate.
Use `esptool.py –port /dev/ttyUSB0 erase_flash`. It seems that when developing and flashing, sometimes it leaves code in the flash that breaks stuff.
Try commenting out the LED stuff in custom.h. I have found that can cause problems. Also try commenting out other entire features or disabling things and reflashing.
You can navigate into espurna/code and do ‘git pull upstream’. Then save the merge file it opens and try building with any new changes in development.
I’ll see if I can help out or fix the problem.
The cost that I built this project for is likely not worth most people’s time especially given that the lowest cost per unit I could get was more than $60. This price isn’t justified given that it only saves a couple minutes a week but it still costs insignificant time and money to build.
The per-plant-cost of this device could be decreased in a number of ways. If the cost could be brought down to $30 per plant it would likely be a reasonable solution to indoor watering. It would also decrease the time investment and the space taken up by the unit on a window sill.
Almost all of the components used to build this device can be purchased for significantly less in bulk. Building 10 or more units would drop the price further, likely to around $40 per plant.
Ordering parts from AliExpress could have resulted in a price decrease in exchange for a multi-month shipping time for parts.
- Potentially using a small solenoid with multiple outlets would allow for watering more plants with the same flow rate. This would also allow for watering more plants with varying water requirements.
- Using small fittings with the silicone tubing with some kind of flow restrictors could also be used to water more than one plant with a single device. This is most likely what I will look into in the future.
The following parts could have been swapped out for cheaper or more effective variants.
- Tubing
- Silicone tubing is likely the most expensive option here. Using clear vinyl tubing is another options.
- Pump
- A peristaltic pump allows for different liquids to be pumped, but is not strictly necessary as fish tank pumps would likely work as well.
- Prototype board
- The project could have been made strictly by soldering wires to each other but I wanted to use project board to make it nicer to pack into the project box.
- Power delivery
- Requiring a 5V regulator adds additional cost. If a microcontroller could be selected that allowed for 12V power and had data pins capable of driving the relay this cost could be eliminated. Also, overvolting the microcontroller is likely to decrease its lifespan.