{"id":210,"date":"2022-11-02T03:13:05","date_gmt":"2022-11-02T02:13:05","guid":{"rendered":"https:\/\/www.moya.no\/wp\/?p=210"},"modified":"2022-11-02T03:20:03","modified_gmt":"2022-11-02T02:20:03","slug":"arduino-controlled-automatic-indoor-plant-watering-system","status":"publish","type":"post","link":"https:\/\/www.moya.no\/wp\/2022\/11\/02\/arduino-controlled-automatic-indoor-plant-watering-system\/","title":{"rendered":"Arduino Controlled Automatic Indoor Plant Watering System"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><a href=\"https:\/\/www.digikey.no\/en\/maker\/profiles\/5eff8323197848aa9dc118bc7909d0be\">By Cody Walseth<\/a><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"alignleft is-resized\"><img data-opt-id=1861186782  fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/www.digikey.ca\/-\/media\/MakerIO\/Images\/projects\/2019\/07\/12\/d33c210866a54fa491772667ae8e06b8.jpg?la=en-CA&amp;ts=557c4ea2-4eba-40b7-b5d4-8cdecca3759a\" alt=\"\" width=\"505\" height=\"674\" title=\"\"\/><\/figure>\n<\/div>\n\n\n<p><strong>Overview<\/strong><\/p>\n\n\n\n<p>This project is an&nbsp;Arduino Uno controlled automatic plant watering system.&nbsp; Using an Adafruit Peristaltic pump, DF Robot capacitive soil moisture sensor, addressable LEDs and a micro servo&nbsp;with a couple 3D printed parts. The way it works, is if the sensed moisture level falls below the desired value, the pump and servo will turn on.&nbsp; The servo will move the pump hose back and forth accross the plant evenly distributing the water.&nbsp; The pump (and servo) will run for 10 seconds and stop for 2 minutes or until the desired moisture level is reached.&nbsp; If after 15 attempts of watering the desired moisture is not reached, one of the LEDs will flash Red and the pump will not run again until the reset button is pressed.&nbsp; This is to alert you when the water source is empty. During normal operation, one of the LEDs will update with the sensor value changing from Green (wet) to Red (dry) giving you an estimated moisture level at a glance.&nbsp; If you would like to reset the desired moisture, simply water the soil until it gets to the moisture level you would like it to maintain, and hold the set button for 3 seconds.&nbsp; Many variables are defined so that&nbsp;you can adjust them to&nbsp;fit the requirements of&nbsp;your plant or soil.<\/p>\n\n\n\n<p><strong>Circuit and Explanation<\/strong><\/p>\n\n\n\n<p>The capacitive moisture sensor and micro servo are connected to analog I\/O pins while also being connected to transistors between the three-pin connector and the GND pin.&nbsp; This was done to use a digital pin to disable the sensor\/servo when not in use. Eliminating servo &#8220;chatter&#8221; and reduce corrosion if a resistive moisture sensor is used.&nbsp; Analog pins were used to make them interchangeable as they both have the same pinout.&nbsp; A third set of components was added for potential future use of a second moisture sensor.&nbsp;The servo is used to distribute water from side to side as it is watering.<\/p>\n\n\n\n<p>The buttons use internal pullup resistors.&nbsp; The purpose of the two buttons is for one to manually turn on the water and the other to reset the &#8220;out of water&#8221; alarm along with resetting the desired moisture level if the button is held in for a set length of time.<\/p>\n\n\n\n<p>The LEDs are addressable 5mm through hole WS2812s.&nbsp; The Adafruit NeoPixel library found&nbsp;<a href=\"https:\/\/github.com\/adafruit\/Adafruit_NeoPixel\">HERE<\/a>&nbsp;is used to set these to the desired color.<\/p>\n\n\n\n<p>Finally, the pump being used is an Adafruit Peristaltic 12V pump.&nbsp; With a peristaltic pump, no part of the pump contacts the water. The pump &#8220;squishes&#8221; the silicone tube to create the water flow.&nbsp; The pump&nbsp;is connected to the two-pin connector at the bottom right of the schematic. An optocoupler was added to the circuit for protection.&nbsp; A mosfet is used to allow digital motor control.<\/p>\n\n\n\n<p><strong>Schematic<\/strong><\/p>\n\n\n\n<p>The&nbsp;<a href=\"https:\/\/media.digikey.com\/Maker-resources\/plant_watering-V2.pdf\" target=\"_blank\" rel=\"noreferrer noopener\">Schematic<\/a>&nbsp;was drawn in KiCad.&nbsp; Many of the components used in this project are available in the&nbsp;<a href=\"https:\/\/github.com\/digikey\/digikey-kicad-library\">Digi-Key KiCad Library<\/a>!<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img data-opt-id=173318004  fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/www.digikey.no\/maker-media\/0a9fbe90-48c8-4910-96c6-f3e338b53902\" alt=\"indoor plant Schematic\" title=\"indoor plant Schematic\"\/><\/figure>\n\n\n\n<p><strong>Parts Needed<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/arduino\/A000066\/1050-1024-ND\/2784006\">1050-1024-ND<\/a>,&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/sparkfun-electronics\/DEV-13975\/1568-1768-ND\/7035333\">1568-1768-ND<\/a>, or&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/adafruit-industries-llc\/2488\/1528-1214-ND\/5353674\">1528-1214-ND<\/a>&nbsp;-Arduino Uno or Similar<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/adafruit-industries-llc\/1150\/1528-1404-ND\/5638299\">1528-1404-ND<\/a>&nbsp;-Peristaltic Pump<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/dfrobot\/SEN0193\/1738-1184-ND\/6588605\">1738-1184-ND<\/a>&nbsp;-Moisture sensor<\/li>\n\n\n\n<li>2x&nbsp;<a href=\"https:\/\/www.digikey.ca\/product-detail\/en\/on-semiconductor\/BC33725TA\/BC33725TACT-ND\/1532787\" target=\"_blank\" rel=\"noreferrer noopener\">BC33725TACT-ND<\/a>&nbsp;-Transistors<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/infineon-technologies\/IRF9540NPBF\/IRF9540NPBF-ND\/812088\">IRF9540NPBF-ND<\/a>&nbsp;-Mosfet<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/dfrobot\/SER0006\/1738-1385-ND\/7597224\">1738-1385-ND<\/a>&nbsp;-Servo<\/li>\n\n\n\n<li>2x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/sparkfun-electronics\/COM-12999\/1568-1214-ND\/5673800\">1568-1214-ND<\/a>&nbsp;-LEDs<\/li>\n\n\n\n<li>2x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/cw-industries\/GPTS203211B\/CW181-ND\/3190590\">CW181-ND<\/a>&nbsp;-Pushbutton Switches<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/lite-on-inc\/LTV-817\/160-1366-5-ND\/385836\">160-1366-5-ND<\/a>&nbsp;-Optoisolator<\/li>\n\n\n\n<li>2x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/yageo\/MFR-25FBF52-1K\/1.00KXBK-ND\/13011\">1.00KXBK-ND<\/a>&nbsp;-1k Ohm Resistors<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/yageo\/MFR-25FBF52-10K\/10.0KXBK-ND\/13219\">10.0KXBK-ND<\/a>&nbsp;-10k Ohm Resistor<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/yageo\/MFR-25FBF52-150R\/150XBK-ND\/12831\">150XBK-ND<\/a>&nbsp;-150 Ohm Resistor<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/nichicon\/UVZ1V471MPD\/493-1321-ND\/589062\">493-1321-ND<\/a>&nbsp;-470uF Capacitor<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/nichicon\/UVZ1C101MDD1TD\/493-13439-1-ND\/4342150\">493-13439-1-ND<\/a>&nbsp;-100uF Capacitor<\/li>\n\n\n\n<li>1x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/molex-llc\/0398890042\/WM13976-ND\/3262076\">WM13976-ND<\/a>&nbsp;-2 Position Connector<\/li>\n\n\n\n<li>2x&nbsp;<a href=\"https:\/\/www.digikey.no\/product-detail\/en\/sullins-connector-solutions\/PRPC003SGAN-M71RC\/S1311EC-03-ND\/2775451\">S1311EC-03-ND<\/a>&nbsp;-3 Position Right Angle Male Header<\/li>\n\n\n\n<li>12V power supply w\/barrel connector for Arduino Uno<\/li>\n\n\n\n<li>Water bottle &#8211; Really anything to hold water and insert the silicone tube from the pump will work.<\/li>\n\n\n\n<li>Breadboard, Perfboard, or Custom PCB<\/li>\n<\/ul>\n\n\n\n<p><strong>Code<\/strong><\/p>\n\n\n\n<p>Both the Adafruit NeoPixel library and the Servo library must be included at the top of the Arduino Sketch.<\/p>\n\n\n\n<p>Copy Code<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">\/*  Desk Plant Watering System <br> * <br> *  Be sure to look through the settings <strong>and<\/strong> test your sensor value on <br> *  your plant <strong>and<\/strong> make adjustments as needed. Different soils <strong>and<\/strong> plants <br> *  may <strong>require<\/strong> modifications to the variables below.<br> *\/<br> <br>#include &lt;Servo.h&gt;<br>#include &lt;Adafruit_NeoPixel.h&gt;<br><br>\/\/#define servoWaterUsed \/\/comment out if servo is not used.<br>const bool debug = 0; \/\/set to 1 to enable serial debugging<br><br>\/***** pin assignments *****\/<br>const int LEDPIN         = 6;<br>const int NUMPIXELS      = 2;<br>const int sensorPin      = A4;<br>const int sensorEn       = 4;<br>const int setButton      = 8; <br>const int waterButton    = 9;<br>const int pumpPin        = 2;  <br>const int servoPowerPin  = 5;<br>const int servoPin       = A5;<br><br>Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, LEDPIN, NEO_GRB   NEO_KHZ800);<br><br>#ifdef servoWaterUsed<br>  Servo waterServo;<br>#endif<br><br>\/***** Global Constants *****\/<br>\/\/color values = switch-case value<br>const int flashRed = 2;<br>const int flashGreen = 3;<br>const int green=4;<br>const int blue =5;<br>const int amber =6;<br>const int led1 = 0;   <br>const int led2 = 1;   <br><br>\/***** Global Variables *****\/<br>float filteredMoisture =0; <br>int moistureValue = 0;  \/\/initialize at max value to keep the water from turning upon power-up<br>int prevMoisture = 600; \/\/this will initialize the beginning average higher - water won't start until it gets a <br>chance to settle<br>int sensorValue = 0;  \/\/ variable to store the value coming from the sensor<br>int attempt = 0;      \/\/variable used to count how many times the plant has tried to water<br>int flashDelay = 250; \/\/delay used for flashing the led<br>int moistureMax = 1000; \/\/moisture value mapped from 0 to this value<br>int rawMoistureMax = 600; \/\/max raw value used to scale sensor reading<br>int rawMoistureMin = 200; \/\/min raw value  used to scale sensor reading<br>int menuPressTime=3000; \/\/time in milliseconds the button needs to be pressed before resetting <br>moisture value<br>int maxServoAngle = 30; \/\/servo starts at 90 and will move to this position in both directions<br>int servoCenter = 90; \/\/center position for the servo<br><br>\/***** Boolean Flags *****\/<br>boolean waterNeeded=false;<br>boolean waterOut=false;<br>boolean firstPress=true;<br>boolean waterButtonState=true;<br><br>\/***** Timer Variables *****\/<br>unsigned long buttonStartTime = 0;<br>unsigned long moistureTimer = 0;<br>unsigned long waterTimer = 0;<br><br>\/************ Settings ***************\/<br>unsigned long moistureCheckTime = 10000; \/\/time in milliseconds between moisture checks<br>unsigned long waterCheckTime = 120000;\/\/time in milliseconds between waterings - when needed<br><br>int flowTime = 10000; \/\/how long the pump will run each cycle\/attempt<br>int maxAttempts =15;   \/\/max number of times the water pump will run before the 'no water' shut off <br>will trigger<br><br>\/***** Custom Plant-dependant Variables *****\/<br>int desiredMoisture = 750; \/\/ this can be changed by holding the button (set moisture function)<br>int moistureDiff = 10;    \/\/pump will run when moisture reading is less than desired moisture - this value<\/pre>\n\n\n\n<p><strong>Setup, Main Loop, and Functions<\/strong><\/p>\n\n\n\n<p>Copy Code<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">void setup() <br>{<br>  pinMode(pumpPin, OUTPUT); <br>  pinMode(servoPowerPin, OUTPUT);<br>  pinMode(setButton,INPUT_PULLUP);<br>  pinMode(waterButton,INPUT_PULLUP);<br>    <br>  pixels.begin(); \/\/initialize neopixels<br>  pixels.setPixelColor(led1, pixels.Color(0,0,0)); \/\/Turn LED off<br>  pixels.setPixelColor(led2, pixels.Color(100,100,100)); \/\/Set LED2 to White<br>  pixels.show();<br>  moistureTimer=millis(); \/\/Begin moisture timer at current millis value<br>  waterTimer=millis();  \/\/Begin water timer at current millis value<br>  checkMoisture();  \/\/get first moisture reading<br>  #ifdef servoWaterUsed<br>    waterServo.attach(servoPin);<br>    digitalWrite(servoPowerPin,HIGH);  \/\/turn on survo<br>    waterServo.write(servoCenter); \/\/rotate servo to the center position (90)<br>    delay(1000); \/\/give the servo time to move to the center.<br>    digitalWrite(servoPowerPin,LOW); \/\/turn off servo<br>  #endif<br>  <strong>if<\/strong>(debug) Serial.begin(9600); \/\/turn on serial <strong>for<\/strong> debugging <strong>or<\/strong> monitoring values<br>  digitalWrite(pumpPin,LOW);<br>}<br><br>void loop() <br>{<br>  \/\/check moisture <strong>if<\/strong> the set amount of time has passed<br>  <strong>if<\/strong>(millis()-moistureTimer&gt;=moistureCheckTime)<br>  {<br>    checkMoisture();<br>    moistureTimer=millis();\/\/reset moisture timer to millis;<br>  }<br>  \/\/If left button is pressed water the plant<br>  <strong>if<\/strong>(digitalRead(waterButton)==!waterButtonState)   <br>  {<br>    water();<br>    waterButtonState=!waterButtonState;<br>  }<br>  <strong>if<\/strong>(digitalRead(setButton)==LOW)  \/\/<strong>if<\/strong> right button is pressed reset the water out alarm.  If held, <br>reset desired moisture level to current moisture<br>  {<br>    <strong>if<\/strong>(firstPress==true) <br>    {<br>      waterOut=false; \/\/reset the waterOut alarm<br>      attempt=0;      \/\/reset watering attempt count<br>      setLED2(amber); <br>      buttonStartTime=millis(); \/\/Start timer to count how long the button is held<br>      firstPress=false; \/\/set flag to skip this <strong>if<\/strong> statement <strong>until<\/strong> after the button has been released<br>    }<br>    \/\/<strong>if<\/strong> button is held <strong>for<\/strong> more than menuPressTime (<strong>in<\/strong> milliseconds) reset desired moisture value to <br>current moisture<br>    <strong>else<\/strong> <strong>if<\/strong>(digitalRead(setButton)==LOW &amp;&amp; (millis()-buttonStartTime)&gt;menuPressTime &amp;&amp; firstPress == false) <br>    {<br>        desiredMoisture=checkMoisture(); \/\/reset desired moisture value<br>        <strong>if<\/strong>(debug) Serial.println(\"Desired Moisture set to: \");<br>        <strong>if<\/strong>(debug) Serial.println(desiredMoisture);<br>        setLED2(flashGreen);<br>    }<br>  }<br>  <strong>else<\/strong> firstPress=true; \/\/reset button flag <br>  <br>  <strong>if<\/strong>(attempt&gt;=maxAttempts)  <br>  { \/\/<strong>if<\/strong> watering attemps has exceded maxAttempts, set waterOut alarm <strong>and<\/strong> flash red LED<br>    waterOut=true;<br>    setLED2(flashRed);<br>  }<br>  <strong>else<\/strong> <strong>if<\/strong>(moistureValue&lt;desiredMoisture-moistureDiff) waterNeeded=true; \/\/<strong>if<\/strong> moisture is lower than<br> desired moisture minus differential set waterNeeded flag<br>  <strong>else<\/strong> <strong>if<\/strong>(moistureValue&gt;=desiredMoisture moistureDiff) <br>  {<br>    waterNeeded=false; \/\/<strong>if<\/strong> moisture is greater than desired moisture plus differential reset waterNeeded<br> flag<br>    attempt=0;<br>  }<br><br>  <strong>if<\/strong>(!waterOut &amp;&amp; waterNeeded==true &amp;&amp; millis()-waterTimer&gt;waterCheckTime)   <br>  {  \/\/water the plant <strong>if<\/strong> the water is <strong>not<\/strong> out, the waterNeeded flag is set, <strong>and<\/strong> the water check time has<br> passed<br>    water();<br>    attempt  ;<br>    waterTimer=millis();<br>  }<br>  <strong>else<\/strong> setLED1(); \/\/led1 will fade with the moisture reading.<br>}<br><br>\/***** Water <strong>function<\/strong> <strong>to<\/strong> <strong>run<\/strong> <strong>pump<\/strong> <strong>without<\/strong> <strong>servo<\/strong> *****\/<br><strong>void<\/strong> <strong>water<\/strong>(void)<br>{<br>  #ifdef servoWaterUsed<br>  {<br>    int positionDelay=flowTime\/4;<br>    \/\/setLED2(blue);<br>    \/\/digitalWrite(pumpPin, HIGH);  \/\/turn on pump<br>    digitalWrite(servoPowerPin,HIGH); \/\/turn on servo power<br>    <strong>for<\/strong>(servoCenter; servoCenter&lt;(90 maxServoAngle); servoCenter  )\/\/move servo from center to max<br> servo position<br>    {<br>      waterServo.write(servoCenter);<br>      delay(positionDelay\/maxServoAngle);<br>    }<br>    <strong>for<\/strong>(servoCenter; servoCenter&gt;(90-maxServoAngle); servoCenter--)\/\/move servo to min servo position<br>    {<br>      waterServo.write(servoCenter);<br>      delay(positionDelay\/maxServoAngle);<br>    }<br>      for(servoCenter; servoCenter&lt;90; servoCenter  ) \/\/move servo to center<br>    {<br>      waterServo.write(servoCenter);<br>      delay(positionDelay\/maxServoAngle);<br>    }<br>    delay(1000);<br>    digitalWrite(servoPowerPin,LOW); \/\/turn off servo power<br>    digitalWrite(pumpPin, LOW); \/\/turn off pump<br>    }<br>  #else<br>  setLED2(blue);<br>  digitalWrite(pumpPin, HIGH);<br>  delay(flowTime);<br>  digitalWrite(pumpPin, LOW);<br>  #endif<br>}<br><br>\/***** Water function to run pump with servo *****\/<br><br>\/***** Check Moisture Value *****\/<br>int checkMoisture()<br>{<br>  float weight=0.5;   \/\/weight used to average the reading - lower value=slower changing average<br>  digitalWrite(sensorEn,HIGH); \/\/turn on sensor<br>  delay(250); \/\/wait here for a bit<br>  filteredMoisture=(weight*analogRead(sensorPin)) (1-weight)*prevMoisture; \/\/filter -weighted average<br> with new reading and previouse reading<br>  moistureValue= map(filteredMoisture,rawMoistureMin,rawMoistureMax,moistureMax,0);<br> \/\/constrain moisture value.<br><br>    if(debug)Serial.print(\"Desired Moisture: \");<br>    if(debug)Serial.println(desiredMoisture);<br>    if(debug)Serial.print(\"Filtered Value: \");<br>    if(debug)Serial.println(filteredMoisture);<br>    if(debug)Serial.print(\"Moisture Value: \");<br>    if(debug)Serial.println(moistureValue);<br>    <br><br>  prevMoisture=filteredMoisture;<br>  return moistureValue;<br>}<br><br>\/***** Set Upper LED *****\/<br>void setLED1(void)<br>{<br>  int colorVal,gColorVal,rColorVal;<br>  \/\/use map function to set colorVal to usable range (0-255) from current moisture value<br>  colorVal=map(moistureValue,desiredMoisture-moistureDiff,desiredMoisture moistureDiff,0,255);  <br>  gColorVal=colorVal;<br>  if(gColorVal&gt;255) gColorVal=255;<br>  rColorVal=255-gColorVal;<br>  if(rColorVal&lt;0) rColorVal=0;<br>  pixels.setPixelColor(led1, pixels.Color(gColorVal,rColorVal,0));\/\/set led1 to match moisture<br>  pixels.setPixelColor(led2, pixels.Color(0,0,0));\/\/turn off led2<br>  pixels.show();<br>}<br><br>\/***** Set Lower LED *****\/<br>void setLED2(int mode)<br>{<br>  switch(mode)<br>  {<br>    case flashRed:<br>      for(int x=0;x&lt;5;x  )<br>      {<br>        pixels.setPixelColor(led2, pixels.Color(0,180,0));<br>        pixels.show();<br>        delay(flashDelay);<br>        pixels.setPixelColor(led2, pixels.Color(0,0,0));<br>        pixels.show();<br>        delay(flashDelay);<br>      }<br>    break;<br>    case flashGreen:<br>      for(int x=0;x&lt;5;x  )<br>      {<br>        pixels.setPixelColor(led2, pixels.Color(180,0,0));<br>        pixels.show();<br>        delay(flashDelay);<br>        pixels.setPixelColor(led2, pixels.Color(0,0,0));<br>        pixels.show();<br>        delay(flashDelay);<br>      }<br>    break;<br>    case green:<br>        pixels.setPixelColor(led2, pixels.Color(180,0,0));<br>        pixels.show();<br>    break;<br>    case blue:<br>        pixels.setPixelColor(led2, pixels.Color(0,0,180));<br>        pixels.show();<br>    break;<br>    case amber:<br>        pixels.setPixelColor(led2, pixels.Color(150,150,0));<br>        pixels.show();<br>    break;    <br>  }<br>}<\/pre>\n\n\n\n<p><strong>Downloadable 3D parts<\/strong><\/p>\n\n\n\n<p>Main Bracket:&nbsp;<a href=\"https:\/\/a360.co\/2LfCHO9\">https:\/\/a360.co\/2LfCHO9<\/a><\/p>\n\n\n\n<p>Servo Arm:&nbsp;<a href=\"https:\/\/a360.co\/2vZIQcu\">https:\/\/a360.co\/2vZIQcu<\/a><\/p>\n\n\n\n<p><a href=\"https:\/\/media.digikey.com\/Maker-resources\/Plant_Watering.zip\" target=\"_blank\" rel=\"noreferrer noopener\">Plant Watering.zip<\/a><\/p>\n\n\n\n<p><strong>Conclusion<\/strong><\/p>\n\n\n\n<p>Keeping a plant watered is not a challenging task, although for me, it is easy to forget. There is also the problem of being away for multiple days at a time and not wanting your plant to go thirsty.&nbsp; Creating an automatic indoor watering system solved both these problems and made for a fun project!&nbsp; The Arduino code can be modified to work with different plant and soil types. Once the desired moisture is set, the water container needs to be filled once it gets low or when the Red light starts flashing.&nbsp; Otherwise just rest easy knowing your plant will stay hydrated!<\/p>\n\n\n\n<figure class=\"wp-block-image is-resized\"><img data-opt-id=1890312498  decoding=\"async\" src=\"https:\/\/www.digikey.no\/maker-media\/23a6b810-0191-4b88-9344-f2bb081973fa\" alt=\"Plant update\" width=\"316\" height=\"421\" title=\"Plant update\"\/><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>By Cody Walseth Overview This project is an&nbsp;Arduino Uno controlled automatic plant watering system.&nbsp; Using an Adafruit Peristaltic pump, DF Robot capacitive soil moisture sensor, addressable LEDs and a micro servo&nbsp;with a couple 3D printed parts. The way it works, is if the sensed moisture level falls below the desired value, the pump and servo&hellip;&nbsp;<\/p>\n","protected":false},"author":1,"featured_media":213,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"neve_meta_sidebar":"","neve_meta_container":"","neve_meta_enable_content_width":"","neve_meta_content_width":0,"neve_meta_title_alignment":"","neve_meta_author_avatar":"","neve_post_elements_order":"","neve_meta_disable_header":"","neve_meta_disable_footer":"","neve_meta_disable_title":"","_themeisle_gutenberg_block_has_review":false,"footnotes":""},"categories":[8],"tags":[],"class_list":["post-210","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-arduino"],"_links":{"self":[{"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/posts\/210","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/comments?post=210"}],"version-history":[{"count":1,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/posts\/210\/revisions"}],"predecessor-version":[{"id":211,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/posts\/210\/revisions\/211"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/media\/213"}],"wp:attachment":[{"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/media?parent=210"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/categories?post=210"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.moya.no\/wp\/wp-json\/wp\/v2\/tags?post=210"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}