Arduino Time Library

Hello there!

I'm about to make a project where I want my Arduino to do things at a certain time. Things like power a LED or power a water valve via a transistor. I have searched for information about how to do this but with no result. I've tried to get the Arduino Time Library but I can't find the actual library file for it. One thing I've figured out is that I don't any external hardware for my arduino if I use the Arduino time library.

Is there anyone that have a link or something to a good time library where I can modify my code to meet my requirements?

Short version: I would like a time library where I can programme when the arduino will power things and not, without any external hardware.

Thanks alot, greetings from Huezzer!

In the Arduino IDE, follow the menu to the Library Manager : Sketch / Include Library / Manage Libraries.
Search for "time". There is a "Time" library by Michael Margolis.
I don't know if it is the newest version. This is the newest version: Time Library, Timekeeping and Time/Date Manipulation on Teensy
An extra library is "TimeAlarms". Also in the Library Manager and also here : TimeAlarms Library, Run Functions At Specific Times

Do you want to turn on a valve at 3 o'clock for 5 minutes, or once a day for 5 minutes regardless the actual time ?

When you have to know the time, a RTC is needed. That is a clock with battery. Or an internet connection or a DCF77 receiver, or something like that.

If you want to power things at intervals of hours or days or weeks, then millis() can be used.

I use millis() to update data to a website every few minutes, but also to check something every day. It starts when I turn on the Arduino.

The time library is here. Good idea to use it. It should be featured much more prominently in the official library list, in my opinion.

Hey! Thank you for your participate!

Koepel:
Do you want to turn on a valve at 3 o'clock for 5 minutes, or once a day for 5 minutes regardless the actual time ?

When you have to know the time, a RTC is needed. That is a clock with battery. Or an internet connection or a DCF77 receiver, or something like that.

If you want to power things at intervals of hours or days or weeks, then millis() can be used.

I use millis() to update data to a website every few minutes, but also to check something every day. It starts when I turn on the Arduino.

Yes, my idea is to turn on the valve, one time in the morning let's say 8o'clock and in the evening 8o'clock, each time for about 5 minutes.

Do you mean I need a RTC or something similar if I want the clock to a LCD or do I need it anyhow?

That you say, "morning and evening" suggest an RTC is better for you. Use a DS3231, it's more accurate and costs about the same. Don't just replace the Time library with some random RTC code, it's worth having it with the RTC.

A RTC is a clock chip running with a battery. If the Arduino is turned off, the RTC still keeps ticking away the time. As soon as the Arduino is turned on, it can read the actual time from the RTC.

The time can be displayed on the LCD, but that is an extra. If the Arduino has to know what time it is, a RTC is needed.

Or do you want to enter the time with buttons every time the Arduino is turned on ?

I suppose your Arduino has no wifi or internet connection ?

I agree with aarg. Using a DS3231 and the Time library is a good set.
The "Time" library in the Library Manager, at pjrc.com and the link to Github mentioned by aarg are three different things, but they all should be the same. Paul Stofregen (pjrc.com) is the maintainer of that libary and he has the library itself at Github.

Can you be more specific ? "morning" and "evening" is too vague. When using millis, something can be done every 12 hours. With some luck that will be in the morning and evening.

There is another option. I have read somewhere that a LDR is used to measure daylight and syncs with that. After a few days it knows roughly what time it is. I can't find it, it should be on this forum somewhere.

Thanks!

The thing is I want the Arduino in some sort of sleepmode to save power if possible during its downtime. I want it to wake up 8 o'clock every morning and 8 o'clock every evening to do its job.

In the job process I would have a humidity and temperature sensor, it will power a water valve for about 5 minutes each time. So from 8:00am to 8:05am and 8:00pm to 8:05pm the system will be active.

The Arduino won't have any internet connection.

Then you need an RTC.
The sleep mode (for example for an Arduino Uno) is not very useful, because other components on the board still require current.
If the Arduino is battery operated, then there are other Arduino boards that require less current.

Koepel:
… There is another option. I have read somewhere that a LDR is used to measure daylight and syncs with that. After a few days it knows roughly what time it is. I can’t find it, it should be on this forum somewhere.

That is such a cool concept! I really want to see it in action. Here’s the thread from 2009.

This is that website: Arduino - KAKU Clock
But I was thinking about a filter (a filter over a few hours) and a software PLL using millis().

Just a thought, instead of using time library, can't I just add some conditions and delay functions for about 12h in code? That means it will "wait"(delay) for 12h before starting another loop?

Or does this consume more power in relative to the time library? Since you said that the Arduino UNO sleep mode wasn't useful enough worth using :slight_smile:

Huezzer:
Just a thought, instead of using time library, can't I just add some conditions and delay functions for about 12h in code? That means it will "wait"(delay) for 12h before starting another loop?

Or does this consump more power instead of time library? Since you said that the Arduino UNO sleep mode wasn't useful enough worth using :slight_smile:

As mentioned use an RTC.
To do this right, recommend you to use DS3231 PCB, lots on eBay.

I've a DS3231 at home, but do if I use one of these and RTC will the Arduino loop all day until the clock is 8 o'clock? And when it's 8 o'clock then run the rest of the code?

You would read the RTC every second, minute or what ever.
When the RTC is at the time you want to do something, you do it.

Hey! Okey I got everything lined up but I still got one problem with the Arduino time thing. I got the 2 alarms from the RTC attached to the code but when the alarm triggers, I don’t know how to power the water valve for 5 minutes and then go back to sleep. Maybe my sleep mode isn’t the best but that doesn’t really matter here, any advices on the 5 minutes problem and maybe on sleep modes? I would like to have one since the system will only be on for about 10-15 min totally a day.

I have some suggestions and thoughts about doing something with a loop but the the power will go like on and off, on and off all the time during the 5 min?

Maybe something like, but how to code it?:

///////////////////////////////////////////
set Pin 13 to high (for example)

while (the time read NOT equls to readRTCtime + 5min)
{
do nothing, just to keep the arduino in work until we set the pin to low next.
}

set Pin 13 to LOW

/////////////////////////////////////////

The code I got this far is:

#include <DS3232RTC.h>
#include <Streaming.h>       
#include <Time.h>             
#include <Wire.h>            
#include <LowPower.h>

#define SQW_PIN 2
#define DS3231_I2C_ADDRESS 0x68

volatile boolean alarmIsrWasCalled = false;
int led_pin = 13;
int rtc_power_pin = 9;


void setup(void)
{
  pinMode(led_pin, OUTPUT);
  digitalWrite(led_pin, LOW);
  pinMode(rtc_power_pin, OUTPUT);
  digitalWrite(rtc_power_pin, HIGH);

  Wire.begin();
  Serial.begin(115200);

  setSyncProvider(RTC.get);
  Serial << "RTC Sync";
  if (timeStatus() != timeSet)
  {
    Serial << " FAIL!";
  }
  Serial << endl;


  RTC.squareWave(SQWAVE_NONE);
  pinMode(SQW_PIN, INPUT_PULLUP);
  attachInterrupt(INT0, alarmIsr, FALLING);


  //Set an alarm at every 20th second of every minute.
  RTC.setAlarm(ALM1_MATCH_HOURS, 0, 49, 6, 1);
  RTC.alarm(ALARM_1);
  RTC.alarmInterrupt(ALARM_1, true);

  //Set an alarm every minute.
  RTC.setAlarm(ALM2_MATCH_HOURS, 0, 54, 6, 1);
  RTC.alarm(ALARM_2);
  RTC.alarmInterrupt(ALARM_2, true);

  displayTime(); // display the real-time clock data on the Serial Monitor,
  delay(1000); // every second
}


void alarmIsr()
{
  alarmIsrWasCalled = true;
}

void loop(void)
{


  if (alarmIsrWasCalled) {
    if (RTC.alarm(ALARM_1)) {
     displayTime(); THIS ONE SHOULD NOT BE HERE; JUST FOR TEST!

      digitalWrite(led_pin, HIGH);
      delay(5000);
      digitalWrite(led_pin, LOW);
      delay(3000);
      digitalWrite(led_pin, HIGH);
      delay(3000);
      digitalWrite(led_pin, LOW);
      delay(3000);

    }
    if (RTC.alarm(ALARM_2)) {
      //need to write some logic
      displayTime();// THIS ONE SHOULD NOT BE HERE; JUST FOR TEST!
      while () // MAYBE HERE?

      digitalWrite(led_pin, HIGH);
      delay(5000);
      digitalWrite(led_pin, LOW);
      delay(3000);
      digitalWrite(led_pin, HIGH);
      delay(3000);
      digitalWrite(led_pin, LOW);
      delay(3000);
    }

    alarmIsrWasCalled = false;
    //digitalWrite(rtc_power_pin, LOW); //if this line is commented it works as expected.
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

  }
}

///////////////////////////////////////////////////////////
// Convert normal decimal numbers to binary coded decimal
byte decToBcd(byte val)
{
  return ( (val / 10 * 16) + (val % 10) );
}
// Convert binary coded decimal to normal decimal numbers
byte bcdToDec(byte val)
{
  return ( (val / 16 * 10) + (val % 16) );
}

void readDS3231time(byte *second,
                    byte *minute,
                    byte *hour,
                    byte *dayOfWeek,
                    byte *dayOfMonth,
                    byte *month,
                    byte *year)
{
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
  Wire.write(0); // set DS3231 register pointer to 00h
  Wire.endTransmission();
  Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
  // request seven bytes of data from DS3231 starting from register 00h
  *second = bcdToDec(Wire.read() & 0x7f);
  *minute = bcdToDec(Wire.read());
  *hour = bcdToDec(Wire.read() & 0x3f);
  *dayOfWeek = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month = bcdToDec(Wire.read());
  *year = bcdToDec(Wire.read());
}
void displayTime()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  // retrieve data from DS3231
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month,
                 &year);
  // send it to the serial monitor
  Serial.print(hour, DEC);
  // convert the byte variable to a decimal number when displayed
  Serial.print(":");
  if (minute < 10)
  {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");
  if (second < 10)
  {
    Serial.print("0");
  }
  Serial.print(second, DEC);
  Serial.print(" ");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print(" Day of week: ");
  switch (dayOfWeek) {
    case 1:
      Serial.println("Sunday");
      break;
    case 2:
      Serial.println("Monday");
      break;
    case 3:
      Serial.println("Tuesday");
      break;
    case 4:
      Serial.println("Wednesday");
      break;
    case 5:
      Serial.println("Thursday");
      break;
    case 6:
      Serial.println("Friday");
      break;
    case 7:
      Serial.println("Saturday");
      break;
  }
}
Time_t 5minAlarmTime = now();
bool alarmActive = false;

void loop()
{
/...
if (now() > 5minAlarmTime && alarmActive)
  {
    operate relay
    alarmActive = false;
  }
/...
} //end loop

void set5minAlarm
{
  5minAlarmTime = now() + 5*SECONDS_PER_MINUTE;
  alarmActive = true;
}

Hey, thanks for your reply!

Got an error I can't figure out "Time_t" was not declared in this scope, where is the right place to declare it and how do I do since this isn't working? :frowning:

Thanks!

Huezzer:
Hey, thanks for your reply!

Got an error I can't figure out "Time_t" was not declared in this scope, where is the right place to declare it and how do I do since this isn't working? :frowning:

Thanks!

Sorry, it's "time_t", which is a type defined for you in the library. It's a 32 bit type, for holding Unix seconds. But what I gave you was just the bare outline of what you need to run. It will probably need some additional code to make it work. The use of the library and its functions and predefined constants, is best understood by looking at the library examples.

A better alarm function should allow you to pass the time interval, so you don't need to have a different one for each interval. I was just trying to kick start things.

Okey! thank you!

When you say look in the library examples, is it the Arduino Time Library you mean?

Do you know any good guide for alarm functions? I've searched but without any result.

Do you know any good guide for alarm functions?

Here's one: TimeMark