Adafruit RTClib date comparison

I have a project that initially changes display mode based upon a pushbutton. When the pushbutton is pressed, the info displayed on a set uo LEDs also changes. What I want to do is to automatically change the display every 10 seconds (simulate the pressing of the pushbutton).
As a noob, I have been experimenting with the Date.Time.().unixtime() function and have not made much headway.
I want to compare the initial unixtime with the current unxtime and if 10 seconds or more (doesn't need to be exactly 10 seconds) as elapsed, then toggle current mode (simulate pressing the pushbutton) and set the initial unitize to the current time (for next comparison) and cycle through the main loop.

Any thoughts about how to do that?

hi @edorbea!

Doing something every ten seconds or so does not need an RTC, nor Unix time or anything sophisticated at all.

Look at the "blink without delay" sketch on offer in the IDE. Google

arduino blink without delay

and read a few of the many hits that come up.

Pressing a button every so often is exactly like blinking an LED.

HTH and welcome to the forum.

a7

1 Like

It appears that I was deficient in providing the 'big picture'. My project is a digital clock, the icon pressing of a button, changes the display from a 24 hr clock (mode 0) to display the current MMDD (mode 1 then displaying the current YYYY (mode 2), thus RTClib is already loaded and it seems to me that using that library would be easiest.

Original code for the project is below...

//RTC Stuff

#include "RTClib.h" // Include RTClib library
RTC_DS1307 rtc; // Create an instance of the DS1307

//DIGITISER Stuff

const int SER = 3;
const int CLK = 4;
const int LATCH = 5;
const int OE = 10;

const int sw1 = A0;
const int Pot = A1;
const int sw2 = A2;


int mode = 0; // counter for Mode select
int swState = 0; // State of Button 1
int lastswState = 0; // previous state of Button 1
int sw2State = 0; // State of Button 2
int lastsw2State = 0; // previous state of Button 2
int potRead = 0;
int potDimVal = 0;

int num = 0;
int thousands = 0;
int hundreds = 0;
int tens = 0;
int ones = 0;

const int digit[4] =
{
  B00001110,B00001101,B00001011,B00000111
};

int digit0 = digit[0];
int digit1 = digit[1];
int digit2 = digit[2];
int digit3 = digit[3];

const int number[10] =
{
  B10001000,B11101011,B01001100,B01001001,B00101011,B00011001,B00111000,B11001011,B00001000,B00001011
};


const int letter[27] =
{
  B11111111, B00001010,B00111000,B10011100,B01101000,B00011100,B00011110,B10011000,B00111010,B10111110,B11101000,B00011010,B10111100,B11011010,B10001010,B10001000,B00001110,B00001011,B10001110,B00011001,B00111100,B10101000,B10101001,B10101101,B00101010,B00101001,B01001101
};

const int xx = 0;
const int a = 1;
const int b = 2;
const int c = 3;
const int d = 4;
const int e = 5;
const int f = 6;
const int g = 7;
const int h = 8;
const int i = 9;
const int j = 10;
const int k = 11;
const int l = 12;
const int m = 13;
const int n = 14;
const int o = 15;
const int p = 16;
const int q = 17;
const int r = 18;
const int s = 19;
const int t = 20;
const int u = 21;
const int v = 22;
const int w = 23;
const int x = 24;
const int y = 25;
const int z = 26;

//char text[] = {xx,xx,xx,s,t,r,e,t,c,h,xx,y,o,u,r,xx,l,e,g,s,xx,xx,xx};
char text[] = {xx,xx,xx,g,e,t,xx,r,e,a,d,y,xx,f,o,r,xx,d,i,n,n,e,r,xx,xx,xx};

void setup() {

// Start Serial Comminication

Serial.begin(9600);

//RTC Stuff

rtc.begin();

//To set the time on the RTC to match your computer's clock, uncomment the next line and upload the code. To prevent it resetting to the same time every time you reset the device, add the "//" to the beginning of the line then uplaod the code again. The time will then be set and saved even after a reset (with a coin cell present). 

//rtc.adjust(DateTime(__DATE__,__TIME__));; // Set the RTC to Compile Date and Time

//DIGITISER Stuff

pinMode(SER, OUTPUT); // SER (data) pin as output
pinMode(CLK, OUTPUT); // CLK (clock) pin as output
pinMode(LATCH, OUTPUT); // LATCH pin as output
pinMode(OE, OUTPUT); // Output Enable

analogWrite(OE, 150); // Set brightness

pinMode(sw1, INPUT); // Switch 1
pinMode(sw2, INPUT); // Switch 2
pinMode(Pot, INPUT); // Potentiometer

}

void loop() {

// Button state / mode changer

// read the pushbutton input pin:
swState = digitalRead(sw1);
sw2State = digitalRead(sw2);

// compare the swState to its previous state
if (swState != lastswState) {
    // if the state has changed, increment the counter
    if (swState == HIGH)
    {
      // if the current state is HIGH then the button went from off to on:
      if (mode < 2)
      {
        mode++;
      }
      else
      {
        mode = 0;
      }
      //Serial.print("number of button pushes: ");
      //Serial.println(mode);
    }

    // Delay a little bit to avoid bouncing
    //delay(10);
  }

// save the current state as the last state, for next time through the loop
lastswState = swState;

//Alarm

DateTime now = rtc.now();      // get the current time

num = (now.hour() * 100 + now.minute());
Serial.println(num);

int alarmNum = 1845; 

if (num == alarmNum)
{
  
// Shift Out DIGITISER

// Message:        s  t  r  e t  c h   y  o  u  r    l  e g s
// letter lookup:  19 20 18 5 20 3 8 0 25 15 21 18 0 12 5 7 19

for (int cha = 0; cha <= sizeof(text) -1; cha++)
{

//Serial.println(letter[text[cha]]);

for (int nm = 0; nm <= 40; nm++)

{
 
int d1 = 2;

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,letter[text[cha]]);
shiftOut(SER,CLK,LSBFIRST,digit0);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,letter[text[cha+1]]);
shiftOut(SER,CLK,LSBFIRST,digit1);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,letter[text[cha+2]]);
shiftOut(SER,CLK,LSBFIRST,digit2);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,letter[text[cha+3]]);
shiftOut(SER,CLK,LSBFIRST,digit3);
digitalWrite(LATCH,HIGH);

delay(d1);

}

}

}


else 

{

if (mode == 0) // Time
  {
    num = (now.hour() * 100 + now.minute());
    digit0 = digit[0] | B10000000;

    //Serial.println(n);
  }

else if (mode == 1) // Day / Month
  {
    num = (now.day() * 100 + now.month());
    digit0 = digit[0] | B01000000;

    //Serial.println(n);
  }

else if (mode == 2) // Year
  {
    num = now.year();    
    digit0 = digit[0] | B00100000;

    //Serial.println(n);
  }

//Serial.println(num);
  
thousands = ((num/1000));      // get the thousands value
hundreds = ((num%1000)/100);   // get the hundreds value
tens = ((num%100)/10);         // get the tens value
ones = ((num%10)/1);           // get the ones value

// Shift Out DIGITISER

int potRead = analogRead(Pot);
int potDimVal = map(potRead,0,1020,255,0);
analogWrite(OE,potDimVal); // Set brightness

int d1 = 2;

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,number[thousands]);
shiftOut(SER,CLK,LSBFIRST,digit0);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,number[hundreds]);
shiftOut(SER,CLK,LSBFIRST,digit1);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,number[tens]);
shiftOut(SER,CLK,LSBFIRST,digit2);
digitalWrite(LATCH,HIGH);

delay(d1);

digitalWrite(LATCH, LOW);
shiftOut(SER,CLK,LSBFIRST,number[ones]);
shiftOut(SER,CLK,LSBFIRST,digit3);
digitalWrite(LATCH,HIGH);

delay(d1);

}

}

What I want to do is to replace the section that monitors the state of SW1 and replace it with a timer (approx 10 seconds).

Thanks for the initial input!

I see. That does not change the fact that you could add doing something every ten seconds or so without consulting or manipulating anything related to the real time of day. Or going very deep into how that code works, or how RTCs work or anything like that if it is code you wrote.

The BWOD pattern code supplant or live beside the current button monitoring, and use the same variables to communicate the buttin oress or "button press" to the rest of the coed, which would have no idea, nor need to have, where the press event was coming from.

A surgical strike, so to speak.

If the "or so" part is true, it could be argued that the easiest way to add your new feature would be to do without touching the RTC or anything else.

Of course with the clock you could get every ten seconds on the minute.

Either way, have fun!

a7

Why bother?

Why not just change the display mode based on the seconds of the current time?

If the seconds are 0 through 9, or 30 through 39, then display the time (hours and minutes).
If the seconds are 10 through 19, or 40 through 49, then display the month and day.
If the seconds are 20 through 29, or 50 through 59, then display the year.

So, change this
if (mode == 0) // Time
to this
if (((now.second() >= 0) && (now.second() <= 9)) || ((now.second() >= 30) && (now.second() <= 39))) // Time
and so forth for the other two display modes.
Or, to save yourself some typing, do
byte ss = now.second();
and then you can just type
if (((ss>=0) && (ss<=9)) || ((ss>=30) && (ss<=39))) // Time
and so forth.

But... as I understand the code in main loop, just 'doing' something to 10 seconds does not refresh the data being send to the LED display. In the mail look it appears to check for a keypress and if no keypress is detected the loop executes but if a keypress is detected the mode switches and the loop continues. I just think what I want to do as opposed to checking for a keypress is to
a) compare the 'current' time to the 'stored time'
b) if less than 10 seconds have passed the loop executes
c) if 10 seconds have passed, the mode change is triggered; the current time is stored and the loop executes.

My idea is for the code to fake a key press. Set whatever is set when a real key press happens.

The rest of the code will have no idea why it is reacting, that is to say it won't know the difference between someone pressing the button, or other code that manipulates the same variables.

I can't look closely at the sketch just now, but it seems like it should be "behaving" well enough for you to slot in the fake press on a timed basis.

Ill look L8R.

a7

Oh for goodness sake

if      (now.second() < 10) mode = 0;
else if (now.second() < 20) mode = 1;
else if (now.second() < 30) mode = 2;
else if (now.second() < 40) mode = 0;
else if (now.second() < 50) mode = 1;
else                        mode = 2; 
1 Like

I agree that @edorbea will be happier with a synchronized solution.

    mode = (now.second() / 10) % 3;

a7

    mode = (now.second() / 10) % 3;

Corrected above, THX.

a7

Damn, I was making it too difficult. Thank you all for (especially alto777) for your input.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.