#include <TM1637Display.h>
#include <RotaryEncoder.h>
// Definisci i pin per il display TM1637
const int CLK_PIN = 2;
const int DIO_PIN = 4;
TM1637Display display(CLK_PIN, DIO_PIN);
// Definisci i pin per il rotary encoder KY-040
const int ENCODER_A_PIN = 19;
const int ENCODER_B_PIN = 18;
const int ENCODER_SW_PIN = 5;
RotaryEncoder encoder(ENCODER_A_PIN, ENCODER_B_PIN); // Rimozione di HALF_STEP
// Variabili per il timer
volatile int minutes = 0;
volatile bool timerRunning = false;
unsigned long startTime;
// Funzione per aggiornare il display con il tempo
void updateDisplay() {
if (timerRunning) {
unsigned long elapsedTime = millis() - startTime;
long remainingSeconds = (minutes * 60) - (elapsedTime / 1000);
if (remainingSeconds < 0) {
remainingSeconds = 0;
timerRunning = false;
// Qui potresti aggiungere un suono o un'altra indicazione di fine timer
}
int displayMinutes = remainingSeconds / 60;
int displaySeconds = remainingSeconds % 60;
// Mostra MM:SS
display.showNumberDecEx(displayMinutes * 100 + displaySeconds, (displaySeconds % 2 == 0) ? 0b01000000 : 0, true);
} else {
display.showNumberDec(minutes, false); // Mostra solo i minuti quando il timer è fermo
}
}
// Gestore dell'interrupt per il rotary encoder (cambiamenti di stato)
void IRAM_ATTR encoderISR() {
encoder.tick();
}
// Gestore dell'interrupt per il pulsante del rotary encoder
void IRAM_ATTR encoderButtonISR() {
static unsigned long lastInterruptTime = 0;
unsigned long interruptTime = millis();
// Debouncing del pulsante (ignora le pressioni troppo ravvicinate)
if (interruptTime - lastInterruptTime > 200) {
if (!timerRunning && minutes > 0) {
timerRunning = true;
startTime = millis();
} else if (timerRunning) {
timerRunning = false; // Pausa/reset del timer
}
}
lastInterruptTime = interruptTime;
}
void setup() {
Serial.begin(115200);
// Inizializza il display
display.setBrightness(7); // Imposta la luminosità (0-7)
display.showNumberDec(0); // Usa showNumberDec
// Inizializza il rotary encoder
pinMode(ENCODER_SW_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), encoderISR, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), encoderISR, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_SW_PIN), encoderButtonISR, FALLING);
encoder.setPosition(minutes); // Inizializza la posizione con i minuti
}
void loop() {
// Leggi la rotazione dell'encoder
encoder.tick();
int newPosition = encoder.getPosition(); // Leggi direttamente la posizione
if (newPosition != minutes) {
minutes = newPosition;
if (minutes < 0) {
minutes = 0;
encoder.setPosition(0);
}
updateDisplay();
}
// Aggiorna il display
updateDisplay();
delay(100);
}