/*
Aquarium Monitor System
- Automatic temperature control (heating and cooling)
- Day-night lighting cycle simulation (assuming day and night for 15-sec intervals)
- Water level detection using ultrasonic sensor (assuming the aquarium to be an averge height of 50cm)
- Oxygen level monitoring and alarm for out-of-range values
- pH level monitoring and alarm for out-of-range values
*/
#include <DHT.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Servo.h>
// Pin Definitions
#define DHTPIN 2 // Data pin for the DHT22 sensor
#define DHTTYPE DHT22 // Define the type of DHT sensor
#define LIGHT_PIN 4 // LED for day-night shifting
#define HEATING_RELAY_PIN 6 // Relay to control the heating element
#define COOLING_RELAY_PIN 7 // Relay to control the cooling element
#define HEATING_LED_PIN 8 // LED to simulate the heating element
#define COOLING_LED_PIN 9 // LED to simulate the cooling element
#define BUZZER_PIN 10 // Buzzer pin
#define OXYGEN_SENSOR_PIN A0 // Analog pin for oxygen sensor (potentiometer)
#define OXYGEN_LED_PIN 11 // LED pin to simulate oxygen pump
#define PH_SENSOR_PIN A1 // Analog pin for pH sensor (potentiometer)
#define TRIG_PIN 12 // Ultrasonic sensor trigger pin
#define ECHO_PIN 13 // Ultrasonic sensor echo pin
// Libraries and Sensor Initialization
DHT dht(DHTPIN, DHTTYPE);
LiquidCrystal_I2C lcd(0x27, 16, 2);
// Time and Threshold Variables
const long interval = 10000; // Interval in milliseconds (10 seconds)
const float TEMP_THRESHOLD_LOW = 15.0; // Lower temperature threshold
const float TEMP_THRESHOLD_HIGH = 28.0; // Upper temperature threshold
// Oxygen and pH thresholds
const float OXYGEN_THRESHOLD = 80.0; // Upper oxygen threshold (percentage)
const float PH_THRESHOLD_LOW = 6.5; // Lower pH threshold
const float PH_THRESHOLD_HIGH = 8.5; // Upper pH threshold
const int WATER_LEVEL_THRESHOLD = 45; // Water level threshold in cm
// Timer for light toggling
unsigned long previousMillis = 0; // Stores the last time LIGHT_PIN was toggled
const long lightInterval = 10000; // Interval for toggling light (30 seconds)
bool lightState = false; // Current state of LIGHT_PIN
void setup()
{
dht.begin(); // Initialize the DHT sensor
pinMode(LIGHT_PIN, OUTPUT);
pinMode(HEATING_RELAY_PIN, OUTPUT);
pinMode(COOLING_RELAY_PIN, OUTPUT);
pinMode(HEATING_LED_PIN, OUTPUT);
pinMode(COOLING_LED_PIN, OUTPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(OXYGEN_SENSOR_PIN, INPUT);
pinMode(OXYGEN_LED_PIN, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Aquarium Monitor");
delay(2000);
lcd.clear();
}
long readUltrasonicDistance()
{
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
long duration = pulseIn(ECHO_PIN, HIGH);
long distance = duration * 0.034 / 2;
return distance;
}
void toggleLight()
{
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= lightInterval)
{
previousMillis = currentMillis; // Save the last toggle time
lightState = !lightState; // Toggle light state
digitalWrite(LIGHT_PIN, lightState ? HIGH : LOW);
}
}
void loop()
{
// Toggle the LIGHT_PIN every 30 seconds
toggleLight();
// Read temperature and humidity from DHT22 sensor
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
if (isnan(temperature)) {
lcd.setCursor(0, 0);
lcd.print("DHT Error ");
delay(2000);
return;
}
// Display temperature on LCD
lcd.setCursor(0, 0);
lcd.print("Temp: ");
lcd.print(temperature);
lcd.print("C ");
// Temperature control logic
if (temperature < TEMP_THRESHOLD_LOW)
{
digitalWrite(HEATING_RELAY_PIN, HIGH);
digitalWrite(HEATING_LED_PIN, HIGH);
digitalWrite(COOLING_RELAY_PIN, LOW);
digitalWrite(COOLING_LED_PIN, LOW);
lcd.setCursor(0, 1);
lcd.print("Heating... ");
}
else if (temperature > TEMP_THRESHOLD_HIGH)
{
digitalWrite(HEATING_RELAY_PIN, LOW);
digitalWrite(HEATING_LED_PIN, LOW);
digitalWrite(COOLING_RELAY_PIN, HIGH);
digitalWrite(COOLING_LED_PIN, HIGH);
lcd.setCursor(0, 1);
lcd.print("Cooling... ");
}
else
{
digitalWrite(HEATING_RELAY_PIN, LOW);
digitalWrite(HEATING_LED_PIN, LOW);
digitalWrite(COOLING_RELAY_PIN, LOW);
digitalWrite(COOLING_LED_PIN, LOW);
lcd.setCursor(0, 1);
lcd.print("Temp Stable ");
}
delay(2000);
// Water Level Detection with Ultrasonic Sensor
long waterLevel = readUltrasonicDistance();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Water: ");
lcd.print(waterLevel);
lcd.print(" cm ");
if (waterLevel < WATER_LEVEL_THRESHOLD)
{
lcd.setCursor(0, 1);
lcd.print("Add Water! ");
digitalWrite(BUZZER_PIN, HIGH);
tone(BUZZER_PIN,464,1000);
}
else
{
lcd.setCursor(0, 1);
lcd.print("Water OK ");
digitalWrite(BUZZER_PIN, LOW);
}
delay(2000);
// Oxygen Level Monitoring
int oxygenSensorValue = analogRead(OXYGEN_SENSOR_PIN);
float oxygenLevel = map(oxygenSensorValue, 0, 1023, 0, 100);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("O2: ");
lcd.print(oxygenLevel);
lcd.print("% ");
if (oxygenLevel < OXYGEN_THRESHOLD)
{
lcd.setCursor(0, 1);
lcd.print("O2 Low! ");
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(OXYGEN_LED_PIN, HIGH);
tone(BUZZER_PIN,696,1000);
}
else
{
lcd.setCursor(0, 1);
lcd.print("O2 Normal ");
}
delay(2000);
// pH Level Monitoring
int phSensorValue = analogRead(PH_SENSOR_PIN);
float phLevel = map(phSensorValue, 0, 1023, 0, 14);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("pH: ");
lcd.print(phLevel);
lcd.print(" ");
if (phLevel < PH_THRESHOLD_LOW)
{
lcd.setCursor(0, 1);
lcd.print("pH Low! ");
digitalWrite(BUZZER_PIN, HIGH);
tone(BUZZER_PIN,232,1000);
}
else if (phLevel > PH_THRESHOLD_HIGH)
{
lcd.setCursor(0, 1);
lcd.print("pH High! ");
digitalWrite(BUZZER_PIN, HIGH);
tone(BUZZER_PIN,232,1000);
}
else
{
lcd.setCursor(0, 1);
lcd.print("pH Normal ");
}
delay(2000);
}