//<< ===================== 1) LIBRARIES =======================================
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <RTClib.h>
//<< ===================== 2) CONSTANTS + GLOBAL VARIABLES =====================
//<< --- OLED setup ---
#define WIDTH 128
#define HEIGHT 64
#define RESET -1
Adafruit_SSD1306 display(WIDTH, HEIGHT, &Wire, RESET);
RTC_DS3231 clock;
#define PREV 4
#define NEXT 3
#define SELECT 2
int counter = 0; // variable to hold current state
//<< --- status options array ---
const char* status[] = {
"Eat",
"Sleep",
"Study",
"Relax",
};
int totalStatus = 4;
int currentStatus = 0;
//<< ---------- MAIN MENU ----------
String mainMenu[] = { //main menu array
"Status",
"Clock",
};
int totalNum = 2; //total number of main menu options
int mainCurrent = 0; //tracks the current selected main menu option
int counterIndex = 0;
int statusTotal = 4;
//<< ===================== 3) SETUP (RUNS ONCE) ===============================
void setup() {
Wire.begin();
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay(); // to clear display
//<< set the modes for the buttons you are using
pinMode(PREV, INPUT_PULLUP);
pinMode(NEXT, INPUT_PULLUP);
pinMode(SELECT, INPUT_PULLUP);
showWelcome(); // show welcome message
delay(2000);
mainmenu();
clock.begin(); //Intialize Clock
}
//<< ===================== 4) LOOP (RUNS FOREVER) ============================
void loop() {
if (counter == 0){
mainmenu(); //go to main menu screen
}
if (counter == 1){ //if the screen mode is 1
showStatusMenu(); //go to that screen display
}
if (counter == 2){ //if the screen mode is 2
Clock(); //go to that screen display
}
}
//<< Your main code will go here
//<< Forever detect button presses
//<< Navigate through the main menu, status menu, and other screens from the button presses
//<< ===================== 5) FUNCTIONS (OUTSIDE setup/loop) =================
//<< Function to show welcome message on screen
void showWelcome() {
display.setTextColor(SSD1306_WHITE);
display.setTextSize(1);
display.println("Welcome to the ");
display.print("Display!");
display.display();
}
//<< Function to show chosen status on screen
//<< Function to show status menu on screen
void showStatusMenu() {
display.clearDisplay(); // clear display
display.setTextSize(1); // set text size to 1
display.setTextColor(SSD1306_WHITE); // set color to white
display.setCursor(0,0); // set cursor location to (0,0)
display.println("statusMenu"); // print your header
display.println("-------------------"); // feel free to change what this looks like
int i = 0;
while (i < totalStatus) {
if (i == currentStatus) {
display.print("> "); // highlight the current status
} else {
display.print(" "); // keep spacing for non-selected
}
display.println(status[i]); // print the status text
i = i + 1; // move to the next item
}
display.display(); // push everything to the screen
//<< --- Place the button logic blocks here in the correct order ---
if (buttonHelper(PREV)) { // If the PREV button is pressed.
counter = 0; // Back to main menu
delay(200); // short delay
}
else if (buttonHelper(NEXT)) { // If the NEXT button is pressed.
counterIndex = counterIndex + 1; // Increase the status index by 1
if (counterIndex > statusTotal - 1) { // If the status index is "greater than" the last index (total statuses - 1)
counterIndex = counterIndex - 1;
}
delay(200); // short delay
}
else if (buttonHelper(SELECT)) { // If the SELECT button is pressed
counter = 3; // Update the screen variable number to show confirmed status screen
delay(200); // short delay
}
}
//<< Function to show main menu on screen
void mainmenu() {
display.clearDisplay(); // clear display
display.setTextSize(1); // set text size to 1
display.setTextColor(SSD1306_WHITE); // set text color to white
display.setCursor(0,0); // set cursor to (0,0)
display.println("mainMenu"); // print header
display.println("----------------");
int i = 0;
while (i < totalNum) { // loop through all main menu options
if (i == mainCurrent) { // check if this is the selected option using the counter variable
display.print(">"); // highlight the current main menu option
} else {
display.print(" "); // keep spacing for non-selected
}
display.println(mainMenu[i]); // print the main menu option text
i = i + 1; // move to the next item
}
//display.display(); // push everything to the screen
display.setCursor(0, 56);
display.println("SEL: Select");
display.display();
// buttons
if (buttonHelper(PREV)) {
mainCurrent = mainCurrent - 1;
if (mainCurrent < 0) mainCurrent= totalNum - 1;
delay(200);
}
if (buttonHelper(NEXT)) {
mainCurrent = mainCurrent + 1;
if (mainCurrent> totalNum - 1) {
mainCurrent = 0;
}
delay(200);
}
if (buttonHelper(SELECT)) {
if (mainCurrent== 0) {
counter= 1; // Status -> goes to Status Menu function
} else if (mainCurrent == 1) {
counter = 2; // Clock
}
delay(200);
}
}
//<< Example of how this function can be used in the void loop()
//<< Button Helper Function
bool buttonHelper(int buttonPin) { //boolean function because it returns true or false. Not a void type.
if (digitalRead(buttonPin)==LOW) { //if high or low
delay(50); //create a short delay
if (digitalRead(buttonPin)==LOW) {//if hight or low
return true; //if the button is still pressed after a delay, return (true/false)
}
return false; //if not, return (true/false)
}
return false;
}
static void Time() {
DateTime now = clock.now();
int hour = now.hour();
int min= now.minute();
int sec = now.second();
if( hour < 10) {
display.print("0");
}
display.print(hour);
display.print(":");
if(min<10){
display.print("0");
}
display.print(min);
display.print(":");
if(sec < 10) {
display.print("0");
}
display.print(sec);
}
//Clock Function
void Clock() {
display.clearDisplay();
display.setTextColor(WHITE);
display.setTextSize(1);
display.setCursor(0,0);
display.println("Clock");
display.setTextSize(2);
display.setCursor(0,20);
Time();
display.setTextSize(1);
display.setCursor(0,56);
display.println("PREV: Menu");
display.display();
if(buttonHelper(PREV)){
counter = 0;
delay(150);
}
}