#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <FastLED.h>
#define btn_left 2
#define btn_middle 3
#define btn_right 4
#define LED_PIN 5
#define LED_TYPE WS2812
#define COLOUR_ORDER GRB
#define NUM_LEDS 38
CRGB leds[NUM_LEDS];
#define BRIGHTNESS 255
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define SCREEN_ADDRESS 0x3C ///< See datasheet for Address; 0x3D for 128x64, 0x3C for 128x32
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
unsigned int timer_preset1 = 30; //timer preset 1 length in seconds
unsigned int timer_preset2 = 60; //timer preset 2 length in seconds
unsigned int timer_length; //length of current timer in seconds
unsigned int timer_colour = 0x33D7FF;
unsigned int timer_value;
unsigned long previous_millis; // milliseconds for timer
bool timer_running = false; //flag if the timer is running
unsigned int hue = 0;
unsigned long previous_millis2; // milliseconds for rainbow
int completed_tasks = 0;
int total_tasks = 8;
unsigned long previous_millis3; // milliseconds for tasks
bool btn_left_clicked = false;
bool btn_middle_clicked = false;
bool btn_right_clicked = false;
void setup() {
Serial.begin(9600);
pinMode(btn_left, INPUT_PULLUP);
pinMode(btn_middle, INPUT_PULLUP);
pinMode(btn_right, INPUT_PULLUP);
FastLED.addLeds<LED_TYPE, LED_PIN, GRB>(leds, NUM_LEDS);
FastLED.setMaxPowerInVoltsAndMilliamps(5,500);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
FastLED.show();
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;); // Don't proceed, loop forever
}
previous_millis3 = millis();
}
void loop() {
timer();
updateLED();
updateScreen();
// LEFT BUTTON
if ((digitalRead(btn_left) == LOW) && (btn_left_clicked == false)){
btn_left_clicked = true;
timer_running = false;
completed_tasks = 0;
previous_millis3 = millis();
}
// MIDDLE BUTTON
if ((digitalRead(btn_middle) == LOW) && (btn_middle_clicked == false)){
btn_middle_clicked = true;
timer_length = timer_preset1;
timer_value = timer_length;
previous_millis = millis();
timer_running = true;
}
// RIGHT BUTTON
if ((digitalRead(btn_right) == LOW) && (btn_right_clicked == false)){
btn_right_clicked = true;
timer_length = timer_preset2;
timer_value = timer_length;
previous_millis = millis();
timer_running = true;
}
// Stops multiple button presses
if ((digitalRead(btn_left) == HIGH) && (btn_left_clicked == true)){
btn_left_clicked = false;
}
if ((digitalRead(btn_middle) == HIGH) && (btn_middle_clicked == true)){
btn_middle_clicked = false;
}
if ((digitalRead(btn_right) == HIGH) && (btn_right_clicked == true)){
btn_right_clicked = false;
}
}
void print_Time(int total_seconds){ // prints the current timer value to the screen
int totalMinutes = int(total_seconds / 60);
int seconds = total_seconds % 60;
int hours = int(totalMinutes / 60);
int minutes = totalMinutes % 60;
display.setCursor(10, 20);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(2);
print2digits(hours);
display.print(":");
print2digits(minutes);
display.print(":");
print2digits(seconds);
}
void print2digits(int number){ // adds a trailing zero if the number is one digit
if (number < 10){
display.print("0");
}
display.print(number);
}
void timer(){ // updates the timer and the completed tasks timer
if (((millis() - previous_millis) >= 1000) && (timer_running == true)){ // updates timer every second if there is a timer active
timer_value = timer_value - 1;
previous_millis = millis();
}
if ((timer_value <= 0) && (timer_running == true)){ // stops timer when it reaches zero
timer_running = false;
}
if (((millis() - previous_millis3) >= 2000) && (completed_tasks < total_tasks)){ // increments completed tasks every 2 seconds
completed_tasks += 1;
previous_millis3 = millis();
}
}
void updateScreen(){ // updates the OLED display
display.clearDisplay();
if (timer_running == false){
display.setCursor(30,10);
display.setTextColor(SSD1306_WHITE);
display.setTextSize(4);
display.print(completed_tasks);
display.print("/");
display.println(total_tasks);
display.setCursor(18,50);
display.setTextSize(1);
display.println("tasks completed");
}
else {
print_Time(timer_value);
}
display.display();
}
void updateLED(){ // updates the LED lightstrip
FastLED.clear();
if (timer_running == true){ // timer LED sequence
if (timer_value == 1){
for (int i=0; i<NUM_LEDS; i++){
leds[i] = timer_colour;
}
}
else if (timer_value <= 0.2*timer_length){
for (int i=0; i<28; i++){
leds[i] = timer_colour;
}
}
else if (timer_value <= 0.4*timer_length){
for (int i=0; i<21; i++){
leds[i] = timer_colour;
}
}
else if (timer_value <= 0.6*timer_length){
for (int i=0; i<14; i++){
leds[i] = timer_colour;
}
}
else if (timer_value <= 0.8*timer_length){
for (int i=0; i<7; i++){
leds[i] = timer_colour;
}
}
}
else if (completed_tasks == total_tasks) { // rainbow sequence when all tasks completed
if ((millis() - previous_millis2) >= 10){
previous_millis2 = millis();
hue += 1;
if (hue >= 255){
hue = 0;
}
}
for (int i=0; i<NUM_LEDS; i++){
leds[i].setHue(hue);
}
}
else { // task gradient sequence
switch (completed_tasks) {
case 0:
hue = 0;
break;
case 1:
hue = 12;
break;
case 2:
hue = 24;
break;
case 3:
hue = 36;
break;
case 4:
hue = 48;
break;
case 5:
hue = 60;
break;
case 6:
hue = 72;
break;
case 7:
hue = 84;
break;
}
for (int i=0; i<NUM_LEDS; i++){
leds[i].setHue(hue);
}
}
FastLED.show();
}