Clock Adjustment

Hi All,

I am making a Clock using a Maxx7219, 2x4 Seven Segment displays, and a DS3231 Clock Module along with three buttons to change the clock time.

I have been playing around with the coding (with help of some of the Gurus on here - Its much appreciated) and have now got the clock working and displaying when its set from the Computer. As it is going to be a retirement presents I dont want to collect the clock every 6 months when the Clocks change and re-code it.

Ive included three push buttons in the circuit connected to Pins 2, 3 & 4 so the theory being you need to hold the "SET" button and then press the "HOUR" or "MIN" button and the clock will increment by 1 hour or min. Ive added a delay of 0.25 seconds into the circuit to stop the increment spiraling out of control.

So far I when the press button 1 & 2 for example it shows on the serial monitor that it reads the input to change the hour but doesn't increment the Hour.

Im pretty sure it is the way I am trying to increase the time, but im strugging to find out what I need to do adjust it.

My code looks like -

#include <ezButton.h>
#include <LedControl.h>
#include <config.h>
#include <ds3231.h>
#include <Wire.h>

 //setup for button press
ezButton button1(2);           //button1 attached to pin 2 - Change time
ezButton button2(3);           //button2 attached to pin 3 - Hour
ezButton button3(4);           //button2 attached to pin 4 - Min

 //setup for Max7219 & 7 Segment
struct ts t; 
LedControl lc=LedControl(12,11,10,1); 

void setup() {
  
  Serial.begin(9600);
  Wire.begin();

     //initial clock setup
  //t.hour=13; 
  //t.min=28;
  //t.sec=55;
  //t.mday=9;
  //t.mon=7;
  //t.year=2020;
   
  //DS3231_set(t);

    // Wakeup and settings for the 7 segment display:
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0); 

    //Button debounce
  button1.setDebounceTime(50);   
  button2.setDebounceTime(50);   //debounce set to 50ms
  button3.setDebounceTime(50);  
}

void printtime(){
  DS3231_get(&t);
  Serial.print("Date : ");
  Serial.print(t.mday);
  Serial.print("/");
  Serial.print(t.mon);
  Serial.print("/");
  Serial.print(t.year);
  Serial.print("\t Time : ");
  Serial.print(t.hour);
  Serial.print(":");
  Serial.print(t.min);
  Serial.print(".");
  Serial.println(t.sec);
 
  delay(1000);  
}

void displaytime(){
    lc.setDigit(0,7,t.hour / 10,false);
    lc.setDigit(0,6,t.hour % 10,false);
    lc.setDigit(0,4,t.min / 10,false);
    lc.setDigit(0,3,t.min % 10,false);
    lc.setDigit(0,1,t.sec / 10,false);
    lc.setDigit(0,0,t.sec % 10,false);
}
void loop() {
   // put your main code here, to run repeatedly: 
  printtime();                 //Prints time to serial monitor
  displaytime();               //Displays time on 7 seg display
  
  button1.loop();
  button2.loop();
  button3.loop();

  int btn1State = button1.getState();
  int btn2State = button2.getState();
  int btn3State = button3.getState();

  if(button1.isPressed() && button2.isPressed()){
    Serial.println("Change Time Hour");
    DS3231_set(t);
    t.hour ++;
    delay(250);
  }

  if(button1.isPressed() && button3.isPressed()){
    Serial.println("Change Time Min");
    DS3231_set(t);
    t.min ++;
    delay(250);
  }
 
}

Any help or pointers in the right direction is much appreciated.

Thanks
Tris

At a guess...
Increment the hour and minute values before calling DS3231_set(t)?

Edit:
Also you'll want to check for out of range (hour >= 24, minute >= 60) and do something about it. usually cycle back around to zero.

The set button is a "maintained" input while the hour and minute buttons are "momentary" inputs. It is necessary to properly debounce hour and minute, but a simple digitalRead() should be all that is necessary for the set button, as it will likely have been held down long before hours or minutes is pressed. The two inputs should not be taken together in one if (although you may want to take hours and minutes together to insure they are not both pressed simulaneously). You can do it either way:

if(digitalRead(SetPin) == LOW) {
  if(hours.isPressed() == true && minutes.isPressed() == false) {
    //set hours
  }
  else if(minutes.isPressed() == true && hours.isPressed() == false) {
    //set minutes
  }
}
if(hours.isPressed() == true && minutes.isPressed() == false) {
  if(digitalRead(SetPin) == LOW) {
    // set hours
  }
}
else if(minutes.isPressed() == true && hours.isPressed() == false) {
  if(digitalRead(SetPin) == LOW) {
    // set minutes
  }
}

pcbbc:
At a guess...
Increment the hour and minute values before calling DS3231_set(t)?

Edit:
Also you'll want to check for out of range (hour >= 24, minute >= 60) and do something about it. usually cycle back around to zero.

Pcbbc - Thats the one! Ive put the increment before and it works, although I reckon one of the buttons I have got is temperamental so its a bit clunkly.

The range of the clock is the next thing on my list to do.

Perehama:
The set button is a "maintained" input while the hour and minute buttons are "momentary" inputs. It is necessary to properly debounce hour and minute, but a simple digitalRead() should be all that is necessary for the set button, as it will likely have been held down long before hours or minutes is pressed. The two inputs should not be taken together in one if (although you may want to take hours and minutes together to insure they are not both pressed simulaneously). You can do it either way:

Perehama - I hadnt considered the scenario of both the min and hour switch being pressed at the same time, so thanks for the advice.

Once I get the range of the clock working I will try to adapt the coding to ensure that someone pressing all the buttons doesnt cause the coding to get its knickers in a twist.

Thanks for your input :slight_smile: