Clock + SetupClock

Sorry for the frequent Forum Topics, but this is a different issue.

I have a Clock Code which runs on a lcd and I'm trying to make the clock adjustable with 2 buttons. One button toggles between units in the clock and the other adjusts it's value.

Heres my Clock code:

#include <LiquidCrystal.h>
#include <DateTimeStrings.h>
#include <DateTime.h>

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

void setup(){
  DateTime.sync(DateTime.makeTime(0, 15, 11, 21, 10, 2009));
  lcd.begin(16,2);
}

void  loop(){    
  if(DateTime.available()) {
    unsigned long prevtime = DateTime.now();
    while( prevtime == DateTime.now() )  // wait for the second to rollover
      ;
    DateTime.available(); //refresh the Date and time properties
    digitalClockDisplay( );   // update digital clock  
  }
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits,DEC);
}

void digitalClockDisplay(){
  lcd.home();
  // digital clock display of current time
  lcd.print(DateTime.Hour,DEC);  
  printDigits(DateTime.Minute);
  lcd.setCursor(0,1);
  lcd.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  lcd.print(" ");
  lcd.print(DateTimeStrings.monthStr(DateTime.Month));
  lcd.print(" ");
  lcd.print(DateTime.Day,DEC);
}

And here is my ATTEMPTED Clock with two buttons code:

#include <LiquidCrystal.h>
#include <DateTimeStrings.h>
#include <DateTime.h>

LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);

int button = 0; 
int val;                     
int state;            
int press = 0;       

int button2 = 1;  
int val2;                  
int state2;               
int press2 = 0; 

int ax = 0;
int bx = 0;
int cx = 0;
int dx = 0;
int ex = 0;

void setup(){
  pinMode(button, INPUT);  
  pinMode(button2,INPUT);
  Serial.begin(9600);         
  state = digitalRead(button);
  state2 = digitalRead(button2);
  DateTime.sync(DateTime.makeTime(0, 0, 0, 0, 0, 2009));
  lcd.begin(16,2);
}

void  loop(){        
  if(DateTime.available()) {
    unsigned long prevtime = DateTime.now();
    while( prevtime == DateTime.now() )  // wait for the second to rollover
      ;
    DateTime.available(); //refresh the Date and time properties
    digitalClockDisplay( );   // update digital clock 
  }
 
  DateTime.sync(DateTime.makeTime(ax, bx, cx, dx, ex, 2009));
  
  val = digitalRead(button);     
  val2 = digitalRead(button2);
  
  if (val != state) {        
    if (val == LOW) {            
      press++; 
    }
  }
  if (press >=6) {
    press = 0;
  }
  state = val;
    
  if (val2 != state2) {
    if (val2 == LOW)   {
      press2++;
    } 
  }
  state2 = val2;
  
  switch (press) {
    case 1:
      ax = press2;
      break;
    case 2:
      bx = press2;
      break;
    case 3:
      cx = press2;
      break;
    case 4:
      dx = press2;
      break;
    case 5:
      ex = press2;
      break;
  }
  if (ax >= 60) {
     ax = press2 % 60;
  }
  if (bx >= 60) {
     bx = press2 % 60;
  }   
  if (cx >= 24) {
     cx = press2 % 24;
  }
  if (dx >= 32) {
     dx = press2 % 31;
  }
  if (ex >= 13) {
     ex = press2 % 12;
  }
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  lcd.print(":");
  if(digits < 10)
    lcd.print('0');
  lcd.print(digits,DEC);
}

void digitalClockDisplay(){
  lcd.home();
  // digital clock display of current time
  lcd.print(DateTime.Hour,DEC);  
  printDigits(DateTime.Minute);
  printDigits(DateTime.Second);
  lcd.setCursor(0,1);
  lcd.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  lcd.print(" ");
  lcd.print(DateTimeStrings.monthStr(DateTime.Month));
  lcd.print(" ");
  lcd.print(DateTime.Day,DEC);
}

The second code does not work and I've tried positioning it in other ways, structuring it, linking it to buttons, using a third button to activate a 'void'. I have yet to figure it out.

If (anything is confusing) {
I will clarify;
}
else {
Thank you very much;
}

The second code does not work

I'll take your word for it that it doesn't work.

But, just in case I was a doubting type, can you expand upon this statement? What proof do you have that it doesn't work?

Does pressing a button let smoke out of some wires? Does the Arduino melt into a puddle. Does the LCD turn pink on orange?

Haha no NOTHING MELTS. don't jinx it...

Usually this is EXACTLY what i see on my lcd


11:15:00
Sat Nov 21


That is normal. The time is counting up. (FIRST sketch)


0:00:01
Wed Dec 31


That is not normal. The time is correct (because I programmed it that way) but it is suppose to be counting up. It is just freezing at that screen. (second sketch)

In your code, you call DateTime.makeTime each time through loop, passing it the values in ax, bx, cz, dx, and ex. Those values depend on button presses to change.

So, no button presses, no change in ax, bx, cx, dx, or ex, so no change in time.

Was that not what you were expecting?

I expected that when the value of button 1 was at zero (i did not assign anything to zero) to just continue on doing its normal clock.
It did not go on to it normal clocking.
Even if I pressed any of the two buttons smashing down on them, the screen froze like it always was.

there is no change in time whether i press anything or not.

The goal is to have the clock continue clocking like normal UNTIL button 1 is pressed, once button 1 is pressed it starts to adjust time based on button 1 and 2. When button 1 is pressed 6 times it returns to zero and continues clocking with the new adjusted time.

I tried (not in the above sketch) to put the time adjust in a different void and call upon that void only when the value of button 1 is greater than 1. was lost upon how to call the void and failed.
void __________( ); does not work for me to call

I think PaulS is referring to this line...

DateTime.sync(DateTime.makeTime(ax, bx, cx, dx, ex, 2009));

...being called every time through loop(). You only want to sync if a/b/c/d/ex have changed.

Also, I don't think you want to assign a/b/c/d/ex to the press2 value (in your switch statement). I think you want to increment a/b/c/d/ex when button2 is pressed.

I haven't stepped through carefully, so maybe not.

Thanks Mitch_CA, I'll try incrementing the ax - ex instead.

as for calling the makeTime im still lost on HOW i should call it only when i want it to. I know i got it runing in the loop and thats no good. so how do i activate it only when i want it to, THEN store the changes I've made to it? and have it continue clocking?

so... dormant, call, activate, set, store, deactive, clock

As was mentioned earlier, you need to call makeTime only when there has been a button press that necessitates a change.

But, makeTime is a convenience function, for setting all 6 parts of the date/time at once. The individual parts of the date are available to read or set. You can, for instance increment just the hour:

DateTime.Hour++;
DateTime.sync(DateTime.now());

The Hour (and other time elements like Minute, Second etc ) are properties that can be read but are not intended to be used to directly set the internal timekeeping used in the library.

You can adjust the time by getting and manipulating the time elements and then writing them back using MakeTime. But the following example shows an easier way. It uses a macro named adjust that I will probably add to the next version of the library as a public method.

#include <DateTime.h>
#include <DateTimeStrings.h>

//the following macro is used by the sketch to adjust the system time
#define  adjust(adjustment)   DateTime.sync(DateTime.now() + adjustment)

unsigned long  prevtime;

void setup(){
  Serial.begin(9600);
  DateTime.sync(1259020800); // start the clock
}

void  loop(){ 
  if(Serial.available() )  {
    char c = Serial.read();
    switch (c){        
      case 'h' : adjust(-SECS_PER_HOUR);  break; // Lower case decrements
      case 'H' : adjust(SECS_PER_HOUR);   break; // Upper case increments
      case 'm' : adjust(-SECS_PER_MIN);  break;  
      case 'M' : adjust(SECS_PER_MIN);   break;  
      case 's' : adjust(-1);  break;
      case 'S' : adjust(1);   break;
      
      case 'y' : adjust(-SECS_PER_YEAR);  break;
      case 'Y' : adjust(SECS_PER_YEAR);   break;
      case 'w' : adjust(-SECS_PER_WEEK);  break;  
      case 'W' : adjust(SECS_PER_WEEK);   break;
      case 'd' : adjust(-SECS_PER_DAY);  break;
      case 'D' : adjust(SECS_PER_DAY);   break;  
    } 
  }
  if( prevtime != DateTime.now() ){  // wait for the second to rollover      
     prevtime = DateTime.now();      // store the new time   
     DateTime.available();           //refresh the Date and Time properties
     digitalClockDisplay( );         // update digital clock     
  } 
}

void digitalClockDisplay(){
  // digital clock display of current date and time
  Serial.print(DateTime.Hour,DEC);
  printDigits(DateTime.Minute);
  printDigits(DateTime.Second);
  Serial.print(" ");
  Serial.print(DateTimeStrings.dayStr(DateTime.DayofWeek));
  Serial.print(" ");
  Serial.print(DateTimeStrings.monthStr(DateTime.Month));
  Serial.print(" ");
  Serial.print(DateTime.Day,DEC); 
  Serial.print(" ");
  Serial.println(DateTime.Year + 1900,DEC); 
}

void printDigits(byte digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits,DEC);
}

For now, add the adjust definition to the top of the sketch and replace the serial calls with button presses (don't forget to debounce the buttons)

Thanks a lot!

The adjust feature works very well.
Didn't know i could do that.

I still have a lot to learn. ::slight_smile:

Thank you PaulS, Mitch_CA, and mem!

Currently I'm adapting the code to the lcd and buttons.
It should work great! Everything is going smoothly!

Thank you!