Scheduling LED shop sign to turn on and off

Try this:

#include <ESP8266WiFi.h>
#include <time.h>

const char* ssid = "";
const char* password = "";

const int ledPin = LED_BUILTIN;

const int timezone = 0 * 3600;
const int dst = 0;

const int ON_HOUR = 21;
const int ON_MINUTE = 40;

const int OFF_HOUR = 21;
const int OFF_MINUTE = 42;

#define INTERVAL 1 // Time in seconds.

unsigned long prevMillis = 0;

void ledControl(int pin, bool state)
{
  Serial.print("Changing pin ");
  Serial.print(pin);
  Serial.print(" to ");
  Serial.println(state ? "HIGH": "LOW");

  digitalWrite(pin, state);
}

int numMins(uint8_t ScheduleHour, uint8_t ScheduleMinute)
{
  return (ScheduleHour * 60) + ScheduleMinute;
}

void setup()
{

  Serial.begin(115200);

  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,LOW);

  Serial.print("\nWifi connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid,password);

  Serial.print("\nConnecting");

  while(WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }

  Serial.println("\nWifi Connected Success!");
  Serial.print("NodeMCU IP Address : ");
  Serial.println(WiFi.localIP() );

  configTime(timezone, dst, "pool.ntp.org","time.nist.gov");
  Serial.println("\nWaiting for Internet time");

  while(!time(nullptr))
  {
    Serial.print("*");
    delay(1000);
  }
  Serial.println("\nTime response....OK");
}

void loop()
{
  if((millis() - prevMillis) > (INTERVAL * 1000UL))
  {
    time_t now = time(nullptr);
    struct tm* p_tm = localtime(&now);
    Serial.print(p_tm->tm_mday);
    Serial.print("/");
    Serial.print(p_tm->tm_mon + 1);
    Serial.print("/");
    Serial.print(p_tm->tm_year + 1900);

    Serial.print(" ");

    Serial.print(p_tm->tm_hour);
    Serial.print(":");
    Serial.print(p_tm->tm_min);
    Serial.print(":");
    Serial.println(p_tm->tm_sec);

    if((numMins(p_tm->tm_hour, p_tm->tm_min) >= numMins(ON_HOUR, ON_MINUTE)) &&
       (numMins(p_tm->tm_hour, p_tm->tm_min) < numMins(OFF_HOUR, OFF_MINUTE)))
    {
      ledControl(ledPin, HIGH);
    }
    else
    {
      ledControl(ledPin, LOW);
    }
    prevMillis = millis();
  }
}

The time zone should be Ok if your current time is 19:42.

//  the library you will need --
//  https://github.com/arduino-libraries/NTPClient
//
//  NodeMCU  NodeMCU  NodeMCU  NodeMCU

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "";
const char *password = "";

const long utcOffsetInSeconds = -25200;  // more or less vs. YOUR TIMEZONE

char daysOfTheWeek[7][12] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

int hh;
int mm;
int ss;
int comparisonsecs = 55;  // to closer sync actual NTP change

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

//SoftwareSerial playerSerial (D5,D6);

void setup()
{
  WiFi.begin(ssid, password);
  delay(2000);
  Serial.begin(115200);  // not essential, OMIT when Ready
  timeClient.begin();
}

void loop() 
{
  timeClient.update();
  Serial.print(hh);
  Serial.print("  ");
  Serial.print(mm);
  Serial.print("  ");
  Serial.println(ss);

  if(hh == 18 && mm == 30 && ss == 00)  // 6:30 PM
  {
    // turn on the light
    // do your pinMode in SETUP()
    // do your digitalWrite here
    Serial.println("Turned ON");
  }

  if(hh == 21 && mm == 00 && ss == 00)  // 9:00 PM
  {
    // turn off the light
    Serial.println("Turned OFF");
  }

}

I don't understand why testing should take days with my current code

Haha, I just mean to see if it turns on and off correctly takes a day. Finding little flaws one by one will take days. So I might make a test to see if it turned on from 0:30 seconds to 0:45 seconds, just stuff the seconds into miutesSince00.

Then worry about making that do something at an hour and minute, setting it like it seems you are doing, like for 5 minutes from now. Or if you are fast enough, 3 minutes… life is short.

Then… a full up 24 hour test. Using a range as I suggest means you can next test the response to a power failure, during and not during the on interval. You may see the point of using a range.

Testing for hh:mm:so exactly is only more problematic. If you aren't there to see it, you don't get to react.

@McGregz I can't offer anything other than to make sure you are doing the modifications correctly and

to liberally dose your code with Serial.pritn() statements to check the values of keys variables and confirm the flow that they inform.


I like functions as much as the next person, but here you have two identical calls to numMins()… or are they?, and two calls that are actually constants.

If you have to use a function, call it once to establish the current time in minutes when you need to, and call it in setup() to fix values for constants ON_MINUTES and OFF_MINUTES or whatever.

I think it's clearer just to say 60 * H + M right when if you need to calculate that. And do the constants as global const variables.

I like your idea of slowing down the loop().

a7

Thanks @anon85221860 this doesn't seem to work, i've added the library and uploaded code exactly but with relevant time, ssid and pw but the serial monitor is just 0 0 0 and there's no light.

Do you know what the 0 0 0's are?

The code could be more simple but I did in this way to allow the OP to use it in others projects.

I'm have used this type of function to execute scheduled tasks with time retrieved from a TXT on SD card or EEPROM.

I'd figure you're not getting network. Mine gets in with network and all expeditiously, so I didn't include any waiting about for that to come round. Maybe your situation is different. This version of setup() allows for a network where things don't go so fast --

void setup()
{
  WiFi.begin(ssid, password);
  delay(1000);
  Serial.begin(115200);
  Serial.println("Acquiring WiFi");//

  while (WiFi.status() != WL_CONNECTED ) 
  {
    delay (500);
    Serial.print ( "." );
  }
  timeClient.begin();
}

I could just paste this code here:

Hey yeah it defo had been taking a while before. Weird thing is that it wont connect to the normal wifi now but if i tether my phone it does the 000 thing but the serial monitor is spewing out the reading in milliseconds

No. If it is okey that On is done "several" times during 30 minutes, and the same for turning Off.
As other helpers suggest, check the connection with the network. Adding a temporary

Serial.print(" Time read from NET. ");Serial.println(millis();

in loop could tell the condition of the connection.

//  https://github.com/arduino-libraries/NTPClient
//
//  NodeMCU  NodeMCU  NodeMCU  NodeMCU

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

const char *ssid     = "";
const char *password = "";

const long utcOffsetInSeconds = -25200;  // more or less vs. YOUR TIMEZONE

//char daysOfTheWeek[7][12] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};

//
int hh;
int mm;
int ss;
int comparisonsecs = 55;  // to closer sync actual NTP change

// Define NTP Client to get time
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org", utcOffsetInSeconds);

//SoftwareSerial playerSerial (D5,D6);

void setup()
{
  WiFi.begin(ssid, password);
  delay(1000);
  Serial.begin(115200);
  Serial.println("Acquiring WiFi");//

  while (WiFi.status() != WL_CONNECTED ) 
  {
    delay (500);
    Serial.print ( "." );
  }
  timeClient.begin();
}

void loop() 
{
  timeClient.update();
  hh = timeClient.getHours();
  mm = timeClient.getMinutes();
  ss = timeClient.getSeconds();
  Serial.print(hh);
  Serial.print("  ");
  Serial.print(mm);
  Serial.print("  ");
  Serial.println(ss);
  delay(500);

  if(hh == 18 && mm == 30 && ss == 00)  // 6:30 PM
  {
    // turn on the light
    // do your pinMode in SETUP()
    // do your digitalWrite here
    Serial.println("Turned ON");
  }

  if(hh == 21 && mm == 00 && ss == 00)  // 9:00 PM
  {
    // turn off the light
    Serial.println("Turned OFF");
  }

}
1 Like

The DS3231 RTC has alarm capability.

  1. Controller toggles the light, sees the time, sets an alarm and goes to sleep.
  2. RTC wakes the controller up. Go to 1.

A RTC is last century. It doesn't do daylight savings, so it's wrong half of the year.

Experimenting with something similar, but using a tzapu WiFiManager configuration portal, which has NTP code built-in. Some lines of code (I live in New Zealand). Not ready to share my full code yet.

  session.time.ntp_server = ("nz.pool.ntp.org"); // https://www.pool.ntp.org/zone/nz
  session.time.timezone_env_string = "NZST-12NZDT,M9.5.0,M4.1.0/3"; // https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv

Leo..

This is the sketch in No.31 (with different time, for brevity) --

Where is nullptr defined?

I assume it is a buffer address used by the Time.h library?

I see WiFi.begin and WiFi.status, WiFi.localIP and configTime with net adresses all in setup(). Does configTime put time data at addtrss nullptr?

Where or how in loop() is the data at nullptr changed? I might want to use that too!

Daylight savings varies. Some don't, some do what they chose, even state to state here there is no standard. I'd expect to have to correct for that because humans need correcting for.

If Dallas Semiconductor has a newer, better RTC I think that not needing wifi once initialized and kept powered (has long life battery) to tick away.

That D1 board must have a crystal, same as an RTC. The Uno has a resonator instead of a crystal, can drift like 3 and a half minutes a day where a crystal you measure tiny drift over a month. The D1 can do the job if it has the code and nothing blocks it which is why I present an RTC as an alternate path.

Every WiFi board has a crystal. That's the only way to get the WiFi channel stable.
Leo..

1 Like

That's fine until power is off across the one second that you allow for anything to happen.

Change it to a range. When you do, you may find using a "seconds since midnight" concept will make testing simpler.

Some other code posted on this thread opens the window for a full minute. Still a problem for a power outrage.

a7

"That's fine until power. . ."

So what?

It has a starting point with an On time and an Off time, pretty easy to understand.
And I demo'd that it works.
All in all, a lot more than anybody else has done.

Hi @anon85221860!

All in all, a lot more than anybody else has done.

I don't agree because my example works perfectly.

It has structure to allow OP to change the time dynamically without hard code the time to turn on or off.

Also the function ledControl is redundant with digitalWrite function but it will allow OP to apply some LED effect like this.

The problem in your code pointed by @alto777 should be resolved by OP because it's only an example.

Hi!

I can't give you a technical response because I'm not an expert but you can find details on google by searching for "nullptr c++".

Best regards.