//LCD Initialization
#include <LiquidCrystal_I2C.h>
#define LDR_PIN 2
using namespace std;
#include <math.h>
// LDR Characteristics
const float GAMMA = 0.7;
const float RL10 = 50;
LiquidCrystal_I2C lcd(0x27, 20, 4);
//DHT Initialization
#include <DHT.h>
#define DHTPIN1 12
#define DHTPIN2 11
#define DHTPIN3 10
#define DHTPIN4 9
#define DHTTYPE DHT22
DHT dht1(DHTPIN1, DHTTYPE);
DHT dht2(DHTPIN2, DHTTYPE);
DHT dht3(DHTPIN3, DHTTYPE);
DHT dht4(DHTPIN4, DHTTYPE);
float humidity[4];
float temperature[4];
float water[4];
float motor_percent[4];
//Servo Initialization
#include <Servo.h>
Servo myservo1; // create servo object to control a servo 1
Servo myservo2; // create servo object to control a servo 2
Servo myservo3; // create servo object to control a servo 3
Servo myservo4; // create servo object to control a servo 4
double forward_pass(double h, double t) {
//variables for matrix multiplication
int i, j, k;
// x stores input humidity,temperature
double x[2][1] = {{h},{t}};
// weight vector 1 i.e. w1 is of dimensions 2x7
// so w1 transpose of dimensions 7x2
double w1_T[7][2] = {
{-0.4151496 , 0.44373405},
{-0.26421493, -0.00803267},
{ 0.3135231 , -0.7766129 },
{-1.2521678 , 0.93123084},
{-0.48760554, -0.73851335},
{-0.61379135, 0.18878712},
{ 0.5947052 , 0.47466454}
};
// mult1 stores the result of matrix multiplication of w1_T(7x2) and x(2x1)
// so dimensions of mult1 is (7x1)
double mult1[7][1] = {
{0},
{0},
{0},
{0},
{0},
{0},
{0}
};
// bias 1 of dimension 7x1
double bias1[7][1] = {
{-3.2539866} ,
{0.0} ,
{-0.02472453},
{-3.6391356} ,
{0.0} ,
{1.6801617} ,
{2.4059265}
};
// matrix multiplication
for (k = 0; k < 2; k++) {
for (i = 0; i < 7; i++) {
float tmp = 0;
tmp = w1_T[i][k];
for (j = 0; j < 1; j++) {
mult1[i][j] = mult1[i][j] + tmp * x[k][j];
}
}
}
// Input to next layer
// Adding bias1 to multiplication result
float x2[7][1];
for (i = 0; i < 7; i++)
{
for (j = 0; j < 1; j++)
{
x2[i][j] = mult1[i][j] + bias1[i][j];
}
}
//RELU Activation Function-
for (i = 0; i < 7; i++)
{
for (j = 0; j < 1; j++)
{
if (x2[i][j] < 0)
x2[i][j] = 0;
}
}
// weight vector 2 i.e. w2 is of dimensions 7x9
// so w2 transpose of dimensions 9x7
double w2_T[9][7] = {
{ 0.5849904 , -0.56390417, -0.00353913, 0.9448879 , -0.4239326 ,
-1.0454929 , -0.2022129 },
{-0.19816121, 0.6891103 , -0.08639619, 0.01231049, -0.34418222,
0.3016038 , -0.18989314},
{-0.4910823 , -0.55388504, 0.10100517, -1.2018261 , -0.23520783,
-0.28672296, 0.27644405},
{-0.31706598, 0.15042147, 0.02635749, -0.06614713, -0.4604447 ,
0.16849387, -0.21372734},
{-0.3657042 , 0.2743768 , -0.0724325 , 0.00811482, 0.6523544 ,
-0.1565325 , -0.49845544},
{-0.27402547, -0.08655491, 0.47995248, 0.0701426 , 0.06492429,
0.03756765, -0.00212658},
{-0.1582511 , -0.2097642 , 0.2948826 , -0.9309507 , 0.21805646,
-1.4061453 , 0.62326103},
{ 0.53360426, -0.06703684, 0.40263915, 0.40564016, 0.62056464,
-1.3094757 , 0.33012542},
{ 0.4281763 , -0.2367927 , 0.08876697, 0.5428177 , 0.29087767,
-1.3731613 , 0.76410127}
};
// mult2 stores the result of matrix multiplication of w2_T(9x7) and x2(7x1)
// so dimensions of mult2 is (9x1)
double mult2[9][1] = {
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0},
{0}
};
//bias 2 of dimension 9x1
double bias2[9][1] = {
{-3.0668378} ,
{0.0} ,
{1.8701594} ,
{0.0} ,
{0.0} ,
{-0.01298803},
{0.58112186},
{-0.93002635},
{-1.089445}
};
// matrix multiplication
for (k = 0; k < 7; k++) {
for (i = 0; i < 9; i++) {
float tmp = 0;
tmp = w2_T[i][k];
for (j = 0; j < 1; j++) {
mult2[i][j] = mult2[i][j] + tmp * x2[k][j];
}
}
}
// input to next layer
// Adding bias2 to multiplication result
double x3[9][1];
for (i = 0; i < 9; i++)
{
for (j = 0; j < 1; j++)
{
x3[i][j] = mult2[i][j] + bias2[i][j];
}
}
//RELU Activation Function
for (i = 0; i < 9; i++)
{
for (j = 0; j < 1; j++)
{
if (x3[i][j] < 0)
x3[i][j] = 0;
}
}
//weight vector 3 i.e. w3 is of dimensions 9x1
//so w3 transpose of dimensions 1x9
double w3_T[1][9] = {
{0.90990716, -0.2506563 , 1.1351497 , -0.40106028, -0.46258327,
-0.0830033 , -1.0956517 , 0.5047472 , 0.26671278 }
};
double mult3[1][1] = {
{0.0}
};
//bias 3 of dimension 1x1
double bias3[1][1] = {
{-0.7577006}
};
//matrix multiplication
for (k = 0; k < 9; k++) {
for (i = 0; i < 1; i++) {
float tmp = 0;
tmp = w3_T[i][k];
for (j = 0; j < 1; j++) {
mult3[i][j] = mult3[i][j] + tmp * x3[k][j];
}
}
}
//output is of dimension 1x1
double op[1][1] = {
{0.0}
};
//Adding bias3 to multiplication result
for (i = 0; i < 1; i++)
{
for (j = 0; j < 1; j++)
{
op[i][j] = mult3[i][j] + bias3[i][j];
}
}
//return result
return op[0][0];
}
void setup()
{
// put your setup code here, to run once:
//LCD Setup
pinMode(LDR_PIN, INPUT);
lcd.init();
lcd.backlight();
//Servo Setup
myservo1.attach(7);
myservo2.attach(6);
myservo3.attach(5);
myservo4.attach(4);
//DHT Setup
Serial.begin(9600);
dht1.begin();
dht2.begin();
dht3.begin();
dht4.begin();
}
void loop() {
// put your main code here, to run repeatedly:
//LCD
int analogValue = analogRead(A0);
float voltage = analogValue / 1024. * 5;
float resistance = 2000 * voltage / (1 - voltage / 5);
float lux = pow(RL10 * 1e3 * pow(10, GAMMA) / resistance, (1 / GAMMA));
// Reading temperature or humidity takes about 250 milliseconds!
// Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
humidity[0] = dht1.readHumidity();
temperature[0]= dht1.readTemperature();
humidity[1] = dht2.readHumidity();
temperature[1]= dht2.readTemperature();
humidity[2] = dht3.readHumidity();
temperature[2]= dht3.readTemperature();
humidity[3] = dht4.readHumidity();
temperature[3]= dht4.readTemperature();
if(lux < 50)
{
motor_percent[0] = 0, motor_percent[1] = 0, motor_percent[2] = 0, motor_percent[3] = 0;
water[0] = 0, water[1] = 0, water[2] = 0, water[3] = 0;
}
else
{
for(int i = 0; i < 4; i++)
{
water[i]=max(0,forward_pass(humidity[i],temperature[i]));
motor_percent[i]=(water[i]*180)/100;
}
}
myservo1.write(motor_percent[0]);
myservo2.write(motor_percent[1]);
myservo3.write(motor_percent[2]);
myservo4.write(motor_percent[3]);
lcd.setCursor(0,0);
lcd.print("1.");
lcd.print(water[0], 1);
lcd.print("% ");
lcd.setCursor(8,0);
lcd.print("2.");
lcd.print(water[1], 1);
lcd.print("%");
lcd.setCursor(0, 1);
lcd.print("3.");
lcd.print(water[2], 1);
lcd.print("% ");
lcd.setCursor(8,1);
lcd.print("4.");
lcd.print(water[3], 1);
lcd.print("%");
}