#include <WiFi.h>
#include <PubSubClient.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
#include <TimeLib.h>
#define BLYNK_PRINT Serial
#include <BlynkSimpleEsp32.h>
#include <WiFiUdp.h>
#include <DHT.h>
// WiFi
char auth[] = "iot2esp32";//58rwI44x1cz4CEF0i-8JRo1nanBif0Ji
const char *ssid = "Wokwi-GUEST"; // Nama SSID WiFi
const char *password = ""; // WiFi password
static const char ntpServerName[] = "0.id.pool.ntp.org";
const int timeZone = 7;
// MQTT Broker
const char *mqtt_broker = "xxxx.sn.mynetname.net";//BROKER PRIVATE TO PUBLIC
const char *topic = "iot/main";
const char *topicDash = "iot/dash";
const char *mqtt_username = "mqtt";
const char *mqtt_password = "support";
const int mqtt_port = 1883;
/*
Author : Ravenusa Arjuna K.
Full SourceCode : https://github.com/ravenusa/IoT-SmartHome
*/
/* HC-SR501 Motion Detector */
#define pirPin 39
#define pinKamarMandi 1
#define DHTPIN 36
#define DHTTYPE DHT22 // DHT 22
#define RFanC 18
#define RFanW 19
#define Buzz 34
#define relay 21
DHT dht(DHTPIN, DHTTYPE);
BlynkTimer timer;
int pirValue;// Place to store read PIR Value
int pinValue;//Variable to read virtual pin
int pirKamarMandi;
int pirValKM = 0;
int pirState = LOW;
int h;
float t;
String statusPir;
String statusPirKm;
String statusDHT;
String statusDHTBly;
BLYNK_WRITE(V0)
{
pinValue = param.asInt();
}
WiFiClient espClient;
PubSubClient client(espClient);
void sendSensor()
{
h = dht.readHumidity();
t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Sensor DHT Tidak Terdeteksi !!");
client.publish(topic, "Sensor DHT Tidak Terdeteksi !!", true);
return;
}
Blynk.virtualWrite(V5, t); //suhu virtual 5
Blynk.virtualWrite(V6, h); //kelembaban virtual 6
}
WiFiUDP Udp;
unsigned int localPort = 8888;
time_t getNtpTime();
void digitalClockDisplay();
void printDigits(int digits);
void sendNTPpacket(IPAddress &address);
LiquidCrystal_I2C lcd(0x27, 16, 2);
void setup() {
// Set software serial baud to 9600;
Serial.begin(9600);
delay(10);
Blynk.begin(auth, ssid, password, "o.tcp.ap.ngrok.io",13312);//Port bisa berubah-ubah ketika ngrok dijalankan
dht.begin();
timer.setInterval(1000L, sendSensor);
pinMode(pirPin, INPUT);
pinMode(DHTPIN, INPUT);
pinMode(RFanC, OUTPUT);
pinMode(RFanW, OUTPUT);
pinMode(Buzz, OUTPUT);
pinMode(relay, OUTPUT);
Serial.print(" Menghubungan ke Jaringan");
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(100);
Serial.print("...");
Wire.begin(2, 3);
lcd.init();
lcd.backlight();
}
delay(1000);
Serial.println("\nBerhasil Terhubung ke Jaringan!!");
//connecting to a mqtt broker
client.setServer(mqtt_broker, mqtt_port);
client.setCallback(terimaPesan);
while (!client.connected()) {
String client_id = "tujuh-client-MAC-";
client_id += String(WiFi.macAddress());
Serial.printf("\nMenghubungkan %s ke Broker\n", client_id.c_str());
if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
delay(1000);
Serial.println("Broker Terhubung!!");
Serial.println("\nHi, Selamat Datang dibroker Kelompok TUJUH\n");
} else {
Serial.print("Gagal Terhubung, Ulangi!! ");
Serial.print(client.state());
delay(2000);
}
}
// publish dan subscribe
client.publish(topic, " Hi, Selamat Datang dibroker Kelompok TUJUH");
client.subscribe(topic);
delay(3000);
Serial.print("IP Addr : ");
Serial.println(WiFi.localIP());
setSyncProvider(getNtpTime);
setSyncInterval(300);
}
void terimaPesan(char *topic, byte *payload,unsigned int length) {
Serial.print("Pesan dari Topic : ");
Serial.println(topic);
Serial.print("Pesan : ");
for (int i = 0; i < length; i++) {
Serial.print((char) payload[i]);
}
Serial.println();
Serial.println("=====================================");
Serial.print("Temperature : ");
Serial.print(t);
Serial.print(" | Humidity : ");
Serial.println(h);
Serial.println("=====================================");
}
time_t prevDisplay = 0;
void loop() {
client.loop();
h = dht.readHumidity();
t = dht.readTemperature();
pirState = digitalRead(pinKamarMandi);
if (pinValue == HIGH)
{
getPirValue();
}
if (pirState == 0) {
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Kamar Mandi");
lcd.setCursor(1, 1);
lcd.print("Kosong");
digitalWrite(relay , LOW);
delay(1000);
pirState = 0;
}else{
kamarMandi();
}
if (t <=28.5 ){
digitalWrite(RFanW , HIGH);
digitalWrite(RFanC , LOW);
statusDHT = "Pemanas Ruangan Hidup";
statusDHTBly = " >> Hidup";
}
else if (t >=33){
digitalWrite(RFanW , LOW);
digitalWrite(RFanC , HIGH);
statusDHT = "Kipas Menyala";
statusDHTBly = " ";
}
else if (t >=28.6 && t <= 33.1){
digitalWrite(RFanW , LOW);
digitalWrite(RFanC , LOW);
statusDHT = "Temp & Humid Normal";
statusDHTBly = " ";
}
if (timeStatus() != timeNotSet) {
if (now() != prevDisplay) {
prevDisplay = now();
digitalClockDisplay();
}
}
if (hour() == 17 && minute() == 15){
digitalWrite(relay, LOW);
}
else if (hour() == 6 && minute() == 0){
digitalWrite(relay, HIGH);
}
String completeValDHT = String(t) + "°C - " + String(h) + "%";
client.publish(topic, completeValDHT.c_str(), true);
Blynk.virtualWrite(V7, statusDHT);
Blynk.virtualWrite(V8, statusDHTBly);
StaticJsonDocument<256> doc;
doc["temp"] = String(t);
doc["humi"] = String(h);
doc["rFanW"] = statusDHT;
doc["PIR"] = statusPir;
String out;
serializeJson(doc, out);
char json[out.length() + 1];
out.toCharArray(json, out.length() + 1);
if (client.publish(topicDash, json)) {
Serial.println("Data berhasil dikirim ke topic " + String(topicDash));
}else{
Serial.println("Gagal mengirim data ke topic " + String(topicDash));
}
Blynk.run();
timer.run();
}
void getPirValue(void){
pirValue = digitalRead(pirPin);
if (pirValue){
Serial.println("Ada Gerakan !!");
Blynk.notify("Ada Gerakan !!");
client.publish(topic, "Ada Gerakan !!", true);
statusPir = "Ada Gerakan !!";
Blynk.virtualWrite(V9, statusPir);
tone(Buzz, 400);
delay(300);
noTone(9);
delay(300);
tone(Buzz, 400);
delay(300);
}else{
statusPir = "Tidak Ada Gerakan !!";
Blynk.virtualWrite(V9, statusPir);
noTone(Buzz);
}
}
void kamarMandi(void){
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Ada Orang");
lcd.setCursor(1, 1);
lcd.print("Tunggu Sebentar");
digitalWrite(relay , HIGH);
delay(1000);
pirState = 0;
}
void digitalClockDisplay(){
// Serial.print("=====================================");
// Serial.println();
// Serial.print(hour());
// printDigits(minute());
// printDigits(second());
// Serial.print(" ");
// Serial.print(day());
// Serial.print(".");
// Serial.print(month());
// Serial.print(".");
// Serial.print(year());
// Serial.println();
String completeTime = String(hour())+":"+String(minute())+":"+String(second());
client.publish(topic, completeTime.c_str(), true);
}
void printDigits(int digits){
Serial.print(":");
if (digits < 10)
Serial.print('0');
Serial.print(digits);
}
/*-------- NTP code ----------*/
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
time_t getNtpTime(){
IPAddress ntpServerIP; // NTP server's ip address
while (Udp.parsePacket() > 0) ; // discard any previously received packets
// Serial.println("Transmit NTP Request");
// get a random server from the pool
WiFi.hostByName(ntpServerName, ntpServerIP);
// Serial.print(ntpServerName);
// Serial.print(": ");
// Serial.println(ntpServerIP);
sendNTPpacket(ntpServerIP);
uint32_t beginWait = millis();
while (millis() - beginWait < 1500) {
int size = Udp.parsePacket();
if (size >= NTP_PACKET_SIZE) {
//Serial.println("\nReceive NTP Response");
Udp.read(packetBuffer, NTP_PACKET_SIZE); // read packet into the buffer
unsigned long secsSince1900;
// convert four bytes starting at location 40 to a long integer
secsSince1900 = (unsigned long)packetBuffer[40] << 24;
secsSince1900 |= (unsigned long)packetBuffer[41] << 16;
secsSince1900 |= (unsigned long)packetBuffer[42] << 8;
secsSince1900 |= (unsigned long)packetBuffer[43];
return secsSince1900 - 2208988800UL + timeZone * SECS_PER_HOUR;
}
}
// Serial.println("No NTP Response :-(");
return 0; // return 0 if unable to get the time
}
// send an NTP request to the time server at the given address
void sendNTPpacket(IPAddress &address)
{
// set all bytes in the buffer to 0
memset(packetBuffer, 0, NTP_PACKET_SIZE);
// Initialize values needed to form NTP request
// (see URL above for details on the packets)
packetBuffer[0] = 0b11100011; // LI, Version, Mode
packetBuffer[1] = 0; // Stratum, or type of clock
packetBuffer[2] = 6; // Polling Interval
packetBuffer[3] = 0xEC; // Peer Clock Precision
// 8 bytes of zero for Root Delay & Root Dispersion
packetBuffer[12] = 49;
packetBuffer[13] = 0x4E;
packetBuffer[14] = 49;
packetBuffer[15] = 52;
// all NTP fields have been given values, now
// you can send a packet requesting a timestamp:
Udp.beginPacket(address, 123); //NTP requests are to port 123
Udp.write(packetBuffer, NTP_PACKET_SIZE);
Udp.endPacket();
}