#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <IRremote.h>
LiquidCrystal_I2C lcd(0x27, 16, 2);
#define LED_PIN 13
#define BUTTON_PIN 12
#define RELAY_PIN 7
#define RECV_PIN 2
#define PIR_PIN 8
#define LED2_PIN 9
#define PIR_STATUS_LED 10 // LED báo trạng thái cảm biến PIR
#define TRIG_PIN 6 // Chân phát tín hiệu của cảm biến siêu âm
#define ECHO_PIN 5 // Chân nhận tín hiệu của cảm biến siêu âm
#define WATER_LEVEL_THRESHOLD 20 // Mức nước cần đo (cm), nếu mực nước nhỏ hơn giá trị này, bật máy bơm
long duration;
int distance;
IRrecv irrecv(RECV_PIN);
decode_results results;
const int IR_LED_ON = 48;
const int IR_LED_OFF = 24;
bool ledState = false;
bool buttonLastState = HIGH;
unsigned long lastButtonPress = 0; // Lưu thời gian nhấn nút gần nhất
int lastPirState = LOW; // Lưu trạng thái PIR trước đó
unsigned long lastWaterLevelCheck = 0; // Thời gian kiểm tra mực nước gần nhất
void setup() {
Serial.begin(9600);
irrecv.enableIRIn();
lcd.begin(16, 2);
lcd.backlight();
pinMode(LED_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
pinMode(RELAY_PIN, OUTPUT);
pinMode(PIR_PIN, INPUT);
pinMode(LED2_PIN, OUTPUT);
pinMode(PIR_STATUS_LED, OUTPUT);
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
lcd.setCursor(0, 0);
lcd.print("System Started");
}
void loop() {
// Kiểm tra mực nước mỗi giây (1000 ms)
if (millis() - lastWaterLevelCheck >= 1000) {
lastWaterLevelCheck = millis();
// Đo khoảng cách từ cảm biến siêu âm
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
duration = pulseIn(ECHO_PIN, HIGH);
distance = duration * 0.034 / 2;
// Kiểm tra mực nước và điều khiển máy bơm
if (distance < WATER_LEVEL_THRESHOLD) {
digitalWrite(RELAY_PIN, HIGH); // Bật máy bơm
lcd.setCursor(0, 0);
lcd.print("Water level low");
lcd.setCursor(0, 1);
lcd.print("Pump on");
delay(3000);
} else {
digitalWrite(RELAY_PIN, LOW); // Tắt máy bơm
lcd.setCursor(0, 0);
lcd.print("Water level ok");
lcd.setCursor(0, 1);
lcd.print("Pump off");
}
}
// Button debounce
int buttonState = digitalRead(BUTTON_PIN);
if (buttonState == LOW && buttonLastState == HIGH && millis() - lastButtonPress > 200) {
ledState = !ledState;
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
digitalWrite(RELAY_PIN, ledState ? HIGH : LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(ledState ? "Pump ON" : "Pump OFF");
lastButtonPress = millis();
}
buttonLastState = buttonState;
// PIR sensor xử lý
int pirState = digitalRead(PIR_PIN);
if (pirState != lastPirState) {
digitalWrite(LED2_PIN, pirState);
digitalWrite(PIR_STATUS_LED, pirState);
lcd.clear();
lcd.setCursor(0, 1);
lcd.print(pirState ? "WC led on" : "WC led off");
lastPirState = pirState;
}
// IR điều khiển
if (irrecv.decode()) {
int command = irrecv.decodedIRData.command;
Serial.println(command);
if (command == IR_LED_ON) {
ledState = true;
} else if (command == IR_LED_OFF) {
ledState = false;
}
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(ledState ? "Pump on" : "Pump off");
digitalWrite(RELAY_PIN, ledState ? HIGH : LOW);
irrecv.resume();
}
}