//*Circuit Diagram #2 - Double LDR Brightness & Darkness Sensor
//**" The coding and solfware process of LDR Brightness & Darkness Sensors in smart home automation system "**//
//Smart Home Automation -> " SHA " (variable)
#include <PubSubClient.h> //Library Contact MQTT
#include <WiFi.h>         //Library Contact WiFi

#define LDR_Pin001    34  //GPIO-34 to 1st-LDR
#define LDR_Pin002    33  //GPIO-33 to 2nd-LDR
#define Relay_LED003  15  //GPIO-15 to 3rd-LEDin 
#define Relay_LED004  14  //GPIO-14 to 4th-LEDin 

#define TOPIC_SUBSCRIBE_LEDin_003   "SHA_on_off_LEDin003"
#define TOPIC_SUBSCRIBE_LEDin_004   "SHA_on_off_LEDin004"
#define TOPIC_PUBLISH_LDR_001       "SHA/LDR001"
#define TOPIC_PUBLISH_LDR_002       "SHA/LDR002"

#define PUBLISH_DELAY 2000  // Delay time for publish data to MQTT Broker
                            // millis() -> loop 2 second
#define ID_MQTT "ESP32_Double_LDR" // Device ID for connect to MQTT Broker

const char SSID[] = "Wokwi-GUEST";   //Enter WiFi SSID
const char PASSWORD[] = "";   //Enter WiFi Password

//URL for MQTT broker
const char *BROKER_MQTT = "broker.hivemq.com";
int BROKER_PORT = 1883; //Port of Broker MQTT

unsigned long Publish_Update;

static char strBrightDark001[10] = {0};
static char strBrightDark002[10] = {0};

WiFiClient espClient;
PubSubClient MQTT(espClient);

void Initial_WiFi(void);
void Initial_MQTT(void);
void Callback_MQTT(char *topic, byte *payload, unsigned int length);
void Reconnect_MQTT(void);
void Reconnect_WiFi(void);
void Check_WiFiAndMQTT(void);

/*Start Beginning of WiFi*/
void Initial_WiFi(void) 
{
  delay(10);
  Serial.println("------Connect to WI-FI------");
  Serial.print("Connecting to : ");
  Serial.println(SSID);

  Reconnect_WiFi();
}

/*Start Beginning of MQTT*/
void Initial_MQTT(void) 
{
  MQTT.setServer(BROKER_MQTT, BROKER_PORT); 
  MQTT.setCallback(Callback_MQTT);
}

// Function Callback: Receive Message from another MQTT Client publish message pass through the MQTT Broker
void Callback_MQTT(char *topic, byte *payload, unsigned int length) 
{
  String msg;

  //Obtem a string do payload recebido
  for (int i = 0; i < length; i++) {
    char c = (char)payload[i];
    msg += c;
  }

  Serial.printf("Receive string via MQTT : %s on topic : %s\n", msg, topic);

  if(String(topic) == TOPIC_SUBSCRIBE_LEDin_003) {
    if (msg.equals("1")) {
      digitalWrite(Relay_LED003, HIGH);
      Serial.println("LEDin 3rd status : 'ON'");
    }
    if (msg.equals("0")) {
      digitalWrite(Relay_LED003, LOW);
      Serial.println("LEDin 3rd status : 'OFF'");
    }
  }

  if(String(topic) == TOPIC_SUBSCRIBE_LEDin_004) {
    if (msg.equals("1")) {
      digitalWrite(Relay_LED004, HIGH);
      Serial.println("LEDin 4th status : 'ON'");
    }
    if (msg.equals("0")) {
      digitalWrite(Relay_LED004, LOW);
      Serial.println("LEDin 4th status : 'OFF'");
    }
  }
}
//Function Reconnect MQTT Broker
void Reconnect_MQTT(void) 
{
  while (!MQTT.connected()) {
    Serial.print("Connecting MQTT Broker : ");
    Serial.println(BROKER_MQTT);
    if (MQTT.connect(ID_MQTT)) {
      Serial.println("Connecting the MQTT Broker success!\n");

      MQTT.subscribe(TOPIC_SUBSCRIBE_LEDin_003);
      MQTT.subscribe(TOPIC_SUBSCRIBE_LEDin_004);

    }
    else {
      Serial.println("Fail! to connect then reconnect MQTT Broker again in 2 seconds.\n");
      delay(2000);
    }
  }
}
//Function Reconnect WiFi Router
void Reconnect_WiFi(void) 
{
  if (WiFi.status() == WL_CONNECTED)
    return;
  
  WiFi.begin(SSID, PASSWORD); 
  
  while (WiFi.status() != WL_CONNECTED) {
    delay(100);
    Serial.print("#.....#\n");
  }
  Serial.print("Connected WiFi success!\n");
  Serial.print(SSID);
  Serial.println("IP Address : ");
  Serial.println(WiFi.localIP());
}
// Function checking connected to WiFi Router and MQTT Broker */
void Check_WiFiAndMQTT(void) 
{
  if (!MQTT.connected())
    Reconnect_MQTT();
  Reconnect_WiFi();
}
//-------------------------------------------------------------------------------------//

int LDR_Sensor_1st = 34 ;
int LDR_Sensor_2nd = 33 ;

int LEDin_3rd = 15 ;
int LEDin_4th = 14 ;

int LDR_1st_Limit_Criterion = 40;
int LDR_2nd_Limit_Criterion = 40;

int LDR_1st_State_Current = LOW;  //Current state of LDR 1st pin
int LDR_1st_State_Previous = LOW; //Previous state of LDR 1st pin

int LDR_2nd_State_Current = LOW;  //Current state of LDR 2nd pin
int LDR_2nd_State_Previous = LOW; //Previous state of LDR 2nd pin

const unsigned long Period_LEDin_3rd = 30000; //Loop State turn on light of LED 3rd
const unsigned long Period_LEDin_4th = 30000; //Loop State turn on light of LED 4th

boolean Delay_Enabled_3rd = false;
boolean Delay_Enabled_4th = false;

unsigned long Delay_Step_Time_3rd = 0;
unsigned long Delay_Step_Time_4th = 0;

unsigned long BeginLoop_Delay = 0;
unsigned long LDR3rd_Loop_Delay = 0;
unsigned long LDR4th_Loop_Delay = 0;

//-------------------------------------------------------------------------------------//

void setup() 
{
  Serial.begin(115200); //Initialize Serial Moniter
  Serial.println("Get Started!!!");

  pinMode(LDR_Sensor_1st, INPUT);
  pinMode(LDR_Sensor_2nd, INPUT);
  pinMode(LEDin_3rd, OUTPUT);
  pinMode(LEDin_4th, OUTPUT);

  Initial_WiFi();
  Initial_MQTT();
}

void loop() 
{
//-----------------------------------------------------//
  Serial.print("******************************\n");
  Serial.print("Check LDR 1st Status : ");
  Serial.println(analogRead(LDR_Sensor_1st));
  Serial.print("Check LDR 2nd Status : ");
  Serial.println(analogRead(LDR_Sensor_2nd));
  Serial.print("******************************\n");
//-----------------------------------------------------//
BeginLoop_Delay = millis();
if ((BeginLoop_Delay - Publish_Update) >= PUBLISH_DELAY) {
    Publish_Update = millis();
    //Verify the operation of the WiFi connection and go to the MQTT broker
    Check_WiFiAndMQTT();
    
    Detect_Darkness_LDR_1st();
    Detect_Darkness_LDR_2nd();

    //Change format of the Data as String for send it via MQTT protocol
    sprintf(strBrightDark001, "%d",analogRead(LDR_Sensor_1st));
    sprintf(strBrightDark002, "%d",analogRead(LDR_Sensor_2nd));
    delay(1000);

    //Send data string to MQTT Broker
    MQTT.publish(TOPIC_PUBLISH_LDR_001, strBrightDark001);
    MQTT.publish(TOPIC_PUBLISH_LDR_002, strBrightDark002);

    // Keep-alive for connected MQTT broker
    MQTT.loop();
  }
}
// "LDR Brightness & Darkness Sensor Function-1st" //
void Detect_Darkness_LDR_1st() 
{
  LDR_1st_State_Previous = LDR_1st_State_Current;       //Store OLD State
  LDR_1st_State_Current = analogRead(LDR_Sensor_1st);   //Read NEW State
  LDR_1st_State_Current = map(LDR_1st_State_Current, 0, 4095, 0, 100);
  Serial.print("LDR 1st Sensor Value : ");
  Serial.println(LDR_1st_State_Current);
  
  LDR3rd_Loop_Delay = millis();

  if(LDR_1st_State_Previous < LDR_1st_Limit_Criterion && LDR_1st_State_Current >= LDR_1st_Limit_Criterion) {
    String text_5 = "Darkness in LDR 1st Detected!!!" ;
    Serial.println(text_5);
    digitalWrite(LEDin_3rd, HIGH);
    Delay_Enabled_3rd = true;       //Enable Loop-Delay
    Delay_Step_Time_3rd = millis(); //Set Start Time
  }
  else if (LDR_1st_State_Previous > LDR_1st_Limit_Criterion && LDR_1st_State_Current <= LDR_1st_Limit_Criterion) {
    String text_6 = "Darkness in LDR 1st Stopped!!!" ;
    Serial.println(text_6);
    digitalWrite(LEDin_3rd, LOW);
    Delay_Enabled_3rd = false;      //Disable Loop-Delay
  }

  if(Delay_Enabled_3rd == true && (LDR3rd_Loop_Delay - Delay_Step_Time_3rd) >= Period_LEDin_3rd) {
    digitalWrite(LEDin_3rd, LOW);
    Delay_Enabled_3rd = false;       //Set New Loop-Delay
    Delay_Step_Time_3rd = 0;         //Set New Step Time
    LDR3rd_Loop_Delay = 0; 
  }
}
// "LDR Brightness & Darkness Sensor Function-2nd" //
void Detect_Darkness_LDR_2nd() 
{
  LDR_2nd_State_Previous = LDR_2nd_State_Current;       //Store OLD State
  LDR_2nd_State_Current = analogRead(LDR_Sensor_2nd);   //Read NEW State
  LDR_2nd_State_Current = map(LDR_2nd_State_Current, 0, 4095, 0, 100);
  Serial.print("LDR 2nd Sensor Value : ");
  Serial.println(LDR_2nd_State_Current);
  
  LDR4th_Loop_Delay = millis();

  if(LDR_2nd_State_Previous < LDR_2nd_Limit_Criterion && LDR_2nd_State_Current >= LDR_2nd_Limit_Criterion) {
    String text_7 = "Darkness in LDR 2nd Detected!!!" ;
    Serial.println(text_7);
    digitalWrite(LEDin_4th, HIGH);
    Delay_Enabled_4th = true;       //Enable Loop-Delay
    Delay_Step_Time_4th = millis(); //Set Start Time
  }
  else if (LDR_2nd_State_Previous > LDR_2nd_Limit_Criterion && LDR_2nd_State_Current <= LDR_2nd_Limit_Criterion) {
    String text_8 = "Darkness in LDR 2nd Stopped!!!" ;
    Serial.println(text_8);
    digitalWrite(LEDin_4th, LOW);
    Delay_Enabled_4th = false;      //Disable Loop-Delay
  }

  if(Delay_Enabled_4th == true && (LDR4th_Loop_Delay - Delay_Step_Time_4th) >= Period_LEDin_4th) {
    digitalWrite(LEDin_4th, LOW);
    Delay_Enabled_4th = false;       //Set New Loop-Delay
    Delay_Step_Time_4th = 0;         //Set New Step Time
    LDR4th_Loop_Delay = 0; 
  }
}
$abcdeabcde151015202530fghijfghij
$abcdeabcde151015202530fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module