#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "Config.h"
#include "Sensors.h"
#include "Actuators.h"
// Objects
LiquidCrystal_I2C lcd(0x27, 16, 2);
SensorManager sensors;
ActuatorManager actuators;
// State Variables
unsigned long lastSensorUpdate = 0;
unsigned long lastButtonPress = 0;
unsigned long lastAutoScrollTime = 0;
unsigned long wateringStartTime = 0;
unsigned long wateringEndTime = 0;
bool isWateringActive = false;
int displayMode = 0;
// Custom Degree Symbol
byte degreeSymbol[8] = {0b00110,0b01001,0b01001,0b00110,0b00000,0b00000,0b00000,0b00000};
void setup() {
Serial.begin(9600);
// Init Components
lcd.init();
lcd.backlight();
lcd.createChar(0, degreeSymbol);
lcd.print("System Init...");
sensors.begin();
actuators.begin();
pinMode(PIN_BUTTON, INPUT_PULLUP);
delay(1000);
}
void loop() {
unsigned long now = millis();
// --- 1. SENSOR UPDATE & LOGIC ---
if (now - lastSensorUpdate >= SENSOR_UPDATE_INTERVAL) {
lastSensorUpdate = now;
sensors.update();
// Debug
Serial.print("T:"); Serial.print(sensors.getTemp());
Serial.print(" Soil:"); Serial.println(sensors.getHumSoil());
// CO2 Logic
if (sensors.getCO2() >= 1500) {
actuators.setBuzzerTone(1000);
} else {
actuators.stopBuzzer();
}
// Soil/Watering Logic
if (sensors.getHumSoil() < 60 && !isWateringActive) {
actuators.setBubbler(HIGH);
actuators.setWatering(HIGH);
wateringStartTime = now;
isWateringActive = true;
}
// Stop Watering after duration
if (isWateringActive && (now - wateringStartTime >= WATERING_DURATION)) {
actuators.setBubbler(LOW);
actuators.setWatering(LOW);
wateringEndTime = now;
isWateringActive = false;
}
// Temperature Logic
actuators.setHeater(sensors.getTemp() < 5);
actuators.setFan(sensors.getTemp() > 25);
// Light Logic
if (sensors.getLight() < 500) {
actuators.setGrowLights(128, 0, 128); // Purple
actuators.setLightIndicator(HIGH);
} else {
actuators.setGrowLights(0, 0, 0); // Off
actuators.setLightIndicator(LOW);
}
// --- 2. DISPLAY LOGIC ---
// Button Handling
if (digitalRead(PIN_BUTTON) == LOW) {
if (now - lastButtonPress > 200) { // Debounce
displayMode = (displayMode + 1) % 4;
lastButtonPress = now;
lastAutoScrollTime = now; // Reset auto-scroll timer
}
}
// Auto-Scroll Logic (AFK mode)
if (now - lastButtonPress > AUTO_SCROLL_DELAY) {
if (now - lastAutoScrollTime > SCROLL_INTERVAL) {
displayMode = (displayMode + 1) % 4;
lastAutoScrollTime = now;
}
}
// Draw LCD
lcd.clear();
lcd.setCursor(0,0);
switch(displayMode) {
case 0: // Temp & Air Humidity
lcd.print("Temp: "); lcd.print(sensors.getTemp()); lcd.write(0); lcd.print("C");
lcd.setCursor(0,1); lcd.print("Air Hum: "); lcd.print(sensors.getHumAir()); lcd.print("%");
break;
case 1: // Soil
lcd.print("Soil Hum: "); lcd.print(sensors.getHumSoil()); lcd.print("%");
if(isWateringActive) { lcd.setCursor(0,1); lcd.print("Watering..."); }
break;
case 2: // Light
lcd.print("Light: "); lcd.print(sensors.getLight());
break;
case 3: // CO2
lcd.print("CO2: "); lcd.print(sensors.getCO2()); lcd.print(" ppm");
break;
}
}
}Light (A1)
Soil Hum (A2)
CO2 (A3)
Bubbler (Pin 2)
Watering (Pin 3)
Heater (Pin 4)
Fan (Pin 5)
Light Indicator (Pin 9)
Air Temp/Hum
Change Menu
Buzzer