#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiClient.h>
#include <MFRC522_I2C.h>
#include <Adafruit_NeoPixel.h>
#include <ESP32_Servo.h>
Servo myservo1;
Servo myservo2;
MFRC522 mfrc522(0x28);
#define servoPin1 13 // Try GPIO5 instead of 13
#define servoPin2 5 // Try GPIO5 instead of 5
String Password = "";
#define LED_PIN 26
// How many NeoPixels are attached to the Arduino?
#define LED_COUNT 4
#define button1Pin 16 // Tlačidlo 1
#define button2Pin 27
String menuItems[] = { "LED", "Temperature", "Window", "Door" };
int menuSize = sizeof(menuItems) / sizeof(menuItems[0]);
int currentMenuIndex = 0; // Aktuálna položka menu
bool newButton1State = LOW; // Tlačidlo stlačené (LOW)
bool newButton2State = LOW;
bool button1State = HIGH;
bool button2State = LOW;
// Declare our NeoPixel strip object:
Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
String item = "0";
//const char* ssid = "ChinaNet-2.4G-0DF0";
//const char* password = "ChinaNet@233";
const char* ssid = "iPhone";
const char* password = "123Richard";
WiFiServer server(80);
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C mylcd(0x27, 16, 2);
//#include < analogWrite.h >
#include "xht11.h"
xht11 xht(17);
#include <ESP32Tone.h>
#define buzzer_pin 25
//#define windowServo 5
//#define doorServo 13
#define waterPin 34
#define fanPin1 19
#define fanPin2 18
#define led_y 12 //Define the yellow led pin to 12
#define waterPin 34
#define gasPin 32
#define pyroelectric 14
unsigned char dht[4] = { 0, 0, 0, 0 }; //Only the first 32 bits of data are received, not the parity bits
//Servo channel
int channel_PWM = 13;
int channel_PWM2 = 10;
int freq_PWM = 50;
int resolution_PWM = 10;
const int PWM_Pin1 = 5;
const int PWM_Pin2 = 13;
int DoorState = 0;
int gasVal;
void setup() {
Serial.begin(115200);
Serial.println ("Run Baby");
mylcd.init();
mylcd.backlight();
pinMode(button1Pin, INPUT); // Nastavenie tlačidiel na vstup
pinMode(button2Pin, INPUT);
pinMode(led_y, OUTPUT);
pinMode(fanPin1, OUTPUT);
pinMode(fanPin2, OUTPUT);
ledcSetup(5, 1200, 8); //Set the frequency of LEDC channel 1 to 1200 and PWM resolution to 8, that is duty cycle to 256.
ledcAttachPin(fanPin2, 5); //Bind the LEDC channel 1 to the specified left motor pin GPIO26 for output.
pinMode(waterPin, INPUT);
pinMode(buzzer_pin, OUTPUT);
pinMode(gasPin, INPUT);
pinMode(pyroelectric, INPUT);
ledcSetup(channel_PWM, freq_PWM, resolution_PWM); //Set servo channel and frequency as well as PWM resolution.
ledcSetup(channel_PWM2, freq_PWM, resolution_PWM);
ledcAttachPin(PWM_Pin1, channel_PWM); //Binds the LEDC channel to the specified IO port for output
ledcAttachPin(PWM_Pin2, channel_PWM2); //Binds the LEDC channel to the specified IO port for output
Wire.begin();
mfrc522.PCD_Init();
ShowReaderDetails();
Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
myservo1.attach(servoPin1,500,2400); // Attach servo at setup
myservo1.write(0);
myservo2.attach(servoPin2,500,2400); // Attach servo at setup
myservo2.write(0);
mylcd.setCursor(0, 0);
//mylcd.print("Card");
// Wservo.attach(windowServo);
// Dservo.attach(doorServo);
// #if defined(__AVR_ATtiny85__) && (F_CPU == 16000000)
// clock_prescale_set(clock_div_1);
// #endif
// // END of Trinket-specific code.
// strip.begin(); // INITIALIZE NeoPixel strip object (REQUIRED)
// strip.show(); // Turn OFF all pixels ASAP
// strip.setBrightness(50); // Set BRIGHTNESS to about 1/5 (max = 255)
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
server.begin();
Serial.println("TCP server started");
MDNS.addService("http", "tcp", 80);
mylcd.setCursor(0, 0);
mylcd.print("ip:");
mylcd.setCursor(0, 1);
mylcd.print(WiFi.localIP()); //LCD displays ip adress
delay(2000);
mylcd.setCursor(0, 0);
mylcd.print("SmartHouse");
mylcd.setCursor(0, 1);
mylcd.print("Richard Gero"); //LCD displays ip adress
delay(2000);
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print(menuItems[currentMenuIndex]);
mylcd.setCursor(0, 1);
mylcd.print(menuItems[currentMenuIndex + 1]);
}
void loop() {
WiFiClient client = server.available();
if (!client) {
return;
}
while (client.connected() && !client.available()) {
delay(1);
}
String req = client.readStringUntil('\r');
int addr_start = req.indexOf(' ');
int addr_end = req.indexOf(' ', addr_start + 1);
if (addr_start == -1 || addr_end == -1) {
Serial.print("Invalid request: ");
Serial.println(req);
return;
}
req = req.substring(addr_start + 1, addr_end);
item = req;
Serial.println(item);
String s;
if (req == "/") //Browser accesses address can read the information sent by the client.println(s);
{
IPAddress ip = WiFi.localIP();
String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n< !DOCTYPE HTML >\r\n< html >ESP32 ip:";
s += ipStr;
s += "< /html >\r\n\r\n";
Serial.println("Sending 200");
client.println(s); //Send the string S, then you can read the information when visiting the address of E smart home using the browser.
}
//button
if (digitalRead(button1Pin) == LOW) {
Serial.println("Button1 Push");
menuItems[currentMenuIndex] = menuItems[currentMenuIndex + 1];
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print(menuItems[currentMenuIndex]);
mylcd.setCursor(0, 1);
mylcd.print(menuItems[currentMenuIndex + 1]);
}
if (digitalRead(button2Pin) == LOW) {
Serial.println("Button2 Push");
menuItems[currentMenuIndex] = menuItems[currentMenuIndex + 1];
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print(menuItems[currentMenuIndex]);
mylcd.setCursor(0, 1);
mylcd.print(menuItems[currentMenuIndex + 1]);
}
//button end
if ((req == "/led/on") || (menuItems[currentMenuIndex] == "LED ON")) //Browser accesses address ip address/led/on
{
client.println("turn on the LED");
digitalWrite(led_y, HIGH);
}
if (req == "/led/off") //Browser accesses address ip address/led/off
{
client.println("turn off the LED");
digitalWrite(led_y, LOW);
}
if ((req == "/window/on") || (menuItems[currentMenuIndex] == "WINDOW OPEN")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Okno - otvorené");
myservo2.write(0);
delay(1000);
client.println("open the window");
//ledcWrite(channel_PWM, 100);
//The high level of 20ms is about 2.5ms, that is, 2.5/20*1024, at this time, the servo angle is 180°.
//Wservo.write(175);
}
if ((req == "/window/off") || (menuItems[currentMenuIndex] == "WINDOW CLOSED")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Okno - Zatvorené");
myservo2.write(180);
delay(1000);
client.println("close the window");
//ledcWrite(channel_PWM, 60);
//The high level of 20ms is about 0.5ms,that is, 0.5/20*1024,at this time, the servo angle is 0°.
//Wservo.write(0);
}
if ((req == "/music/on") || (menuItems[currentMenuIndex] == "MUSIC ON")) {
//client.println("play music");
}
if ((req == "/music/off") || (menuItems[currentMenuIndex] == "MUSIC OFF")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Hudba - OFF");
client.println("play music");
birthday();
noTone(buzzer_pin, 0);
mylcd.clear();
}
if ((req == "/buz/on") || (menuItems[currentMenuIndex] == "BUZZER ON")) {
client.println("buzzer");
tone(buzzer_pin, 392, 250, 0);
Serial.println("1");
}
if ((req == "/buz/off") || (menuItems[currentMenuIndex] == "BUZZER OFF")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Reprak - OFF");
client.println("off");
noTone(buzzer_pin, 0);
mylcd.clear();
}
if ((req == "/door/on") || (menuItems[currentMenuIndex] == "DOOR OPEN")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Dvere - otvorené");
delay(1000);
client.println("open the door");
ledcWrite(channel_PWM2, 120);
myservo1.write(180);
}
if ((req == "/door/off") || (menuItems[currentMenuIndex] == "DOOR CLOSED")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Dvere - zatvorené");
delay(1000);
client.println("close the door");
ledcWrite(channel_PWM2, 20);
myservo1.write(0);
}
if ((req == "/fan/on") || (menuItems[currentMenuIndex] == "FAN ON")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Ventilátor");
mylcd.setCursor(0, 1);
mylcd.print("ON");
client.println("turn on the fan");
digitalWrite(fanPin1, LOW); //pwm = 0
ledcWrite(5, 100);
// mylcd.clear();
//The LEDC channel 1 is bound to the specified left motor output PWM value of 100.
}
if ((req == "/fan/off") || (menuItems[currentMenuIndex] == "FAN OFF")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Ventilátor");
mylcd.setCursor(0, 1);
mylcd.print("OFF");
delay(1000);
client.println("turn off the fan");
digitalWrite(fanPin1, LOW); //pwm = 0
ledcWrite(5, 0);
// mylcd.clear();
//The LEDC channel 1 is bound to the specified left motor output PWM value of 0.
}
if (req == "/red/on") {
client.println("red on");
colorWipe(strip.Color(255, 0, 0), 50);
}
if (req == "/red/off") {
client.println("red off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/oringe/on") {
client.println("oringe on");
colorWipe(strip.Color(200, 100, 0), 50);
}
if (req == "/oringe/off") {
client.println("oringe off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/yellow/on") {
client.println("yellow on");
colorWipe(strip.Color(200, 200, 0), 50);
}
if (req == "/yellow/off") {
client.println("yellow off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/green/on") {
client.println("green on");
colorWipe(strip.Color(0, 255, 0), 50);
}
if (req == "/green/off") {
client.println("green off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/cyan/on") {
client.println("cyan on");
colorWipe(strip.Color(0, 100, 255), 50);
}
if (req == "/cyan/off") {
client.println("cyan off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/blue/on") {
client.println("blue on");
colorWipe(strip.Color(0, 0, 255), 50);
}
if (req == "/blue/off") {
client.println("blue off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/purple/on") {
client.println("purple on");
colorWipe(strip.Color(100, 0, 255), 50);
}
if (req == "/purple/off") {
client.println("purple off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/white/on") {
client.println("white on");
colorWipe(strip.Color(255, 255, 255), 50);
}
if (req == "/white/off") {
client.println("white off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/sfx1/on") {
client.println("sfx1 on");
rainbow(10);
}
if (req == "/sfx1/off") {
client.println("sfx1 off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if (req == "/sfx2/on") {
client.println("sfx2 on");
theaterChaseRainbow(50);
}
if (req == "/sfx2/off") {
client.println("sfx2 off");
colorWipe(strip.Color(0, 0, 0), 50);
}
if ((req == "/rain/on") || (menuItems[currentMenuIndex] == "RAIN ON")) {
mylcd.clear();
int rainVal = analogRead(waterPin);
mylcd.setCursor(0, 0);
mylcd.print(rainVal);
delay(1000);
client.println(rainVal);
}
if ((req == "/rain/off") || (menuItems[currentMenuIndex] == "RAIN OFF")) {
client.println("off");
}
while ((req == "/gas/on") || (menuItems[currentMenuIndex] == "GAS ON")) {
mylcd.clear();
gasVal = analogRead(gasPin);
if (gasVal <= 300) {
mylcd.setCursor(0, 0);
Serial.print ("GasVal: ");
Serial.println (gasVal,DEC);
client.print(" safety");
mylcd.print(" Bezpečie");
}
if (gasVal > 300 && gasVal <= 1000 ){
mylcd.setCursor(0, 0);
Serial.print ("GasVal: ");
Serial.println (gasVal,DEC);
client.print(" Warning");
mylcd.print(" Pozor");
beep(1000, 200);// Keep it ON for 100ms
/*tone(buzzer_pin, 294, 250, 0);
delay(1);
tone(buzzer_pin, 294, 250, 0);
delay(1);*/
}
if (gasVal > 1000 ) {
mylcd.setCursor(0, 0);
Serial.print ("GasVal: ");
Serial.println (gasVal,DEC);
client.print(" Dangerous");
mylcd.print(" Nebezpecné");
beep(1000, 200); // Keep it ON for 100ms
/*tone(buzzer_pin, 294, 250, 0);
delay(1);
tone(buzzer_pin, 294, 250, 0);
delay(1);*/
}
mylcd.setCursor(0, 1);
mylcd.print(gasVal,DEC);
delay(300);
}
if ((req == "/gas/off") || (menuItems[currentMenuIndex] == "GAS OFF")) {
mylcd.clear();
client.println("off");
mylcd.clear();
}
if ((req == "/body/on") || (menuItems[currentMenuIndex] == "BODY ON")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("PIR Stav");
boolean pyroelectric_val = digitalRead(pyroelectric);
if (pyroelectric_val == 1) {
mylcd.setCursor(0, 1);
mylcd.print("Pohyb detekovaný");
client.println("someone");
} else {
mylcd.setCursor(0, 1);
mylcd.print("Žiaden pohyb");
client.println("no one");
}
//mylcd.setCursor(0, 1);
//mylcd.print(pyroelectric_val);
delay(300);
}
if ((req == "/body/off") || (menuItems[currentMenuIndex] == "BODY OFF")) {
client.println("off");
}
if ((req == "/temp/on") || (menuItems[currentMenuIndex] == "TEMP ON")) {
if (xht.receive(dht)) {
mylcd.clear(); //Returns true when checked correctly
mylcd.print("Teplota:");
mylcd.print(dht[2]); //The integral part of temperature, DHT [3] is the fractional part
mylcd.print("C");
Serial.print("Temp:");
Serial.print(dht[2]); //The integral part of temperature, DHT [3] is the fractional part
Serial.println("C");
delay(200);
} else { //Read error
Serial.println("sensor error");
}
client.println(dht[2]);
delay(1000); //It takes 1000ms to wait for the device to read
}
if ((req == "/temp/off") || (menuItems[currentMenuIndex] == "TEMP OFF")) {
client.println("off");
}
if ((req == "/humidity/on") || (menuItems[currentMenuIndex] == "HUMIDITY ON")) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Vlhkost");
if (xht.receive(dht)) { //Returns true when checked correctly
Serial.print("Humidity:");
Serial.print(dht[0]); //The integral part of temperature, DHT [3] is the fractional part
mylcd.setCursor(0, 1);
mylcd.print(dht[0]);
mylcd.setCursor(5, 1);
mylcd.print("%");
Serial.println("%");
delay(200);
} else { //Read error
Serial.println("sensor error");
}
client.println(dht[0]);
delay(1000); //It takes 1000ms to wait for the device to read
}
if ((req == "/humidity/off") || (menuItems[currentMenuIndex] == "HUMIDITY OFF")) {
client.println("off");
}
/*
// Kontrola tlačidla 1 pre posun v menu
if (newButton1State && !button1State) {
currentMenuIndex = (currentMenuIndex + 1) % menuSize; // Posun v menu
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print(menuItems[currentMenuIndex]); // Zobrazenie aktuálnej položky
mylcd.setCursor(0, 1);
mylcd.print(menuItems[(currentMenuIndex + 1) % menuSize]); // Ďalšia položka
delay(200); // Odrušenie preťaženia
}
*/
// Kontrola tlačidla 2 pre výber aktuálnej položky
/*if (newButton2State && !button2State) {
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Selected:");
mylcd.setCursor(0, 1);
mylcd.print(menuItems[currentMenuIndex]); // Zobrazenie zvolenej položky
handleMenuSelection(); // Funkcia na spracovanie výberu
delay(200); // Odrušenie preťaženia
}
// Aktualizácia predchádzajúcich stavov tlačidiel
/*newButton1State = digitalRead(button1Pin) == LOW; // Tlačidlo stlačené (LOW)
newButton2State = digitalRead(button2Pin) == LOW;
button1State = newButton1State;
button2State = newButton2State;*/
//client.stop();
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
delay(50);
Password = "";
//Serial.println ("Reading the card");
return;
}
Serial.print(F("Card UID:"));
Password = "";
for (byte i = 0; i < mfrc522.uid.size; i++) {
//Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i]);
Password += String(mfrc522.uid.uidByte[i]);
}
Serial.println(); // New line after UID print
//if (Password == "42 141 63 181") {
if (Password == "4214163181" && DoorState == 0) {
Serial.println("Access granted: Opening door");
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Otvorené");
DoorState = 1;
myservo1.attach(servoPin1,500,2400); // Ensure servo is attached
myservo1.write(180);
delay(2000); // Wait before closing
myservo1.write(0);
myservo1.detach(); // Detach to prevent jitter
} else if (Password == "4214163181" && DoorState == 1) {
Serial.println("Access granted: Closing door");
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("Zatvorené");
DoorState = 0;
myservo1.attach(servoPin1,500,2400); // Ensure servo is attached
myservo1.write(0);
delay(2000); // Wait before closing
myservo1.write(0);
myservo1.detach(); // Detach to prevent jitter
} else {
Serial.println("Access denied");
mylcd.clear();
mylcd.setCursor(0, 0);
mylcd.print("error");
delay(2000);
}
Password = "";
}
void birthday() {
tone(buzzer_pin, 294, 250, 0); //The four parameters are pin, frequency, delay and channel
tone(buzzer_pin, 440, 250, 0);
tone(buzzer_pin, 392, 250, 0);
tone(buzzer_pin, 532, 250, 0);
tone(buzzer_pin, 494, 250, 0);
tone(buzzer_pin, 392, 250, 0);
tone(buzzer_pin, 440, 250, 0);
tone(buzzer_pin, 392, 250, 0);
tone(buzzer_pin, 587, 250, 0);
tone(buzzer_pin, 532, 250, 0);
tone(buzzer_pin, 392, 250, 0);
tone(buzzer_pin, 784, 250, 0);
tone(buzzer_pin, 659, 250, 0);
tone(buzzer_pin, 532, 250, 0);
tone(buzzer_pin, 494, 250, 0);
tone(buzzer_pin, 440, 250, 0);
tone(buzzer_pin, 698, 250, 0);
tone(buzzer_pin, 659, 250, 0);
tone(buzzer_pin, 532, 250, 0);
tone(buzzer_pin, 587, 250, 0);
tone(buzzer_pin, 532, 500, 0);
noTone(buzzer_pin, 0);
}
void colorWipe(uint32_t color, int wait) {
for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
strip.setPixelColor(i, color); // Set pixel's color (in RAM)
strip.show(); // Update strip to match
delay(wait); // Pause for a moment
}
}
// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
for (long firstPixelHue = 0; firstPixelHue < 5 * 65536; firstPixelHue += 256) {
for (int i = 0; i < strip.numPixels(); i++) { // For each pixel in strip...
int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
}
strip.show(); // Update strip with new contents
delay(wait); // Pause for a moment
}
}
// Rainbow-enhanced theater marquee. Pass delay time (in ms) between frames.
void theaterChaseRainbow(int wait) {
int firstPixelHue = 0; // First pixel starts at red (hue 0)
for (int a = 0; a < 30; a++) { // Repeat 30 times...
for (int b = 0; b < 3; b++) { // 'b' counts from 0 to 2...
strip.clear(); // Set all pixels in RAM to 0 (off)
// 'c' counts up from 'b' to end of strip in increments of 3...
for (int c = b; c < strip.numPixels(); c += 3) {
int hue = firstPixelHue + c * 65536L / strip.numPixels();
uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue - > RGB
strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
}
strip.show(); // Update strip with new contents
delay(wait); // Pause for a moment
firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
}
}
}
void handleMenuSelection() {
if (menuItems[currentMenuIndex] == "LED") {
Serial.println("LED selected");
// Pridaj kód na spracovanie výberu LED
} else if (menuItems[currentMenuIndex] == "Temperature") {
Serial.println("Temperature selected");
// Pridaj kód na spracovanie teploty
} else if (menuItems[currentMenuIndex] == "Window") {
Serial.println("Window selected");
// Pridaj kód na spracovanie okna
} else if (menuItems[currentMenuIndex] == "Door") {
Serial.println("Door selected");
// Pridaj kód na spracovanie dverí
}
}
void ShowReaderDetails() {
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
Serial.print(F("MFRC522 Software Version: 0x"));
Serial.print(v, HEX);
if (v == 0x91)
Serial.print(F(" = v1.0"));
else if (v == 0x92)
Serial.print(F(" = v2.0"));
else
Serial.print(F(" (unknown)"));
Serial.println("");
if ((v == 0x00) || (v == 0xFF)) {
Serial.println(F("WARNING: Communication failure, check connections"));
}
}
void beep(int frequency, int duration) {
ledcAttachPin(buzzer_pin, 1);
ledcWriteTone(1, frequency);
delay(duration);
ledcWriteTone(1, 0);
}