Timed Based Relay Controlled

by iamrachelle in Circuits > Electronics

2418 Views, 6 Favorites, 0 Comments

Timed Based Relay Controlled

IMG_0626.JPG
IMG_0624.JPG

Hardware

schematics.png
20200924_231424.jpg
20200924_233032.jpg
20200924_233050.jpg
20200924_233105.jpg

See the pictures for the schematic and the hardware I used. Here's the components:

  • WEMOS D1 Mini NodeMCU WiFi Board
    • Any ESP8266 board can be used. i used it since it small.
  • HI-Link HLK-PM01 AC-DC 220V to 5V Step-down Power Supply Module
    • convert a 220V AC to 5VDC to power the Wemos, relay, RTC and LCD
  • 2 Channel 5V Relay Module SPDT
    • To turn on/off the load connected to the relay
  • DS1307 RTC Module
    • To get the time,day and weekday
  • IIC Serial I2C 1602 2004 LCD Adapter Board for Arduino
    • used with the LCD Display to be able to use 2 I2C Wires only
  • 20×4 LCD Display I2C Black on Green
    • Display text on the LCD screen
  • Jumper wires with Male end
    • Connect the components

Upload the Webpage and Schedule Files

Capture1.JPG
Screenshot (1).png

Make A folder named "data" inside this Arduino project folder. Make files named sched_1.json, sched_2.json and index.html save it in your newly named "data". Here's a guide on how to upload this using spiff. Make sure your Serial monitor is closed when uploading to spiff.

I can't upload html and json files in instructables so download the following files and save it as sched_1.json, sched_2.json and index.html

Find the Address of RTC and LCD

Screenshot (1).png

Upload this code to find the RTC and LCD I2C address

#include <Wire.h>
 
 
void setup()
{
  Wire.begin();
 
  Serial.begin(9600);
  while (!Serial);             // Leonardo: wait for serial monitor
  Serial.println("\nI2C Scanner");
}
 
 
void loop()
{
  byte error, address;
  int nDevices;
 
  Serial.println("Scanning...");
 
  nDevices = 0;
  for(address = 1; address < 127; address++ )
  {
    // The i2c_scanner uses the return value of
    // the Write.endTransmisstion to see if
    // a device did acknowledge to the address.
    Wire.beginTransmission(address);
    error = Wire.endTransmission();
 
    if (error == 0)
    {
      Serial.print("I2C device found at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.print(address,HEX);
      Serial.println("  !");
 
      nDevices++;
    }
    else if (error==4)
    {
      Serial.print("Unknown error at address 0x");
      if (address<16)
        Serial.print("0");
      Serial.println(address,HEX);
    }    
  }
  if (nDevices == 0)
    Serial.println("No I2C devices found\n");
  else
    Serial.println("done\n");
 
  delay(5000);           // wait 5 seconds for next scan
}<br>

Arduino Code

IMG_E0912.JPG

See the picture to know the outline of what the code do.

Add the following libraries to your Arduino IDE:

Here's the code I used with commented explanation. Copy this to your arduino IDE and upload.

//Initiakize Libraries
#include <ESP8266WiFi.h>// included when ESP8266 boards such as wemos is used
#include <ESP8266WebServer.h> //To use the ESP8266 as a Server
#include <WiFiClient.h>
#include <FS.h>//Flie system to be able to save file on Wemos's memory
#include <Arduino.h>//Arduino library
#include <WebSocketsServer.h>//Enable Websocket to enable server to client and vice cersa communication
#include <Hash.h> 


ESP8266WebServer server(80); //Server connection on port 80
WebSocketsServer webSocket = WebSocketsServer(81);//Websocket connection on port 81

//LCD Library
#include <Wire.h>// Allows I2C Communication for more info:https://www.circuitbasics.com/basics-of-the-i2c-communication-protocol/
#include <LiquidCrystal_I2C.h>//To use I2C LCD functions
LiquidCrystal_I2C lcd(0x27, 20, 4); //0x27 = I2C Address, 20x4 = LCD Size

//RTC Library
#include "RTClib.h" //To use real time clock(RTC) functions
RTC_DS1307 rtc;// Initialize rtc
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //Array for printing the days of the week 

//JSON Library
#include <ArduinoJson.h> //To handle JSON data for more information: <a href="https://www.w3schools.com/js/js_json.asp" rel="nofollow">  https://www.w3schools.com/js/js_json.asp

</a>

//variables to change
int duration = 5000; //time before LCD Display changes
String ssid = "Garden"; //  SSID of the Wemos
String password="b11l4546"; //PASS of the Wemos


//Other variables 
int screen = 1;
String date;
String time_now;
int sym = 0;
int  day_of_the_week;
bool count_duration1 = true;
long  start_sec1;
bool count_duration2 = true;
long  start_sec2;
unsigned long prev_time = 0;
String time_1;
int mins_1;
bool days_1[7];
bool relay_1[2];
String time_2;
int mins_2;
bool days_2[7];
bool relay_2[2];

/*
Function that is called whenever Webscoket connection happens. 
      >if a device connected, it will print the information o the serial monitor
      >If disconected, it will print "disconnected" on the serial monitor
      >if a message form the client is received, with regards to "time" "relay" "sched1" or "sched2"
        "time" 
          Adjust the date and time similar to client's device
        "relay" 
          Turn on/off the Specific relay
        "sched1" or "sched2"
          save the JSON data to Wemos and set the schedule
 */
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        webSocket.sendTXT(num, "Connected");
      }
      break;
    case WStype_TEXT:
      Serial.printf("[%u] Data: %s\n", num, payload);
      DynamicJsonBuffer jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(payload);
      String _data = root["data"];
      Serial.println(_data);
      if (_data == "time") {
        int _year = root["year"];
        byte _month = root["month"];
        byte _day = root["day"];
        byte _hour = root["hour"];
        byte _min = root["min"];
        byte _secs = root["secs"];
        rtc.adjust(DateTime(_year, _month, _day, _hour,  _min, _secs));
        Serial.println("_time adjusted");
      }
      else if (_data == "relay") {
        int relay = root["relay"];
        bool value = root["value"];
        digitalWrite(relay, value);
        Serial.print("relay , value");
        Serial.print(relay);
        Serial.println(value);
      }
      else if (_data == "sched_1" || _data == "sched_2") {
        //         var schedule = { data: "sched_"+sched, time: time, mins: mins, days: days, relay: relays }
        String _name = root["data"];

        File file_name = SPIFFS.open(_name + ".json", "w");
        root.printTo(file_name);
        file_name.close();
        set_schedule(_name);

      }
      break;
  }
}

/*
 * Open the schedule files and save to global variables the days and relays are save as arrays while the
 * time is a string 
 * mins is an integer
 */
void set_schedule(String _name) {
  File file = SPIFFS.open(_name + ".json", "r");
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(file);

  if (_name == "sched_1") {
    String _time_1 = root["time"];
    int _mins_1 = root["mins"];
    time_1 = _time_1;
    mins_1 = _mins_1;
    bool _days[7];

    
    Serial.print("Days");
    for (int i = 0; i < 7 ; i++) {
      _days[i] = root["days"][i];
      Serial.print(_days[i]);
      days_1[i] = _days[i];
    }

    bool _relay[2];
    Serial.print("Relay");
    for (int i = 0; i < 2 ; i++) {
      _relay[i] = root["relay"][i];
      Serial.print(_relay[i]);
      relay_1[i] = _relay[i];
    }

  }
  else if (_name == "sched_2") {
    String _time_2 = root["time"];
    int _mins_2 = root["mins"];
    time_2 = _time_2;
    mins_2 = _mins_2;

    Serial.print("Days");
    bool _days[7];
    for (int i = 0; i < 7 ; i++) {
      _days[i] = root["days"][i];
      Serial.print(_days[i]);
      days_2[i] = _days[i];
    }

    bool _relay[2];
    Serial.print("Relay");
    for (int i = 0; i < 2 ; i++) {
      _relay[i] = root["relay"][i];
      Serial.print(_relay[i]);
      relay_2[i] = _relay[i];
    }
  }

  root.printTo(Serial);
  file.close();

  Serial.println("set schedule");
}




void setup() {
  Serial.begin(57600);  //Set the Serial monitor Baud rate to 57600. Pls lower this if problems on the clock happens
  pinMode(LED_BUILTIN, OUTPUT);//set the led
  pinMode(13, OUTPUT);//set the  relays as output
  pinMode(12, OUTPUT);//set the  relays as output
  SPIFFS.begin();//Initialize the file system in the Wemos

  //Check RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  //LOAD schedule
  set_schedule("sched_1");
  set_schedule("sched_2");


  //LCD initalization and turn on back light
  lcd.init();
  lcd.backlight();


  //SERVER initalization and configuration
  WiFi.mode(WIFI_AP); //WIFI_AP to be able to connect to it
  IPAddress apIP = WiFi.softAPIP();//Generate the IP of The device. it is always 192.168.4.1
  Serial.print("AP IP address: ");
  Serial.println(apIP);
  WiFi.softAP(ssid,password);

  //WEBSOCKET initalization and configuration
  webSocket.begin();
  webSocket.onEvent(webSocketEvent); //Call the function named "webSocketEvent" when Websocket events happens such as connection, disconnection and received message
  Serial.println("WebSocket server started.");

  //SERVE HTML named "index.html" saved/uploaded on the WEMOS Memory 
  server.onNotFound([]() {
    File file = SPIFFS.open("/index.html", "r"); //Opens the index.html file
    size_t sent = server.streamFile(file, "text/html"); //Send it to the client(clinet = connected deivce)
    file.close();//Close the file
  });

  //SERVE FILES
  server.begin(); //Start the esp8266 as a Server
  Serial.println("HTTP server started");
}

//do not use delays here. Websocket.loop and server.handle cient may not work properly.
void loop() {
  server.handleClient(); //Allow sthe WEMOS to run as a server continuosly
  webSocket.loop();//Check for Websockets connection 

  unsigned long curr_time = millis();
  if (curr_time - prev_time >= duration) { //Every duration(whcih is 5) the code within happens
    prev_time = millis();
    String time_now = get_time(); //Gets time and print it on the Serial monitor
    schedule_checker(1, time_now, days_1, time_1, relay_1, mins_1); //Check the schedule 1 and turn on/off the relay based on schedule
    String date_time = schedule_checker(2, time_now, days_2, time_2, relay_2, mins_2); //Check the schedule 1 and turn on/off the relay based on schedule and return the date and time
    set_lcd(date_time);//Set LCD Displays
  }
}


/*
 * Function to check the schedule and curent time and day:
 * 1. Determine is the schedule to check: 1 or 2 
 * 2. Get the duration since the schedule was met(Ex. time the relays are turned on)
 * 3.Get the Day of the week
 * 4.If the day of the week is on the scheduled days
 * if the current time and scheduled time is the same, turn on/off the relays
 * 5.Turn the relays off after the scheduled duration
 * 6.Returns the date and time 
 */
String schedule_checker(int sched, String time_now,  bool _days[7], String _time, bool relay[2], int mins) {

  bool count_duration;
  long start_sec;
  if (sched == 1) {
    count_duration = count_duration1 ;
    start_sec =  start_sec1;
  }
  else if (sched == 2) {
    count_duration = count_duration2;
    start_sec =  start_sec2;
  }

  DateTime now = rtc.now();
  day_of_the_week = now.dayOfTheWeek();

  if (_days[day_of_the_week]) {
    if (time_now == _time) {
      if (count_duration) {
        start_sec = now.secondstime();
        count_duration = false;
      }
      digitalWrite(13, relay[1]);
      digitalWrite(12, relay[0]);
    }
    if (!count_duration) {
      if ( long( now.secondstime() - start_sec) >=  long(mins * 60)) {
        digitalWrite(12, LOW);
        digitalWrite(13, LOW);
        count_duration = true;
      }
    }
  }
  if (sched == 1) {
    count_duration1 = count_duration;
    start_sec1 =  start_sec;
  }
  else if (sched == 2) {
    count_duration2 = count_duration ;
    start_sec2 =  start_sec;
  }
  String date_time = String(daysOfTheWeek[day_of_the_week]) + " " + time_now ;
  return date_time;
}


//Get time
String get_time() {
  DateTime now = rtc.now();
  day_of_the_week = now.dayOfTheWeek();
  String curr_hour = String(now.hour());
  String curr_min = String(now.minute());


  if (now.hour() < 10) {
    curr_hour = "0" + String(now.hour());
  }
  if (now.minute() < 10) {
    curr_min = "0" + String(now.minute());
  }

  date = String(daysOfTheWeek[now.dayOfTheWeek()]) + " " + String(now.month()) + "/" + String(now.day()) + "/" + String( now.year());
  time_now = curr_hour + ":" + curr_min;
  
  Serial.print("Current date: "); Serial.print(date);
  Serial.print("Current time: "); Serial.println("time_now");
  
  return time_now;
}

/*
 * Set LCD Displays. There are 3 Displays
 * 1. Shows the time, day and Connection instructions
 * 2. Shows the time Schedule 1
 * 3. Shows the time Schedule 2
 */

void  set_lcd(String time_now) {

  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print(time_now);

  if (screen == 1) {
    lcd.setCursor(1, 1);
    lcd.print("Connect to 'Garden'");
    lcd.setCursor(5, 2);
    lcd.print("and go to");
    lcd.setCursor(4, 3);
    lcd.print("192.168.4.1");
    screen = 2;
    return;
  }


  String _days = "SMTWTFS";
  String _rel = "12";
  String _time_;
  String _mins_;
  String schedule;
  String _days_chosen;
  String  _relay_chosen;


  if (screen == 3) {
    _time_ = time_2;
    _mins_ = String(mins_2);
    screen = 1;
    schedule = "Schedule 2";
    for (int i = 0; i < 7; i++) {

      if (days_2[i]) {
        _days_chosen += _days[i];
      }
    }
    for (int i = 0; i < 2; i++) {
      if (relay_2[i]) {
        _relay_chosen += _rel[i];
      }
    }

  }
  else if (screen == 2) {
    _time_ = time_1;
    _mins_ = String(mins_1);
    screen = 3;
    schedule = "Schedule 1";

    for (int i = 0; i < 7; i++) {

      if (days_1[i]) {

        _days_chosen += _days[i];
      }
    }
    for (int i = 0; i < 2; i++) {
      if (relay_1[i]) {
        _relay_chosen += _rel[i];
      }
    }
  }

  String sched_time = "Time:" + _time_;
  String sched_min = "min:" + _mins_;
  String sched_day = "Days:" + _days_chosen;
  String sched_rel = "Rel:" + _relay_chosen;
  lcd.setCursor(5, 1);
  lcd.print(schedule);
  lcd.setCursor(0, 2);
  lcd.print(sched_time);
  lcd.setCursor(13, 2);
  lcd.print(sched_min);
  lcd.setCursor(0, 3);
  lcd.print(sched_day);
  lcd.setCursor(13, 3);
  lcd.print(sched_rel);

}

For active low relay modules, try this code. I dont have a active low relay module at the moment but I've made code modifications. Try it out and please tell me if theres a problem. thank you!

//Initiakize Libraries
#include <ESP8266WiFi.h>// included when ESP8266 boards such as wemos is used
#include <ESP8266WebServer.h> //To use the ESP8266 as a Server
#include <WiFiClient.h>
#include <FS.h>//Flie system to be able to save file on Wemos's memory
#include <Arduino.h>//Arduino library
#include <WebSocketsServer.h>//Enable Websocket to enable server to client and vice cersa communication
#include <Hash.h> 


ESP8266WebServer server(80); //Server connection on port 80
WebSocketsServer webSocket = WebSocketsServer(81);//Websocket connection on port 81

//LCD Library
#include <Wire.h>// Allows I2C Communication for more info:https://www.circuitbasics.com/basics-of-the-i2c-communication-protocol/
#include <LiquidCrystal_I2C.h>//To use I2C LCD functions
LiquidCrystal_I2C lcd(0x27, 20, 4); //0x27 = I2C Address, 20x4 = LCD Size

//RTC Library
#include "RTClib.h" //To use real time clock(RTC) functions
RTC_DS1307 rtc;// Initialize rtc
char daysOfTheWeek[7][12] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; //Array for printing the days of the week 

//JSON Library
#include <ArduinoJson.h> //To handle JSON data for more information: <a href="https://www.w3schools.com/js/js_json.asp" rel="nofollow"> https://www.w3schools.com/js/js_json.asp
</a>

//variables to change
int duration = 5000; //time before LCD Display changes
String ssid = "WifiName"; //  SSID of the Wemos
String password="password"; //PASS of the Wemos


//Other variables 
int screen = 1;
String date;
String time_now;
int sym = 0;
int  day_of_the_week;
bool count_duration1 = true;
long  start_sec1;
bool count_duration2 = true;
long  start_sec2;
unsigned long prev_time = 0;
String time_1;
int mins_1;
bool days_1[7];
bool relay_1[2];
String time_2;
int mins_2;
bool days_2[7];
bool relay_2[2];

/*
Function that is called whenever Webscoket connection happens. 
      >if a device connected, it will print the information o the serial monitor
      >If disconected, it will print "disconnected" on the serial monitor
      >if a message form the client is received, with regards to "time" "relay" "sched1" or "sched2"
        "time" 
          Adjust the date and time similar to client's device
        "relay" 
          Turn on/off the Specific relay
        "sched1" or "sched2"
          save the JSON data to Wemos and set the schedule
 */
void webSocketEvent(uint8_t num, WStype_t type, uint8_t * payload, size_t length) {

  switch (type) {
    case WStype_DISCONNECTED:
      Serial.printf("[%u] Disconnected!\n", num);
      break;
    case WStype_CONNECTED: {
        IPAddress ip = webSocket.remoteIP(num);
        Serial.printf("[%u] Connected from %d.%d.%d.%d url: %s\n", num, ip[0], ip[1], ip[2], ip[3], payload);
        webSocket.sendTXT(num, "Connected");
      }
      break;
    case WStype_TEXT:
      Serial.printf("[%u] Data: %s\n", num, payload);
      DynamicJsonBuffer jsonBuffer;
      JsonObject& root = jsonBuffer.parseObject(payload);
      String _data = root["data"];
      Serial.println(_data);
      if (_data == "time") {
        int _year = root["year"];
        byte _month = root["month"];
        byte _day = root["day"];
        byte _hour = root["hour"];
        byte _min = root["min"];
        byte _secs = root["secs"];
        rtc.adjust(DateTime(_year, _month, _day, _hour,  _min, _secs));
        Serial.println("_time adjusted");
      }
      else if (_data == "relay") {
        int relay = root["relay"];
        bool value = root["value"];
        digitalWrite(relay, value);
        Serial.print("relay , value");
        Serial.print(relay);
        Serial.println(value);
      }
      else if (_data == "sched_1" || _data == "sched_2") {
        //         var schedule = { data: "sched_"+sched, time: time, mins: mins, days: days, relay: relays }
        String _name = root["data"];

        File file_name = SPIFFS.open(_name + ".json", "w");
        root.printTo(file_name);
        file_name.close();
        set_schedule(_name);

      }
      break;
  }
}

/*
 * Open the schedule files and save to global variables the days and relays are save as arrays while the
 * time is a string 
 * mins is an integer
 */
void set_schedule(String _name) {
  File file = SPIFFS.open(_name + ".json", "r");
  DynamicJsonBuffer jsonBuffer;
  JsonObject& root = jsonBuffer.parseObject(file);

  if (_name == "sched_1") {
    String _time_1 = root["time"];
    int _mins_1 = root["mins"];
    time_1 = _time_1;
    mins_1 = _mins_1;
    bool _days[7];

    
    Serial.print("Days");
    for (int i = 0; i < 7 ; i++) {
      _days[i] = root["days"][i];
      Serial.print(_days[i]);
      days_1[i] = _days[i];
    }

    bool _relay[2];
    Serial.print("Relay");
    for (int i = 0; i < 2 ; i++) {
      _relay[i] = root["relay"][i];
      Serial.print(_relay[i]);
      relay_1[i] = _relay[i];
    }

  }
  else if (_name == "sched_2") {
    String _time_2 = root["time"];
    int _mins_2 = root["mins"];
    time_2 = _time_2;
    mins_2 = _mins_2;

    Serial.print("Days");
    bool _days[7];
    for (int i = 0; i < 7 ; i++) {
      _days[i] = root["days"][i];
      Serial.print(_days[i]);
      days_2[i] = _days[i];
    }

    bool _relay[2];
    Serial.print("Relay");
    for (int i = 0; i < 2 ; i++) {
      _relay[i] = root["relay"][i];
      Serial.print(_relay[i]);
      relay_2[i] = _relay[i];
    }
  }

  root.printTo(Serial);
  file.close();

  Serial.println("set schedule");
}




void setup() {
  Serial.begin(57600);  //Set the Serial monitor Baud rate to 57600. Pls lower this if problems on the clock happens
  pinMode(LED_BUILTIN, OUTPUT);//set the led
  pinMode(13, OUTPUT);//set the  relays as output
  pinMode(12, OUTPUT);//set the  relays as output
  pinMode(13, HIGH);//set the  relays as output
  pinMode(12, HIGH);//set the  relays as output
  SPIFFS.begin();//Initialize the file system in the Wemos

  //Check RTC
  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
  }

  if (! rtc.isrunning()) {
    Serial.println("RTC is NOT running, let's set the time!");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }

  //LOAD schedule
  set_schedule("sched_1");
  set_schedule("sched_2");


  //LCD initalization and turn on back light
  lcd.init();
  lcd.backlight();


  //SERVER initalization and configuration
  WiFi.mode(WIFI_AP); //WIFI_AP to be able to connect to it
  IPAddress apIP = WiFi.softAPIP();//Generate the IP of The device. it is always 192.168.4.1
  Serial.print("AP IP address: ");
  Serial.println(apIP);
  WiFi.softAP(ssid,password);

  //WEBSOCKET initalization and configuration
  webSocket.begin();
  webSocket.onEvent(webSocketEvent); //Call the function named "webSocketEvent" when Websocket events happens such as connection, disconnection and received message
  Serial.println("WebSocket server started.");

  //SERVE HTML named "index.html" saved/uploaded on the WEMOS Memory 
  server.onNotFound([]() {
    File file = SPIFFS.open("/index.html", "r"); //Opens the index.html file
    size_t sent = server.streamFile(file, "text/html"); //Send it to the client(clinet = connected deivce)
    file.close();//Close the file
  });

  //SERVE FILES
  server.begin(); //Start the esp8266 as a Server
  Serial.println("HTTP server started");
}

//do not use delays here. Websocket.loop and server.handle cient may not work properly.
void loop() {
  server.handleClient(); //Allow sthe WEMOS to run as a server continuosly
  webSocket.loop();//Check for Websockets connection 

  unsigned long curr_time = millis();
  if (curr_time - prev_time >= duration) { //Every duration(whcih is 5) the code within happens
    prev_time = millis();
    String time_now = get_time(); //Gets time and print it on the Serial monitor
    schedule_checker(1, time_now, days_1, time_1, relay_1, mins_1); //Check the schedule 1 and turn on/off the relay based on schedule
    String date_time = schedule_checker(2, time_now, days_2, time_2, relay_2, mins_2); //Check the schedule 1 and turn on/off the relay based on schedule and return the date and time
    set_lcd(date_time);//Set LCD Displays
  }
}


/*
 * Function to check the schedule and curent time and day:
 * 1. Determine is the schedule to check: 1 or 2 
 * 2. Get the duration since the schedule was met(Ex. time the relays are turned on)
 * 3.Get the Day of the week
 * 4.If the day of the week is on the scheduled days
 * if the current time and scheduled time is the same, turn on/off the relays
 * 5.Turn the relays off after the scheduled duration
 * 6.Returns the date and time 
 */
String schedule_checker(int sched, String time_now,  bool _days[7], String _time, bool relay[2], int mins) {

  bool count_duration;
  long start_sec;
  if (sched == 1) {
    count_duration = count_duration1 ;
    start_sec =  start_sec1;
  }
  else if (sched == 2) {
    count_duration = count_duration2;
    start_sec =  start_sec2;
  }

  DateTime now = rtc.now();
  day_of_the_week = now.dayOfTheWeek();

  if (_days[day_of_the_week]) {
    if (time_now == _time) {
      if (count_duration) {
        start_sec = now.secondstime();
        count_duration = false;
      }
      digitalWrite(13, !relay[1]);
      digitalWrite(12, !relay[0]);
    }
    if (!count_duration) {
      if ( long( now.secondstime() - start_sec) >=  long(mins * 60)) {
        digitalWrite(12, HIGH);
        digitalWrite(13, HIGH);
        count_duration = true;
      }
    }
  }
  if (sched == 1) {
    count_duration1 = count_duration;
    start_sec1 =  start_sec;
  }
  else if (sched == 2) {
    count_duration2 = count_duration ;
    start_sec2 =  start_sec;
  }
  String date_time = String(daysOfTheWeek[day_of_the_week]) + " " + time_now ;
  return date_time;
}


//Get time
String get_time() {
  DateTime now = rtc.now();
  day_of_the_week = now.dayOfTheWeek();
  String curr_hour = String(now.hour());
  String curr_min = String(now.minute());


  if (now.hour() < 10) {
    curr_hour = "0" + String(now.hour());
  }
  if (now.minute() < 10) {
    curr_min = "0" + String(now.minute());
  }

  date = String(daysOfTheWeek[now.dayOfTheWeek()]) + " " + String(now.month()) + "/" + String(now.day()) + "/" + String( now.year());
  time_now = curr_hour + ":" + curr_min;
  
  Serial.print("Current date: "); Serial.print(date);
  Serial.print("Current time: "); Serial.println("time_now");
  
  return time_now;
}

/*
 * Set LCD Displays. There are 3 Displays
 * 1. Shows the time, day and Connection instructions
 * 2. Shows the time Schedule 1
 * 3. Shows the time Schedule 2
 */

void  set_lcd(String time_now) {

  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print(time_now);

  if (screen == 1) {
    lcd.setCursor(1, 1);
    lcd.print("Connect to 'Garden'");
    lcd.setCursor(5, 2);
    lcd.print("and go to");
    lcd.setCursor(4, 3);
    lcd.print("192.168.4.1");
    screen = 2;
    return;
  }


  String _days = "SMTWTFS";
  String _rel = "12";
  String _time_;
  String _mins_;
  String schedule;
  String _days_chosen;
  String  _relay_chosen;


  if (screen == 3) {
    _time_ = time_2;
    _mins_ = String(mins_2);
    screen = 1;
    schedule = "Schedule 2";
    for (int i = 0; i < 7; i++) {

      if (days_2[i]) {
        _days_chosen += _days[i];
      }
    }
    for (int i = 0; i < 2; i++) {
      if (relay_2[i]) {
        _relay_chosen += _rel[i];
      }
    }

  }
  else if (screen == 2) {
    _time_ = time_1;
    _mins_ = String(mins_1);
    screen = 3;
    schedule = "Schedule 1";

    for (int i = 0; i < 7; i++) {

      if (days_1[i]) {

        _days_chosen += _days[i];
      }
    }
    for (int i = 0; i < 2; i++) {
      if (relay_1[i]) {
        _relay_chosen += _rel[i];
      }
    }
  }

  String sched_time = "Time:" + _time_;
  String sched_min = "min:" + _mins_;
  String sched_day = "Days:" + _days_chosen;
  String sched_rel = "Rel:" + _relay_chosen;
  lcd.setCursor(5, 1);
  lcd.print(schedule);
  lcd.setCursor(0, 2);
  lcd.print(sched_time);
  lcd.setCursor(13, 2);
  lcd.print(sched_min);
  lcd.setCursor(0, 3);
  lcd.print(sched_day);
  lcd.setCursor(13, 3);
  lcd.print(sched_rel);

}

See It Work!

Time Based Relay Control
IMG_0624.JPG
IMG_0625.JPG
IMG_0626.JPG

I connected the relay to a 12V Solenoid lock that I have to test it. Here's the video and pictures of the screen! Had a lot of fun doing this, I hope you do too :)