/* Prova Countdown su 2 Tipi di schermo
Con Spegnimento uscita alla fine */

// Creazione Display LCD I2C
#include <LiquidCrystal_I2C.h> // Libreria Display LCD I2C

#define I2C_ADDR 0x27 // Indirizzo I2C Display LcD
#define LCD_COLUMNS 16 // N. Colonne
#define LCD_LINES 2 // N. Righe
LiquidCrystal_I2C lcd(I2C_ADDR, LCD_COLUMNS, LCD_LINES);

// Creazione Display a 4 Pin TM1637
#include <TM1637.h> // Libreria Display a 4 Pin TM1637

const int CLK = 2; // Pin CLK
const int DIO = 3; // Pin DIO
TM1637 tm(CLK, DIO);

// Variabili Countdown
int countdown = 10; // Valore Countdown
unsigned long previousMillis = 0; // Memorizza l'ultimo momento in cui il contatore è stato decrementato
const long interval = 1000; // Intervallo in millisecondi (1 secondo)
bool continuaCountdown = true; // Variabile per Start / Stop Countdown
// Pin collegato all'ingresso per lo start
const int In = 4;
// Variabile per In
int val = 0;

// Pin collegato all'uscita che vuoi monitorare
const int Led = 8;

void setup() {
  Serial.begin(9600); // Inizializzazione Stampante Seriale
  tm.init(); // Inizializzazione Display TM1637
  tm.set(BRIGHT_TYPICAL); // Luminosità Tipica Display TM1637
  lcd.init(); // Inizializzazione Display LCD
  lcd.backlight(); // Attiva Retroilluminazione Display LCD
  pinMode(Led, OUTPUT); // Imposta Led come Uscita
  pinMode(In, INPUT); // Imposta In come Ingresso
  }

void loop() {
  // Mostra su Stampante Seriale Valore Countdown
  Serial.print(countdown);
  // Associa val a stato In
  val = digitalRead(In);
  
  // Se In (val) è  Basso o Se il Countdown è minore di 0 ...
  if ((val == LOW) || (countdown < -1)) {
  digitalWrite(Led, LOW); // Spegni il Led
  lcd.clear(); // Pulisci il Display LCD
  // Spegni display TM1637 (Visualizza "0000')
  tm.display(0, 0);
  tm.display(1, 0);
  tm.display(2, 0);
  tm.display(3, 0);
  }

  // Se In (val) è Alto ...
  if ((val == HIGH)) {
  StartCountdown(); // Attiva countdown da 10 a 0
  // E se il Countdown è in corso ...
  if (countdown > -1) {
  visualizzazione(); // Visualizza il valore sui Display
  digitalWrite(Led, HIGH); // Accendi il Led
  }
  } else { // Se In (val) è Basso ...
    countdown = 10; // Resetta Countdown
  }
  }

// Sketch Countdown 
void StartCountdown() {
  // Variabile di Tempo con funziond millis
  unsigned long currentMillis = millis();
  
  /* Se la differenza tra il Tempo Attuale (millis)
  e quello del ultimo decremento è maggiore o uguale
  a 1 secondo e se countdown è < -2 */
  if (currentMillis - previousMillis >= interval && countdown > -2) {
  // Se è passato almeno un secondo
  previousMillis = currentMillis; // Associa alla variabile il Tempo Attuale
  countdown--; // Countdown
  }
}

// Sketch Display
void visualizzazione() {
  // Visualizza Valore Countdown su Stampante e Display
  lcd.setCursor(0, 0); // Set posizione, Colonna e Riga 0
  lcd.print("Secondi: "); // Scrivi sul display secondi:
  lcd.print((countdown) % 10); // Scrivi sul display Valore
  delay(100);
  // Impostazioni Visualizzazione su Display TM1637
  tm.display(0, ((countdown) / 1000) % 10); // Cifra in migliaia
  tm.display(1, ((countdown) / 100) % 10); // Cifra in centinaia
  tm.display(2, ((countdown) / 10) % 10); // Cifra in decine
  tm.display(3, ((countdown) / 1) % 10); // Cifra in unità
  }
4-Digit Display