Using NTP time to make arduino preform action on certain days at certain times

Hello, for my project I am making a School bell. I am attempting to make it ring according to the school period schedule which changes depending on the day.
The general idea is
if (day == 1 ||2||3||5) && (hour == 12) && (minutes == 30) && (0<seconds < 10) {
ringbell
}
and then ill copy this format for each time I need the bell to ring. Currently I have my arduino connected to wifi, connected to the NTP server, but now I am struggling on what the "day" "hour" "minutes" or "seconds" variable is. Please help me. This is the current code.

#include <Arduino.h>
#include <WiFi.h> //includes the libraries for wifi capability 
#include <time.h> // includes the libraries for NTP Time 
#include <sntp.h>

#define WIFI_NETWORK "Wifi"        // these lines of code allow the arduino to connect to the wifi network
#define WIFI_PASSWORD "Wifipassword"
#define WIFI_TIMEOUT_MICROS 2000     // times out connection after 20 secs if not connected 
const char* NTP_SERVER = "us.pool.ntp.org";     // server for NTP time
const char* TZ_INFO = "EST5EDT,M3.2.0/2:00:00,M11.1.0/2:00:00";  //time zone 


void connectToWifi(){                           //this entire void allows the arduino to print if it is connected 
  Serial.print("Connecting to WiFi");
  WiFi.mode(WIFI_STA);                                    //sets the mode as a standalone wifi user as opposed to a node
  WiFi.begin(WIFI_NETWORK, WIFI_PASSWORD) ;                // my password and network name

  unsigned long startAttemptTime = micros();                //defining variable for network connect timeout

  while(WiFi.status() !=WL_CONNECTED && micros() - startAttemptTime < WIFI_TIMEOUT_MICROS){     // 
    Serial.print(".");
    delay(100);
  }
  if(WiFi.status() != WL_CONNECTED){
    Serial.println("Failed");
  }else{
    Serial.print("Connected");                   // I could include here code to make the arduino sleep and stop attempting to connect, but I did not, I want it to conintously attempt 
  }
}

void printLocalTime()            //code for NTP Time 
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
}




void timeavailable(struct timeval *t)   // Callback function (get's called when time adjusts via NTP)
{
  Serial.println("Got time adjustment from NTP!");
  printLocalTime();
}

void bellringing() {
  struct tm; {
  if (int8_t tm::tm_wday == 1||2||3||5) {
  if (tm_hour == 8 && tm_)               {

  digitalWrite(14, HIGH);
    
}
}
}
}
void setup() {
  // put your setup code here, to run once:
Serial.begin(9600);           // sets baud rate
sntp_set_time_sync_notification_cb( timeavailable ); 
configTzTime(TZ_INFO, NTP_SERVER);      // Tells what the TZ and NTP server are 
connectToWifi();             // runs wifi void 
pinMode(14, OUTPUT);

}


void loop() {
  if(WiFi.status() !=WL_CONNECTED) {
    connectToWifi();
  }
delay(5000);                   //prints time every 5 secounds
printLocalTime();
}

Thank you!

Hello, I changed my code to what you suggested and I am now getting this error

C:\Users\\Documents\science_fair_project_v2\science_fair_project_v2.ino:52:13: error: expected ')'
   if (int8_t tm::tm_wday == 1||int8_t tm::tm_wday == 2||int8_t tm::tm_wday == 3||int8_t tm::tm_wday == 5) {
      ~      ^~~
             )

exit status 1

Compilation error: expected primary-expression

Ok so I attempted to make wday a variable with this code

int wday = struct tm tm_wday;

but I got the error "Compilation error: expected primary-expression before 'struct'"

Update: I used <TimeLib.h> which makes weekday a function, so my code now works! thank you!

I put struct tm tm_wday in because I thought it would work like it did for struct tm timeinfo in the print local time void. As far as I know {} are used after if to tell the arduino what to do if the "if" condition is met.

Sorry I forgot to reply to your comment above ^^^^

How would I make struct tm tm_wday into a variable I can use in my if statement? I want to be able to check what day it is according to my NTP clock

I think time gets its value from the NTP server, it might be unix time, and then its translated into the month,day, year, hour, etc.

Ok so I can just put my code in this same function?, would it be better practice to make a new void for my bell ringing?

I changed my code to this

void bellringing() {
    struct tm timeinfo;
    getLocalTime(&timeinfo);
    if (timeinfo.tm_wday == 6){

  digitalWrite(14, HIGH);

but it still does not work, it is Saturday and the pin is not high.

Have you tried printing the variable that you are testing to see what its value is ?

1 Like

Yes, it always comes back 0, then I did digitalWrite(14,high) in the setup and it came back 1.

Im sorry, did you mean ```
timeinfo.tm_wday

Im going to print this variable now.

Yes, that is the variable whose value you are testing and it would be helpful to know its value before testing it

For instance, are you sure that 6 == Saturday ?

Success thank you. I changed the code to this, and the pin 14 now reads high!

void printLocalTime()            //code for NTP Time 
{
  struct tm timeinfo;
  if(!getLocalTime(&timeinfo)){
    Serial.println("No time available (yet)");
    return;
  }
  Serial.println(&timeinfo, "%A, %B %d %Y %H:%M:%S");
  Serial.println(timeinfo.tm_wday);
  if(timeinfo.tm_wday==6){
      digitalWrite(14, HIGH);

  }
}

Would you mind linking me to some information about structures? I still dont really understand them very well.

It is probably just as easy to explain structs here, or at least the basics of them

For instance, this struct

struct personData  //NOTE : name was changed after originally posting this as it was originally wrong
{
    byte age;
    char gender;
    char name[20];
};

creates a new data type named personData. Note that is contains a mixture of data types relating to a person

You can use it just like other data types and declare a new variable of that type to hold data

personData person;  //a variable to hold data about a person

and put data in the variable like this

struct personData  //data to be held about a person
{
    byte age;
    char gender;
    char * name;
};

personData person;  //a variable to hold data about a person

void setup()
{
    Serial.begin(115200);
    person.age = 35;
    person.gender = 'M';
    person.name = "Fred";
}

void loop()
{
}

Then you can use the data like this

struct personData  //data to be held about a person
{
    byte age;
    char gender;
    char* name;
};

personData person;  //a variable to hold data about a person

void setup()
{
    Serial.begin(115200);
    person.age = 35;
    person.gender = 'M';
    person.name = "Fred";

    Serial.print(person.name);
    Serial.print(" ");
    Serial.print(person.age);
    Serial.print(" ");
    Serial.println(person.gender);
}

void loop()
{
}

Using a struct allows data of diverse types to be associated with one another and even if they are of the same type they are still associated

Even more useful is the ability to create a=n array of structs. Something like this

struct personData  //data to be held about a person
{
    byte age;
    char gender;
    char* name;
};

personData people[10];  //a variable to hold data about 10 people

void setup()
{
    Serial.begin(115200);
    people[0].age = 35;
    people[0].gender = 'M';
    people[0].name = "Fred";
   
    people[1].age = 22;
    people[1].gender = 'F';
    people[1].name = "Joan";

    for (int p = 0; p < 2; p++)
    {
        Serial.print(people[p].name);
        Serial.print(" ");
        Serial.print(people[p].age);
        Serial.print(" ");
        Serial.println(people[p].gender);
    }
}

void loop()
{
}

There is more to structs than this. For instance they can contain functions, but I think that you will get the idea of the basics if you experiment with the examples above

Thank you so much!

Hello I have my code

if(timeinfo.tm_hour==19){
  
  
   digitalWrite(14, HIGH);
   delay(3500);
   digitalWrite(14, LOW); 
   delay(6500); 
  
 }

However, it does not work when the hour is 19, my serial monitor says the hours is 19 when i use

Serial.println(timeinfo.tm_hour);