#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EasyButton.h>
#include <EEPROM.h>
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
#define BUTTON_UP_PIN 32
#define BUTTON_DOWN_PIN 33
#define BUTTON_STAR_PIN 25
#define BUTTON_HASH_PIN 26
EasyButton button_up(BUTTON_UP_PIN);
EasyButton button_down(BUTTON_DOWN_PIN);
EasyButton button_star(BUTTON_STAR_PIN);
EasyButton button_hash(BUTTON_HASH_PIN);
const int TOTAL_MENU = 4;
int current_menu = 1;
bool in_menu = false;
unsigned long last_button_press = 0;
int open_time = 10;
int open_unit = 1;
int close_time = 30;
int close_unit = 1;
bool start_with = false;
bool lock_work = true;
String get_unit(int unit) {
switch(unit){
case 0: return "SEC";
case 1: return "MIN";
case 2: return "HR";
default: return "";
}
}
void display_main_screen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 0);
display.print("ON : ");
display.print(open_time);
display.print(" ");
display.print(get_unit(open_unit));
display.setCursor(0, 12);
display.print("OFF : ");
display.print(close_time);
display.print(" ");
display.print(get_unit(close_unit));
display.display();
}
void display_menu() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
for(int i=1; i<=TOTAL_MENU; i++){
display.setCursor(0, (i-1)*12);
if(in_menu && i == current_menu){
display.print("> ");
}
else{
display.print(" ");
}
switch(i){
case 1:
display.print("1. ON ");
display.print(open_time);
display.print(" ");
display.print(get_unit(open_unit));
break;
case 2:
display.print("2. OFF ");
display.print(close_time);
display.print(" ");
display.print(get_unit(close_unit));
break;
case 3:
display.print("3. START ");
display.print(start_with ? "ON" : "OFF");
break;
case 4:
display.print("4. LOCK ");
display.print(lock_work ? "YES" : "NO");
break;
}
}
display.display();
}
void setup() {
Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
display.clearDisplay();
EEPROM.begin(512);
open_time = (EEPROM.read(0) | (EEPROM.read(1) << 8)) <= 999 ? (EEPROM.read(0) | (EEPROM.read(1) << 8)) : 10;
close_time = (EEPROM.read(2) | (EEPROM.read(3) << 8)) <= 999 ? (EEPROM.read(2) | (EEPROM.read(3) << 8)) : 30;
start_with = EEPROM.read(4) <= 1 ? (bool)EEPROM.read(4) : false;
lock_work = EEPROM.read(5) <= 1 ? (bool)EEPROM.read(5) : true;
open_unit = (EEPROM.read(6) >= 0 && EEPROM.read(6) <= 2) ? EEPROM.read(6) : 1;
close_unit = (EEPROM.read(7) >= 0 && EEPROM.read(7) <= 2) ? EEPROM.read(7) : 1;
display_main_screen();
pinMode(BUTTON_UP_PIN, INPUT_PULLUP);
pinMode(BUTTON_DOWN_PIN, INPUT_PULLUP);
pinMode(BUTTON_STAR_PIN, INPUT_PULLUP);
pinMode(BUTTON_HASH_PIN, INPUT_PULLUP);
button_up.begin();
button_down.begin();
button_star.begin();
button_hash.begin();
button_down.onPressed(handle_menu_navigation_down);
button_up.onPressed(handle_menu_toggle);
button_star.onPressed(handle_star_press);
button_hash.onPressed([](){
handle_hash_press_short();
});
button_hash.onPressedFor(1000, [](){
handle_hash_press_long();
});
}
void loop() {
button_up.read();
button_down.read();
button_star.read();
button_hash.read();
}
void handle_menu_navigation_down() {
Serial.println("Button Down Pressed");
if(!in_menu){
in_menu = true;
current_menu = 1;
}
else{
current_menu++;
if(current_menu > TOTAL_MENU) current_menu = 1;
}
display_menu();
last_button_press = millis();
}
void handle_menu_toggle() {
Serial.println("Button Up Pressed");
if(in_menu){
in_menu = false;
display_main_screen();
Serial.println("Switched to Main Screen");
save_settings();
}
else{
in_menu = true;
current_menu = 1;
display_menu();
Serial.println("Switched to Menu");
}
last_button_press = millis();
}
void handle_star_press() {
if(!in_menu) return;
switch(current_menu){
case 1:
case 2:
if(current_menu == 1){
open_unit = (open_unit + 1) % 3;
}
else{
close_unit = (close_unit + 1) % 3;
}
break;
case 3:
start_with = !start_with;
break;
case 4:
lock_work = !lock_work;
break;
}
display_menu();
last_button_press = millis();
}
void handle_hash_press_short() {
if(!in_menu) return;
switch(current_menu){
case 1:
open_time += 1;
if(open_time > 999) open_time = 0;
break;
case 2:
close_time += 1;
if(close_time > 999) close_time = 0;
break;
}
display_menu();
last_button_press = millis();
}
void handle_hash_press_long() {
if(!in_menu) return;
switch(current_menu){
case 1:
open_time = 0;
break;
case 2:
close_time = 0;
break;
}
display_menu();
last_button_press = millis();
}
void save_settings() {
bool need_save = false;
if(EEPROM.read(0) != (open_time & 0xFF) || EEPROM.read(1) != ((open_time >> 8) & 0xFF)){
EEPROM.write(0, open_time & 0xFF);
EEPROM.write(1, (open_time >> 8) & 0xFF);
need_save = true;
}
if(EEPROM.read(2) != (close_time & 0xFF) || EEPROM.read(3) != ((close_time >> 8) & 0xFF)){
EEPROM.write(2, close_time & 0xFF);
EEPROM.write(3, (close_time >> 8) & 0xFF);
need_save = true;
}
if(EEPROM.read(4) != (start_with ? 1 : 0)){
EEPROM.write(4, start_with ? 1 : 0);
need_save = true;
}
if(EEPROM.read(5) != (lock_work ? 1 : 0)){
EEPROM.write(5, lock_work ? 1 : 0);
need_save = true;
}
if(EEPROM.read(6) != open_unit){
EEPROM.write(6, open_unit);
need_save = true;
}
if(EEPROM.read(7) != close_unit){
EEPROM.write(7, close_unit);
need_save = true;
}
if(need_save){
EEPROM.commit();
Serial.println("Settings saved to EEPROM");
}
else{
Serial.println("No changes detected, EEPROM not written");
}
}