#include <EEPROM.h>
#include <LiquidCrystal.h>
#include <Adafruit_NeoPixel.h>
#include "pitches.h"
#include <Servo.h>
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
Servo servo1;
Adafruit_NeoPixel ring1 = Adafruit_NeoPixel(16, 6, NEO_GRB + NEO_KHZ800);
long duration, inches;
int set_val, percentage;
bool state, pump, buzzerFlag;
unsigned long buzzerStartTime;
#define BUZZER_PIN 13
void setup() {
lcd.begin(16, 2);
lcd.print("SOIL WET:");
lcd.setCursor(0, 1);
lcd.print("PUMP:OFF MANUAL");
pinMode(8, OUTPUT);
pinMode(9, INPUT);
pinMode(10, INPUT_PULLUP);
pinMode(11, INPUT_PULLUP);
pinMode(12, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
servo1.attach(6);
ring1.begin();
set_val = EEPROM.read(0);
if (set_val > 150) set_val = 150;
buzzerFlag = false;
colorWipe(ring1.Color(0, 255, 0), 50);
}
void loop() {
digitalWrite(8, LOW);
delayMicroseconds(2);
digitalWrite(8, HIGH);
delayMicroseconds(10);
digitalWrite(8, LOW);
duration = pulseIn(9, HIGH);
inches = microsecondsToInches(duration);
percentage = (set_val - inches) * 100 / set_val;
// Check water level and control buzzer accordingly
if (percentage < 20) {
buzzerSpeedy();
} else if (percentage < 50) {
buzzerMild();
} else if (percentage >= 99) {
if (!buzzerFlag) {
buzzerMotorFull();
buzzerStartTime = millis();
buzzerFlag = true;
} else {
if (millis() - buzzerStartTime >= 5000) {
noTone(BUZZER_PIN);
pump = false;
digitalWrite(12, !pump);
}
}
} else {
noTone(BUZZER_PIN);
buzzerFlag = false;
}
lcd.setCursor(12, 0);
if (percentage < 0) percentage = 0;
lcd.print(percentage);
lcd.print("% ");
int servoAngle = map(percentage, 0, 100, 0, 180);
servo1.write(servoAngle);
// Control pump based on water level and mode
if (!digitalRead(11)) { // Check if in automatic mode
if (percentage < 10) {
pump = true; // Turn on pump if water level is below 10%
} else if (percentage > 99) {
pump = false; // Turn off pump if water level is above 99%
}
} else {
pump = false; // In manual mode, pump is always off
}
digitalWrite(12, !pump);
lcd.setCursor(5, 1);
lcd.print(pump ? "ON " : "OFF");
lcd.setCursor(9, 1);
lcd.print(digitalRead(11) ? "MANUAL" : "AUTO ");
if (!digitalRead(10) && !state && digitalRead(11)) {
state = true;
set_val = inches;
EEPROM.write(0, set_val);
}
if (!digitalRead(10) && !state && !digitalRead(11)) {
state = true;
pump = !pump;
}
if (digitalRead(10)) state = false;
updateNeopixelColor(percentage);
delay(500);
}
void buzzerSpeedy() {
tone(BUZZER_PIN, NOTE_C5, 50);
}
void buzzerMild() {
tone(BUZZER_PIN, NOTE_E5, 200);
}
void buzzerMotorFull() {
tone(BUZZER_PIN, NOTE_CS2, 500);
}
long microsecondsToInches(long microseconds) {
return microseconds / 74 / 2;
}
void updateNeopixelColor(int percentage) {
if (percentage >= 80) {
colorWipe(ring1.Color(139,69,19), 50);
} else if (percentage >= 60) {
colorWipe(ring1.Color(139, 69, 19), 50);
} else if (percentage >= 30) {
colorWipe(ring1.Color(210, 180, 140), 50);
} else {
colorWipe(ring1.Color(192, 192, 192), 50);
}
}
void colorWipe(uint32_t color, int wait) {
for (int i = 0; i < ring1.numPixels(); i++) {
ring1.setPixelColor(i, color);
ring1.show();
delay(wait);
}
}