Timed Based Relay Controlled

Introduction: Timed Based Relay Controlled

Step 1: Hardware

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

Step 2: Upload the Webpage and Schedule Files

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

Step 3: Find the Address of RTC and LCD

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>

Step 4: Arduino Code

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);

}

Step 5: See It Work!

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 :)

Be the First to Share

    Recommendations

    • Rocks, Gems, and Stones Speed Challenge

      Rocks, Gems, and Stones Speed Challenge
    • Tinkercad Student Design Contest

      Tinkercad Student Design Contest
    • Retro Tech Challenge

      Retro Tech Challenge

    12 Comments

    0
    gyrkinaround
    gyrkinaround

    4 months ago on Step 4

    Hi There,
    Been working away on this this evening and found that there seems to be an error(s) in Index.html as reported by Chrome Console. Please see attached screenshot
    thanks
    Iain

    Screenshot (2).png
    0
    gyrkinaround
    gyrkinaround

    4 months ago on Step 2

    HI There,

    Many thanks for all your hard work on this I really appreciate you trying to help me.

    I have downloaded and implemented the new JSON files and the new HTML files.

    The index html looks much better but the "Submit" buttons do not operate at all. To select the days of the week you have to click just above the days for it to register.

    I have implemented the new code you made for relays which require a low signal and the relays still remain on and noticed straight away in the serial monitor that it is outputting the time and not just " time_now" which I think is an improvement.

    I am sending you a screen shot of the web page along side the serial monitor so you can see nothing happens when trying to use the web page.

    Many Thanks

    Iain

    PS if you drop me a note in comments if you update anything I get an email to say so I do not always check this page every day. Thank you again

    Screenshot (1).pngPXL_20210526_182404604.jpg
    0
    gyrkinaround
    gyrkinaround

    Reply 4 months ago

    I also tried it on my mobile phone and the webpage looks much better on there. The buttons seem to work but there is no change on the serial monitor.

    Screenshot_20210526-154044.png
    0
    gyrkinaround
    gyrkinaround

    Tip 4 months ago on Step 5

    I have built this project and bearing in mind I am a complete newbie I found it really challenging. First off this project uses ver 5 Json so to get it to compile I had to rollback my JSON library to 5 from 6. I had a real problem getting the 3 files to upload to spiffs I followed all the instructions carefully but not until I switched my IDE for the latest version would it work. So now I have the spiffs uploaded and the code and it will not run. I can open the web page and enter the schedule but it has no effect whatsoever. The LCD display just cycles through its three screens but does not acknowledge the changes to the schedule. Any help much appreciated.

    0
    iamrachelle
    iamrachelle

    Reply 4 months ago

    Can i see the serial monitor when you connect and pick a schedule for it?

    0
    gyrkinaround
    gyrkinaround

    Reply 4 months ago

    Many thanks for getting back to me. There is no change in the output from the serial monitor when you access the webpage . Here is the output following a re-set.
    1. The output to the relays are on all the time.
    2. The 2 Sched files are shown as 0. Bytes in file explorer - I see yours are at 1K.

    Many thanks for your help. I have battled this for hours!
    Best wishes, Iain

    PXL_20210518_154621567.jpg
    0
    iamrachelle
    iamrachelle

    Reply 4 months ago

    For problem 1: it seems we are using a different relay. Mine is active high, so it turns on when given a command 1. Yours seems to be active low. Is there a jumper on the relay similiar to this? If so, Please change its connection.if not, I'll make a code for that later.
    2. It seems it hasn't receive a schedule. Please connect to the controller, pick a schedule and send the serial monitor output. It would help me to know what is really happening. Thank you!

    Screenshot_20210519-131154_Lazada.jpg
    0
    gyrkinaround
    gyrkinaround

    Reply 4 months ago

    Hi Rachelle, thank you for your reply. The web page opens okay but if I set a schedule nothing happens at all. Nothing appears on the serial monitor.If I try to synchronize the time that does not change the time either.
    Many thanks for helping me.
    I will check the relays. Best regards
    Iain.

    0
    gyrkinaround
    gyrkinaround

    Reply 4 months ago

    I wondered if I might have a problem with the code? I copied it off the screen and I noticed there was some HTML in there. Is there a link to download the code?
    Many thanks
    Iain.

    0
    iamrachelle
    iamrachelle

    Reply 4 months ago

    You can copy paste the html code from this instructable. However, I'll make a downloadable copy later.

    0
    gyrkinaround
    gyrkinaround

    Question 4 months ago on Step 1

    Hi There this is a fantastic project and would solve a major problem for me. Is it possible to modify the code in a way that would let you set the "On" period for the relays to be entered in seconds? I have one valve that I need to trigger for about 20 seconds. Many thanks ,Iain.