#define FADE_IN 3       // Pin del pulsante che fa partire il fade-in del led
#define FADE_OUT 2      // Pin del pulsante che fa partire il fade-out del led
#define LED_OUT 11      // Uscita PWM su cui è collegato il led

unsigned int stepTime = 50;   // "delay" che intercorre tra uno step ed il successivo  durante in dimming

bool fadeIn = false;     // Variabile di appoggio per far partire il fade-in
bool fadeOut = false;    // Variabile di appoggio per far partire il fade-out

unsigned char stepNum;   // Variabile per memorizzare lo step corrente

void setup() {
  Serial.begin(115200);
  pinMode(LED_OUT, OUTPUT);
	pinMode(FADE_OUT, INPUT_PULLUP);
	pinMode(FADE_IN, INPUT_PULLUP);

  analogWrite(LED_OUT, 0);
}


void loop()  { 
 
  // Memorizzo il momento in cui aggiorno lo stato dell uscite PWM nella variabile locale doStepTime
  // la keyword static fa in modo che il valore della variabile non venga resettato ad ogni ciclo di loop()
  // ovvero si comporta come se fosse una variabile globale
	static unsigned long doStepTime;

	// Fade in non bloccante del led //
	if ((millis() - doStepTime > stepTime) && fadeIn) {		
    // Imposto doStepTime == millis() -> in questo modo nei "loop" successivi 
    // l'if sarà == false fino a che non trascorre il tempo stepTime e la variabile fadeIn == true
		doStepTime = millis();		
    // Incremento il numero dello step attuale
		stepNum++;	    
    // Aggiorno lo stato dell'uscita PWM
    analogWrite(LED_OUT, stepNum);			

    // Fintanto che stepNum è < 255 fadeIn == true e quindi eseguo questo ciclo nel prossimo loop
		fadeIn = (stepNum < 255);

		// Serial.print(stepNum);
		// Serial.print(" - ");
		// Serial.println(dim);
	}

	// Fade out non bloccante del led  (Stesso principio di funzionamento di fade-in)
	if ((millis() - doStepTime > stepTime) && fadeOut) {		
		doStepTime = millis();		
    stepNum--;	
    analogWrite(LED_OUT, stepNum);		
		fadeOut = (stepNum > 0);

		// Serial.print(stepNum);
		// Serial.print(" - ");
		// Serial.println(dim);
	}

	// Lettura dello stato del pulsante con debounce //
  static unsigned long debounceTime;  	  // Variabile per memorizzare  il "momento" in cui viene premuto il pulsante

  // Questo if può diventare == true, solo dopo che sono trascorsi 200ms tra una pressione e la successiva
  if (!digitalRead(FADE_IN) && millis() - debounceTime > 200) {    
    // memorizzo il momento in cui viene premuto il pulsante
    debounceTime = millis();

    // Imposto le variabili fadeOut o fadeIn == true per avviare il ciclo corrispondente (al prossimo loop)
    fadeOut = false;	
		fadeIn = true;			
		Serial.print("Fade in. Tempo step(ms): ");	
		Serial.println(stepTime);
  }

  // Funzionamento pulsante fade-out analogo al pulsante per il fade-in
	if (!digitalRead(FADE_OUT) && millis() - debounceTime > 200) {    
    debounceTime = millis();
    fadeOut = true;	
		fadeIn = false;	
		Serial.print("Fade out. Tempo step(ms): ");	
		Serial.println(stepTime);
  }

}