#include <SPI.h>
#include <U8g2lib.h> //OLED
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>//TFT
#include <Fonts/FreeMono12pt7b.h>
#include <ESP32Servo.h> //servo motor libary
#include "bitmaps.h" //include bitmaps tab
//Focus Encoder
#define CLK 25
#define DT 26
#define SW 14
//break Encoder
#define SWb 27
#define DTb 33
#define CLKb 32
//TFT Screen
#define TFT_CS 5
#define TFT_DC 2
#define TFT_SCK 18
#define TFT_SDA 23
#define TFT_RST 4
Adafruit_ST7735 tft = Adafruit_ST7735(&SPI1, TFT_CS, TFT_DC, TFT_RST);
unsigned long previousFrame = 0; //how long since the last animation frame was drawn
const unsigned long frameInterval = 500; //how long to wait between frames (500ms)
bool breakFrame = false; //which frame shld be displayed: false = 1, true = 2
//working OLED
U8G2_SSD1306_128X64_NONAME_1_SW_I2C oled (
0, // rotation
22, // clk
21); // sda
Servo myservo;
const int Spos = 180; //open postion
const int Epos = 90; //closed position
int pos = 0; //starting postion is open (1 is closed)
const int button = 2;
int lastCLK;
int lastCLKb;
int testcount = 1;
//Variables for focus timer
int seconds = 0;
int minutes = 1;
int hours = 0;
int loops = 2;
int horm = 1; //1 = minutes, 0 = hours, 2 = loops
//variables for break timer
int second = 10;
int minute = 0;
int repeats = 2;
int mors = 0; //0 = seconds, 1 = minutes, 2 = repeats
//states in my timer routine
enum TimerState {
SETUP,
FOCUS, //focus session on
BREAK, //taking a break
FINISHED //both timers have reached 0 time and repeats
};
TimerState timerState = SETUP;
//save timer durations in seconds (easier for counting down)
long focusStartSeconds = 0;
long breakStartSeconds = 0;
//number of sessions remaining
int focusRemaining = 0;
int breakRemaining = 0;
//timer counting varaibles
unsigned long previousSecond = 0;
const unsigned long secondInterval = 1000; //1000 miliseconds = 1 second
void drawBox() {
oled.setFont(u8g2_font_profont29_mn);
int width = oled.getStrWidth("00");
int width2 = oled.getStrWidth("00");
int semiW = oled.getStrWidth(":");
oled.setFont(u8g2_font_profont17_mn);
int ww = oled.getStrWidth("h");
int wid = width2 + semiW + ww;
int xpos[] = { 0, wid + 6 };
int widthadd[] = { 2, 5 };
if (horm == 2) {
oled.setFont(u8g2_font_profont22_mn);
int w = oled.getStrWidth("0");
oled.drawFrame(111, 42, (w + 4), 22);
} else {
oled.drawFrame(xpos[horm], 13, (width + widthadd[horm]), 29);
}
}
void drawBoxb() {
oled2.setFont(u8g2_font_profont29_mn);
int width = oled2.getStrWidth("00");
int width2 = oled2.getStrWidth("00");
int semiW = oled2.getStrWidth(":");
oled2.setFont(u8g2_font_profont17_mn);
int ww = oled2.getStrWidth("h");
int wid = width2 + semiW + ww;
int xpos[] = { 0, wid + 6 };
int widthadd[] = { 2, 5 };
if (horm == 2) {
oled2.setFont(u8g2_font_profont22_mn);
int w = oled2.getStrWidth("0");
oled2.drawFrame(111, 42, (w + 4), 22);
} else {
oled2.drawFrame(xpos[horm], 13, (width + widthadd[horm]), 29);
}
}
void drawClock() { //print our timer
oled.clearBuffer();
oled.setFont(u8g2_font_profont29_mn);
oled.setCursor(2, 38);
if (hours < 10) {
oled.print("0");
}
oled.print(hours);
oled.setFont(u8g2_font_profont17_mf);
oled.print("h");
oled.setFont(u8g2_font_profont29_mn);
oled.print(":");
if (minutes < 10) {
oled.print("0");
}
oled.print(minutes);
oled.setFont(u8g2_font_profont17_mf);
oled.print("m");
oled.setFont(u8g2_font_profont22_mn);
if (seconds < 10) {
oled.print("0");
}
oled.print(seconds);
oled.setCursor(114, 60);
if (timerState == SETUP) {
oled.print(loops);
} else {
oled.print(focusRemaining);
}
if (timerState == SETUP) {
drawBox();
}
oled.sendBuffer();
}
void drawBtimer() {
if (minute < 10) {
Serial.print("0");
}
Serial.print(minute);
Serial.print("m:");
if (second < 10) {
Serial.print("0");
}
Serial.print(second);
Serial.print("s ");
Serial.print("repeats = ");
if (timerState == SETUP) {
Serial.println(repeats);
} else {
Serial.println(breakRemaining);
}
}
//for the not working OLED
void drawBclock() {
oled2.clearBuffer();
oled2.setFont(u8g2_font_profont29_mn);
oled2.setCursor(2, 38);
if (minute < 10) {
oled2.print("0");
}
oled2.print(minute);
oled2.setFont(u8g2_font_profont17_mf);
oled2.print("m");
oled2.setFont(u8g2_font_profont29_mn);
oled2.print(":");
if (second < 10) {
oled2.print("0");
}
oled2.print(second);
oled2.setFont(u8g2_font_profont17_mf);
oled2.print("s");
oled2.setFont(u8g2_font_profont22_mn);
oled2.setCursor(114, 60);
oled2.print(repeats);
drawBoxb();
oled2.sendBuffer();
}
long getFocusDuration() { //convert the inputed time into seconds
return (long)hours * 3600L + (long)minutes * 60L;
}
long getBreakDuration() { //convert inputed variables into secodns
return (long)minute * 60L + second;
}
//convert total number of seconds into focus hours, minutes and seconds
void loadFocusTime(long total) {
hours = total / 3600;
minutes = (total % 3600) / 60;
seconds = total % 60;
}
//convert total number of seconds into break minutes and seconds
void loadBreakTime(long total) {
minute = total / 60;
second = total % 60;
}
void startFocus() { //start our focus timer
tft.drawRGBBitmap(0, 0, home, 160, 128);
loadFocusTime(focusStartSeconds);
timerState = FOCUS;
previousSecond = millis();
tft.drawRGBBitmap(0, 0, eat, 160, 128);
drawClock();
}
void startBreak() {
loadBreakTime(breakStartSeconds);
timerState = BREAK;
previousSecond = millis();
tft.drawRGBBitmap(0, 0, tip, 160, 128);
drawBtimer();
}
void finishTimer() {
timerState = SETUP;
myservo.write(Spos);
pos = 0;
tft.drawRGBBitmap(0, 0, home, 160, 128);
drawClock();
drawBtimer();
}
void startTimer() {
// Save the settings before the countdown changes them
focusStartSeconds = getFocusDuration();
breakStartSeconds = getBreakDuration();
focusRemaining = loops;
breakRemaining = repeats;
myservo.write(Epos);
pos = 1;
// Start whichever type of session remains
if (focusRemaining > 0) {
startFocus();
} else if (breakRemaining > 0) {
startBreak();
} else {
finishTimer();
}
}
void updateTimer() {
//do nothing while setting up or after finishing
if (timerState != FOCUS && timerState != BREAK) {
return;
}
unsigned long now = millis();
//Has one second passed
if (now - previousSecond < secondInterval) {
return;
}
previousSecond += secondInterval;
if (timerState == FOCUS) {
// Count down the focus timer
if (seconds > 0) {
seconds--;
} else if (minutes > 0) {
minutes--;
seconds = 59;
} else if (hours > 0) {
hours--;
minutes = 59;
seconds = 59;
}
drawClock();
//has the focus timer reached zero?
if (hours == 0 && minutes == 0 && seconds == 0) {
focusRemaining--;
// Use a break if one remains
if (breakRemaining > 0) {
startBreak();
}
//Otherwise continue with another focus session
else if (focusRemaining > 0) {
startFocus();
} else { //or finsish if everything is done
finishTimer();
}
}
}
else if (timerState == BREAK) {
// Count down the break timer
if (second > 0) {
second--;
} else if (minute > 0) {
minute--;
second = 59;
}
drawBtimer();
// Has the break timer reached zero?
if (minute == 0 && second == 0) {
breakRemaining--;
// Return to focus if one remains
if (focusRemaining > 0) {
startFocus();
}
// Otherwise finish any remaining breaks
else if (breakRemaining > 0) {
startBreak();
} else {
finishTimer();
}
}
}
}
void setup() {
Serial.begin(115200);
oled.begin();
//set up TFT SPI communication
SPI1.setSCK(TFT_SCK);
SPI1.setTX(TFT_SDA);
SPI1.begin();
pinMode(CLK, INPUT_PULLUP);
pinMode(DT, INPUT_PULLUP);
pinMode(SW, INPUT_PULLUP);
pinMode(CLKb, INPUT_PULLUP);
pinMode(DTb, INPUT_PULLUP);
pinMode(SWb, INPUT_PULLUP);
pinMode(button, INPUT_PULLUP);
lastCLK = digitalRead(CLK);
lastCLKb = digitalRead(CLKb);
drawClock();
tft.initR(INITR_BLACKTAB);
tft.setRotation(1);
tft.fillScreen(ST7735_BLACK);
tft.drawRGBBitmap(0, 0, home, 160, 128);
myservo.attach(3);
myservo.write(Spos);
}
void loop() {
int currentCLK = digitalRead(CLK);
int currentCLKb = digitalRead(CLKb);
if (timerState == SETUP && currentCLK != lastCLK) {
if (digitalRead(DT) != currentCLK) {
if (horm == 1) {
if (minutes < 60) {
minutes++;
}
if (minutes >= 60) {
minutes = 0;
}
}
if (horm == 0) {
if (hours < 12) {
hours++;
}
if (hours == 12) {
hours = 0;
}
}
if (horm == 2) {
if (loops < 9) {
loops++;
}
if (loops == 9) {
loops = 0;
}
}
} else {
if (horm == 1) {
if (minutes > 0) {
minutes--;
}
if (minutes <= 0) {
minutes = 59;
}
}
if (horm == 0) {
if (hours > 0) {
hours--;
}
if (hours <= 0) {
hours = 12;
}
}
if (horm == 2) {
if (loops > 0) {
loops--;
}
if (loops <= 0) {
loops = 9;
}
}
}
drawClock();
}
lastCLK = currentCLK;
if (timerState == SETUP && digitalRead(SW) == LOW) {
delay(200);
if (horm == 1) {
horm = 0;
} else if (horm == 0) {
horm = 2;
} else if (horm == 2) {
horm = 1;
}
drawClock();
}
if (timerState == SETUP && currentCLKb != lastCLKb) {
if (digitalRead(DTb) != currentCLKb) {
// Increase selected value
if (mors == 0) {
second++;
if (second >= 60) {
second = 0;
}
}
if (mors == 1) {
minute++;
if (minute >= 60) {
minute = 0;
}
}
if (mors == 2) {
repeats++;
if (repeats >= 8) {
repeats = 0;
}
}
} else {
// Decrease selected value
if (mors == 0) {
second--;
if (second < 0) {
second = 59;
}
}
if (mors == 1) {
minute--;
if (minute < 0) {
minute = 59;
}
}
if (mors == 2) {
repeats--;
if (repeats < 0) {
repeats = 7;
}
}
}
// Print the updated break timer
drawBtimer();
}
lastCLKb = currentCLKb;
if (timerState == SETUP && digitalRead(SWb) == LOW) {
delay(200);
if (mors == 0) {
mors = 1;
} else if (mors == 1) {
mors = 2;
} else if (mors == 2) {
mors = 0;
}
Serial.print("mors =");
Serial.println(mors);
}
if (digitalRead(button) == LOW) {
delay(200);
if (timerState == SETUP || timerState == FINISHED) {
startTimer();
}
while (digitalRead(button) == LOW) {
delay(10);
}
}
updateTimer();
}
Loading
esp32-devkit-c-v4
esp32-devkit-c-v4
Loading
ssd1306
ssd1306
Focus
Break