//CONFIGURATION OF CIRCUIT
//SD Card Module:
//DO to Digital Pin 12
//GND to GND
//SCK to Digital Pin 13
//VCC to 5V Pin
//DI to Digital Pin 11
//CS to Digital Pin 10
//Temperature Sensor:
//VCC to 5V Pin
//GND to GND
//DQ to Digital Pin 8
//Moisture Sensor:
//VCC to 5V Pin
//GND to GND
//Analog Output to A0 Pin
//LCD 20x4 i2c:
//GND to GND
//VCC to 5V Pin
//SDA to A4 Pin
//SCL to A5 Pin
//Button:
//GND to GND
//Terminal 2 to Digital Pin 5
//Motor:
//GND to GND
//VCC to Digital Pin 9
//File Indicator LED:
//GND to GND
//VCC to Digital Pin 4
//NPK Sensor
//Cathode(Brown wire) to 9v/12v Power supply
//GND(Black wire) to power supply and GND Pin of MAX485 Modbus Module
//485B(Blue wire) to B Pin of MAX485 Modbus Module
//485A(Yellow wire) to A Pin of MAX485 Modbus Module
//MAX485 Modbus Module
//GND to GND
//VCC to 5V Pin
//DI to Digital Pin 3
//RO to Digital Pin 2
//DE to Digital Pin 6
//RE to Digital Pin 1
#include <SD.h>
#include <SPI.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>
#include <SoftwareSerial.h>
#include <Wire.h>
File tempFile;
File moistFile;
File NPKFile;
#define ONE_WIRE_BUS 8
#define motorPin 9
#define vccMoist 7
#define AOUT_PIN A0
#define I2C_ADDR 0x27
#define LCD_COLUMNS 20
#define LCD_LINES 4
#define RE 1
#define DE 6
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
int temp;
const int pinCS = 10;
bool motorState = false;
String motorOnorOff = "OFF";
bool wetState;
//Button (Press this button to switch between the NPK sensor and other
//sensor values to be displayed in the LCD)
int button = 5;
int status = false;
bool lcdClearStatus = false;
const byte nitro[] = {0x01,0x03, 0x00, 0x1e, 0x00, 0x01, 0xe4, 0x0c};
const byte phos[] = {0x01,0x03, 0x00, 0x1f, 0x00, 0x01, 0xb5, 0xcc};
const byte pota[] = {0x01,0x03, 0x00, 0x20, 0x00, 0x01, 0x85, 0xc0};
byte values[11];
SoftwareSerial mod(2,3);
void setup() {
Serial.begin(9600);
sensors.begin();
mod.begin(9600);
pinMode (pinCS, OUTPUT);
pinMode (4, OUTPUT);
pinMode (motorPin, OUTPUT);
pinMode (vccMoist, OUTPUT);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
pinMode (button, INPUT_PULLUP);
lcd.init();
lcd.backlight();
if (SD.begin()){
Serial.println("SD Card is ready to use");
Serial.println("");
} else{
Serial.println("SD Card Initialization Failed");
return;
}
}
void loop() {
sensors.requestTemperatures();
int temp = sensors.getTempCByIndex(0);
int value = analogRead(AOUT_PIN);
int percValue = value/1023.0*100; //Converts the moisture value to percentage
tempFile = SD.open("temp.txt", FILE_WRITE);
moistFile = SD.open("moist.txt", FILE_WRITE);
NPKFile = SD.open("NPK.txt", FILE_WRITE);
//NPK SENSOR
byte val1,val2,val3;
val1 = nitrogen();
delay(100);
val2 = phosphorous();
delay(100);
val3 = potassium();
delay(100);
if(digitalRead(button) == false){
status = !status;
lcd.clear();
//NPK Values print to lcd
lcd.setCursor(5, 0);
lcd.println("NPK Sensor");
lcd.setCursor(0, 1);
lcd.print("N: ");
lcd.print(val1);
lcd.print(" mg/kg");
lcd.setCursor(0, 2);
lcd.print("P: ");
lcd.print(val2);
lcd.print(" mg/kg");
lcd.setCursor(0, 3);
lcd.print("K: ");
lcd.print(val3);
lcd.print(" mg/kg");
} else {
lcd.clear();
lcd.setCursor(6, 0);
lcd.println("SENSORS");
//Temperature value print to lcd
lcd.setCursor(0, 1);
lcd.print("Temperature: ");
lcd.println((String)temp+ " C");
lcd.setCursor(0, 2);
lcd.print("Motor ");
lcd.println(motorOnorOff);
//Moisture value print to lcd
lcd.setCursor(0, 3);
lcd.print("Moisture lvl: ");
lcd.println((String)percValue+ " %");
}
//WRITE TEMPERATURE DATA TO SD CARD
if(tempFile){
tempFile.print(temp);
tempFile.close();
digitalWrite(4, HIGH); //This line is just to check if the txt file is created
} else {
Serial.println("Error Opening file");
}
//WRITE MOISTURE DATA TO SD CARD
if(moistFile){
moistFile.print(percValue);
moistFile.close();
digitalWrite(4, HIGH); //This line is just to check if the txt file is created
} else {
Serial.println("Error Opening file");
}
//WRITE NPK SENSOR DATA TO SD CARD
if(NPKFile){
NPKFile.println("N: " +val1);
NPKFile.println("P: " +val2);
NPKFile.println("K: " +val3);
NPKFile.println("");
NPKFile.close();
digitalWrite(4, HIGH); //This line is just to check if the txt file is created
} else {
Serial.println("Error Opening file");
}
//Set motor On or Off based on temperature
while(temp >= 90 && !motorState){
digitalWrite(motorPin, HIGH);
Serial.println("Motor ON");
motorState = true;
motorOnorOff = "ON";
}
while(temp <90 && motorState == true){
digitalWrite(motorPin, LOW);
Serial.println("Motor OFF");
motorState = false;
motorOnorOff = "OFF";
}
Serial.print("Moisture Level: ");
Serial.print(value);
Serial.println("");
Serial.print("Celsius Temperature: ");
Serial.println(sensors.getTempCByIndex(0));
Serial.println("");
delay(2000);
}
byte nitrogen(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(nitro,sizeof(nitro))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte phosphorous(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(phos,sizeof(phos))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}
byte potassium(){
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(pota,sizeof(pota))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
for(byte i=0;i<7;i++){
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
Serial.print(values[i],HEX);
}
Serial.println();
}
return values[4];
}