/*
Millis() clock with timed event intervals.
Version 1/25/25
Set all values in seconds.
- Set event duration time, max is 999
- Set event repeat time, max is 9999, 3600 = 1 hour
Replace led with DC motor. Have motor run a small animation.
Make a 'peanut' man and have him sawing wood.
*/
#include <TinyWireM.h>
#include <Tiny4kOLED.h>
#define led PB3
#define navButton PB1 // Navigation/Increment button
#define selButton PB4 // Confirm/Select button
const uint8_t width = 128;
const uint8_t height = 64;
// Time variables
uint8_t second, minute, hour;
int eventCountdown = 0; // Time to next event countdown
int eventDurationCount = 0; // Event duration countdown
int eventDuration = 0; // User-adjustable
int eventRepeatInterval = 0; // User-adjustable
int navButtonRead;
int selButtonRead;
uint8_t oldNavButtonRead = 0;
uint8_t oldSelButtonRead = 0;
const uint8_t debounceTime = 10;
int menuState = 0; // 0: Viewing eventDuration, 1: Editing eventDuration, 2: Viewing eventRepeatInterval, 3: Editing eventRepeatInterval
void setup() {
pinMode(navButton, INPUT_PULLUP);
pinMode(selButton, INPUT_PULLUP);
pinMode(led, OUTPUT);
oled.begin(width, height, sizeof(tiny4koled_init_128x64br), tiny4koled_init_128x64br);
oled.setInternalIref(true); // Provides brighter display using internal voltage reference
oled.setFont(FONT8X16);
oled.clear(); // Clear the memory before turning on the display
oled.on(); // Turn on the display
digitalWrite(led, LOW);
}
// - - - - - START FUNCTIONS - - - - -
void displayTime() {
oled.setCursor(0, 0);
oled.print("Time");
oled.setCursor(63, 0);
if (hour < 10) oled.print("0");
oled.print(hour); oled.print(":");
if (minute < 10) oled.print("0");
oled.print(minute); oled.print(":");
if (second < 10) oled.print("0");
oled.print(second);
}
void displayEventCountdown() {
oled.setCursor(0, 2);
oled.print("Next Event");
oled.setCursor(95, 2);
if (eventCountdown < 10) oled.print("000");
else if (eventCountdown < 100) oled.print("00");
else if (eventCountdown < 1000) oled.print("0");
oled.print(eventCountdown);
}
void displayEventDuration() {
oled.setCursor(0, 4);
oled.print("Event On");
oled.setCursor(103, 4);
if (eventDurationCount < 10) oled.print("00");
else if (eventDurationCount < 100) oled.print("0");
oled.print(eventDurationCount);
}
void displayMenu() {
if (menuState == 0 || menuState == 1) {
oled.setCursor(0, 6);
oled.print("Duration:");
oled.setCursor(95, 6);
if (eventDuration < 10) oled.print("000");
else if (eventDuration < 100) oled.print("00");
else if (eventDuration < 1000) oled.print("0");
oled.print(eventDuration);
if (menuState == 1) {
oled.setCursor(80, 6);
oled.print("*"); // Editing indicator
oled.clear();
}
}
else if (menuState == 2 || menuState == 3) {
oled.setCursor(0, 6);
oled.print("Interval:");
oled.setCursor(95, 6);
if (eventRepeatInterval < 10) oled.print("000");
else if (eventRepeatInterval < 100) oled.print("00");
else if (eventRepeatInterval < 1000) oled.print("0");
oled.print(eventRepeatInterval);
if (menuState == 3) {
oled.setCursor(80, 6);
oled.print("*"); // Editing indicator
oled.clear();
}
}
}
void handleNavButton() {
navButtonRead = digitalRead(navButton); // reads 1 with pull-up
if (navButtonRead != oldNavButtonRead) { // debounce routine
oldNavButtonRead = navButtonRead;
delay (debounceTime);
if (navButtonRead == LOW) {
if (menuState % 2 == 0) {
menuState = (menuState + 2) % 4; // Cycle between viewing options
} else {
if (menuState == 1) eventDuration += 10; // Increment during editing, 10 sec
if (menuState == 3) eventRepeatInterval += 60; // Increment during editing, 60 sec
}
}
}
}
void handleSelButton() {
selButtonRead = digitalRead(selButton); // reads 1 with pull-up
if (selButtonRead != oldSelButtonRead) { // debounce routine
oldSelButtonRead = selButtonRead;
delay (debounceTime);
if (selButtonRead == LOW) {
if (menuState % 2 == 0) {
menuState++; // Enter edit mode
} else {
menuState--; // Exit edit mode
}
}
}
}
// - - - - - END FUNCTIONS - - - - -
void loop() {
handleNavButton();
handleSelButton();
displayMenu();
unsigned long currentMillis = millis();
unsigned long elapsedSeconds = currentMillis / 1000;
// Convert current time to hours, minutes, and seconds
hour = (elapsedSeconds / 3600) % 12; // 12-hour format
minute = (elapsedSeconds / 60) % 60;
second = elapsedSeconds % 60;
// Calculate time to the next event
eventCountdown = (eventRepeatInterval - (elapsedSeconds % eventRepeatInterval)) % eventRepeatInterval;
// Check if the current second is within the event duration
if ((elapsedSeconds % eventRepeatInterval) >= 0 &&
(elapsedSeconds % eventRepeatInterval) < (eventDuration)) {
eventDurationCount = eventDuration - (elapsedSeconds % eventRepeatInterval);
digitalWrite(led, HIGH);
} else {
eventDurationCount = 0;
digitalWrite(led, LOW);
}
displayTime();
displayEventCountdown();
displayEventDuration();
delay(10);
}
Nav
Select