#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define TRIGGER_PIN 2 // Ultrasonic sensor trigger pin
#define ECHO_PIN 3 // Ultrasonic sensor echo pin
#define PUMP_PIN 7 // Pump control pin
#define MANUAL_SWITCH_PIN 4 // Manual mode switch pin
#define PUMP_TOGGLE_BUTTON_PIN 5 // Single button for pump toggle
#define WATER_LEVEL_THRESHOLD_LOW 10 // Low water level threshold for automatic mode
#define WATER_LEVEL_THRESHOLD_HIGH 90 // High water level threshold for automatic mode
int manualMode = 0; // 0: Auto mode, 1: Manual mode
int waterLevel = 0;
bool pumpState = false; // Pump initial state: OFF
bool lastPumpToggleState = LOW; // Last state of pump toggle button
bool lastManualModeState = LOW; // Last state of manual mode switch
void setup() {
pinMode(PUMP_PIN, OUTPUT);
pinMode(MANUAL_SWITCH_PIN, INPUT_PULLUP);
pinMode(PUMP_TOGGLE_BUTTON_PIN, INPUT);
Serial.begin(9600);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.display();
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
pinMode(TRIGGER_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
}
void loop() {
int currentManualModeState = digitalRead(MANUAL_SWITCH_PIN);
if (currentManualModeState != lastManualModeState) {
delay(50); // Debounce delay
lastManualModeState = currentManualModeState;
}
if(currentManualModeState == LOW) {
manualMode = 0; // Auto mode
waterLevel = getWaterLevel();
if(waterLevel < WATER_LEVEL_THRESHOLD_LOW) {
pumpState = true; // Turn on pump
} else if(waterLevel > WATER_LEVEL_THRESHOLD_HIGH) {
pumpState = false; // Turn off pump
}
} else {
manualMode = 1; // Manual mode
waterLevel = getWaterLevel(); // Update water level in manual mode
int currentPumpToggleState = digitalRead(PUMP_TOGGLE_BUTTON_PIN);
if (currentPumpToggleState != lastPumpToggleState) {
delay(50); // Debounce delay
lastPumpToggleState = currentPumpToggleState;
if(currentPumpToggleState == HIGH) {
pumpState = !pumpState; // Toggle pump state
}
}
if(waterLevel >= WATER_LEVEL_THRESHOLD_HIGH) {
pumpState = false; // Turn off pump when tank is full
}
}
digitalWrite(PUMP_PIN, pumpState); // Control pump based on pumpState
display.clearDisplay();
display.setCursor(0, 0);
display.println("Water Level:");
display.print(waterLevel);
display.println("%");
display.setCursor(0, 20);
display.print("Pump: ");
if(pumpState) {
display.println("ON");
} else {
display.println("OFF");
}
display.setCursor(0, 34);
display.print("Mode: ");
if(manualMode == 0) {
display.println("Auto");
} else {
display.println("Manual");
}
// Draw a simple tank image
drawTankImage(85, 23, 40, waterLevel);
display.display();
delay(1000); // Add a delay to avoid flickering
}
int getWaterLevel() {
long duration, distance;
digitalWrite(TRIGGER_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIGGER_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIGGER_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 8; // Calculate distance in cm
int level = map(distance, 0, 100, 100, 0); // Map distance to water level percentage
return constrain(level, 0, 100); // Ensure water level is within 0-100 range
}
void drawTankImage(int x, int y, int width, int waterLevel) {
// Draw tank outline
display.drawRect(x, y, width, 40, WHITE);
display.drawRect(x + 2, y + 2, width - 4, 36, WHITE);
// Calculate the tank fill level based on waterLevel
int tankFillHeight = map(waterLevel, 0, 100, 2, 36);
// Draw tank fill based on water level
display.fillRect(x + 4, y + 38 - tankFillHeight, width - 8, tankFillHeight, WHITE);
}