#include <Wire.h>
#include <RTClib.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_NeoPixel.h>
RTC_DS3231 rtc;
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define NUM_LEDS 16 // Number of NeoPixel LEDs
#define NEOPIXEL_PIN 6 // Data pin connected to pin 6 on ESP32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
#define SSD1306_I2C_ADDRESS 0x3C
const int buzzerPin = 5; // Adjust this according to your wiring
int trig = 2; // Ultrasonic sensor trigger pin
int echo = 3; // Ultrasonic sensor echo pin
const float maxWaterLevel = 1.0; // Maximum distance in centimeters
const float minWaterLevel = 25.0; // Minimum distance in centimeters
// Function declaration
void colorWipe(uint32_t color, int delayTime);
void printWaterLevel(float waterPercentage);
void setup() {
Serial.begin(115200);
Wire.begin();
pinMode(buzzerPin, OUTPUT); // Set the buzzer pin as an output
pinMode(trig, OUTPUT);
pinMode(echo, INPUT);
if (!rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (rtc.lostPower()) {
Serial.println("RTC lost power, let's set the time!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
if (!display.begin(SSD1306_I2C_ADDRESS, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
strip.begin();
strip.show(); // Initialize all pixels to 'off'
}
float measureWaterLevel() {
digitalWrite(trig, LOW);
delayMicroseconds(2);
digitalWrite(trig, HIGH);
delayMicroseconds(10);
digitalWrite(trig, LOW);
float duration = pulseIn(echo, HIGH);
float distance = duration * 0.0343 / 2;
return distance;
}
void displayRTC(DateTime now) {
display.clearDisplay();
display.setCursor(13, 0);
display.setTextSize(3.5);
// Display hour in double digits
if (now.hour() < 10) {
display.print("0");
}
display.print(now.hour(), DEC);
display.print(':');
// Display minute in double digits
if (now.minute() < 10) {
display.print("0");
}
display.print(now.minute(), DEC);
display.setCursor(30, 40);
display.setTextSize(1);
// Display day in double digits
if (now.day() < 10) {
display.print("0");
}
display.print(now.day(), DEC);
display.print('/');
// Display month in double digits
if (now.month() < 10) {
display.print("0");
}
display.print(now.month(), DEC);
display.print('/');
display.println(now.year(), DEC);
display.display();
}
void glowBlueRed(int delayTime) {
// Set all LEDs to sea blue
colorWipe(strip.Color(21, 92, 67), delayTime);
// Set all LEDs to sea green
colorWipe(strip.Color(0, 255, 50), delayTime);
}
void colorWipe(uint32_t color, int delayTime) {
for (int i = 0; i < strip.numPixels(); i++) {
strip.setPixelColor(i, color);
strip.show();
delay(delayTime);
}
}
void printWaterLevel(float waterPercentage) {
Serial.print("Water Percentage: ");
Serial.print(waterPercentage);
Serial.println("%");
}
void displayUltrasonic(float waterPercentage) {
// Cap waterPercentage at 100%
waterPercentage = constrain(waterPercentage, 0, 100);
display.clearDisplay();
display.setCursor(0, 0);
display.setTextSize(2);
display.print("Water lev");
display.setCursor(10, 20);
display.setTextSize(2);
display.print(waterPercentage);
display.print(F("%"));
display.setCursor(0, 50);
if (waterPercentage <= 25) {
display.print(F("LOW"));
printWaterLevel(waterPercentage);
// Buzzer on for 5 seconds when water level is low
tone(buzzerPin, 1); // Adjust the frequency as needed
strip.fill(strip.Color(255, 0, 0)); // Set NeoPixel LED color to red
strip.show();
delay(5000);
noTone(buzzerPin);
strip.clear();
strip.show();
} else {
display.print(F("NORMAL"));
delay(2000);
printWaterLevel(waterPercentage);
glowBlueRed(1000); // Keep NeoPixel LEDs glowing sea blue and sea green
}
display.display();
}
void loop() {
DateTime now = rtc.now();
// Display RTC information continuously
displayRTC(now);
// Read the ultrasonic sensor data every 15 seconds
if (now.second() % 15 == 0) {
float waterLevel = measureWaterLevel();
float waterPercentage = map(waterLevel, minWaterLevel, maxWaterLevel, 0, 100);
// Cap waterPercentage at 100%
waterPercentage = constrain(waterPercentage, 0, 100);
displayUltrasonic(waterPercentage);
}
// Every 2 minutes, play the buzzer for 5 seconds
if (now.minute() % 2 == 0 && now.second() == 0) {
tone(buzzerPin, 1); // Adjust the frequency as needed
delay(2000);
noTone(buzzerPin);
}
}