#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const int buttonPin = 8; // Change to your button pin
bool buttonPressed = false;
int dropPositionX[10]; // Array to store X positions of water drops
int dropPositionY[10]; // Array to store Y positions of water drops
#define MAX_DISTANCE 100 // Maximum distance to consider as empty (in cm)
#define FULL_LEVEL_OFFSET 10 // The distance from the sensor to the full water level in cm
#define TEMP_SENSOR_PIN 6 // Pin for temperature sensor data
OneWire oneWire(TEMP_SENSOR_PIN);
DallasTemperature sensors(&oneWire);
#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)
#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(buttonPin, INPUT_PULLUP);
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for (;;) {}
}
display.clearDisplay();
pinMode(PUMP_PIN, OUTPUT);
pinMode(MANUAL_SWITCH_PIN, INPUT);
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);
sensors.begin(); // Initialize temperature sensor
}
void loop() {
buttonPressed = digitalRead(buttonPin);
if (buttonPressed) {
animateWater();
} else {
// Your existing code when the button is not pressed
}
int currentManualModeState = digitalRead(MANUAL_SWITCH_PIN);
if (currentManualModeState != lastManualModeState) {
delay(5); // 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(5); // 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, 1);
display.println("Water Level:");
display.print(waterLevel);
display.println("%");
display.setCursor(0, 22);
display.print("Pump: ");
if(pumpState) {
display.println("ON");
} else {
display.println("OFF");
}
display.setCursor(0, 37);
display.print("Mode: ");
if(manualMode == 0) {
display.println("Auto");
} else {
display.println("Manual");
}
// Draw a simple tank image
drawTankImage(80, 14, 48, 52, waterLevel);
display.display();
delay(1); // 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
// Subtract the offset from the measured distance
int adjustedDistance = distance - FULL_LEVEL_OFFSET;
// Map the adjusted distance to the water level percentage
int level = map(adjustedDistance, 0, MAX_DISTANCE - FULL_LEVEL_OFFSET, 100, 0);
return constrain(level, 0, 100); // Ensure water level is within 0-100 range
}
void drawTankImage(int x, int y, int width, int height, 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);
sensors.requestTemperatures(); // Request temperature readings
// Read temperature in Celsius
float temperatureC = sensors.getTempCByIndex(0);
// Display temperature
display.setCursor(0, 52);
display.print("Temp: ");
display.print(temperatureC);
display.println("C");
}
void animateWater() {
// Erase the previous water drops
for (int i = 0; i < 10; i++) {
display.fillRect(dropPositionX[i], dropPositionY[i], 3, 3, BLACK);
}
// Move water drops diagonally
for (int i = 0; i < 10; i++) {
dropPositionX[i] -= 1; // Move the water drop towards left
dropPositionY[i] += 1; // Move the water drop downwards
if (dropPositionX[i] < 100 || dropPositionY[i] > 63) { // If water drop reaches the end of the pipe or the bottom of the display
dropPositionX[i] = random(113, 117); // Reset its X position to a random point between 113 and 117
dropPositionY[i] = random(0, 5); // Reset its Y position to a random point between 0 and 5
}
// Draw the water drops at the new positions
display.fillCircle(dropPositionX[i], dropPositionY[i], 1, WHITE); // Draw water droplets
}
// Display the changes
display.display();
// Introduce a short delay to control animation speed
delay(1); // Adjust the delay for desired animation speed
}