#include <Wire.h>
#include <Keypad.h>
#include <Servo.h>
#include <SoftwareSerial.h>
#include <LiquidCrystal_I2C.h>
#include "HX711.h"
bool ALLOW_SENSORS = false;
const byte KEYPAD_ROWS = 4;
const byte KEYPAD_COLS = 4;
byte rowPins[KEYPAD_ROWS] = {9, 8, 7, 6};
byte colPins[KEYPAD_COLS] = {5, 4, 3, 2};
char keys[KEYPAD_ROWS][KEYPAD_COLS] = {
{'1', '2', '3', '+'},
{'4', '5', '6', '-'},
{'7', '8', '9', '*'},
{'.', '0', '=', '/'}};
HX711 scale;
#define LOADCELL_DOUT_PIN 11
#define LOADCELL_SCK_PIN 10
int CALIB_FACTOR = 0;
bool initMsgShown = false;
#define RE 8
#define DE 7
#define SOIL_MOISTURE_SENSOR_PIN A0
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);
LiquidCrystal_I2C lcd(0x27, 16, 4);
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KEYPAD_ROWS, KEYPAD_COLS);
String authCode;
void clearScreen()
{
lcd.clear();
}
void showMsg(String msg, int line = 0)
{
lcd.setCursor(1, line);
lcd.print(msg);
}
void updateCursor()
{
if (millis() / 250 % 2 == 0)
{
lcd.cursor();
}
else
{
lcd.noCursor();
}
}
void checkAuthCode(char key)
{
if (ALLOW_SENSORS)
return;
if (key == '=')
{
if (authCode.length() > 4 || authCode.length() <= 0)
{
showMsg("Invalid Auth Code, Retry");
authCode = "";
}
else
{
if (authCode == "0008")
{
showMsg("Auth Success!!");
ALLOW_SENSORS = true;
clearScreen();
showMsg("Loading Sensor Data...");
}
else if (authCode == "0000")
{
runCalibration();
}
else
{
showMsg("Wrong Code, Retry");
authCode = "";
}
}
}
else
{
lcd.print(key);
authCode += key;
}
}
void setup()
{
Serial.begin(9600);
lcd.begin();
lcd.backlight();
lcd.cursor();
lcd.setCursor(1, 0);
authCode = "";
mod.begin(9600);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN);
scale.set_scale(CALIB_FACTOR);
scale.tare();
}
void loop()
{
if (!ALLOW_SENSORS)
{
if (!initMsgShown)
{
showMsg("Enter Auth Code");
initMsgShown = true;
}
char key = keypad.getKey();
if (key)
{
checkAuthCode(key);
}
}
else
{
static unsigned long previousUpdateTime = 0;
const unsigned long updateInterval = 2000; // Update LCD every 2 seconds
if (millis() - previousUpdateTime >= updateInterval)
{
readAndUpdateSensors();
previousUpdateTime = millis();
}
}
}
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++)
{
values[i] = mod.read();
}
}
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++)
{
values[i] = mod.read();
}
}
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++)
{
values[i] = mod.read();
}
}
return values[4];
}
String soilNPKSensors()
{
byte val1, val2, val3;
val1 = nitrogen();
delay(250);
val2 = phosphorous();
delay(250);
val3 = potassium();
delay(250);
String msg = "N: " + String(val1) + "mg/kg P: " + String(val2) + "mg/kg K: " + String(val3) + "mg/kg";
return msg;
}
String soilMoisture()
{
int sensorValue = analogRead(SOIL_MOISTURE_SENSOR_PIN);
String s = String(sensorValue);
return "Soil Moisture: " + s;
}
String phSensor()
{
String phData;
for (int i = 1; i <= 10; i++)
{
String phdata = Serial.readStringUntil(':');
if (phdata != "")
{
String ph = Serial.readStringUntil('$');
float phValue = ph.toFloat();
phData = String(phValue);
}
}
return "ph: " + phData;
}
String loadCell()
{
float weight = scale.get_units();
return "Load: " + String(weight, 1) + "kg";
}
void runCalibration()
{
showMsg("Load cell calibrate");
clearScreen();
showMsg("Use + / - ");
showMsg("To calibrate ", 1);
showMsg("Press = to finish", 2);
clearScreen();
while (1)
{
char temp = keypad.getKey();
if (temp == '=')
{
return;
}
else if (temp == '+' || temp == 'a')
{
CALIB_FACTOR += 10;
}
else if (temp == '-' || temp == 'z')
{
CALIB_FACTOR -= 10;
}
}
}
void readAndUpdateSensors()
{
// clearScreen();
String lines[] = {
loadCell(),
soilNPKSensors(),
soilMoisture(),
phSensor()
};
for (int i = 0; i < 4; i++)
{
clearScreen();
showMsg(lines[i]);
delay(2000);
}
}