Centralina presepe con bottone

Buonasera a tutti, ho realizzato una centralina il mio presepe che devo portare ad una mostra con le fasi alba - giorno - tramonto - notte da uno sketch che ho trovato su internet.
Allo sketch originale ho aggiunto un sensore capacitivo in modo che chi va a vedere il presepe se "preme" sul sensore si attivano le fasi del giorno e vede un solo ciclo di giorno per poi tornare alla modalità statica altrimenti il presepe rimane statico con delle luci accese.
Il problema è che se "premo" sul sensore durante l'esecuzione delle fasi del giorno, il ciclo si blocca e rimane fermo fino a quando non "ripremo" il sensore , io invece vorrei che se "ripremo" le luci ritornino in modalità statica.
Se non si ripreme sul sensore funziona tutto correttamente, una volta finito il ciclo il presepe ritorna in modalità statica.
Posto lo sketch, dove ho sbagliato???

#define pin_down   9
#define pin_sun    11
#define pin_sunset 10
#define pin_moon   2
#define pin_starsA 3
#define pin_starsB 4 

int oneminrome[4] = { 4194,22958,4195,28651 };
int oneminbtlm[4] = { 3668,25189,3668,27474 };
int timeStepOld = 0;
int timeStep = 0;

int TouchSensor = 5;  // Collegato a pin SIG del sensore
int val = 0;          // si userà val per conservare lo stato del pin di input
int vecchio_val = 0;  // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
int stato = 0;

 
long timeCurr = 0;
 
byte fade[]  = {255,250,245,240,235,230,225,220,215,210,205,200,195,190,185,180,175,170,165,160,155,150,145,140,135,130,125,120,115,110,105,100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5,0}; // 52 step
byte curr   = 0;
 
void setup() {
  Serial.begin( 9600 );
   
  pinMode( pin_down  ,OUTPUT );
  pinMode( pin_sun   ,OUTPUT );
  pinMode( pin_sunset,OUTPUT );
  pinMode( pin_moon  ,OUTPUT );
  pinMode( pin_starsA,OUTPUT );
  pinMode( pin_starsB,OUTPUT );

 pinMode(TouchSensor, INPUT);
 
  analogWrite( pin_down  ,LOW );
  analogWrite( pin_sun   ,LOW );
  analogWrite( pin_sunset,LOW );
  digitalWrite( pin_moon  ,LOW );
  digitalWrite( pin_starsA,LOW );
  digitalWrite( pin_starsB,LOW );
   
  Serial.println("-- START --");
}
 
void loop() {
  timeCurr = oneminrome[curr];
  timeStep = (timeCurr/52);
 
  Serial.print("Current: "); Serial.println(curr);
  Serial.print("Time current: "); Serial.println(timeCurr);
  Serial.print("Time single step: "); Serial.println(timeStep);

val = digitalRead(TouchSensor);  // legge il valore dell'input e lo conserva

  // controlla se è accaduto qualcosa
  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);                // attesa di 15 millisecondi
  }

  vecchio_val = val;            // memorizza il valore precedente di val

   if (stato == 1) {

 //ciclo delle fasi giorno notte
 
  // down 
  if ( curr == 0 ) { 
     Serial.print("Fase: "); Serial.println("DOWN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[(51-i)]);
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, 0 );
       digitalWrite(pin_moon,   HIGH );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW);
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
 
  // sun
  if ( curr == 1 ) {
     Serial.print("Fase: "); Serial.println("SUN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[i]);
       if ( fade[i] < 125) analogWrite(pin_sun,    fade[(51-i)]*2 );
       analogWrite(pin_sunset, 0 );
       digitalWrite(pin_moon,   LOW );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW );
       delay( timeStepOld );
     }
     timeStepOld = (timeStepOld*52); // elapsed time
     timeCurr = (timeCurr - timeStepOld);
     delay( timeCurr );
  }
 
  // sunset
  if ( curr == 2 ) {
     Serial.print("Fase: "); Serial.println("SUNSET");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    fade[i] );
       analogWrite(pin_sunset, fade[(51-i)] );
       digitalWrite(pin_moon,   HIGH );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW );
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
   
  // moon 
  if ( curr == 3 ) {
     Serial.print("Fase: "); Serial.println("MOON");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, fade[i] );
       digitalWrite(pin_moon,   HIGH);
       digitalWrite(pin_starsA, HIGH );
      digitalWrite(pin_starsB, LOW );
       delay( timeStepOld );      
   }      
   timeStepOld = (timeStepOld*52); // elapsed time      
   timeCurr = (timeCurr - timeStepOld);      
   delay( timeCurr );
  }   
  curr++   ;
if ( curr == 4 ) {stato = 0; }
if ( curr >= 4 ) { curr = 0; }

}

 else {   
  
  //modalità statica
    analogWrite(pin_sun, 52);
    digitalWrite(pin_starsB, HIGH);
}
}

se non sbaglio ti basta spostare vecchio_val= val dentro all'if

  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);                // attesa di 15 millisecondi
    vecchio_val = val;            // memorizza il valore precedente di val  
 }

e poi in fondo

    if ( curr == 4 ) {
      stato = 0;
      vecchio_val=LOW;
    }

in questo modo anche se premi non succede nulla fino alla fine del ciclo
al contrario se vuoi che una nuova pressione del pulsante resetti immediatamente tutto...
aggiungi un else

 if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);                // attesa di 15 millisecondi
    vecchio_val = val;            // memorizza il valore precedente di val
  }else if ((val == HIGH) && (vecchio_val == HIGH)) {
     stato=0;
     vecchio_val=LOW
     curr=0;
  }

Grazie mille per l'aiuto sei sempre molto disponibile.... ho fatto la prima modifica e funziona ora se premo durante il ciclo giorno notte non si blocca più....
Ora però alla prima accensione come premo sul sensore si attiva subito il ciclo, le succesive volte se premo il sensore non parte subito il ciclo ma devo aspettare molto più del delay..... ho provato anche a toglierlo ma niente!!

non ho capito molto bene che succede
per favore riposta il programma.... mi sa che ho dimenticato qualche cosa

Quando premo il pulsante ci sono circa 10 secondi prima che inizi il ciclo giorno notte

#define pin_down   9
#define pin_sun    11
#define pin_sunset 10
#define pin_moon   2
#define pin_starsA 3
#define pin_starsB 4 

int oneminrome[4] = { 4194,22958,4195,28651 };
int oneminbtlm[4] = { 3668,25189,3668,27474 };
int timeStepOld = 0;
int timeStep = 0;

int TouchSensor = 5;  // Collegato a pin SIG del sensore
int val = 0;          // si userà val per conservare lo stato del pin di input
int vecchio_val = 0;  // si userà vecchio_val per conservare lo stato del pin di input al passo precedente
int stato = 0;

 
long timeCurr = 0;
 
byte fade[]  = {255,250,245,240,235,230,225,220,215,210,205,200,195,190,185,180,175,170,165,160,155,150,145,140,135,130,125,120,115,110,105,100,95,90,85,80,75,70,65,60,55,50,45,40,35,30,25,20,15,10,5,0}; // 52 step
byte curr   = 0;
 
void setup() {
  Serial.begin( 9600 );
   
  pinMode( pin_down  ,OUTPUT );
  pinMode( pin_sun   ,OUTPUT );
  pinMode( pin_sunset,OUTPUT );
  pinMode( pin_moon  ,OUTPUT );
  pinMode( pin_starsA,OUTPUT );
  pinMode( pin_starsB,OUTPUT );

 pinMode(TouchSensor, INPUT);
 
  analogWrite( pin_down  ,LOW );
  analogWrite( pin_sun   ,LOW );
  analogWrite( pin_sunset,LOW );
  digitalWrite( pin_moon  ,LOW );
  digitalWrite( pin_starsA,LOW );
  digitalWrite( pin_starsB,LOW );
   
  Serial.println("-- START --");
}
 
void loop() {
  timeCurr = oneminrome[curr];
  timeStep = (timeCurr/52);
 
  Serial.print("Current: "); Serial.println(curr);
  Serial.print("Time current: "); Serial.println(timeCurr);
  Serial.print("Time single step: "); Serial.println(timeStep);

val = digitalRead(TouchSensor);  // legge il valore dell'input e lo conserva

  // controlla se è accaduto qualcosa
  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);                // attesa di 15 millisecondi

  vecchio_val = val;            // memorizza il valore precedente di val
  }



   if (stato == 1) {

 //ciclo delle fasi giorno notte
 
  // down 
  if ( curr == 0 ) { 
     Serial.print("Fase: "); Serial.println("DOWN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[(51-i)]);
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, 0 );
       digitalWrite(pin_moon,   HIGH );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW);
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
 
  // sun
  if ( curr == 1 ) {
     Serial.print("Fase: "); Serial.println("SUN");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   fade[i]);
       if ( fade[i] < 125) analogWrite(pin_sun,    fade[(51-i)]*2 );
       analogWrite(pin_sunset, 0 );
       digitalWrite(pin_moon,   LOW );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW );
       delay( timeStepOld );
     }
     timeStepOld = (timeStepOld*52); // elapsed time
     timeCurr = (timeCurr - timeStepOld);
     delay( timeCurr );
  }
 
  // sunset
  if ( curr == 2 ) {
     Serial.print("Fase: "); Serial.println("SUNSET");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    fade[i] );
       analogWrite(pin_sunset, fade[(51-i)] );
       digitalWrite(pin_moon,   HIGH );
       digitalWrite(pin_starsA, LOW );
       digitalWrite(pin_starsB, LOW );
       delay( timeStep );
     }
     timeStepOld = timeStep;
  }
   
  // moon 
  if ( curr == 3 ) {
     Serial.print("Fase: "); Serial.println("MOON");
     for ( int i=0; i<52; i++) {
       analogWrite(pin_down,   0);
       analogWrite(pin_sun,    0 );
       analogWrite(pin_sunset, fade[i] );
       digitalWrite(pin_moon,   HIGH);
       digitalWrite(pin_starsA, HIGH );
      digitalWrite(pin_starsB, LOW );
       delay( timeStepOld );      
   }      
   timeStepOld = (timeStepOld*52); // elapsed time      
   timeCurr = (timeCurr - timeStepOld);      
   delay( timeCurr );
  }   
  curr++   ;
if ( curr == 4 ){
stato == 0;

  vecchio_val = LOW;
}

}

 else {   
  
  //modalità statica
    analogWrite(pin_sun, 52);
    digitalWrite(pin_starsB, HIGH);
}
}

prova a cambiare questo e occhio all'errore stato==0 :wink:

   if ( curr == 4 ) {
      stato == 0;      // ERRORE!!!!!!
      vecchio_val = LOW;
   }

in questo

   if ( curr > 3 ) {
      stato = 0;
      vecchio_val = LOW;
   }

e aggiungere curr=0

  if ((val == HIGH) && (vecchio_val == LOW)) {
    stato = 1 - stato;
    delay(15);                // attesa di 15 millisecondi
    vecchio_val = val;            // memorizza il valore precedente di val
    curr=0;
  }

ti do un paio di dritte...

Serial.print("Fase: "); Serial.println("DOWN");

essendo due stampe sul monitor seriale che non provengono da variabili.... puoi tranquillamente scrivere così:

Serial.println("Fase: DOWN");

risparmi una riga/istruzione :slight_smile:

if ( curr == 0 ) {
      Serial.print("Fase: "); Serial.println("DOWN");
      for ( int i = 0; i < 52; i++) {
        analogWrite(pin_down,   fade[(51 - i)]);
        analogWrite(pin_sun,    0 );
        analogWrite(pin_sunset, 0 );
        digitalWrite(pin_moon,   HIGH );
        digitalWrite(pin_starsA, LOW );
        digitalWrite(pin_starsB, LOW);
        delay( timeStep );
      }
      timeStepOld = timeStep;
    }

in questo for c'è solamente un comando che cambia ad ogni passaggio cioè:

analogWrite(pin_down,   fade[(51 - i)]);

quindi è inutile ripetere 52 volte accendi pin_moon e tutto il resto quindi è più corretto scrivere:

    if ( curr == 0 ) {
      Serial.print("Fase: DOWN");
      analogWrite(pin_sun,    0 );
      analogWrite(pin_sunset, 0 );
      digitalWrite(pin_moon,   HIGH );
      digitalWrite(pin_starsA, LOW );
      digitalWrite(pin_starsB, LOW);

      for ( int i = 0; i < 52; i++) {
        analogWrite(pin_down,   fade[(51 - i)]);
        delay( timeStep );
      }
      timeStepOld = timeStep;
    }

l'array fade[] con i 52 valori qui è abbastanza inutile....
nel DOWN basta mettere:

analogWrite(pin_down, 0+(5*i));  // da 0 a 255 con step 5

nel SUN si complica la storia :slight_smile:
nella prima riga basta fare

analogWrite(pin_down,255-(5*i));  // da 255 a 0 step 5

la seconda riga va studiata....

if ( fade[i] < 125) analogWrite(pin_sun,    fade[(51 - i)] * 2 );

fade[i] è minore di 125 a partire dal valore di i=27 (corrisponde al valore 120)
quindi la analogWrite diventa
analogWrite(pin_sun,    fade[(51 - 27)] * 2 );in posizione 24 (51-27) troviamo il valore 135 che moltiplicato per 2 da 270 che è maggiore del massimo (che è 255) quindi è come se scrivessimo 255
lo stesso risultato si ha per tutti i seguenti valori di i quindi mi sa che qui c'è un errore :wink:

nel SUNSET di nuovo basta fare

analogWrite(pin_sunset, 0+(5*i)); //da 0 a 255 step 5

e nel MOON

analogWrite(pin_sunset, 255-(5*i));

(le parentesi nelle moltiplicazioni sono ridondanti.... ma si capisce meglio il calcolo :wink:
quindi una volta risolta la questione del SUN l'array fade puoi buttarlo via :wink:

Grazie mille... Ho provato e ora funziona tutto a dovere... Grazie per le dritte, è tutto spiegato molto bene proverò a modificare lo sketch.