#define BLYNK_TEMPLATE_ID "TMPL65NRrgLAD"
#define BLYNK_TEMPLATE_NAME "Node2 Template"
#define BLYNK_AUTH_TOKEN "dWVc4NfSaAD2bcHg_9FmnUl_YgRdn1oG"
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <ESP32Servo.h>
#include <ArduinoJson.h>
#include <BlynkSimpleEsp32.h>
bool OLEDLOCK = false;
char auth[] = BLYNK_AUTH_TOKEN;
BlynkTimer timer;
#define BLYNK_PRINT Serial
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET 0 // GPIO0
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
int PirPin = 14; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
#define LDR_PIN 27
int LDRState = LOW;
const int servoPin = 23;
Servo servo;
bool isServoOn = true;
// Wi-Fi credentials
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// MQTT broker details private
const char* mqtt_broker = "f0d086f337ef47e69eeebf1d993c6e33.s1.eu.hivemq.cloud";
const int mqtt_port = 8883;
const char* mqtt_username = "Nodes";
const char* mqtt_password = "2A357689a";
// MQTT topics
const char* topic_publish1 = "Node2-motion";
const char* topic_publish2 = "Node2-light";
const char* topic_subscribe1 = "Node1-TempHumdata";
const char* topic_subscribe2 = "Node3-Buttons"; // Topic to receive messages
// Create instances
WiFiClientSecure wifiClient;
PubSubClient mqttClient(wifiClient);
void setupMQTT() {
mqttClient.setServer(mqtt_broker, mqtt_port);
mqttClient.setCallback(mqttCallback);
}
void reconnect() {
Serial.println("Connecting to MQTT Broker...");
while (!mqttClient.connected()) {
Serial.println("Reconnecting to MQTT Broker...");
String clientId = "ESP32Client-";
clientId += String(random(0xffff), HEX);
if (mqttClient.connect(clientId.c_str(), mqtt_username, mqtt_password)) {
Serial.println("Connected to MQTT Broker.");
// Subscribe to the control topic
mqttClient.subscribe(topic_subscribe1);
mqttClient.subscribe(topic_subscribe2);
} else {
Serial.print("Failed, rc=");
Serial.print(mqttClient.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
int stepSize = 1;
// Callback function to handle incoming messages
void mqttCallback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived on topic: [");
Serial.print(topic);
Serial.print("]: \t");
String message;
for (int i = 0; i < length; i++) {
message += (char)payload[i];
}
Serial.println(message);
if (String(topic) == "Node1-TempHumdata") {
DynamicJsonDocument DHTDoc(1024);
DeserializationError error = deserializeJson(DHTDoc, message);
if (error) {
Serial.print("Failed to parse JSON: ");
Serial.println(error.f_str());
return;
}
float temperature = DHTDoc["temperature"]; // Get temperature
float humidity = DHTDoc["humidity"]; // Get humidity
if (!OLEDLOCK) {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Temperature = " + String(temperature));
display.println("Humidity = " + String(humidity));
display.display();
}
if (temperature > 35 && humidity > 60 && isServoOn) {
if (!OLEDLOCK) {
display.println("Fan Speed = " + String(stepSize * 10) + "%");
display.display();
}
for (int pos = 0; pos <= 180; pos += 1) {
servo.write(pos);
delay(0.1);
}
for (int pos = 180; pos >= 0; pos -= 1) {
servo.write(pos);
delay(0.1);
}
}
}
else if (String(topic) == "Node3-Buttons") {
DynamicJsonDocument ButtonsDoc(1024);
DeserializationError error = deserializeJson(ButtonsDoc, message);
if (error) {
Serial.print("Failed to parse JSON: ");
Serial.println(error.f_str());
return;
}
int button_1 = ButtonsDoc["button_1"];
int button_2 = ButtonsDoc["button_2"];
if (button_1 == 1 && stepSize < 10) {
stepSize++;
}
else if (button_2 == 1 && stepSize > 1) {
stepSize--;
}
}
}
void wifiSetup() {
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.println("Connencting to the network.");
}
Serial.println("");
Serial.println("Connected to Wi-Fi");
}
void setup() {
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println("Welcome\nSumaya");
display.display();
Serial.begin(115200);
Serial.println("Hello, ESP32!");
pinMode(PirPin, INPUT); // declare sensor as input
pinMode(LDR_PIN, INPUT);
servo.attach(servoPin);
wifiSetup();
// Initialize secure WiFiClient
wifiClient.setInsecure(); // Use this only for testing, it allows connecting without a root certificate
setupMQTT();
Blynk.begin(auth, ssid, password);
}
void loop() {
Blynk.run();
timer.run();
if (!mqttClient.connected()) {
reconnect();
}
mqttClient.loop();
int val = digitalRead(PirPin); // read input value
if (val == HIGH) { // check if the input is HIGH
if (pirState == LOW) {
// we have just turned on
mqttClient.publish(topic_publish1, "Motion_detected");
Serial.println("Motion_detected");
Blynk.virtualWrite(V0, "Motion_detected");
Blynk.virtualWrite(V1, HIGH);
// We only want to print on the output change, not state
pirState = HIGH;
}
} else {
if (pirState == HIGH) {
// we have just turned of
mqttClient.publish(topic_publish1, "No_Motion");
Serial.println("No_Motion");
Blynk.virtualWrite(V0, "No_Motion");
Blynk.virtualWrite(V1, LOW);
// We only want to print on the output change, not state
pirState = LOW;
}
}
int LDRVal = digitalRead(LDR_PIN); // read input value
if (LDRVal == HIGH) { // check if the input is HIGH
if (LDRState == LOW) {
// we have just turned on
mqttClient.publish(topic_publish2, "NO_Light");
Serial.println("NO_Light");
Blynk.virtualWrite(V2, "NO_Light");
Blynk.virtualWrite(V3, LOW);
// We only want to print on the output change, not state
LDRState = HIGH;
}
} else {
if (LDRState == HIGH) {
// we have just turned of
mqttClient.publish(topic_publish2, "Light_Detected");
Serial.println("Light_Detected");
Blynk.virtualWrite(V2, "Light_Detected");
Blynk.virtualWrite(V3, HIGH);
// We only want to print on the output change, not state
LDRState = LOW;
}
}
}
BLYNK_WRITE(V4) {
int pinValue = param.asInt();
Serial.print("From Blynk Fan Switch value is: ");
Serial.println(pinValue);
if (pinValue) {
isServoOn = true;
}
else {
isServoOn = false;
}
}
BLYNK_WRITE(V5) {
int pinValue = param.asInt();
Serial.print("From Blynk Fan speed value is: ");
Serial.println(pinValue);
stepSize = pinValue;
}
BLYNK_WRITE(V6) {
String Text = param.asString();
Serial.print("Text from Blynk: " + Text);
if (Text != "-1") {
display.clearDisplay();
display.setTextSize(2);
display.setTextColor(WHITE);
display.setCursor(0, 0);
display.println(Text);
display.display();
OLEDLOCK = true;
}
else {
OLEDLOCK = false;
}
}