#include <Wire.h> // Libreria per la comunicazione I2C
#include <Adafruit_GFX.h> // Libreria grafica per il display OLED
#include <Adafruit_SSD1306.h> // Libreria per il display OLED
// Impostazioni del display OLED
#define SCREEN_WIDTH 128 // Larghezza del display OLED
#define SCREEN_HEIGHT 64 // Altezza del display OLED
#define OLED_RESET -1 // Non usiamo il pin di reset
#define SCREEN_ADDRESS 0x3C // Indirizzo I2C del display (comune per SSD1306)
// Creazione dell'oggetto display
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// Definizione dei pin per i tasti
const int buttonPin1 = 2; // Pin per il tasto del Gruppo 1
const int buttonPin2 = 3; // Pin per il tasto del Gruppo 2
// Variabili per gestire lo stato dei tasti
int buttonState1 = 0;
int lastButtonState1 = 0;
unsigned long pressStartTime1 = 0;
unsigned long pressDuration1 = 0;
int buttonState2 = 0;
int lastButtonState2 = 0;
unsigned long pressStartTime2 = 0;
unsigned long pressDuration2 = 0;
// Variabili per gestire il tempo di visualizzazione del risultato
unsigned long displayTime1 = 0; // Tempo in cui il Gruppo 1 è stato rilasciato
unsigned long displayTime2 = 0; // Tempo in cui il Gruppo 2 è stato rilasciato
const unsigned long displayDuration = 60000; // Tempo di visualizzazione (in millisecondi) - 60 secondi
// Variabile per gestire il tempo di inattività e lo screensaver
unsigned long lastActivityTime = 0; // Ultima attività (premere un tasto o cambiare display)
const unsigned long inactiveTimeout = 30000; // Timeout di inattività (in millisecondi) - 30 secondi per attivare lo screensaver
void setup() {
// Inizializza la comunicazione seriale
Serial.begin(9600);
// Imposta i pin dei tasti come input
pinMode(buttonPin1, INPUT);
pinMode(buttonPin2, INPUT);
// Inizializza il display OLED
if (!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) { // Usa 0x3C come indirizzo I2C
Serial.println(F("Errore nell'inizializzazione del display OLED"));
for (;;); // Rimane bloccato se il display non viene trovato
}
// Inizializza il display
display.clearDisplay();
display.setTextColor(SSD1306_WHITE); // Imposta il colore del testo
display.setTextSize(1); // Imposta la dimensione del testo iniziale
}
void loop() {
// Leggi lo stato dei tasti
buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
// Gestione del Gruppo 1
if (buttonState1 == HIGH && lastButtonState1 == LOW) {
pressStartTime1 = millis(); // Salva il tempo di inizio pressione per il Gruppo 1
}
if (buttonState1 == HIGH) {
pressDuration1 = millis() - pressStartTime1; // Calcola la durata della pressione per il Gruppo 1
}
// Gestione del Gruppo 2
if (buttonState2 == HIGH && lastButtonState2 == LOW) {
pressStartTime2 = millis(); // Salva il tempo di inizio pressione per il Gruppo 2
}
if (buttonState2 == HIGH) {
pressDuration2 = millis() - pressStartTime2; // Calcola la durata della pressione per il Gruppo 2
}
// Se un tasto è stato appena rilasciato, mostra il tempo per un po'
if ((buttonState1 == LOW && lastButtonState1 == HIGH)) {
displayTime1 = millis(); // Salva il tempo in cui è stato rilasciato il tasto del Gruppo 1
}
if ((buttonState2 == LOW && lastButtonState2 == HIGH)) {
displayTime2 = millis(); // Salva il tempo in cui è stato rilasciato il tasto del Gruppo 2
}
// Pulisce il display prima di scrivere nuovi valori
display.clearDisplay();
// Se sono passati 30 secondi di inattività, attiva lo screensaver con "Vancheri"
if (millis() - lastActivityTime > inactiveTimeout) {
display.setTextSize(2); // Imposta una dimensione del testo più piccola per "Vancheri"
// Calcolare la larghezza del testo "Vancheri"
int16_t x, y;
uint16_t textWidth, textHeight;
String screensaverText = "Vancheri";
display.getTextBounds(screensaverText, 0, 0, &x, &y, &textWidth, &textHeight);
// Posiziona il testo al centro del display
int xPos = (SCREEN_WIDTH - textWidth) / 2;
int yPos = (SCREEN_HEIGHT - textHeight) / 2;
display.setCursor(xPos, yPos); // Posiziona il testo centrato
display.print(screensaverText); // Mostra "Vancheri"
} else {
// Mostra il risultato per il Gruppo 1 se il tasto del Gruppo 1 è stato premuto o se il tempo di visualizzazione è in corso
if (buttonState1 == HIGH || (millis() - displayTime1 < displayDuration)) {
display.setTextSize(2); // Aumenta la dimensione del testo per la visibilità
String group1Text = "GR1: ";
String timeString1 = String(pressDuration1 / 1000.0, 2); // Tempo in secondi per il Gruppo 1
int16_t x1, y1;
uint16_t textWidth1, textHeight1;
// Calcola la larghezza del testo per il Gruppo 1
display.getTextBounds(group1Text + timeString1, 0, 0, &x1, &y1, &textWidth1, &textHeight1);
// Calcola la posizione centrale per il testo del Gruppo 1 (parte superiore)
int x1Pos = (SCREEN_WIDTH / 2 - textWidth1 / 2); // Calcola la posizione X per centrare il testo
int y1Pos = 10; // Posiziona il Gruppo 1 nella parte superiore
display.setCursor(x1Pos, y1Pos); // Posiziona il testo nella parte superiore
display.print(group1Text + timeString1); // Mostra il tempo per il Gruppo 1
}
// Mostra il risultato per il Gruppo 2 se il tasto del Gruppo 2 è stato premuto o se il tempo di visualizzazione è in corso
if (buttonState2 == HIGH || (millis() - displayTime2 < displayDuration)) {
display.setTextSize(2); // Aumenta la dimensione del testo per la visibilità
String group2Text = "GR2: ";
String timeString2 = String(pressDuration2 / 1000.0, 2); // Tempo in secondi per il Gruppo 2
int16_t x2, y2;
uint16_t textWidth2, textHeight2;
// Calcola la larghezza del testo per il Gruppo 2
display.getTextBounds(group2Text + timeString2, 0, 0, &x2, &y2, &textWidth2, &textHeight2);
// Calcola la posizione centrale per il testo del Gruppo 2 (parte inferiore)
int x2Pos = (SCREEN_WIDTH / 2 - textWidth2 / 2); // Calcola la posizione X per centrare il testo
int y2Pos = SCREEN_HEIGHT - textHeight2 - 10; // Posiziona il Gruppo 2 nella parte inferiore
display.setCursor(x2Pos, y2Pos); // Posiziona il testo nella parte inferiore
display.print(group2Text + timeString2); // Mostra il tempo per il Gruppo 2
}
}
// Aggiorna il display
display.display();
// Salva lo stato precedente dei tasti
lastButtonState1 = buttonState1;
lastButtonState2 = buttonState2;
// Aggiorna il tempo dell'ultima attività
if (buttonState1 == HIGH || buttonState2 == HIGH) {
lastActivityTime = millis(); // Resetta il timer di inattività ogni volta che un tasto viene premuto
}
delay(100); // Delay di 100 millisecondi per evitare letture troppo rapide
}