Last active
July 1, 2025 09:15
-
-
Save Steven24K/8929808e401c44b22d49e5d2a97f1af9 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <Wire.h> | |
| #include <LiquidCrystal_I2C.h> | |
| #include <DHT11.h> | |
| // INPUT PINS | |
| const int SOIL_MOISTURE_PIN = 0; | |
| const int WATER_LEVEL_PIN = 1; | |
| const int BUTTON_PIN = 7; | |
| // Density, Humidity and Temperature sensor (DHT11) | |
| const int DHT_PIN = 8; | |
| DHT11 dht11(DHT_PIN); | |
| // OUTPUT PINS | |
| const int PUMP_RELAIS_PIN = 2; | |
| const int BUZZER_PIN = 3; | |
| const int RED_LED_PIN = 4; | |
| const int BLUE_LED_PIN = 5; | |
| const int GREEN_LED_PIN = 6; | |
| // LCD Display | |
| LiquidCrystal_I2C lcd(0x27, 16, 2); | |
| // display modes | |
| enum DisplayMode { | |
| DISPLAY_DHT, | |
| DISPLAY_WATER_SOIL, | |
| DISPLAY_OFF | |
| } | |
| current_display_mode = DISPLAY_DHT; | |
| const int MIN_WATER_LEVEL = 400; | |
| const int MIN_MOISTURE_VALUE = 30; // in percentage | |
| int moisturePercentage = 0; | |
| int water_level = 0; | |
| void setup() { | |
| pinMode(SOIL_MOISTURE_PIN, INPUT); | |
| pinMode(WATER_LEVEL_PIN, INPUT); | |
| // button | |
| pinMode(BUTTON_PIN, INPUT); | |
| attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), mode_button, FALLING); | |
| // buzzer | |
| pinMode(BUZZER_PIN, OUTPUT); | |
| // LED pins | |
| pinMode(RED_LED_PIN, OUTPUT); | |
| pinMode(BLUE_LED_PIN, OUTPUT); | |
| pinMode(GREEN_LED_PIN, OUTPUT); | |
| pinMode(PUMP_RELAIS_PIN, OUTPUT); | |
| digitalWrite(PUMP_RELAIS_PIN, HIGH); | |
| delay(500); | |
| digitalWrite(PUMP_RELAIS_PIN, LOW); | |
| // Test output pins | |
| buzz(100, 1); | |
| digitalWrite(RED_LED_PIN, HIGH); | |
| digitalWrite(BLUE_LED_PIN, HIGH); | |
| digitalWrite(GREEN_LED_PIN, HIGH); | |
| lcd.init(); | |
| lcd.backlight(); | |
| lcd.setCursor(0, 0); | |
| lcd.print("Hello world!"); | |
| lcd.setCursor(0, 1); | |
| lcd.print("I'm Steven"); | |
| delay(1000); | |
| digitalWrite(RED_LED_PIN, LOW); | |
| digitalWrite(BLUE_LED_PIN, LOW); | |
| digitalWrite(GREEN_LED_PIN, LOW); | |
| lcd.noBacklight(); | |
| lcd.clear(); | |
| } | |
| void loop() { | |
| const int button_pressed = digitalRead(BUTTON_PIN); | |
| // Only if there is water in the reservoir and if the soil is too dry than activate the pump | |
| if (button_pressed == HIGH && water_level > MIN_WATER_LEVEL && moisturePercentage <= MIN_MOISTURE_VALUE) { | |
| // To prevent flooding and over watering only give water in intervals of 2 seconds. | |
| // Then determine in the next iteration if it should water again or is enough | |
| digitalWrite(PUMP_RELAIS_PIN, HIGH); | |
| delay(2000); | |
| digitalWrite(PUMP_RELAIS_PIN, LOW); | |
| } else { | |
| digitalWrite(PUMP_RELAIS_PIN, LOW); | |
| } | |
| // Read temperature and humidity | |
| int temperature = 0; | |
| int humidity = 0; | |
| dht11.readTemperatureHumidity(temperature, humidity); | |
| // Read moisture sensor | |
| int moistureValue = analogRead(SOIL_MOISTURE_PIN); | |
| moisturePercentage = map(moistureValue, 300, 900, 0, 100); | |
| moisturePercentage = constrain(moisturePercentage, 0, 100); | |
| // Read water lever | |
| water_level = analogRead(WATER_LEVEL_PIN); | |
| if (water_level <= MIN_WATER_LEVEL) { | |
| digitalWrite(BLUE_LED_PIN, HIGH); | |
| // buzz(100, 2); | |
| // buzz(200, 1); | |
| delay(500); | |
| } else { | |
| digitalWrite(BLUE_LED_PIN, LOW); | |
| } | |
| if (moisturePercentage <= MIN_MOISTURE_VALUE) { | |
| digitalWrite(RED_LED_PIN, HIGH); | |
| digitalWrite(GREEN_LED_PIN, LOW); | |
| // buzz(200, 1); | |
| // buzz(100, 2); | |
| delay(500); | |
| } else { | |
| digitalWrite(RED_LED_PIN, LOW); | |
| digitalWrite(GREEN_LED_PIN, HIGH); | |
| } | |
| if (current_display_mode == DISPLAY_DHT) { // Display temp and humidity values | |
| lcd.backlight(); | |
| lcd.setCursor(0, 0); | |
| lcd.print("Temp:" + String(temperature) + " C "); | |
| lcd.setCursor(0, 1); | |
| lcd.print("Humidity:" + String(humidity) + "% "); | |
| } else if (current_display_mode == DISPLAY_WATER_SOIL) { // Display moisture soil and water level values | |
| lcd.backlight(); | |
| lcd.setCursor(0, 0); | |
| if (water_level <= MIN_WATER_LEVEL) { | |
| lcd.print("Refill water (" + String(water_level) + ")"); | |
| } else { | |
| lcd.print("Enough water "); | |
| } | |
| lcd.setCursor(0, 1); | |
| lcd.print("Soil Moist:" + String(moisturePercentage) + "% "); | |
| } else if (current_display_mode == DISPLAY_OFF) { // Display off, for energy saving mode | |
| lcd.noBacklight(); | |
| lcd.clear(); | |
| } | |
| } | |
| void buzz(int duration, int tone) { | |
| for (int i = 0; i < duration; i++) { // make a sound | |
| digitalWrite(BUZZER_PIN, HIGH); // send high signal to buzzer | |
| delay(tone); // delay 1ms | |
| digitalWrite(BUZZER_PIN, LOW); // send low signal to buzzer | |
| delay(tone); | |
| } | |
| } | |
| void change_display() { | |
| if (current_display_mode == DISPLAY_DHT) { | |
| current_display_mode = DISPLAY_WATER_SOIL; | |
| } else if (current_display_mode == DISPLAY_WATER_SOIL) { | |
| current_display_mode = DISPLAY_OFF; | |
| } else if (current_display_mode == DISPLAY_OFF) { | |
| current_display_mode = DISPLAY_DHT; | |
| } | |
| } | |
| void mode_button() { | |
| change_display(); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment