#include <Wire.h>
#include <RTClib.h>
#include <TM1637.h> // Libreria Grove 4-Digit Display
#include <Adafruit_NeoPixel.h> // Libreria per striscia LED RGB
// Pin del display
#define CLK 3
#define DIO 2
// Pin pulsanti
#define BUTTON_HOURS 4
#define BUTTON_MINUTES 5
#define BUTTON_DISPLAY 6
#define BUTTON_COLOR 7
#define BUTTON_BRIGHTNESS 9 // Pulsante per regolare la luminosità dei LED
// Configurazione LED RGB
#define LED_PIN 8 // Pin di controllo della striscia LED
#define NUM_LEDS 30 // Numero di LED nella striscia
Adafruit_NeoPixel strip(NUM_LEDS, LED_PIN, NEO_GRB + NEO_KHZ800);
RTC_DS3231 rtc; // Oggetto per l'RTC
TM1637 tm1637(CLK, DIO); // Oggetto per il display TM1637 della Grove
bool adjustMode = false; // Modalità regolazione
int hourAdjust = 0;
int minuteAdjust = 0;
unsigned long displayTimeout = 0; // Timeout per spegnere il display
bool displayOn = false; // Stato del display
bool showingTime = false; // Mostra ora o nome colore
bool showingColor = false;
bool showingBrightness = false; // Mostra luminosità
int brightnessLevel = 5; // Livello iniziale di luminosità (1-5)
// Colori disponibili per la striscia LED
struct Color {
uint8_t r, g, b;
const char *name; // Nome del colore per il display
};
Color colors[] = {
{255, 255, 255, "A--"}, // Bianco
{255, 255, 0, "B--"}, // Giallo
{255, 0, 0, "C--"}, // Rosso
{0, 0, 255, "D--"}, // Blu
{128, 0, 128, "E--"}, // Viola
{0, 255, 0, "F--"} // Verde
};
int currentColorIndex = 0; // Indice del colore attuale
void setup() {
// Inizializzazione
Wire.begin();
rtc.begin();
tm1637.init(); // Inizializza il display Grove
tm1637.set(2); // Imposta una luminosità predefinita
pinMode(BUTTON_HOURS, INPUT_PULLUP);
pinMode(BUTTON_MINUTES, INPUT_PULLUP);
pinMode(BUTTON_DISPLAY, INPUT_PULLUP);
pinMode(BUTTON_COLOR, INPUT_PULLUP);
pinMode(BUTTON_BRIGHTNESS, INPUT_PULLUP);
// Inizializza la striscia LED
strip.begin();
strip.show(); // Spegne tutti i LED inizialmente
setLEDColor(colors[currentColorIndex]); // Imposta il colore iniziale
// Controlla se l'RTC ha un valore valido
DateTime now = rtc.now();
if (now.year() < 2000) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Imposta l'ora di compilazione come default
}
}
void loop() {
static unsigned long lastDebounceTime = 0;
static bool lastHourButtonState = HIGH;
static bool lastMinuteButtonState = HIGH;
static bool lastDisplayButtonState = HIGH;
static bool lastColorButtonState = HIGH;
static bool lastBrightnessButtonState = HIGH;
// Lettura dell'ora corrente
DateTime now = rtc.now();
// Controllo pulsanti
bool hourButtonState = digitalRead(BUTTON_HOURS);
bool minuteButtonState = digitalRead(BUTTON_MINUTES);
bool displayButtonState = digitalRead(BUTTON_DISPLAY);
bool colorButtonState = digitalRead(BUTTON_COLOR);
bool brightnessButtonState = digitalRead(BUTTON_BRIGHTNESS);
// Controllo pulsante ore
if (hourButtonState == LOW && lastHourButtonState == HIGH && millis() - lastDebounceTime > 200) {
lastDebounceTime = millis();
if (!adjustMode) adjustMode = true;
addTimeToRTC(1, 0); // Aggiunge 1 ora all'orario corrente
turnOnDisplay(true, false, false); // Accende il display e mostra l'ora
}
// Controllo pulsante minuti
if (minuteButtonState == LOW && lastMinuteButtonState == HIGH && millis() - lastDebounceTime > 200) {
lastDebounceTime = millis();
if (!adjustMode) adjustMode = true;
addTimeToRTC(0, 1); // Aggiunge 1 minuto all'orario corrente
turnOnDisplay(true, false, false); // Accende il display e mostra l'ora
}
// Controllo pulsante display
if (displayButtonState == LOW && lastDisplayButtonState == HIGH && millis() - lastDebounceTime > 200) {
lastDebounceTime = millis();
turnOnDisplay(true, false, false); // Accende il display e mostra l'ora
}
// Controllo pulsante colore
if (colorButtonState == LOW && lastColorButtonState == HIGH && millis() - lastDebounceTime > 200) {
lastDebounceTime = millis();
changeColor(); // Cambia il colore della striscia LED
turnOnDisplay(false, true, false); // Accende il display per mostrare il nome del colore
}
// Controllo pulsante luminosità
if (brightnessButtonState == LOW && lastBrightnessButtonState == HIGH && millis() - lastDebounceTime > 200) {
lastDebounceTime = millis();
adjustBrightness(); // Regola la luminosità
turnOnDisplay(false, false, true); // Mostra il livello di luminosità sul display
}
lastHourButtonState = hourButtonState;
lastMinuteButtonState = minuteButtonState;
lastDisplayButtonState = displayButtonState;
lastColorButtonState = colorButtonState;
lastBrightnessButtonState = brightnessButtonState;
// Spegnimento del display dopo il timeout
if (displayOn && millis() > displayTimeout) {
clearDisplay(); // Spegne il display
}
delay(50); // Riduce il carico della CPU
}
// Funzione per accendere il display
void turnOnDisplay(bool showTime, bool showColor, bool showBrightness) {
displayOn = true;
showingTime = showTime;
showingColor = showColor;
showingBrightness = showBrightness;
displayTimeout = millis() + 10000; // Mantiene il display acceso per 10 secondi
if (showTime) {
DateTime now = rtc.now();
int timeValue = now.hour() * 100 + now.minute();
tm1637.display(0, timeValue / 1000 % 10); // Primo carattere
tm1637.display(1, timeValue / 100 % 10); // Secondo carattere
tm1637.display(2, timeValue / 10 % 10); // Terzo carattere
tm1637.display(3, timeValue % 10); // Quarto carattere
} else if (showColor) {
showTextOnDisplay(colors[currentColorIndex].name); // Mostra il nome del colore
} else if (showBrightness) {
tm1637.display(0, brightnessLevel); // Mostra la luminosità
for (int i = 1; i < 4; i++) tm1637.display(i, 0x7F); // Spazi vuoti
}
}
// Funzione per cambiare il colore della striscia LED
void changeColor() {
currentColorIndex = (currentColorIndex + 1) % (sizeof(colors) / sizeof(colors[0])); // Passa al colore successivo
setLEDColor(colors[currentColorIndex]); // Imposta il nuovo colore
}
// Funzione per regolare la luminosità dei LED
void adjustBrightness() {
brightnessLevel = (brightnessLevel % 5) + 1; // Passa al livello successivo (1-5)
strip.setBrightness(map(brightnessLevel, 1, 5, 50, 255)); // Regola la luminosità
strip.show();
}
// Funzione per impostare il colore della striscia LED
void setLEDColor(Color color) {
for (int i = 0; i < NUM_LEDS; i++) {
strip.setPixelColor(i, strip.Color(color.r, color.g, color.b)); // Imposta il colore per ogni LED
}
strip.show(); // Aggiorna la striscia LED
}
// Funzione per aggiungere tempo all'RTC
void addTimeToRTC(int addHours, int addMinutes) {
DateTime now = rtc.now(); // Ottiene l'ora attuale
DateTime newTime = now + TimeSpan(0, addHours, addMinutes, 0); // Aggiunge ore e minuti
rtc.adjust(newTime); // Regola l'RTC con il nuovo valore
}
// Funzione per mostrare testo sul display
void showTextOnDisplay(const char *text) {
for (int i = 0; i < 4; i++) {
tm1637.display(i, text[i] ? text[i] - 'A' + 10 : 0x7F); // Mappa le lettere ai segmenti
}
}
// Funzione per spegnere il display
void clearDisplay() {
for (int i = 0; i < 4; i++) {
tm1637.display(i, 0x7F); // Spegne ogni segmento
}
displayOn = false;
}