#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include "RTClib.h"
RTC_DS1307 rtc;
LiquidCrystal_I2C lcd(0x27, 20, 4);
char *pszMenuItems[] =
{
"clock",
"MenuItem1",
"MenuItem2",
"MenuItem3",
"MenuItem4"
};
bool action1();
bool action2();
bool action3();
bool action4();
typedef bool(*myFunc)();
myFunc Functions[4] =
{
&action1,
&action2,
&action3,
&action4
};
int upButton = 10;
int downButton = 11;
int selectButton = 12;
int menu = 1;
void setup()
{
Serial.begin(9600);
lcd.init();
lcd.backlight();
pinMode(upButton, INPUT_PULLUP);
pinMode(downButton, INPUT_PULLUP);
pinMode(selectButton, INPUT_PULLUP);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (!rtc.isrunning()) {
Serial.println("RTC lost power, lets set the time!");
// Comment out below lines once you set the date & time.
// Following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(__DATE__, __TIME__));
}
updateMenu();
}
void loop()
{
static unsigned long
timeButtonRead = 0;
static byte
lastupButton = 0xff,
lastselButton = 0xff,
lastdownButton = 0xff;
byte
currButton;
unsigned long
timeNow;
//check buttons every 75mS
timeNow = millis();
if (timeNow - timeButtonRead < 75)
return;
timeButtonRead = timeNow;
//read the button...
currButton = digitalRead(downButton);
//...if it's state is not the same as last...
if (currButton != lastdownButton)
{
//...save the new state
lastdownButton = currButton;
//if it's low indicating it has been pressed...
if (currButton == LOW)
{
//process action; in this case, if menu is greater than 1...
if (menu > 1)
{
//...decrement it
menu--;
//and update the menu
updateMenu();
}//if
}//if
}//if
//same comments for downbutton apply for up and select
currButton = digitalRead(upButton);
if (currButton != lastupButton)
{
lastupButton = currButton;
if (currButton == LOW)
{
if (menu < 4)
{
menu++;
updateMenu();
}//if
}//if
}//if
currButton = digitalRead(selectButton);
if (currButton != lastselButton)
{
lastselButton = currButton;
if (currButton == LOW)
{
//call the function pointed to by menu in the Functions[] array
Functions[menu - 2]();
//when it returns, update the menu
updateMenu();
}//if
}//if
DateTime now = rtc.now(); //Attaches now to action1 scope
lcd.setCursor(0, 0);
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.print(" ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
}//loop
void updateMenu()
{
lcd.clear();
Serial.print("\n\n\n\n");
for (int i = 1; i < 4; i++)
{
//if menu line is selected, print a '>', otherwise a space
if (i == (menu - 1))
{
Serial.print(">");
lcd.setCursor(0, i);
lcd.print(">");
lcd.print(pszMenuItems[i]);
//print the text of the line item
Serial.println(pszMenuItems[i]);
}
else
{
Serial.print(" ");
lcd.setCursor(0, i);
lcd.print(" ");
lcd.print(pszMenuItems[i]);
//print the text of the line item
Serial.println(pszMenuItems[i]);
}//else
}//for
}//updateMenu
bool action1()
{
while(1){
DateTime now = rtc.now(); //Attaches now to action1 scope
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Current Date & Time: ");
lcd.setCursor(0, 1);
lcd.print(now.year(), DEC);
lcd.print('/');
lcd.print(now.month(), DEC);
lcd.print('/');
lcd.print(now.day(), DEC);
lcd.print(" ");
lcd.print(now.hour(), DEC);
lcd.print(':');
lcd.print(now.minute(), DEC);
lcd.print(':');
lcd.print(now.second(), DEC);
Serial.println(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
if (digitalRead(downButton) == LOW) {
delay(1000);
}
else {
break;
}
}
}//action1
bool action2()
{
while(1){
lcd.clear();
lcd.print(">Executing #2");
Serial.println(">Executing #2");
if (digitalRead(downButton) == LOW)
{
delay(1000);
}
else{
return;
}
}
}
//action2
bool action3()
{
lcd.clear();
lcd.print(">Executing #3");
Serial.println(">Executing #3");
delay(1500);
}//action3
bool action4()
{
lcd.clear();
lcd.print(">Executing #4");
Serial.println(">Executing #4");
delay(1500);
}//action4
How would I add scrolling to my menu so I can go through more then 4 menu items? Would you name a int of MenuPage to cut the menu items in sections so when MenuPage = 1 lcd.setCursor gets set to 0,1 and prints the following menu items that werent displayed at MenuPage = 0 in the updateMenu section?
Would like to use this for my sub menu's as well so can have multiple items in the sub menu's.
This came after deciding or believing i'd like the date & time displayed on the first line and the menu items below that with scrolling ability to go through more menu items.
I see Switches being used in a lot of menu's online but have little experience/understanding of switches yet, and wouldn't a if(MenuPage > 4) lcd.setcursor(0,1) lcd.print(pszMenuItems*) work? Where should it go?*