Code to display time

Hello!
I have a code to display seconds and minutes but can't work out the logic for hours.

void countTime() {
 Time++;
 int seconds = Time%60;
 secLsd = seconds%10;
 secMsd = seconds/10;
 int minutes = (Time/60)%60;
 minLsd = minutes%10;
}

This is the particular section where the logic is.

How many minutes in an hour?
How many seconds?

1 Like

You haven't shown your complete sketch

This is a different approach

/* This software belongs to the public domain
 * Attention: a software-RTC like this one 
 * which uses the onboard-oscillator of the microcontroller-board
 * has a deviation from exact time of up to multiple seconds per day
 * This means of you want real time with a higher precision use a
 * hardware based RTC which will be much more precise
 */

unsigned long RTC_Timer  = 0;
unsigned long MyTestTimer;

int RTC_Hour   = 0;
int RTC_Minute = 59;
int RTC_Second = 50;
int RTC_10nth_Seconds = 0;
int minutesOfDay;
long secondsOfDay;


// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &periodStartTime, unsigned long TimePeriod) {
  unsigned long currentMillis  = millis();
  if ( currentMillis - periodStartTime >= TimePeriod )
  {
    periodStartTime = currentMillis; // set new expireTime
    return true;                // more time than TimePeriod) has elapsed since last time if-condition was true
  }
  else return false;            // not expired
}


void PrintRTC_Data() {
  Serial.print("Software RTC time: ");
  Serial.print(RTC_Hour);
  Serial.print(":");
  Serial.print(RTC_Minute);
  Serial.print(":");
  Serial.print(RTC_Second);

  minutesOfDay = RTC_Hour * 60 + RTC_Minute;
  secondsOfDay = RTC_Hour * 3600 + RTC_Minute * 60 + RTC_Second;

  Serial.print(" minutesOfDay:");
  Serial.print(minutesOfDay);

  Serial.print("  secondsOfDay:");
  Serial.print(secondsOfDay);  
  Serial.println();
  
}


void SoftRTC() {
  if ( TimePeriodIsOver(RTC_Timer, 100) ) { // once every 100 milliseconds 
    RTC_10nth_Seconds ++;                   // increase 1/10th-seconds counter
    
    if (RTC_10nth_Seconds == 10) {          // if 1/10th-seconds reaches 10
      RTC_10nth_Seconds = 0;                // reset 1/10th-seconds counterto zero
      RTC_Second++;                         // increase seconds counter by 1

      if (RTC_Second == 60) {               // if seconds counter reaches 60
        RTC_Minute++;                       // increase minutes counter by 1
        RTC_Second = 0;                     // reset seconds counter to zero
      }
    }

    if (RTC_Minute == 60) {                 // if minutes counter reaches 60
      RTC_Hour++;                           // increase hour counter by 1
      RTC_Minute = 0;                       // reset minutes counter to zero
    }

    if (RTC_Hour == 24) {                   // if hours counter reaches 24 
      RTC_Hour = 0;                         // reset hours counter to zero
    }
  }
}


void setup() {
  Serial.begin(115200);
  Serial.println("Setup-Start");
}


void loop() {
  SoftRTC(); // must be called very regular and repeatedly to update the 0.1 second time-ticks
             // this means you CAN'T use delay(). 
             // Each and every single delay() must be replaced NON-blocking timing
  if ( TimePeriodIsOver(MyTestTimer, 1000) ) { // if 1000 milliseconds have passed by
    PrintRTC_Data();                           // print time
  }
}

Be the change you want to see in the world
best regards Stefan

1 Like

Just like your minutes...

int minutes = (Time/60)%60;

So are your hours...

int hours = (minutes/60)%60;

[edit] MY ENTRY HERE IS WRONG. I THOUGHT I CANCELED IT, PUT I POSTED IT. Leaving it up so comments are relevant. Thanks for pointed it out.[/edit]

1 Like

Nope. If you try that, then hours will always be zero.

1 Like
void countTime() {
  Time++;
  int Hour = Time / 3600;
  int Minutes = (Time - Hour * 3600) / 60;
  int Seconds = Time % 60;
  secLsd = Seconds % 10;
  secMsd = Seconds / 10;
  minLsd = Minutes % 10;
  minMsd = Minutes / 10;
  Serial.print(Hour);
  Serial.print(':');
  Serial.print(minMsd);
  Serial.print(minLsd);
  Serial.print(':');
  Serial.print(secMsd);
  Serial.println(secLsd);
}
 minMsd = minutes/10;

 int hours = ((Time/60)/60)%24;
 hourLsd = hours%10;
 hourMsd = hours/10;

Except 'minutes' is %60 so dividing by 60 always gives you zero. It works if you save the modulo operations til later:

auto seconds = Time;
auto minutes = seconds / 60;
auto hours = minutes / 60;
seconds %= 60;
minutes %= 60;
hours %= 24;
1 Like

Hi guys! Sorry for the late reply thank you all for your contribution and its working thanks alot!!

// ----------------------------------------------------------------------------------------------- Digital Clock ------------------------------------------------------------------------------
char secLsd = 0; // Global variable holds seconds least significent digit
char secMsd = 0; // Global variable holds seconds most significent digit
char minLsd = 0;
char minMsd = 0;
char hrsLsd = 0;
char hrsMsd = 0;
const int AA2 = 5; //---------------------------------------------------------------------- define i/o pins -----------------------------------------------------------
const int AA1 = 4;
const int AA0 = 3;
const int E3 = 2;
const int D3 = 11;
const int D2 = 10;
const int D1 = 9;
const int D0 = 8;
#define SW1 13

#define SW2 7

#define SW3 12

int Time=0;
int dog=0;
void setup() {
  Serial.begin(9600);
 pinMode(AA2, OUTPUT);
 pinMode(AA1, OUTPUT);
 pinMode(AA0, OUTPUT);
 pinMode(E3, OUTPUT); 
 pinMode(D3, OUTPUT); 
 pinMode(D2, OUTPUT); 
 pinMode(D1, OUTPUT); 
 pinMode(D0, OUTPUT); 
 digitalWrite(E3,LOW);
 writeDigit(5,5); //----------------------------------- write 5,4,3,2,1,0 to the displays for one second ----------------------------------------------
 writeDigit(4,4);
 writeDigit(3,3);
writeDigit(2,2);
 writeDigit(1,1);
 writeDigit(0,0);
}
void loop() {
 controlTime();
 dispTime();
 delay(100);// ------------------- Uses the delay() function method to set one second time interval -----------------------------
countTime();
delay(1000);
}
void writeDigit(int address, int value) { //--------------- function to put address and data values on pins, then pulse E3 to write data into selected display --------
 digitalWrite(AA2,bitRead(address,2));
 digitalWrite(AA1,bitRead(address,1));
 digitalWrite(AA0,bitRead(address,0));
 digitalWrite(D3,bitRead(value,3));
 digitalWrite(D2,bitRead(value,2));
 digitalWrite(D1,bitRead(value,1));
 digitalWrite(D0,bitRead(value,0));
 digitalWrite(E3,HIGH);
 delay(1);
 digitalWrite(E3,LOW);
}
void dispTime() { //------------------------------------ function to write seconds, minutes, hours to display -----------------------------------------------
 writeDigit(0,secLsd);
 writeDigit(1,secMsd); 
 writeDigit(2,minLsd); 
 writeDigit(3,minMsd);
 writeDigit(4,hrsLsd);
 writeDigit(5,hrsMsd);
}
void controlTime() {
 Time++;
 if(digitalRead(SW1)==HIGH){//Switch is active HIGH
 int seconds = Time%60;
 secMsd = seconds/10;
 }
 
else if(digitalRead(SW2)==HIGH){//Switch is active HIGH
//int minutes = (Time/60)%60;
// minLsd = minutes%10;
// minMsd=minutes/10;
  int minutes = Time%60;
 minMsd = minutes/10;
 }
  
  else if (digitalRead(SW3)==HIGH){
   dog++;
   int hours = Time%100;
 hrsLsd =dog;
    //Serial.println(hours);
    if(dog>=10){
       //Serial.println(hours);
      hrsMsd+=1;
    dog=0;  
      hrsLsd =dog; 
 //hrsMsd = hours/10;
      
    }
    if(hrsMsd>1){
      if(dog>=4){
        hrsMsd=0;
        dog=0;
         hrsLsd =dog;
      }
    }
    Serial.println(dog);
   }
  
}
void countTime() {
 Time++;
 int seconds = Time%60;
 secLsd = seconds%10;
 secMsd = seconds/10;
 int minutes = (Time/60)%60;
 minLsd = minutes%10;
 minMsd=minutes/10;
  int hours = ((Time/60)/60)%24;
 hrsLsd = hours%10;
 hrsMsd = hours/10;

So thanks to you guys I decided to include a code to set the time but I can't seem to know how to display the time set.Any tips?

My tip is:

provide detailed information about your display.
and provide detailed information about what is shown on your display and how this deviates from what you wish that should be shown on your display

You load a lot of analysing work to you potential helpers because they would have to analyse how your hardware might look like then reproduce your hardware-setup and take a look what is shown on the display

Do a rough estimation: how many users will take this additional work that could be done by you?

best regards Stefan

My display uses a BCD to 7 segment decoder which is the CD4511 to display numbers on the 7 segment it also uses the other gates to know what segment to load it on.
Right now,my display counts as a timer in the format hours:minutes:seconds and in steps of 2 probably to an error of my delays.I can set time but it doesn't show on the display.

what does this mean:

  • display stays dark all the time?
  • display shows nonsense?
  • display is flickering?

using BCD to 7 segment decoders is a nice exercise to work with logic-chips.
But is very outdated. There are more modern chips with can be driven with libraries where you just handover digit and number and all the rest is done by the library.

Have you googled for "Github Arduino 4511" ? There is a good chance that there is already existing a library

Did you do a pre-test with a single digit? What was the result of this single-digit-pre-test?

Something like this is not done by posting a 40-digit long cheatcode for entering platinum-level.
It is analysing. You should provide download-links to the datasheet of the logic-chips you are using and adding a few lines of text where in the datasheet is the information which you used to write the code.

Usually datasheets of logic-chips have a truth-table that show the relations between inputs and outputs beeing HIGH-LOW. You should post a picture of this truth-table and write how you interpret this truth-table.

best regards Stefan

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