Shashank Prasanna
Published © GPL3+

Self Sufficient Automated Greenhouse

This greenhouse only needs quarterly maintenance, water refills, and heat maintenance to grow high-quality plants in the optimal conditions.

IntermediateWork in progress5 hours10,885
Self Sufficient Automated Greenhouse

Things used in this project

Hardware components

Arduino UNO Wifi Rev.2
Arduino UNO Wifi Rev.2
×1
Arduino MKR WiFi 1010
Arduino MKR WiFi 1010
×1
Arduino MKR ENV Shield
Arduino MKR ENV Shield
×1
Breadboard (generic)
Breadboard (generic)
×1
LED Strip, NeoPixel Digital RGB
LED Strip, NeoPixel Digital RGB
×1
Electrolytic Capacitor, 4700 µF
Electrolytic Capacitor, 4700 µF
×1
DC POWER JACK 2.1MM BARREL-TYPE PCB MOUNT
TaydaElectronics DC POWER JACK 2.1MM BARREL-TYPE PCB MOUNT
×2
9V 1A Switching Wall Power Supply
9V 1A Switching Wall Power Supply
×1
Adafruit 5V 1A
×2
Adafruit STEMMA Soil Sensor
This one is optional/ There are two programs, one with the soil sensor and one without. It won't majorly affect the greenhouse.
×1
Adafruit JST PH 4-Pin To Female Socket Cable
×1
Adafruit Digital Liquid Level Sensor
×1
Male/Male Jumper Wires
×1
Male/Female Jumper Wires
Male/Female Jumper Wires
×1
Adafruit Peristaltic Liquid Pump
×1
Greenhouse
×1
Resistor 330 ohm
Resistor 330 ohm
×1
Power MOSFET N-Channel
Power MOSFET N-Channel
×1
Adafruit 5V 2A power supply
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Schematic For The Uno WiFi Rev.2

Schematic For The MKR WiFi 1010

If you are not using the soil sensor, simply do not connect the wires in the schematic.

Code

Arduino MKR WiFi 1010 with ENV Shield Code (With Soil Sensor)

Arduino
This is the code that you upload to the MKR with the ENV Shield. It will read data, store some, and send the rest to the Arduino Uno WiFi.
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
// for Blynk
#include <Arduino_MKRENV.h>
// For the ENV Shield


char auth[] = "Your Blynk Auth"; 
char ssid[] = "Your WiFi SSID";
char pass[] = "Your WiFi password";
// Blynk credentials
int temperature; 
int illuminance;
int water; 
// the variables from the ENV shield and water sensor 

BlynkTimer timer;
WidgetBridge bridge1(V1); 
WidgetLED led(V2); 
// Declares the functions that the MKR will utilize with Blynk. 

void (* resetFunc) (void) = 0; 
/* I found that after running for about seven minutes, the MKR and the UNO crash. Doing a reset every five minutes solves the problem, and doesn't affect anything else.*/

void Sensor() {
  //This is the function that does all the sensor reading
  water = analogRead(A1); 
  if (water == 0) {
    Blynk.setProperty(V2, "color", "#23C48E"); 
    led.on(); 
  }
  else if (water != 0) {
    Blynk.setProperty(V2, "color", "#D3435C"); 
  }
  temperature = ENV.readTemperature(FAHRENHEIT);
  Blynk.virtualWrite(V0, temperature - 5); 
  illuminance = ENV.readIlluminance(LUX);
  Serial.println(illuminance);
  Blynk.virtualWrite(V4, illuminance); 
  if (illuminance < 1400 and illuminance >1300) {
    bridge1.virtualWrite(V1, 1); 
  }
  
  else if (illuminance < 1300 and illuminance > 1200) {
    bridge1.virtualWrite(V1, 2);
  }
  
  else if (illuminance < 1200 and illuminance > 1100) {
    bridge1.virtualWrite(V1, 3);
  }
  
  else if (illuminance < 1100 and illuminance > 1000) {
    bridge1.virtualWrite(V1, 4);
  }
  
  else if (illuminance < 1000 and illuminance > 900) {
    bridge1.virtualWrite(V1, 5);
  }
  else if (illuminance > 1400) {
    bridge1.virtualWrite(V1, 6); 
  }
  else if (illuminance < 900) {
    bridge1.virtualWrite(V1, 5);  
  }
}




  

void setup() {
  
  Serial.begin(9600); 
  Blynk.begin(auth, ssid, pass); 
  bridge1.setAuthToken("The UNO WiFi's Auth Token");  
  if (!ENV.begin()) {
    Serial.println("Failed to initialize MKR ENV shield!");
    while (1);
  }
  timer.setInterval(333L, Sensor); 
  // Executes Sensor() every 333 milliseconds
  timer.setInterval(300000, resetFunc); 
  // resets the board every five minutes
  
  }
  

void loop() { 
  Blynk.run();
  // Runs Blynk
  timer.run(); 
  // Runs the Blynk timer
}
















  

Arduino MKR WiFi 1010 with ENV Shield Code (Without Soil Sensor)

Arduino
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
#include <WidgetRTC.h>
#include <TimeLib.h>
// for Blynk and the RTC widget
#include <Arduino_MKRENV.h>
// For the ENV Shield
#include "Adafruit_seesaw.h"



//Blynk auth token and WiFi credentials, replace with yours
char auth[] = "Blynk_Auth_Token"; 
char ssid[] = "WiFi_SSID";
char pass[] = "WiFi_Password";
//Values that are used later on 
int temperature; 
int illuminance;
int water;  
bool pumpState = false; 
unsigned long whenWater = 0; 
unsigned long Now; 
int currentHour; 
int currentMinute; 

// Instances and Virtual Pin declarations 
BlynkTimer timer;
WidgetBridge bridge1(V1); 
WidgetBridge bridge2(V6); 
WidgetLED led(V2); 
WidgetRTC rtc; 
Adafruit_seesaw ss;

/* I've found that after a while, the Arduino just shuts down due to the burden held upon it. If you reset it every once in a while, it seems to be fine*/
void(* resetFunc) (void) = 0;

/* Checks sensor values, executes functions dependent on the values, and sends the values to the Blynk app*/
void Sensor() {
  water = analogRead(A1); 
  if (water == 0 and pumpState == false) { 
    Now = millis();
    if (Now - 60000 >= whenWater and pumpState == true) {
      Blynk.setProperty(V2, "color", "#23C48E"); 
      led.on(); 
    }
  }
  else if (water != 0) {
    Blynk.setProperty(V2, "color", "#D3435C"); 
    whenWater = millis();
  }
  
  temperature = ENV.readTemperature(FAHRENHEIT);
  Blynk.virtualWrite(V0, temperature - 5); 
  
  illuminance = ENV.readIlluminance(LUX);
  Serial.println(illuminance);
  Blynk.virtualWrite(V4, illuminance); 
  
  if (illuminance < 1400 and illuminance >1300) {
    bridge1.virtualWrite(V1, 1); 
  }
  
  else if (illuminance < 1300 and illuminance > 1200) {
    bridge1.virtualWrite(V1, 2);
  }
  
  else if (illuminance < 1200 and illuminance > 1100) {
    bridge1.virtualWrite(V1, 3);
  }
  
  else if (illuminance < 1100 and illuminance > 1000) {
    bridge1.virtualWrite(V1, 4);
  }
  
  else if (illuminance < 1000 and illuminance > 900) {
    bridge1.virtualWrite(V1, 5);
  }
  else if (illuminance > 1400) {
    bridge1.virtualWrite(V1, 6); 
  }
  else if (illuminance < 900) {
    bridge1.virtualWrite(V1, 5);  
  }
}

// Pours water to the plant if the time is 7:00 PM(19:00) and stops it two minutes later 
void Pour() {
  currentHour = hour(); 
  currentMinute = minute();
  /*change the 19 and the 0 if you want to change when the plant is watered*/
  if (currentHour == 19) {
      if (currentMinute == 0) {
        bridge2.virtualWrite(V6, 1); 
        pumpState = true; 
      }
      /* Change the number 3 if you want to change the length of time that the plant is watered. Keep in ming that the pump outputs about 100 ml per minute.*/
      else if (currentMinute == 3) {
        bridge2.virtualWrite(V6, 0); 
        pumpState = false; 
      }
      }
  }

// initializes the rtc when it connects to the Blynk server
BLYNK_CONNECTED() {
  rtc.begin(); 
}

void setup() {
  //Begin serial, useful for debugging
  Serial.begin(9600); 
  //Initializes Blynk
  Blynk.begin(auth, ssid, pass); 
  bridge1.setAuthToken("3M7_KAqE_eksQxq4uSuATTpknVCsjrdy");
  bridge2.setAuthToken("3M7_KAqE_eksQxq4uSuATTpknVCsjrdy");  
  // Sends an error message if the shield is not connected or broken
  if (!ENV.begin()) {
    Serial.println("Failed to initialize MKR ENV shield!");
    while (1);
  }
  else {
    Serial.println("The MKR ENV shield in connected!"); 
  }
  /*Sets timer intervals, runs Sensor every 2 minutes, Pour every minute, and resets every five minutes. */
  timer.setInterval(2000L, Sensor); 
  timer.setInterval(1000L, Pour); 
  timer.setInterval(5000L, resetFunc); 
  setSyncInterval(1*60);   
  bridge2.virtualWrite(V6, 0); 
  }
  

void loop() { 
  //Runs Blynk every iteration of the loop. 
  Blynk.run();
  timer.run(); 
}
















  

Arduino Uno WiFi Rev.2 Code

Arduino
This is the code used in the Arduino Uno WiFi Rev.2.
#include <SPI.h>
#include <WiFiNINA.h>
#include <BlynkSimpleWiFiNINA.h>
//needed for Blynk
#include <Adafruit_NeoPixel.h>
#define LED_PIN 9
#define LED_COUNT 30
//needed for the Neopixel strip

char auth[] = "Your auth";
char ssid[] = "Your WiFi ssid";
char pass[] = "Your WiFi password";
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
//change for your strip
uint32_t gLight1 = strip.Color(51, 0, 17);
uint32_t gLight2 = strip.Color(102, 0, 34);
uint32_t gLight3 = strip.Color(153, 0, 51);
uint32_t gLight4 = strip.Color(204, 0, 68);
uint32_t gLight5 = strip.Color(255, 0, 85);
//the five brightnesses of the Neopixel strip
int pinData; 
BlynkTimer timer; 
//the blynk timer definition
void (* resetFunc) (void) = 0; 
/* I've found that around seven minutes of runtime, the Uno runs into
errors. Reseting every five minutes solves this problem, and 
doesn'y affect anything.*/
BLYNK_WRITE(V1){
  /*reads the pindata over the bridge, so it can change the brightness of the neopixels*/
  pinData = param.asInt(); // pinData variable will store value that came via Bridge
  Serial.println(pinData);
  if (pinData == 1) {
     strip.fill(gLight1, 0, 30); 
     strip.show();
  }

  else if (pinData == 2) {
     strip.fill(gLight2, 0, 30); 
     strip.show();
       
  }

  else if (pinData == 3) {
     strip.fill(gLight3, 0, 30); 
     strip.show();
       
  }
  else if (pinData == 4) {
     strip.fill(gLight4, 0, 30);
     strip.show();
       
  }
  else if (pinData == 5) {
     strip.fill(gLight5, 0, 30);
     strip.show();
       
  }
  else if (pinData == 6) {
    strip.clear();
    strip.show();  
  }
}
BLYNK_WRITE(V6){
  // Checks if the soil is dry, sensor data coming over bridge2
  pinData2 = param.asInt(); 
  if (pinData2 == 1) {
    // If the soil is dry, turn on the pump
    digitalWrite(motorPin, HIGH); 
  }
  else if (pinData2 == 0) {
    //If the soil is moist enough, turn off the pump
    digitalWrite(motorPin, LOW); 
  }
}



void setup() {
  Serial.begin(9600); 
  Blynk.begin(auth, ssid, pass);
  strip.begin(); 
  strip.show();  
  // starts and resets neopixels
  timer.setInterval(300000, resetFunc); 
  //resets every 5 minutes

}

void loop() {
  // put your main code here, to run repeatedly:
  Blynk.run();  
  //runs Blynk
  timer.run(); 
  // runs Blynk timer
  Blynk.syncVirtual(V1, V6); 
  //syncs the bridge and bridge2 info
}

Credits

Shashank Prasanna

Shashank Prasanna

1 project • 11 followers
An avid Arduino and Raspberry Pi engineer.

Comments