Two Timers using DS1307

Hi all,

I am trying to create a system that has two timers. One is a start delay timer. The second timer is a run-timer.

The start delay timer is able to be set from 15 to 99 minutes via a 20 key matrix keypad. I can enter this value. Although the data is entered in minutes, the subroutine stores this as minutes if the time is less than 60 mins, or as an hour and a number of minutes if the time is over an hour. This bit works well, and gives me a number of flags as well as the time. (code included here, just to give a variable list)

     lcd.setCursor (1,2);
           do {

             
             char stKey = keypad.getKey();

             if (stKey) {
                 lcd.setCursor ((csr)+1, 2); //move cursor on LCD
                 lcd.print (stKey);           //display character pressed on keypad

             if  (stKey >= '0' && stKey <= '9') {     // only act on numeric keys
                 startDelay += stKey;               // append new character to input string
                 csr++; //increase cursor count to move on lcd
               
                 } else if (stKey == 'E') {
                   if ((startDelay.length() > 0) && (startDelay.length() <= 2)) {
                   startDelayMins = startDelay.toInt(); // YOU GOT AN INTEGER NUMBER
                    if (startDelayMins < 5){ 
                    lcd.clear();
                    lcd.setCursor (3,1);
                    lcd.print ("Invalid Input");
                    delay (2000);
                    lcd.clear();
                    startDelayFlag = ""; 
                    break;
                    }
                    if (startDelayMins > 99){
                        lcd.clear();
                        lcd.setCursor (3,1);
                        lcd.print ("Invalid Input");
                        delay (2000);
                        lcd.clear();
                        startDelayFlag = ""; 
                         break;
                       }
                   startDelayFlag = 1;            // DO YOUR WORK HERE
                   if (startDelayMins > 60){
                    delayHrs = 1;
                    delayMins = (startDelayMins - 60);
                    Serial.print ("start Delay = ");
                    Serial.print (delayHrs);
                    Serial.print (":");
                    Serial.println (delayMins);
                    delayFlag = 1;
                   }
                   if (startDelayMins < 60){
                    delayHrs = 0;
                    delayMins = startDelayMins;
                    Serial.print ("start Delay = ");
                    Serial.print (delayHrs);
                    Serial.print (":");
                    Serial.println (delayMins);
                    delayFlag = 1;

                  
                   }
                   
                   startDelay = "";               // clear input
                   } 
                 } else if (stKey == 'C') {
                   startDelayFlag = 2;
                   startDelay = "";              // clear input
                   lcd.clear();
                   break;
                     }
                    } 
                   } while (startDelayFlag !=1);
                   
                  lcd.clear();

                  break;

Then there is the run-time setting. This can either be in minutes, if less than 60 minutes: Or it can be in whole hours ( 1-99 hours) again this bit of code works well, but again will be included for completeness. The menu allows flags to be set to indicate whether the number represents minutes or hours.

     case 'B':
           csr = 0;
           runTimeNum = 0;
           runTimeFlag = 0;  
           runTimeHrsFlag = 0;
           runTimeMinFlag = 0;    
           lcd.clear();
           lcd.setCursor (3,0);
           lcd.print ("Enter Run Time");
           lcd.setCursor (2,1);
           lcd.print ("Hours OR Minutes");
           lcd.setCursor (1,2);
           lcd.print ("Hours");
           lcd.setCursor (12,2);
           lcd.print ("Minutes");
           lcd.setCursor(3,3);
           lcd.write (2);
           lcd.setCursor (15,3);
           lcd.write (3);
           char key2 = keypad.getKey();
            while(key2 == NO_KEY) key2 = keypad.getKey();                           //curly bracket 1
             if (key2 == 'U'){
             runTimeHrsFlag = 1;
             runTimeMinFlag = 0;
             }
             if (key2 == 'D'){
             runTimeHrsFlag = 0;
             runTimeMinFlag = 1;
             }
             if ((key2 != 'U') && (key2 != 'D')) {
             lcd.clear();
             lcd.setCursor (3,1);
             lcd.print ("No Data Input");
             delay (2000);
             lcd.clear();
             break;
             lcd.clear();
             } 
           
           lcd.clear();
          
           if ((runTimeHrsFlag == 1) && (runTimeMinFlag == 0)){
              lcd.setCursor (2,0);
              lcd.print("Hours Range 1");
              lcd.setCursor (15,0);
              lcd.write (1);
              lcd.setCursor (16,0);
              lcd.print ("99");
               }
           if ((runTimeMinFlag == 1) && runTimeHrsFlag == 0){
              lcd.setCursor (3,0);
              lcd.print ("Minutes range");
              lcd.setCursor (4,1);
              lcd.print ("From 15");
              lcd.setCursor (11,1);
              lcd.write (1);
              lcd.setCursor (13,1);
              lcd.print ("99");
               }
              lcd.setCursor (5,2);
              lcd.print ("Enter time");
           do {

             char rtKey = keypad.getKey();

             if (rtKey) {
                 lcd.setCursor ((csr)+1, 3); //move cursor on LCD
                 lcd.print (rtKey);           //display character pressed on keypad

             if  (rtKey >= '0' && rtKey <= '9') {     // only act on numeric keys
                 runTime += rtKey;               // append new character to input string
                 csr++; //increase cursor count to move on lcd
               
                 } else if (rtKey == 'E') {
                   if ((runTime.length() > 0) && (runTime.length() <= 2)) {
                   runTimeNum = runTime.toInt(); // YOU GOT AN INTEGER NUMBER

                   if ((runTimeNum  >=15) && (runTimeNum <= 99) && (runTimeMinFlag ==1)) {
                    lcd.clear();
                                                  // DO YOUR WORK HERE
                  
                    runTime = "";
                    break;
                   }
                   
                   if ((runTimeNum < 15) && (runTimeMinFlag == 1)){
                    lcd.clear();
                    lcd.setCursor (3,1);
                    lcd.print ("Invalid Input");
                    delay (2000);
                    lcd.clear();
                    runTimeHrsFlag = 0;
                    runTimeMinFlag = 0;
                    runTimeFlag = "";
                    break;
            

the area I am struggling with is how to set up the two individual timers.

I have a subroutine (void) called runTime. When this is called (all requirements met) I want to run a delay timer. During this timer, I need to monitor an input from a PIR unit, and also output to a sounder device. This gives time to leave the area.

The next timer is a run timer. During this time, I will still need to monitor the PIR and output to the sounder and also output to one other pin.

at the end of the run-time, a simple message ("Process Complete") will be shown on the LCD. again, not a problem. My problem is that I have never used an RTC before. I do not care about days, date, or the current time. everything is relative to the point the 'start button' is pressed.

could someone off any assistance please?

You could zero the H,M & S in the RTC when the user has input the start delay. Then poll the RTC H,M & S registers to see when you get a match to the start delay. You can then zero H,M & S again and poll the registers to see when you get a match to the run time.

You could avoid using the DS1307 RTC and use the millis() function to note the passage of time instead, which will probably be fine for your scenario.

If you don't care about days, date or the current time, why are you using a RTC? An Arduino can meet your requirements without it.

Also, I would strongly suggest you rework you code so all your timing variables represent just seconds or minutes. This will make the internal math very straight forward. You only have to convert it to a normal time format if you display it on the LCD or Serial.

Hi there, thank you for your messages so far.

The reason I am working the way I am, is partially for this project, but I also have other projects waiting, such as data-loggers and other projects where date and time are essential. I thought that as the majority of code is written for this, it would give me the chance to learn the functions of an RTC module so I am ready when I need it

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