Mithun Das
Published © GPL3+

Smart Indoor Harvesting Using Wio Terminal & Blynk

Cloud connected, fully automated, smart indoor herb harvesting using Seeed Studio's Wio Terminal and Blynk app.

BeginnerFull instructions provided10 hours999
Smart Indoor Harvesting Using Wio Terminal & Blynk

Things used in this project

Hardware components

Wio Terminal
Seeed Wio Terminal
×1
Seeed Wio-Terminal-Chassis-Battery
×1
Seeed Grove-Temperature-Humidity-Sensor-DHT11
×1
Grove - Relay
Seeed Grove - Relay
×1
M5Stack Watering Unit + Soil Moisture
×1
LED Strip, 1 m
LED Strip, 1 m
×1

Software apps and online services

Arduino IDE
Arduino IDE
Blynk
Blynk

Hand tools and fabrication machines

3D Printer (generic)
3D Printer (generic)

Story

Read more

Code

Maalee.ino

Arduino
#define BLYNK_PRINT Serial
#include "TFT_eSPI.h" //TFT LCD library 
#include "DHT.h" // DHT library 
#include <Wire.h>
#include <rpcWiFi.h>
#include <WiFiClient.h>
#include <BlynkSimpleWioTerminal.h>

char auth[] = "your_blynk_token";
char ssid[] = "your_wifi_name";
char pass[] = "your_wifi_password";


//Definitions of pins
#define PIN_PUMP  3
#define PIN_SOIL  2
#define DHTPIN    4
#define PIN_LIGHT 6
#define PIN_RELAY 0
#define DHTTYPE DHT11 //Define DHT sensor type 

//Initializations
DHT dht(DHTPIN, DHTTYPE); //Initializing DHT sensor
TFT_eSPI tft; //Initializing TFT LCD'
TFT_eSprite spr = TFT_eSprite(&tft); //Initializing buffer

//Variables
int sensorValue = 0;
int inBetweenTimer = 0;
long lastNotification = 0;
int moistureThreshold = 50;
int lightThreshold = 750;
long moistureAvr = 0;
long moistureReadingCounter = 0 ;

/**
   This method is called from Blynk Timer settings.
   When the timer starts, relay is turned on
   When the timer stops, relay is turned off
*/
BLYNK_WRITE(V5)
{

  int value = param.asInt();
  //value 1 is sent from Blynk when timer starts
  if (value == 1 ) {
    Serial.println("Turn on LEDS");
    digitalWrite(PIN_RELAY, HIGH);
    inBetweenTimer = 1;
  } else {
    //value 0 is sent from Blynk when timer stops
    Serial.println("Turn off LEDS");
    digitalWrite(PIN_RELAY, LOW);
    inBetweenTimer = 0;
  }
}

//slider to change moistureThreshold from Blynk
BLYNK_WRITE(V6)
{
  moistureThreshold = param.asInt();
}

//slider to change lightThreshold from Blynk
BLYNK_WRITE(V7)
{
  lightThreshold = param.asInt();
}


void setup() {
  //Start serial communication
  Serial.begin(9600);

  pinMode(PIN_PUMP, OUTPUT);
  pinMode(PIN_SOIL, INPUT);
  pinMode(PIN_LIGHT, INPUT);
  pinMode(PIN_RELAY, OUTPUT);

  //turning the LEDs off at startup
  digitalWrite(PIN_RELAY, LOW);

  //Start DHT sensor
  dht.begin();

  //Start TFT LCD
  tft.begin();
  //Set TFT LCD rotation
  tft.setRotation(3);

  tft.setTextSize(2);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_LIGHTGREY);
  tft.drawString("Connecting to ", 70, 80);
  tft.setTextSize(4);
  tft.drawString("Blynk", 80, 120);
  //connecting to Blynk cloud
  Blynk.begin(auth, ssid, pass);

  //Syncing all variable values from Blynk cloud to device
  Blynk.syncAll();

  tft.fillScreen(TFT_BLACK);

  //Setting the title header
  tft.fillRect(0, 0, 320, 50, TFT_YELLOW); //Rectangle fill with dark green
  tft.setTextColor(TFT_BLACK); //Setting text color
  tft.setTextSize(3); //Setting text size
  tft.drawString("Maalee", 100, 10); //Drawing a text string



  tft.drawFastVLine(150, 50, 160, TFT_DARKGREEN); //Drawing verticle line
  tft.drawFastHLine(0, 130, 320, TFT_DARKGREEN); //Drawing horizontal line
  tft.drawFastHLine(0, 210, 320, TFT_DARKGREEN); //Drawing horizontal line 2

  tft.setTextColor(TFT_LIGHTGREY);
  tft.setTextSize(1);
  tft.drawString("Temperature", 10, 60);

  tft.setTextSize(1);
  tft.drawString("Humidity", 10, 140);

  tft.setTextSize(1);
  tft.drawString("Soil Moisture", 160, 60);

  tft.setTextSize(1);
  tft.drawString("Darkness", 160, 140);

}

void loop() {
  int t = dht.readTemperature(); //Assign variable to store temperature
  t = t * 1.8 + 32;
  int h = dht.readHumidity(); //Assign variable to store humidity


  //Setting temperature
  spr.createSprite(100, 30);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_LIGHTGREY);
  spr.setTextSize(3);
  spr.drawNumber(t, 5, 5);
  spr.drawString("F", 45, 5);
  spr.pushSprite(35, 80);
  spr.deleteSprite();




  //Setting humidity
  spr.createSprite(100, 30);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_LIGHTGREY);
  spr.setTextSize(3);
  spr.drawNumber(h, 5, 5);
  spr.drawString("%", 45, 5);
  spr.pushSprite(35, 160);
  spr.deleteSprite();

  //Setting soil moisture
  sensorValue = analogRead(PIN_SOIL); //Store moisture sensor value

  //map moisture reading to 0-100 %
  int moistPct = map(sensorValue, 450, 560, 0, 100);
  if (moistPct > 100) {
    moistPct = 100;
  } else if (moistPct < 0) {
    moistPct = 0;
  }
  moistPct = 100 - moistPct;

  moistureReadingCounter = moistureReadingCounter + 1;
  moistureAvr = moistureAvr + moistPct;

  spr.createSprite(150, 50);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_LIGHTGREY);
  spr.setTextSize(3);
  spr.setTextColor(TFT_LIGHTGREY);
  spr.drawNumber(moistPct,  5, 5);
  spr.drawString("%", 45, 5);
  spr.setTextSize(1);
  spr.drawNumber(sensorValue,  105, 25);
  spr.pushSprite(165, 80);
  spr.deleteSprite();


  //Setting light
  int light = analogRead(PIN_LIGHT);  //Store light sensor value
  spr.createSprite(150, 30);
  spr.fillSprite(TFT_BLACK);
  spr.setTextColor(TFT_LIGHTGREY);
  spr.setTextSize(3);
  spr.drawNumber(light, 5, 5);
  spr.pushSprite(165, 160);
  spr.deleteSprite();

  //take moisture reading for 2 minutes and calculate average
  if (moistureReadingCounter > 120 ) {
    moistPct = (int) (moistureAvr / moistureReadingCounter);
    //turn on the pump for 2 seconds if moisture level goes below threshold
    if (moistPct < moistureThreshold ) {
//      String msg = "Pump is on. Moisture level is " + String(moistPct);
//      Blynk.notify(msg);

      digitalWrite(PIN_PUMP, HIGH);
      delay(2000);
      digitalWrite(PIN_PUMP, LOW);

    }

    moistureReadingCounter = 0;
    moistureAvr = 0;
  }

  //send notification if moisture level goes below 25%
  if (moistPct < 25) {
    if (lastNotification == 0 || (millis() - lastNotification) > 60 * 60 * 1000) {
      lastNotification = millis();
      Blynk.notify("Soil is too dry. Check the reservoir.");
    }
  }

  //turn off the LEDs when ambient light is bright and Blynk timer is on.
  if (inBetweenTimer == 1) {

    if (light > lightThreshold) {  //DARK
      digitalWrite(PIN_RELAY, HIGH);
    }
    else { //BRIGHT
      digitalWrite(PIN_RELAY, LOW);
    }
  }


  Blynk.virtualWrite(V1, t);
  Blynk.virtualWrite(V2, h);
  Blynk.virtualWrite(V3, moistPct);
  Blynk.virtualWrite(V4, light);

  delay(100);

}

Credits

Mithun Das

Mithun Das

23 projects β€’ 100 followers
Hacker and Maker driven by passion. Ambassador at Edge Impulse and Balena. Follow me on Twitter @tweetmithund

Comments

Add projectSign up / Login