Clock using 7 seg display and buttons EDITED

Hello,

I'm using a 4 digit 7 seg display (TM1637), to avoid using a bunch of wires, this way I only have 4. I've got a clock working using a Nano and a DS1307. But now I'd like to integrate some buttons, to change hours and minutes when needed.

It displays data but whenever I press the buttons, everything changes to zero or just doesn't work. But no time is displayed. There are three buttons, a menu button and then a button each for hours and minutues. The menu button is pressed to scroll through the menu and save.

Anybody see the issue with the code as I'm at a loss here, thank you

This code works without buttons

#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;

#include <TM1637.h>

// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

TM1637 tm1637(CLK, DIO);
int8_t TimeDisp[] = { 0x00, 0x00, 0x00, 0x00 };
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char second;
unsigned char minute;
unsigned char hour;


void setup() {

tm1637.init();
tm1637.set(7); //dull = 0, bright = 7

Serial.begin(57600);
if (! rtc.begin()) {
  Serial.println("RTC ERROR");
  while (1);
}

if (! rtc.isrunning()){
  Serial.println("RTC Not Set!");

  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}

}

void loop() {

DateTime now = rtc.now();

Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);

Serial.println();
hour = now.hour();
minute = now.minute();

delay(1000);

TimeUpdate();
tm1637.display(TimeDisp);

ClockPoint = (~ClockPoint) & 0x01;

}

void TimeUpdate(void)
{
  if(ClockPoint)tm1637.point(POINT_ON);
  else tm1637.point(POINT_OFF);
  TimeDisp[0] = hour / 10;
  TimeDisp[1] = hour % 10;
  TimeDisp[2] = minute / 10;
  TimeDisp[3] = minute % 10;
  //Update = OFF;


}

Code with buttons, not working

#include <Wire.h>
//#include <RTClib.h>
#include "RTClib.h"
#include <TM1637.h>
//#include <LiquidCrystal_I2C.h>

//************************************//
//LiquidCrystal_I2C lcd(0x3F,16,2); // Display  I2C 16 x 2
RTC_DS1307 RTC;

// Module connection pins (Digital Pins)
#define CLK 2
#define DIO 3

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

//************Variables**************//
TM1637 tm1637(CLK, DIO);
int8_t TimeDisp[] = { 0x00, 0x00, 0x00, 0x00 };
unsigned char ClockPoint = 1;
unsigned char Update;
unsigned char second;
unsigned char minute;
unsigned char hour;

int hourupg;
int minupg;
//int yearupg;
//int monthupg;
//int dayupg;
int menu =0;

void setup() {

tm1637.init();
tm1637.set(0); //dull = 0, bright = 7

  //lcd.begin();
  //lcd.backlight();
  //lcd.clear();

  pinMode(P1,INPUT);
  pinMode(P2,INPUT);
  pinMode(P3,INPUT);

  Serial.begin(57600);
  Wire.begin();
  RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // Set the date and time at compile time
    RTC.adjust(DateTime(__DATE__, __TIME__));
  }
  // RTC.adjust(DateTime(__DATE__, __TIME__)); //removing "//" to adjust the time
    // The default display shows the date and time
  int menu=0;
}
 
void loop(){



DateTime now = RTC.now();

Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);

Serial.println();
hour = now.hour();
minute = now.minute();

delay(1000);

TimeUpdate();
tm1637.display(TimeDisp);

ClockPoint = (~ClockPoint) & 0x01;


//}








// check if you press the SET button and increase the menu index
  if(digitalRead(P1))
  {
   menu=menu+1;
  }
// in which subroutine should we go?
 if (menu==0)
    {
     DisplayDateTime(); // void DisplayDateTime

    }

  if (menu==1)
    {
    DisplaySetHour();
    }
  if (menu==2)
    {
    DisplaySetMinute();
    }
  if (menu==3)
    {
    StoreAgg(); 
    delay(500);
    menu=0;
    }
    delay(100);
}

void TimeUpdate(void)
{
  if(ClockPoint)tm1637.point(POINT_ON);
  else tm1637.point(POINT_OFF);
  TimeDisp[0] = hour / 10;
  TimeDisp[1] = hour % 10;
  TimeDisp[2] = minute / 10;
  TimeDisp[3] = minute % 10;
  //Update = OFF;


}

void DisplayDateTime ()
{
// We show the current date and time
  DateTime now = RTC.now();

  //lcd.setCursor(0, 1);
  //lcd.print("Hour:");
  tm1637.display("Hour:");
  if (now.hour()<=9)
  {
    //lcd.print("0");
    tm1637.display("0");
  }
  //lcd.print(now.hour(), DEC);
  tm1637.display(now.hour(), DEC);
  hourupg=now.hour();
  //lcd.print(":");
  tm1637.display(":");
  if (now.minute()<=9)
  {
    //lcd.print("0");
    tm1637.display("0");
  }
  //lcd.print(now.minute(), DEC);
  tm1637.display(now.minute(), DEC);
  minupg=now.minute();
  //lcd.print(":");
  tm1637.display(":");
  if (now.second()<=9)
  {
    //lcd.print("0");
    tm1637.display("0");
  }
  //lcd.print(now.second(), DEC);

}


void DisplaySetHour()
{
// time setting
//  tm1637.clear();
  DateTime now = RTC.now();
  if(digitalRead(P2)==HIGH)
  {
    if(hourupg==23)
    {
      hourupg=0;
    }
    else
    {
      hourupg=hourupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if(hourupg==0)
    {
      hourupg=23;
    }
    else
    {
      hourupg=hourupg-1;
    }
  }


  tm1637.display(hourupg,DEC);
  delay(200);
}

void DisplaySetMinute()
{
// Setting the minutes

  if(digitalRead(P2)==HIGH)
  {
    if (minupg==59)
    {
      minupg=0;
    }
    else
    {
      minupg=minupg+1;
    }
  }
   if(digitalRead(P3)==HIGH)
  {
    if (minupg==0)
    {
      minupg=59;
    }
    else
    {
      minupg=minupg-1;
    }
  }
  tm1637.display(minupg,DEC);
  delay(200);
}
  
//}

void StoreAgg()
{
  RTC.adjust(DateTime(hourupg,minupg,0));
  delay(200);
}

[/code]

Hello,
I've edited the OP and added a little more info. The working code and the code with buttons added, which is not working.

Any ideas?

I've searched only for information regarding using this display and buttons but I can't find anything. There's a bunch using liquid crystal displays, which I've tested and got working but none with this 7 seg display.

Hi.

Please define "just doesn't work".

Your code-with-buttons seems to depend on:

int hourupg;
int minupg;

Do you know at any time in your sketch the contents of these ?
I'd check that by sending those out through serial so you can see what these values do, once every iteration.
Not only after some change has occurred, because it's also interesting to know where it starts.

The serial connection is a very powerful debug tool.
You might be able to think of some other things you could monitor that way.
Once your sketch works as planned, you can comment out or delete all parts in it related to the serial port.

MAS3:
Hi.

Please define "just doesn't work".

Your code-with-buttons seems to depend on:

int hourupg;

int minupg;




Do you know at any time in your sketch the contents of these ?
I'd check that by sending those out through serial so you can see what these values do, once every iteration.
Not only after some change has occurred, because it's also interesting to know where it starts.

The serial connection is a very powerful debug tool.
You might be able to think of some other things you could monitor that way.
Once your sketch works as planned, you can comment out or delete all parts in it related to the serial port.

Thanks for the reply.

It doesn’t work, as in no time or numbers are displayed, just zero’s and when I press any button the display jumps around, like it’s trying to display something but doesn’t.

I’ll try the serial port, thank you.

exiledyorkie:
There are three buttons, a menu button and then a button each for hours and minutues. The menu button is pressed to scroll through the menu and save.

Why three buttons, then?
If you have separate buttons for hours and minutes, then what need is there for a menu button?
If you have a menu button, then what need is there to have separate buttons for hours and minutes?

Another thing I have noticed wrong with your code is that your code does not test for when a button becomes pressed; rather, it tests whether it is being pressed.

I think you should read about "state change detection" as it relates to buttons. You should also read about "debouncing".

That's not what the code says.
The 2 buttons are up and down, and a menu button to enter the setup mode, scroll through it and save the set values.

Three buttons does make parameter setting a lot easier with a "select" plus "up" and "down" buttons. :grinning:

Otherwise you have to work through the whole range of each parameter, very annoying if you step past the desired setting.

A very practical implementation of this with three inputs to the microprocessor is the rotary encoder with a "push" function. :sunglasses:

Thanks for the input guys. I worked through it one evening but got into a muddle and scrapped it. Been away since, so I’ll have another go next week.

A rotary encoder, sounds like a good idea. I was going to use cap switches, so I could hide them within an enclosure.

Paul__B:
Three buttons does make parameter setting a lot easier with a "select" plus "up" and "down" buttons. :grinning:

Otherwise you have to work through the whole range of each parameter, very annoying if you step past the desired setting.

A very practical implementation of this with three inputs to the microprocessor is the rotary encoder with a "push" function. :sunglasses:

Oh me oh my. I didn’t click what you meant (no pun intended) with regards to the rotary encoder. Just randomly come across one and that is a great idea, thank you for that. Just ordered a KY-040 encoder to test out.

Yes. Rotary encoders are used for much professional (medical, for one) equipment to implement menus effectively.

Just don't get into thinking you need interrupts to work with them - at least for manual operation. :grinning:

Paul__B:
Three buttons does make parameter setting a lot easier with a "select" plus "up" and "down" buttons. :grinning:

Otherwise you have to work through the whole range of each parameter, very annoying if you step past the desired setting.

If you treat "tens digit of minutes" and "ones digit of minutes" as separate parameters, then the range becomes much smaller, so that you can set the time very quickly.
I cannot help but wonder why the alarm feature on a digital watch treats the minutes as one parameter (range 0~59), rather than two parameters (ranges 0~5 and 0~9, respectively). It is indeed annoying when you pass the correct number. I would not be surprised if the programming was done by someone who does not even wear a watch.