// https://forum.arduino.cc/t/cambio-effetti-con-switch-stato/1347177/65


const int P_LED = 3;
const int P_TASTO = 2;

int stato = 0;
uint32_t blinkTime;
bool pLedState = HIGH;
uint16_t oldPotValue = 1024;

// calcAndPrintTcm Calcola e stampa il tempo di ciclo medio
// tcm è espresso in millesimi di secondo.
// moltiplicare tcm x 1000 per ottenere il tempo in microsecondi
// Decommentare (1) e (2) per stampare il valore  di loopCounter
// oppure calcolarlo manualmente così: lc = 1000 / tcm.
void calcAndPrintTcm() {
    static uint32_t loopCounter;
    static uint32_t oneSec = millis();
    loopCounter++;
    if (millis() - oneSec >= 1000) {
        oneSec = millis();
        float tcm = 1000.0/loopCounter;
        Serial.print("Tcm: ");
        Serial.print(tcm, 5);
        Serial.println(" ms");
        //Serial.print("loopCounter: ");  // (1)
        //Serial.println(loopCounter);    // (2)

        loopCounter = 0;
    }
}


void setup() {
  Serial.begin(115200);
  pinMode(P_LED, OUTPUT);
  pinMode(P_TASTO, INPUT_PULLUP);
}

void loop() {
  calcAndPrintTcm();

  switch (stato) {
    case 0:
      //digitalWrite(P_LED, LOW);
      if (!digitalRead(P_TASTO)) {
        delay(300);
        // I punti di uscita da uno stato devono essere ben evidenziati
        // al fine di seguire la successione.
        // prenoto il prossimo stato
        stato = 1;
      }
      break;
    case 1:
      fadeLed();
      if (!digitalRead(P_TASTO)) {
        delay(300);
        // prenoto il prossimo stato
        stato = 2;
        oldPotValue = 1024;
      }
      break;
    case 2:
      blinkLed();
      if (!digitalRead(P_TASTO)) {
        // Spengo il P_LED che potrebbe essere acceso
        // costa meno che chiamare due volte digitalRead(P_LED)
        // per verificare se è acceso e poi digitalWrite per spegnerlo.
        // Però lo stato del led puoi conservarlo in una variabile 
        // bool pLedState e allora ha senso if (pLedState) pLedState = LOW;
        // ma sono dettagli.
        digitalWrite(P_LED, LOW); 
        pLedState = HIGH;
        delay(300);
        // prenoto il prossimo stato
        stato = 0;
        blinkTime = 0;  // azzero blinkTime per ripristinarlo al valore iniziale
        oldPotValue = 1024;
      }
      break;
  }
  delay(1);
}

void fadeLed() {

  int pot = analogRead(A0);
  if (oldPotValue != pot) {
    oldPotValue = pot;
    int convert = map(pot, 0, 1023, 0, 255);
    analogWrite(P_LED, convert);
  }
}

void blinkLed() {
  // tcm = 0.11786 ms
  static uint16_t msTime;
  uint16_t pot = analogRead(A0);
  
  if (oldPotValue != pot) {
      oldPotValue = pot;
      msTime = map(pot, 0, 1023, 0, 500);
  }
  // solo la prima volta blinkTime vale zero.
  // millis() - 0 = operazione nulla.
  // Se millis() >= 500 entra subito
  // dalla seconda volta in poi blinkTime è caricato con il valore
  // di millis().
  // (tcm) La maggior parte del tempo si perde qui
  // ma non ci si può fare nulla
  if (millis() - blinkTime >= msTime) {
      blinkTime = millis();
      
      digitalWrite(P_LED, pLedState);
      pLedState = !pLedState;
  }
  //digitalWrite(P_LED, !digitalRead(P_LED));
  ///delay(flash);
}
$abcdeabcde151015202530fghijfghij
uno:A5.2
uno:A4.2
uno:AREF
uno:GND.1
uno:13
uno:12
uno:11
uno:10
uno:9
uno:8
uno:7
uno:6
uno:5
uno:4
uno:3
uno:2
uno:1
uno:0
uno:IOREF
uno:RESET
uno:3.3V
uno:5V
uno:GND.2
uno:GND.3
uno:VIN
uno:A0
uno:A1
uno:A2
uno:A3
uno:A4
uno:A5
led1:A
led1:C
btn1:1.l
btn1:2.l
btn1:1.r
btn1:2.r
pot1:GND
pot1:SIG
pot1:VCC
r1:1
r1:2