manual adjust digital clock -> TM1637

Hi !
I know this topic is well disputed, but for me it’s an older issue.
This is the program, with a few additions from me.

#include "TM1637.h"
//{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
//0~9,A,b,C,d,E,F,"-"," ",degree,r,h
#define CLK 4//Pins for TM1637       
#define DIO 5
TM1637 tm1637(CLK,DIO);

// Date and time functions using a DS3231 RTC connected via I2C and Wire lib
#include <Wire.h>
#include "RTClib.h"
RTC_DS3231 rtc;
//************Button*****************//
int P1=6; // Button SET MENU'
int P2=7; // Button +
int P3=8; // Button -
int menu = 0;
int hh, mm; 
int state = 0;
int old = 0;
int pressbutton = 0;

void setup()
{
  tm1637.init();
  tm1637.set(5); 
  //BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7;

  pinMode(P1,INPUT);
  pinMode(P2,INPUT);
  pinMode(P3,INPUT);
  menu = 0;
  rtc.begin();
  // Check if the RTC lost power and if so, set the time:
  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // The following line sets the RTC to the date & time this sketch was compiled:
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    //rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
    }
  // manual adjust
  // January 21, 2014 at 3am you would call:
  // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  // automatic adjust
  //rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  Serial.begin(9600);
}//end "setup()"
 
void loop(){
DateTime now = rtc.now();
hh = now.hour(), DEC;
mm = now.minute(), DEC;

// check if you press the p1SET button and increase the menu index

  if(digitalRead(P1))
  {
   menu=menu+1;
  }
// in which subroutine should we go?
  if (menu==0)
    {
      Serial.println("P1 Default");
     DisplayTime(); // void DisplayDateTime

    }
  if (menu==1) // if 1
    {
      Serial.println("P1 pressed 1");
    SetHour();
    }
  if (menu==2) // if 2
    {
      Serial.println("P1 pressed 2");
      SetMinute();
    }
  if (menu==3) // if 3
    {
      Serial.println("P1 pressed 3");
      SaveTime();
      delay(500);
      menu = 0;
    }
  delay(100);  
}// end loop()

void DisplayTime(){
  tm1637.point(POINT_ON);
if ((hh/10) == 0) tm1637.display(0,17);
else
    tm1637.display(0,hh/10);     // hour
    tm1637.display(1,hh%10);
    tm1637.display(2,mm/10);    // minutes
    tm1637.display(3,mm%10);    // 
delay(500);
    tm1637.point(POINT_OFF);
if ((hh/10) == 0) tm1637.display(0,17);
else
    tm1637.display(0,hh/10);     // hour
    tm1637.display(1,hh%10);
    tm1637.display(2,mm/10);    // minutes
    tm1637.display(3,mm%10);    // 
delay(500);
  }//DisplayTime
  
void SetHour(){
  DateTime now = rtc.now();
    if(digitalRead(P2)==HIGH)
  {
    if(hh==23)
    {
      hh=0;
    }
    else
    {
      hh=hh+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if(hh==0)
    {
      hh=23;
    }
    else
    {
      hh=hh-1;
    }
  }
    tm1637.display(0,hh/10);     // hour
    tm1637.display(1,hh%10);
    tm1637.display(2,0);
    tm1637.display(3,0);
  delay(200);
  }//SetHour  
void SetMinute(){
  // Setting the minutes
  if(digitalRead(P2)==HIGH)
  {
    if (mm==59)
    {
      mm=0;
    }
    else
    {
      mm=mm+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (mm==0)
    {
      mm=59;
    }
    else
    {
      mm=mm-1;
    }
  }
    tm1637.display(0,0);     // hour
    tm1637.display(1,0);
    tm1637.display(2,mm/10);
    tm1637.display(3,mm%10);
    delay(200);
  }//SetMinute
  
void SaveTime(){
  // Variable saving
  rtc.adjust(DateTime(F(__DATE__),hh,mm,0));
  delay(200);
  }//SaveTime

I found a time adjustment method with if functions (I think I will replace them with switch cases) on a DS3231 & LCD project, and it works. It’s pretty simple, but on TM6137 it doesn’t work, I can switch from if 1 to if 2 or 3 (see the serial monitor message) but the commands for changing the hours or minutes do not have a correct effect. In short, I want to adjust the hours or minutes, I should see how the values increase / decrease on the display, press continuously and for nothing, but after calling the SaveTime function, time changes but chaotic. So the problem would be the chaotic change of time. Any suggestions ?

How are your buttons wired up? Do you have pull-down resistors attached? Your code is expecting that. If not, you can wire one side of the button to ground and the other to your input pin. Declare that pin as INPUT_PULLUP and you will get the reverse logic (LOW = pressed, HIGH = not pressed).

You will also need to debounce your buttons. If you are constantly checking the state of the button, the processor will actually see several presses since the physical act of making contact is noisy. You could also check out the StateChangeDetection example in the IDE (File->examples->02.Digital->StateChangeDetection) to see how to detect when the button transistors, not the current state.

Also, your SaveTime() function can't mix a string Date with hour variables, it is one of the other. Create a DateTime variable to get the compile Date, then create the new time by using that plus hours and minutes. You can also simply just specify the year, month, day as some valid number if you don't care.

void SaveTime() {
  // Variable saving
  DateTime myTime(DateTime(F(__DATE__), F(__TIME__)));
  DateTime newTime( myTime.year(), myTime.month(), myTime.day(), hh, mm, 0);
  rtc.adjust(newTime);
  delay(200);
}//SaveTime

blh64:
How are your buttons wired up? Do you have pull-down resistors attached? Your code is expecting that. If not, you can wire one side of the button to ground and the other to your input pin. Declare that pin as INPUT_PULLUP and you will get the reverse logic (LOW = pressed, HIGH = not pressed).

You will also need to debounce your buttons. If you are constantly checking the state of the button, the processor will actually see several presses since the physical act of making contact is noisy. You could also check out the StateChangeDetection example in the IDE (File->examples->02.Digital->StateChangeDetection) to see how to detect when the button transistors, not the current state.

Also, your SaveTime() function can’t mix a string Date with hour variables, it is one of the other. Create a DateTime variable to get the compile Date, then create the new time by using that plus hours and minutes. You can also simply just specify the year, month, day as some valid number if you don’t care.

void SaveTime() {

// Variable saving
  DateTime myTime(DateTime(F(DATE), F(TIME)));
  DateTime newTime( myTime.year(), myTime.month(), myTime.day(), hh, mm, 0);
  rtc.adjust(newTime);
  delay(200);
}//SaveTime

Thank you for your reply ! It’s been a while since I accessed this post because I was working on my license. But now I’m back to this project. I changed something in the program, but no result.
#include <Wire.h>
#include “RTClib.h”
#include <TM1637Display.h>

#define CLK 2
#define DIO 3

RTC_DS3231 rtc;
TM1637Display display = TM1637Display(CLK, DIO);

int P1=6; // Button SET MENU’
int P2=7; // Button +
int P3=8; // Button -

byte hh;
byte mm;
int menu = 0;

void setup() {

// The default display shows the date and time
menu = 0;
Wire.begin();
pinMode(P1,INPUT);// With 10k pull-down resistors → gnd
pinMode(P2,INPUT);
pinMode(P3,INPUT);

// Begin serial communication at a baud rate of 9600:
Serial.begin(9600);
// Wait for console opening:
delay(3000);
rtc.begin();
// Check if RTC is connected correctly:
if (! rtc.begin()) {
Serial.println(“Couldn’t find RTC”);
while (1);
}
// Check if the RTC lost power and if so, set the time:
/*if (rtc.lostPower()) {
Serial.println(“RTC lost power, lets set the time!”);
// The following line sets the RTC to the date & time this sketch was compiled:
rtc.adjust(DateTime(F(DATE), F(TIME)));
// This line sets the RTC with an explicit date & time, for example to set
// January 21, 2014 at 3am you would call:
//rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
} */
// Set the display brightness (0-7):
display.setBrightness(5);
// Clear the display:
display.clear();
} // setup

void loop() {
// in which subroutine should we go?
if (menu==0)
{
DisplayTime();
}
// check if you press the SET button and increase the menu index
if(digitalRead(P1))
{
menu=menu+1;
}
if (menu==1)
{
DisplaySetHour();
}
if (menu==2)
{
DisplaySetMinute();
}
if (menu==3)
{
SaveTime();
delay(500);
menu=0;
}
delay(100);
} // loop

void DisplayTime (){
// Get current date and time:
DateTime now = rtc.now();
//hh = now.hour();
//mm = now.minute();
// Create time format to display:
int displaytime = (now.hour() * 100) + now.minute();

// Print displaytime to the Serial Monitor:
Serial.println(displaytime);

// Display the current time in 24 hour format with leading zeros enabled and a center colon:
display.showNumberDecEx(displaytime, 0b11100000, true);

// Remove the following lines of code if you want a static instead of a blinking center colon:
delay(1000);
display.showNumberDec(displaytime, true); // Prints displaytime without center colon.
delay(1000); } // DisplayTime

void DisplaySetHour()
{
// time setting
display.clear();
DateTime now = rtc.now();
hh = now.hour();
if(digitalRead(P2)==HIGH)
{
if(hh==23)
{
hh=0;
}
else
{
hh=hh+1;
}
}
if(digitalRead(P3)==HIGH)
{
if(hh==0)
{
hh=23;
}
else
{
hh=hh-1;
}
}
display.showNumberDec(hh, true, 2, 0); // Expect: 14__
delay(200); }// SetHour

void DisplaySetMinute()
{
// Setting the minutes
display.clear();
DateTime now = rtc.now();
mm=now.minute();
if(digitalRead(P2)==HIGH)
{
if (mm==59)
{
mm=0;
}
else
{
mm=mm+1;
}
}
if(digitalRead(P3)==HIGH)
{
if (mm==0)
{
mm=59;
}
else
{
mm=mm-1;
}
}
display.showNumberDec(mm, true, 2, 2); // Expect: __04
delay(200); } // SetMinute

void SaveTime()
{
display.clear();
// Variable saving
DateTime myTime(DateTime(F(DATE), F(TIME)));
DateTime newTime( myTime.year(), myTime.month(), myTime.day(), hh, mm, 0);
rtc.adjust(newTime);
}
/* void SaveTime()
{
// Variable saving
display.clear();
rtc.adjust(DateTime(F(DATE),hh,mm,0));
delay(200);
} */

First time when I ran the program, it went well, then I checked if I can change the time, and since then the problems have appeared. So now it doesn’t even display the time correctly, as if it enters those if statements for menu = 1, menu = 2 …, but very quickly. Somehow it is locked in a loop for setting the time.
I don’t think I know how to use these buttons correctly.