#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <RTClib.h>
#include <DHT.h>
#include <Servo.h>
#include <Adafruit_NeoPixel.h>
#include <IRremote.h>
#include <Keypad.h>
// ==== Піни ====
#define GAS_PIN A0
#define DHT_PIN 2
#define POT_PIN A1
#define SERVO_PIN 3
#define IR_RECEIVE_PIN 5
#define BUZZER_PIN 6
#define NEOPIXEL_PIN 7
#define RED_LED_PIN 8
#define NEOPIXEL_PIN_PPM 12
#define NEOPIXEL_PIN_TEMP 13
LiquidCrystal_I2C lcd1(0x27, 20, 4);
LiquidCrystal_I2C lcd2(0x26, 16, 2);
// ==== Компоненти ====
#define NUMPIXELS 30
#define NUM_LEDS 20
#define TEMP_THRESHOLD 40
#define GAS_THRESHOLD 975
DHT dht(DHT_PIN, DHT22);
Servo windowServo;
Adafruit_NeoPixel pixels(NUMPIXELS, NEOPIXEL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripPPM(NUM_LEDS, NEOPIXEL_PIN_PPM, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel stripTemp(NUM_LEDS, NEOPIXEL_PIN_TEMP, NEO_GRB + NEO_KHZ800);
RTC_DS3231 rtc;
// ==== Змінні ====
bool manualLightOff = false;
bool emergency = false;
unsigned long lastBlink = 0;
bool ledState = false;
float irBrightnessLevel = 1.0;
bool potActive = false;
int lastPotValue = -1;
float temp;
float hum;
int gas;
const uint8_t ROWS = 4;
const uint8_t COLS = 3;
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
uint8_t rowPins[ROWS] = {22, 23, 24, 25}; // Adjust based on your wiring
uint8_t colPins[COLS] = {26, 27, 28};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const String correctPIN = "9314";
String enteredPIN = "";
bool systemUnlocked = false;
void handleSecurity() {
lcd2.setCursor(0, 0);
lcd2.print("Enter PIN:");
lcd2.setCursor(0, 1);
lcd2.print("PIN: ");
for (int i = 0; i < enteredPIN.length(); i++) {
lcd2.print('*');
}
char key = keypad.getKey();
if (key) {
if (key >= '0' && key <= '9' && enteredPIN.length() < 4) {
enteredPIN += key;
} else if (key == '#') {
if (enteredPIN == correctPIN) {
lcd2.clear();
lcd2.print("Access Granted");
delay(1000);
lcd2.clear();
systemUnlocked = true;
lcd1.begin(20, 4);
lcd1.print("Hotel Room Ready 2");
delay(2000);
lcd1.clear();
} else {
lcd2.clear();
lcd2.print("Wrong PIN");
delay(1000);
lcd2.clear();
enteredPIN = "";
}
} else if (key == '*') {
enteredPIN = "";
lcd2.clear();
}
}
}
void updateGasBarGraph(Adafruit_NeoPixel &strip, int gasValue) {
int litLEDs = map(gasValue, 900, 975, 0, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
if (i < litLEDs) {
if (i <= 4) strip.setPixelColor(i, strip.Color(0, 255, 0));
else if (i <= 8) strip.setPixelColor(i, strip.Color(179, 255, 0));
else if (i <= 13) strip.setPixelColor(i, strip.Color(255, 255, 0));
else if (i <= 15) strip.setPixelColor(i, strip.Color(255, 187, 0));
else if (i <= 17) strip.setPixelColor(i, strip.Color(255, 85, 0));
else strip.setPixelColor(i, strip.Color(140, 0, 0));
} else {
strip.setPixelColor(i, 0);
}
if (gasValue <= 900) {
strip.setPixelColor(0, strip.Color(0, 255, 0));
strip.show();
}
}
strip.show();
}
void updateTempBarGraph(Adafruit_NeoPixel &strip, float tempValue) {
int litLEDs = map(tempValue, 10, 40, 0, NUM_LEDS);
for (int i = 0; i < NUM_LEDS; i++) {
if (i < litLEDs) {
if (i <= 4) strip.setPixelColor(i, strip.Color(0, 255, 0));
else if (i <= 8) strip.setPixelColor(i, strip.Color(179, 255, 0));
else if (i <= 13) strip.setPixelColor(i, strip.Color(255, 255, 0));
else if (i <= 15) strip.setPixelColor(i, strip.Color(255, 187, 0));
else if (i <= 17) strip.setPixelColor(i, strip.Color(255, 85, 0));
else strip.setPixelColor(i, strip.Color(140, 0, 0));
} else {
strip.setPixelColor(i, 0);
}
if (tempValue <= 12) {
for (int i = 0; i < NUMPIXELS; i++) {
strip.setPixelColor(i, strip.Color(0, 150, 255));
}
strip.show();
}
}
strip.show();
}
void translateIR() {
switch (IrReceiver.decodedIRData.command) {
case 162: // POWER OFF
manualLightOff = !manualLightOff;
pixels.show();
break;
case 2: // PLUS
irBrightnessLevel += 0.2;
if (irBrightnessLevel >= 1.0) {
irBrightnessLevel = 1;
break;
};
break;
case 152: // MINUS
irBrightnessLevel -= 0.2;
if (irBrightnessLevel <= 0.2) {
irBrightnessLevel = 0.2;
break;
};
break;
}
}
void updateRoomBrightness() {
int potValue = analogRead(POT_PIN);
if (potValue != lastPotValue) {
lastPotValue = potValue;
float potScale = potValue / 1023.0;
irBrightnessLevel = potScale;
}
int finalBrightness = irBrightnessLevel * 255;
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(finalBrightness, finalBrightness, finalBrightness));
}
pixels.show();
}
void displayInfo(DateTime now, float temperature, float humidity, int gasVal) {
lcd1.setCursor(0, 0);
lcd1.print("Brightness: ");
lcd1.print(irBrightnessLevel, 1);
lcd1.setCursor(0, 1);
lcd1.print("Time: ");
lcd1.print(now.hour());
lcd1.print(':');
if (now.minute() < 10) lcd1.print('0');
lcd1.print(now.minute());
lcd1.setCursor(0, 2);
lcd1.print("T:");
lcd1.print(temperature, 1);
lcd1.print("C H:");
lcd1.print(humidity, 0);
lcd1.print("% ");
lcd1.setCursor(0, 3);
lcd1.print("Gas:");
lcd1.print(gasVal);
lcd1.print("ppm");
}
void handleEmergency(float temperature, int gasVal) {
if (gasVal >= GAS_THRESHOLD || temperature >= TEMP_THRESHOLD || temperature <= 10) {
emergency = true;
analogWrite(BUZZER_PIN, 128);
delay(500);
analogWrite(BUZZER_PIN, 0);
if (millis() - lastBlink >= 500) {
ledState = !ledState;
digitalWrite(RED_LED_PIN, ledState);
lastBlink = millis();
}
windowServo.write(0);
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(255, 0, 0));
}
pixels.show();
} else {
emergency = false;
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RED_LED_PIN, LOW);
windowServo.write(90);
if (manualLightOff) {
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, 0);
}
} else {
int finalBrightness = irBrightnessLevel * 255;
for (int i = 0; i < NUMPIXELS; i++) {
pixels.setPixelColor(i, pixels.Color(finalBrightness, finalBrightness, finalBrightness));
}
}
pixels.show();
}
}
void setup() {
Serial.begin(9600);
dht.begin();
rtc.begin();
pixels.begin();
stripPPM.begin();
stripPPM.show();
stripTemp.begin();
stripTemp.show();
IrReceiver.begin(IR_RECEIVE_PIN);
lcd1.init();
lcd1.backlight();
lcd1.clear();
lcd2.init();
lcd2.backlight();
lcd2.clear();
lcd1.clear();
lcd2.clear();
windowServo.attach(SERVO_PIN);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RED_LED_PIN, OUTPUT);
}
void loop() {
if (!systemUnlocked) {
handleSecurity();
return; // Skip rest of loop() until unlocked
}
DateTime now = rtc.now();
temp = dht.readTemperature();
hum = dht.readHumidity();
gas = analogRead(GAS_PIN);
lcd1.setCursor(0, 0);
lcd1.print("Brightness: ");
lcd1.print(irBrightnessLevel, 1);
lcd1.setCursor(0, 1);
lcd1.print("Time: ");
lcd1.print(now.hour());
lcd1.print(':');
if (now.minute() < 10) lcd1.print('0');
lcd1.print(now.minute());
lcd1.setCursor(0, 2);
lcd1.print("T:");
lcd1.print(temp, 1);
lcd1.print("C H:");
lcd1.print(hum, 0);
lcd1.print("% ");
lcd1.setCursor(0, 3);
lcd1.print("Gas:");
lcd1.print(gas);
lcd1.print("ppm");
displayInfo(now, temp, hum, gas);
handleEmergency(temp, gas);
if (!emergency && !manualLightOff) updateRoomBrightness();
if (IrReceiver.decode() && !emergency) {
translateIR();
IrReceiver.resume();
}
}