#include "FastLED.h"
#include "Wire.h"
#include "Adafruit_GFX.h"
#include "Adafruit_SSD1306.h"
#include "Encoder.h"
#include "Bounce2.h"
#define LED_STRIP1_PIN 6
#define LED_STRIP2_PIN 8
#define LED_STRIP3_PIN 9
#define OLED_RESET 7
Adafruit_SSD1306 display(OLED_RESET);
#define ROTARY_ENCODER_PIN_A 2
#define ROTARY_ENCODER_PIN_B 3
#define BUTTON_PIN 12
Encoder myEncoder(ROTARY_ENCODER_PIN_A, ROTARY_ENCODER_PIN_B);
Bounce button = Bounce();
long lastEncoderValue;
unsigned long timerSettings[3] = {0, 0, 0};
unsigned long timerStartTimes[3] = {0, 0, 0};
bool timerActive[3] = {false, false, false};
int selectedTimer = 0;
unsigned long buttonPressTime = 0;
unsigned long lastDisplayUpdate;
#define NUM_LEDS 8
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds1[NUM_LEDS];
CRGB leds2[NUM_LEDS];
CRGB leds3[NUM_LEDS];
void setup() {
pinMode(LED_STRIP1_PIN, OUTPUT);
pinMode(LED_STRIP2_PIN, OUTPUT);
pinMode(LED_STRIP3_PIN, OUTPUT);
display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
button.attach(BUTTON_PIN, INPUT_PULLUP);
button.interval(5);
lastEncoderValue = myEncoder.read();
lastDisplayUpdate = 0;
FastLED.addLeds<LED_TYPE, LED_STRIP1_PIN, COLOR_ORDER>(leds1, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, LED_STRIP2_PIN, COLOR_ORDER>(leds2, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.addLeds<LED_TYPE, LED_STRIP3_PIN, COLOR_ORDER>(leds3, NUM_LEDS).setCorrection(TypicalLEDStrip);
}
void loop() {
button.update();
long encoderValue = myEncoder.read();
if (button.fell()) {
buttonPressTime = millis(); // Store the time when the button was pressed
} else if (button.rose()) {
if (millis() - buttonPressTime >= 1000) {
resetTimers(); // Reset timers if button press duration was >= 1000 ms
} else {
updateTimerSettings(selectedTimer, encoderValue - lastEncoderValue);
selectedTimer = (selectedTimer + 1) % 3; // Change the timer selection on short button press
}
}
if (encoderValue != lastEncoderValue) {
lastEncoderValue = encoderValue;
}
updateLEDs();
if (millis() - lastDisplayUpdate >= 500) {
updateDisplay();
lastDisplayUpdate = millis();
}
}
void resetTimers() {
for (int i = 0; i < 3; i++) {
timerSettings[i] = 0;
timerActive[i] = false;
}
fill_solid(leds1, NUM_LEDS, CRGB::Black);
fill_solid(leds2, NUM_LEDS, CRGB::Black);
fill_solid(leds3, NUM_LEDS, CRGB::Black);
FastLED.show();
}
void updateTimerSettings(int timer, long encoderChange) {
timerSettings[timer] += encoderChange * 1000;
if (timerSettings[timer] < 0) {
timerSettings[timer] = 0;
}
timerActive[timer] = true;
timerStartTimes[timer] = millis();
}
void updateLEDs() {
for (int i = 0; i < 3; i++) {
if (timerActive[i]) {
unsigned long elapsedTime = millis() - timerStartTimes[i];
if (elapsedTime >= timerSettings[i]) {
if (i == 0) {
fill_solid(leds1, NUM_LEDS, CRGB::Black);
} else if (i == 1) {
fill_solid(leds2, NUM_LEDS, CRGB::Black);
} else {
fill_solid(leds3, NUM_LEDS, CRGB::Black);
}
FastLED.show();
timerActive[i] = false;
} else {
if (i == 0) {
fill_solid(leds1, NUM_LEDS, CRGB::Red);
} else if (i == 1) {
fill_solid(leds2, NUM_LEDS, CRGB::Green);
} else {
fill_solid(leds3, NUM_LEDS, CRGB::Blue);
}
FastLED.show();
}
}
}
}
void updateDisplay() {
display.clearDisplay();
for (int i = 0; i < 3; i++) {
display.setCursor(0, i * 8);
if (timerActive[i]) {
int percentage = 100 - ((millis() - timerStartTimes[i]) * 100 / timerSettings[i]);
display.print("Timer ");
display.print(i + 1);
display.print(": ");
display.print(percentage);
display.print("%");
} else {
display.print("Timer ");
display.print(i + 1);
display.print(": --");
}
if (i == selectedTimer) {
display.fillRect(0, i * 8, 128, 2, WHITE); // Draw a line on top of the selected timer to indicate it's selected
}
}
display.display();
}