Real Time Clock (RTC)

I'm using this code to display Time and date on a LCD. Can I do the same without having to use Void Loop(). I'm using a pcf8563 chip with battery backup. any attempt I've made to remove the code from "Loop", just freezes the clock. The clock sketch is below.

How I want it to work, is for the time and date to be displayed until I enter a "Menu". The lcd will then show the "Menu" until I exit back to clock.
I have included the begining of the menu BELOW this sketch.

/* Demonstration of Rtc_Pcf8563 Clock on LCD. 
 *
 * I used a RBBB with Arduino IDE, the pins are mapped a 
 * bit differently.  Change for your hw.
 * SCK - A5, SDA - A4, INT - D3/INT1
 *
 * This sketch connects a lcd to display the clock output.
 * 
 * setup:  see Pcf8563 data sheet.
 *         1x 10Kohm pullup on Pin3 INT
 *         No pullups on Pin5 or Pin6 (I2C internals used)
 *         1x 0.1pf on power
 *         1x 32khz chrystal
 *         1x h44780 LCD
 *
 * Joe Robertson, jmr
 * orbitalair@bellsouth.net
 */

#include <Wire.h>
#include <Rtc_Pcf8563.h>
/* add the lcd support */ 
#include <LiquidCrystal.h>

//init the real time clock
Rtc_Pcf8563 rtc;

/* initialize the library objects */
/* LiquidCrystal lcd(rs, en, d4, d5, d6, d7); */
LiquidCrystal lcd(7,8,9,10,11,12);

void setup()
{
  // set up the LCD's number of rows and columns: 
  lcd.begin(16, 2);
  
  //clear out all the registers
  rtc.initClock();
  //set a time to start with.
  //day, weekday, month, century, year
  rtc.setDate(14, 4, 1, 20, 13);
  //hr, min, sec
  rtc.setTime(23, 23, 40);
}

void loop()
{
  // set the cursor to column 0, line 1
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 0);
  //lcd.print(rtc.formatTime(RTCC_TIME_HM));
  lcd.print(rtc.formatTime());
  lcd.setCursor(0, 1);
  //lcd.print(rtc.formatDate(RTCC_DATE_ASIA));
  lcd.print(rtc.formatDate());
  
  delay(1000);
    
}

and part of my menu

void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu

  lcd.setCursor(0,0); //set the start position for lcd printing

  if(newMenuItem.getName()==menu.getRoot())
  { 
    //lcd.clear();
        lcd.print("Main Menu");    
  }
  //MENU SET CLOCK
  else if(newMenuItem.getName()=="menuSetClock"){
    lcd.clear();
    lcd.print("Set Clock");
  }

I have tried putting the Clock "loop" code into a function and then calling the function from

if(newMenuItem.getName()==menu.getRoot())
clock();

But all I get is the clock overlaying other menu items because I had to put clock(); in the main Loop otherwise the clock wont update. Do I need an interupt?
My full Sketch is a little long to upload but I can email it .ino

What you need is some form of flag to determine if clock should display or not and wrap the clock code in a if condition that checks this flag. As soon as you start to navigate down through the menus set it to false and when you back all the way out of the menu to the top set it mack to true.

// A global flag. true = root (top) menu and display clock. false = don't display clock
int menuRoot = true;

// In loop()
if (menuRoot == true){
    // set the cursor to column 0, line 1
    // (note: line 1 is the second row, since counting begins with 0):
    lcd.setCursor(0, 0);
    //lcd.print(rtc.formatTime(RTCC_TIME_HM));
    lcd.print(rtc.formatTime());
    lcd.setCursor(0, 1);
    //lcd.print(rtc.formatDate(RTCC_DATE_ASIA));
    lcd.print(rtc.formatDate());
}

Thanks Riva, I see this makes sense. I have put the code in and have the clock displayed over the menu still. From your snippet I read it as.

"If your at the top of the menu (the menuroot = true) display the clock."

else the menuroot = false, so hide the clock.

I have the menu running in my loop so I think what happens is the clock is displaying as it should but also the menu is displaying under the clock because it is in the loop
and the menuroot prints "main menu". seems I need to be a level above this?

If I move through the menu the clock is still displayed. I have a feel for what is happening but think I have not implimented your code correctly. Here is an cutdown of what I have.

I will play around with the code to see what I can get. Here's a cutdown of what I have at the moment.

#include <MenuBackend.h> //MenuBackend library - copyright by Alexander Brevig
// A global flag. true = root (top) menu and display clock. false = don't display clock
int menuRoot = true;

void setup()
{
  menu.getRoot().addRight(menuSetClock).addRight(menuSetDate).addRight(menuCommunications).addRight(menuExit); //set main menu items
  menuSetClock.add(menuItemHr).addRight(menuItemMin); // add first sub menu then addright additional sub menues for that menu
  menuExit.add(menuExit);
  menu.toRoot();
}
void loop()
{ 
  if (menuRoot == true){
    lcd.setCursor(0, 0);
    lcd.print(rtc.formatTime());
    lcd.setCursor(0, 1);
    lcd.print(rtc.formatDate());
  }
  readButtons(); //I splitted button reading and navigation in two procedures because 
  readEncoder();
  navigateMenus(); //in some situations I want to use the button for other purpose (eg. to change some settings)
     
}
void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu

  lcd.setCursor(0,0); //set the start position for lcd printing to the second row

  if(newMenuItem.getName()==menu.getRoot()) && menuRoot = true;
  { //this code will change to have time and date displayed  
    lcd.print("Main Menu       ");
    }
  //MENU SET CLOCK
  else if(newMenuItem.getName()=="menuSetClock"){
    lcd.clear();
    lcd.print("Set Clock");
  }
  else if(newMenuItem.getName()=="menuItemHr"){
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Hr");
  }
  else if(newMenuItem.getName()=="menuItemMin"){
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Min");
  }
}

If you move off the root (top) menu then you will need to set 'menuRoot = false' to stop the clock from being displayed and remember to set it back to true when the user backs out of the menu structure to the top menu.

I think you just need to set/reset the menuRoot flag in the menu code

void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu

  lcd.setCursor(0,0); //set the start position for lcd printing to the second row

  if(newMenuItem.getName()==menu.getRoot()) && menuRoot = true;
  { //this code will change to have time and date displayed  
    lcd.print("Main Menu       ");
menuRoot = true;
    }
  //MENU SET CLOCK
  else if(newMenuItem.getName()=="menuSetClock"){
    lcd.clear();
    lcd.print("Set Clock");
menuRoot = false;
  }
  else if(newMenuItem.getName()=="menuItemHr"){
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Hr");
 menuRoot = false;
  }
  else if(newMenuItem.getName()=="menuItemMin"){
    lcd.clear();
    lcd.setCursor(0,1);
    lcd.print("Min");
menuRoot = false;
   }
}

Thanks again Riva, I removed my code just before you posted your last reply, and came up with something very similar to your code.

Its Now Working :smiley:

void menuChanged(MenuChangeEvent changed){

  MenuItem newMenuItem=changed.to; //get the destination menu

  lcd.setCursor(0,0); //set the start position for lcd printing to the second row
     if(newMenuItem.getName()==menu.getRoot()){
    lcd.clear();
       menuRoot = true;    
  }
    //MENU SET CLOCK
  else if(newMenuItem.getName()=="menuSetClock"){
    menuRoot = false;
    lcd.clear();
    lcd.print("Set Clock");

I used

 if(newMenuItem.getName()==menu.getRoot()){

instead of

if(newMenuItem.getName()==menu.getRoot()) && menuRoot = true;

I only have

menuRoot = false

set up once in the 2nd menu option, the rest of the menu seems to work from this.

Rather than have clock displayed then "Main menu" I replaced "Main menu" which is the root-- For the clock display.
The code is now working. If I feel the need for a "Main menu" I can create an instance of this in the menu setup. Hope this makes sense. If you see any potential problems in what I have let me know. But for now thanks for all the help, would not have got this far without it. :slight_smile:

No problem, glade it works okay.

hello, i'm stuck with the same problem but i'm using ds1307 ... would you like to sharing your full code ?

thanks,

mike