how to store RTC time in an arduino uno board, which library should i use...?

:confused:

i have a code as follows;;;

        #include <Arduino.h>
#include <Wire.h>
#include <RTClib.h>

const int light = 13;
int y1;
int y2;
int y3;
int x1;
int x2;
int x3;
int hour1 =5 ;
int min1 = 19;
int sec1 = 0;
int a = 6; 
int b = 7;
int c = 8;
int d = 9;
int e = 10;
int f = 11;
int g = 12;
int h = 13;
int i = 14;
int j = 15;
int k = 16;
int l = 17;
int m = 18;
int n = 19;
int o = 20;
int p = 21;
int q = 22;
int r = 23;
int s =  0;
int t = 1;
int u = 2;
int v = 3;
int w = 4;
int hour2 = 21 ;
int min2 = 32;
int hour3 = 17 ;
int min3 = 19;
int buttonState1 = 0;
int buttonState2 = 0;
int buttonState3 = 0;
RTC_DS1307 rtc;


void setup()
{

  Serial.begin(9600);
  Wire.begin();
  rtc.begin();

  pinMode(light, OUTPUT);
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);

}



void loop()
{
  DateTime now = rtc.now();
  buttonState1 = digitalRead(2);
  if ( buttonState1 ==  LOW)
  { if (now.hour() == hour1 && now.minute() == min1 && now.second() == sec1)
    {
      digitalWrite(light, HIGH);
    }
      if (now.hour() == a)
    {
      digitalWrite(light, HIGH);

      
    }
     if (now.hour() == b)
    {
      digitalWrite(light, HIGH);
    }
     if (now.hour() == c)
    {
      digitalWrite(light, HIGH);
    }
     if (now.hour() == d)
    {
      digitalWrite(light, HIGH);
    }
    if (now.hour() == e)
    {
      digitalWrite(light, HIGH);
    }
    if (now.hour() == f)
    {
      digitalWrite(light, HIGH);
    }
     if (now.hour() == g)
    {
      digitalWrite(light, HIGH);
    }if (now.hour() == h)
    {
      digitalWrite(light, HIGH);
    }
     if (now.hour() == i)
    {
      digitalWrite(light, HIGH);
    }
     if (now.hour() == j)
    {
      digitalWrite(light, HIGH);
    }
    if (now.hour() == k)
    {
      digitalWrite(light, HIGH);
    }
    
    if (now.hour() == hour3 && now.minute() == min3)
    {
      digitalWrite(light, LOW);
    }
  }
  
   buttonState2 = digitalRead(3);
  if(buttonState2 ==  LOW)
  {int x1 = now.hour();
  int x2 = now.minute();
  int x3 = now.second();
  if(now.hour() == x1 && now.minute()== x2 && now.second() == x3)
        { 
          digitalWrite(light, HIGH);
        }
        if (now.hour() == c)
    {
      digitalWrite(light, HIGH);
    }
    if (now.hour() == d)
    {
      digitalWrite(light, HIGH);
    }
    if (now.hour() == e)
    {
      digitalWrite(light, HIGH);
    }
    
   }
  else(buttonState2 ==  HIGH);
   
    if(now.hour() == hour3 && now.minute()== min2)
        { 
          digitalWrite(light, LOW);
        }
  buttonState3 = digitalRead(4);
  if (buttonState3 ==  LOW)
  { int y1 = now.hour();
    int y2 = now.minute();
    int y3 = now.second();
    if (now.hour() == y1 && now.minute() == y2)
    {
      digitalWrite(light, LOW);
    }
if  (now.hour() == hour1)
    {
      digitalWrite(light, HIGH);
    }
    
if  (now.hour() == a)
    {
      digitalWrite(light, HIGH);
    }
    if  (now.hour() == b)
    {
      digitalWrite(light, HIGH);
    }
    if  (now.hour() == c)
    {
      digitalWrite(light, HIGH);
    }
    if  (now.hour() == d)
    {
      digitalWrite(light, HIGH);
    }
    
  }

  }



[code]




i want to store the time when i made the pin 3 high;;;
and the loop should continue...
same function for pin 4

Why do you need to store the time that you get from the RTC? The time changes at least every second, so you need to read it at least that often.

i am pushing the button.. and making led on,,,,,i want to store buttn press time so that next time i won't have to press the button

i want to store buttn press time so that next time i won't have to press the button

I don't understand that. If you press the switch on September 13th, 2016 at 2:30AM, it will never be September 13th, 2016 at 2:30AM again, so knowing that you pressed the switch at September 13th, 2016 at 2:30AM is rather useless information.

However, there are functions (hour(), minute(), etc. that return VALUES that you can store in variables...

exactly... i dont want to store "September 13th 2016" i just want to store hour i. e. "2:30 AM'' for that i am using hour(), minute(), and second(),... controller reads the value and perform according to time but i want controller to store hour(), minute(), in some variable when the button is pressed. i can use them afterwards....

but i want controller to store hour(), minute(), in some variable when the button is pressed.

So, what is the problem?

#include <WhateverIsNeededToMakeHourAndMinuteFunctionsAvailable.h>

int switchPressedHour = 0;
int switchPressedMinute = 0;

int switchPin = 42;

void setup()
{
   pinMode(switchPin, INPUT_PULLUP);
}

void loop()
{
   if(digitalRead(switchPin) == LOW)
   {
      switchPressedHour = hour();
      switchPressedMinute = minute();
   }
}

i am unable to store time button press time in x and y variables,,, i want to know should i use eeprom library to store or is it possible with this code only...and how...?

#include <WhateverIsNeededToMakeHourAndMinuteFunctionsAvailable.h>

int switchPressedHour = 0;
int switchPressedMinute = 0;

int switchPin = 42;

void setup()
{
pinMode(switchPin, INPUT_PULLUP);
}

void loop()
{
if(digitalRead(switchPin) == LOW)
{
switchPressedHour = hour();
switchPressedMinute = minute();
}
}

in this one... if i am using hour(); and minute();
its telling me that hour and minute are not initialised....
but now.hour(); is also not working.....what to do

The cunningly named <Time.h> may be of interest, but I am still not clear what you are doing or why.

i am unable to store time button press time in x and y variables

Using what code? Why do the names x and y mean anything to you? To me, they look like variables to hold coordinates, not times.

i want to know should i use eeprom library to store

Do you need to save the times in the event that the Arduino looses power/is reset? If not, no.

is it possible with this code only...and how...?

With what code? For how long?

i have read button press time of pin 3 in x variable (x1 == now.hour(),,x2 == now.minute()..)and exactly at that instant i am making led on....and after some time at hour3, i am making it low.....
same function for pin 3..i am reading button press time (y1 == now.hour(),,y2 == now.minute()..) and making led off at that instant and after some time at hour 1 led will be on automatically...
plz let me know if u still dont understand the working of thee two pins....

<time.h> library is helpless. i tried that one earlier

pranav2016:
<time.h> library is helpless. i tried that one earlier

I have no idea what library that is.
The "Time" library is very useful i.e. <Time.h>
The key is to track time using epoch based time values not "human" or "wall clock" type of time that you are using.

If using epoch based time values you can get something like the time in seconds (which is what Time uses as well as pretty much any mainstream OS to track time internall)
Then to tell how much time has elapsed you do simple subtraction.

The key is stop thinking of human/"wall clock" type time and use epoch based time values.
And then convert from an epoch value to a human time only when necessary.

BTW, the Time library also has a companion TimeAlarms library that can help doing the type of interval or repeated alarms like you have mentioned.

--- bill

Actually the library, Time.h, can be quite helpful. But you don't need it if all you want is to get hours and minutes (and seconds, etc.) from an RTC that has been set already. Setting the RTC is another topic.

Last summer, I wrote a demonstration sketch that reads the hours, minutes and seconds from an RTC using I2C (and the Wire.h library) and sends it to the serial monitor. The demo assumes that you are using a UNO and an RTC breakout that has 4 connectors, SDA, SCL, GND and VIN. Perhaps you could modify this code to do what you want (which I am not quite clear on.) Just upload this sketch and open the serial monitor window:

/*
   Simplest clock with RTC, output to serial
   061316 Chris101 4106 bytes flash and 412 bytes RAM on a UNO

   Connect A4 on the UNO to SDA on the RTC
       "   A5 "   "   "  "  SCL "   "   "
       "  GND "   "   "  "  GND "   "   "
       "   5V "   "   "  "  VIN "   "   "

   Upload and open the serial monitor window.
   Assuming the time has been set on the RTC,
   the hours:minutes:seconds will scroll down
   the serial monitor window, one line a second.

 */

#include "Wire.h"
#define rtcAddress 0x68

unsigned long previousSecondMillis;
const long oneSecond = 1000UL;

void setup()
{
  Wire.begin();
  Serial.begin(9600);
  previousSecondMillis = millis();

}

void loop() {

  if (millis() - previousSecondMillis >= oneSecond) {
    previousSecondMillis += oneSecond; // do this once a second

    // get bcd data from the rtc
    Wire.beginTransmission(rtcAddress); // 0x68 is DS3231 device address
    Wire.write((byte)0); // start at register 0
    Wire.endTransmission();
    Wire.requestFrom(rtcAddress, 3); // request three bytes (seconds, minutes, hours)

    while (Wire.available())
    {
      byte seconds = Wire.read(); // get seconds
      byte minutes = Wire.read(); // get minutes
      byte hours = Wire.read(); // get hours

      // convert BCD to decimal: (number & 0b11110000) is the 'tens place' digit
      //                    and (number & 0b00001111) is the 'ones place' digit
      // of a two digit, decimal number (as are the hours, minutes and seconds)
      seconds = ((seconds & 0b11110000) >> 4) * 10 + (seconds & 0b00001111);
      minutes = ((minutes & 0b11110000) >> 4) * 10 + (minutes & 0b00001111);
      hours =   ((hours   & 0b00110000) >> 4) * 10 + (hours   & 0b00001111);

      // serial.print the bcd values
      Serial.print(hours);
      Serial.print(':');
      Serial.print(minutes);
      Serial.print(':');
      Serial.println(seconds);
    }
  }
}

@pranav2016, can you tell us, without reference to the code, what your project is supposed to do? Turn on a mechanical system, wake the baby, or check a life support system to see if it's still working? I suspect that you do not really need all those variables and comparisons. What's happening is known as an XY problem. Literally in this case!

ChrisTenone:
What's happening is known as an XY problem. Literally in this case!

:slight_smile:

But he did give a hint in post #10 that this involved elapsed time, hence my comments about favoring epoch based time values as using those make it trivial to calculate time durations.
Wheras using hours/mins for that can get messy depending on the duration and the time when the events occur.

Heck you could even use millis() if all you need is a semi accurate time duration.
The Time and TimeLibraries can work without an RTC as well.... :wink:

-- bill

my project is having three functions
1st function.... turn on the light automatically at 6 pm and turn off at 6 am daily.

2nd function.... turn on the the light when button is pressed and off automatically at 12 pm. and once button is pressed we should not have to press it again....light should be on at the same time when button is pressed earlier and off at 12 automatically.

3rd function...same function as 2nd but it is for making the light off;;;;

i am using pushbutton to switch between these functions

Hi Bill,

If our OP were making a general purpose timer, I would agree that using 'epoch time' would be simpler due to having all the same units, say seconds or milliseconds, and thus all calculations would be continuous. From the last post however, it looks like he's building a programmable on/off switch. If this was my project, I would probably use clock time though. When you push the button, set a variable with the hms. I'd compare that variable to the clock time once a second and set the light switch accordingly.


Hi Pranav,

Now it makes sense to me. I outlined my idea above. The example I posted earlier is how I interact with a modern RTC chip, such as the DS3231, or the older DS1307 using I2C, without a Time library. You can also count millis (or seconds) without a library. The function millis() is made for this - it's the milliseconds since you last started your Arduino. Theoretically* there are 1000 milliseconds in a second, 3,600,000 in an hour, and 86,400,000 per day.

I said theoretical, because the milliseconds that are counted by an Arduino are not exactly a millisecond long. They use a resonator that is within 5% of the real time, but it changes with temperature, and age. This is the big advantage of an RTC chip. It is accurate to much less that a percent. And it provides both a precise one second pulse (useful for accurate epoch timing), as well as stream the clock time over I2C.

In addition to your Arduino circuit (with or without an RTC), with interface components like the button, a mode switch, and perhaps a time and status display, you will also need the power switching circuitry. Probably using relays.

Start by drawing your circuit in block-schematic form. This is so you (and others) can tell exactly what is hooked to what. And write the first iteration of your sketch. Come back, post your schematic and code (use code tags!!), and folks will jump right into it.

This project sounds like it could be even solved with some of the X10 modules and its companion s/w.

For any time based s/w I still prefer to use unix epoch based time. With something like the Time library, you get the flexibility of using either form of time and can convert back and forth if/when necessary.
This allow tracking time efficiently as an epoch which also allows easy delta calculations and then convert to and/or use human time only when necessary - which might be in the user interface used to display and configure things.

The Time and TimeAlarms library seem like a good fit for this project based on the descriptions i've seen so far.
TimeAlarms can be used to create the daily periodic events/alarms and you can create/destroy timers as necessary to handle the time based events needed after button presses.

Seems pretty simple if Time & TimeAlarms is used.
Just set up a sync provider to allow the Time library to periodically read the time from the RTC to keep the time accurate.
The main code doesn't have to do any polling or comparison of the time as
the TimeAlarms library will call the designated functions for any/all configured alarms or timers at the appropriate time.

If it were me, I'd use a DS3231 and combine these libraries:

This should provide all the needed time and button reading capabilities.
I've used these libraries on several clock projects and it allows for a very quick development cycle as all the "hard" stuff is already done and debugged.

Why create all this (or some subset of it) from scratch when you could use existing libraries and get on with the project?

If existing libraries are not used, code to do all the time comparisons and track the back ground events for the button pushes has to be written.
While it isn't that difficult, if things change or more functionality is added, it can start to get messy depending on the initial architecture used.
i.e. you can get away with lots of stuff when there is only a single event, single time, single button etc, but if things change or expand it can get messy to update the s/w, depending on how it was written.

I recommend using a DS3231 over the older DS1307 for several reasons

  • they are now the same price (less than $1USD shipped to your door with a battery)
  • DS32321 is more accurate
  • DS1307 only runs a 100kHz so you can't speed the bus up to 400Khz
    (pretty much all current I2C devices support 400Khz - faster can be important in some environments as it frees up the processor to do other things)

Be prepared to do some slight h/w mods to most of the RTC boards you buy on Ebay and/or directly from other suppliers as most of these modules were designed for a re-chargable battery and the charge circuit is total CRAP. It should be removed. It is typically one trace cut to to it. Also, many of the modules come with a non chargeable battery, which means that after some period of time, the battery will leak and fail unless the charge circuit is disabled.
I'd recommend buying a DS3231 that comes with a non chargeable battery, then modding the module to disable the charge circuit. (I've done this on all the RTC modules I've used)

But this is just my views.....
Others will likely have alternative ways of handling this.

--- bill

Another advantage the 3231` has over the 1307 is the crystal is inside the chip, so there is one less (delicate) component to worry about.