Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 2 | ||||
| × | 1 | ||||
| × | 2 | ||||
Software apps and online services | ||||||
| ||||||
|
This work was inspired by the effects of climate change taking place on our planet and affecting agriculture. It is immediately applicable to the optimization of agricultural production in greenhouses and contributes to slowing down the phenomenon of climate change through water and energy savings.
For this purpose, a complete functional unit for monitoring and controlling the internal environmental conditions of a greenhouse was implemented using a microcontroller (Arduino) and the development of the appropriate software.
Also with internet connection we can remote monitor and control with an android or iOS device (a common smartphone or PC), using the application created for this purpose.
Although it did not exist at initial objectives of the work, at the process, export of automated crop yield measurements was achieved. But the most important addition would be the use of machine learning so that the unit can continuously improve the settings of the environmental conditions, therefore without external intervention to apply the ideal conditions for each type of crop and soil.
The total construction cost of the unit is very low, in our case a few tens of euros.
Features:
i. Water saving through controlled irrigation based on the existing soil moisture and the definition of the desired value.
ii. Energy saving through controlled heating and cooling in combination with external conditions.
iii. Monitoring and display of internal (temperature - humidity, soil humidity) and external environmental conditions (temperature - humidity) in real time and on a graph for a period of time.
iv. Control of internal conditions (greenhouse), with selection by the user of the desired value of temperature (heating) and soil moisture (automatic irrigation).
v. Monitoring and controlling system processes in real time, at any location, using a mobile phone or computer application.
vi. Fire detection - fire extinguishing.
vii. Motion detection in space (damage from animals).
viii. Measurement of production growth.
#define BLYNK_PRINT Serial
#include <SPI.h>
#include <Ethernet.h>
#include <BlynkSimpleEthernet.h>
#include <DHT.h>
#include "NewPing.h"
// You should get Auth Token in the Blynk App.
char auth[] = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
// This function will run every time Blynk connection is established
BLYNK_CONNECTED() {
Blynk.syncVirtual(V1, V7);
}
#define W5100_CS 10
#define SDCARD_CS 4
#define DHTaPIN 2
#define DHTbPIN 3
#define DHTaTYPE DHT11 // DHT 11)
#define DHTbTYPE DHT22 // DHT 22 (AM2302), AM2321
DHT dhta(DHTaPIN, DHTaTYPE); // Initialize DHT sensor for normal 16mhz Arduino
DHT dhtb(DHTbPIN, DHTbTYPE); // Initialize DHT sensor for normal 16mhz Arduino
#define TRIGGER_PIN 9
#define ECHO_PIN 8
#define MAX_DISTANCE 50
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);
float duration, distance;
int iterations = 5;
float soundsp; // Stores calculated speed of sound in M/S
float soundcm; // Stores calculated speed of sound in cm/ms
// Select your pin with physical button-output
const int btn2Pin = 7;
const int btn3Pin = 6;
const int btn4Pin = 4;
const int btn5Pin = 5;
const int btn6Pin = A2;
const int btn7Pin = A4;
WidgetLED led2(V2);
WidgetLED led3(V3);
WidgetLED led4(V4);
WidgetLED led5(V8);
WidgetLED led6(V10);
WidgetLED led7(V0);
BlynkTimer timer;
// V2 LED Widget represents the physical button state
boolean btn2State = false;
void buttonLed2Widget()
{
// Read button
boolean isPressed = (digitalRead(btn2Pin) == HIGH);
// If state has changed...
if (isPressed != btn2State) {
if (isPressed) {
led2.on();
} else {
led2.off();
}
btn2State = isPressed;
}
}
// V3 LED Widget represents the physical button state
boolean btn3State = false;
void buttonLed3Widget()
{
// Read button
boolean isPressed = (digitalRead(btn3Pin) == HIGH);
// If state has changed...
if (isPressed != btn3State) {
if (isPressed) {
led3.on();
} else {
led3.off();
}
btn3State = isPressed;
}
}
// V4 LED Widget represents the physical button state
boolean btn4State = false;
void buttonLed4Widget()
{
// Read button
boolean isPressed = (digitalRead(btn4Pin) == HIGH);
// If state has changed...
if (isPressed != btn4State) {
if (isPressed) {
led4.on();
} else {
led4.off();
}
btn4State = isPressed;
}
}
// V5 LED Widget represents the physical button state
boolean btn5State = false;
void buttonLed5Widget()
{
// Read button
boolean isPressed = (digitalRead(btn5Pin) == HIGH);
// If state has changed...
if (isPressed != btn5State) {
if (isPressed) {
led5.on();
} else {
led5.off();
}
btn5State = isPressed;
}
}
// V6 LED Widget represents the physical button state
boolean btn6State = false;
void buttonLed6Widget()
{
// Read button
boolean isPressed = (digitalRead(btn6Pin) == HIGH);
// If state has changed...
if (isPressed != btn6State) {
if (isPressed) {
led6.on();
} else {
led6.off();
}
btn6State = isPressed;
}
}
// V7 LED Widget represents the physical button state
boolean btn7State = false;
void buttonLed7Widget()
{
// Read button
boolean isPressed = (digitalRead(btn7Pin) == HIGH);
// If state has changed...
if (isPressed != btn7State) {
if (isPressed) {
led7.on();
} else {
led7.off();
}
btn7State = isPressed;
}
}
// Variable Definitions
float temp_internal; // Stores internal temperature value
float hum_internal; // Stores internal humidity value
float temp_external; // Stores external temperature value
float hum_external; // Stores external humidity value
int state; // Condition of pins
int valMoisture = 0; // Stores Moisture value
int LimM = 25; // Stores value after edit
int LimT = 22; // Stores value after edit
float hysteresis = 0.4;
//pin definitions
int MoisturePin = A0; // Moisture Analog pin
int Relay4_AirIn = 4; // airRelay4 Blower Air Fan IN
int Relay3_AirOut = 5; // airRelay3 Blower Air Fan OUT
int Relay2_Lamp = 6; // Relay2 Hot Lamp
int Relay1_Water = 7; // Relay1 Water Pump
int fire = A4; //virtual pin for led
int fire2 = A3; //buzzer,pumb
int smokeA0 = A5; //analog input
BLYNK_WRITE(V1){
LimT = param.asInt(); //write temp from slider
}
BLYNK_WRITE(V7){
LimM = param.asInt(); //write hum from slider
}
void soil()
{Blynk.virtualWrite(V9, valMoisture);}
void temp ()
{Blynk.virtualWrite(V11, hum_external);
Blynk.virtualWrite(V12, temp_external);}
void sendSensor()
{
float h = dhta.readHumidity(); //read from DHT11
float t = dhta.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT11 sensor!");
return;
}
Blynk.virtualWrite(V5, h);
Blynk.virtualWrite(V6, t);
}
/*
* PIR sensor
*/
int ledPin = A2; // choose the pin for the LED
int inputPin = A1; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
void myDistance()
{
Blynk.virtualWrite(V13,distance);// virtualpin 13 distance
}
void setup()
{
// Debug console
Serial.begin(9600);
pinMode(SDCARD_CS, OUTPUT);
digitalWrite(SDCARD_CS, HIGH); // Deselect the SD card
Blynk.begin(auth);
dhta.begin();
dhtb.begin();
pinMode(smokeA0, INPUT);
pinMode(fire, OUTPUT);
pinMode(fire2, OUTPUT);
digitalWrite(fire, LOW);
digitalWrite(fire2, LOW);
// Setup a function to be called every second
timer.setInterval(1000L, sendSensor);
timer.setInterval(1000L, temp);
timer.setInterval(1000L, myDistance);
//LEDS
pinMode(btn2Pin, INPUT_PULLUP);
timer.setInterval(1000L, buttonLed2Widget);
pinMode(btn3Pin, INPUT_PULLUP);
timer.setInterval(1000L, buttonLed3Widget);
pinMode(btn4Pin, INPUT_PULLUP);
timer.setInterval(1000L, buttonLed4Widget);
pinMode(btn5Pin, INPUT_PULLUP);
timer.setInterval(1000L, buttonLed5Widget);
pinMode(btn6Pin, INPUT_PULLUP);
timer.setInterval(500L, buttonLed6Widget);
pinMode(btn7Pin, INPUT_PULLUP);
timer.setInterval(1000L, buttonLed7Widget);
timer.setInterval(1000L, soil);
pinMode(ledPin, OUTPUT); // declare LED as output pir
pinMode(inputPin, INPUT); // declare sensor as input pir
// Initialize Relays
pinMode(Relay4_AirIn, OUTPUT);
pinMode(Relay3_AirOut, OUTPUT);
pinMode(Relay2_Lamp, OUTPUT);
pinMode(Relay1_Water, OUTPUT);
digitalWrite(Relay4_AirIn, LOW);
digitalWrite(Relay3_AirOut, LOW);
digitalWrite(Relay2_Lamp, LOW);
digitalWrite(Relay1_Water, LOW);
}
void loop()
{
Blynk.run();
timer.run();
//SMOKE
int analogSensor = analogRead(smokeA0);
Serial.print("Pin A5: ");
Serial.println(analogSensor);
// Checks if it has reached the threshold value
if (analogSensor >= 500) {
digitalWrite(fire, HIGH);
digitalWrite(fire2, HIGH);
}
else {
digitalWrite(fire, LOW);
digitalWrite(fire2, LOW);
}
// Read data from Sensors
// 1. Read data from Internal Sensor and store it to variables temp_internal and hum_internal
hum_internal = dhta.readHumidity();
temp_internal = dhta.readTemperature();
// 2. Read data from DHT22 and store it to variables hum and temp
hum_external = dhtb.readHumidity();
temp_external = dhtb.readTemperature();
valMoisture = ( analogRead(MoisturePin)) ;
valMoisture = map(valMoisture,980,250,0,100); //map for % moisture
//temp and hum add to calculate sound of speed
soundsp = 331.4 + (0.606 * temp_internal) + (0.0124 * hum_internal);
// Convert to cm/ms
soundcm = soundsp / 10000;
duration = sonar.ping_median(iterations);
// Calculate the distance
distance = 13 - (duration / 2) * soundcm;
//distance = 10-(duration/2)*0.0343;
// ***************************************************************************
// Print on Serial Window readed values
state = digitalRead(Relay4_AirIn);
Serial.print("Air In = ");
Serial.println(state);
state = digitalRead(Relay3_AirOut);
Serial.print("Air Out = ");
Serial.println(state);
state = digitalRead(Relay2_Lamp);
Serial.print("Lamp = ");
Serial.println(state);
state = digitalRead(Relay1_Water);
Serial.print("Water = ");
Serial.println(state);
Serial.println("");
Serial.print("Temperature set = ");
Serial.println(LimT);
Serial.print("Soil humidity set = ");
Serial.println(LimM);
// ***************************************************************************
// 1. Check limit value for Moisture Soil Sensor and control Relay1_Water
Serial.print("Soil: ");
Serial.println(valMoisture);
if (valMoisture <= LimM) {
digitalWrite(Relay1_Water, HIGH);
}
else {
digitalWrite(Relay1_Water, LOW);
}
// 2. Check greenhouse's Internal Condition and control Relays of Fans & Hot Lamp
// > LimT + hysteresis
if (temp_internal > LimT + hysteresis) {
if (temp_internal > temp_external) {
state = digitalRead(Relay4_AirIn);
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay4_AirIn, HIGH);
}
state = digitalRead(Relay3_AirOut);
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay3_AirOut, HIGH);
}
state = digitalRead(Relay2_Lamp);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay2_Lamp, LOW);
}
}
else {
state = digitalRead(Relay4_AirIn);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay4_AirIn, LOW);
}
state = digitalRead(Relay3_AirOut);
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay3_AirOut, HIGH);
}
state = digitalRead(Relay2_Lamp);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay2_Lamp, LOW);
}
}
}
////LimT - hysteresis
if (temp_internal < LimT - hysteresis) {
if (temp_internal < temp_external) {
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay4_AirIn, HIGH);
}
state = digitalRead(Relay3_AirOut);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay3_AirOut, LOW);
}
state = digitalRead(Relay2_Lamp);
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay2_Lamp, HIGH);
}
}
else {
state = digitalRead(Relay4_AirIn);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay4_AirIn, LOW);
}
state = digitalRead(Relay3_AirOut);
if (state == 0) {
// do nothing
}
else {
digitalWrite(Relay3_AirOut, LOW);
}
state = digitalRead(Relay2_Lamp);
if (state == 1) {
// do nothing
}
else {
digitalWrite(Relay2_Lamp, HIGH);
}
}
}
//pir code
{ val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(ledPin, HIGH); // turn LED ON
if (pirState == LOW) {
pirState = HIGH;
}
} else {
digitalWrite(ledPin, LOW); // turn LED OFF
if (pirState == HIGH){
pirState = LOW;}}}
}
Comments