Go Down

Topic: Centralina presepe con bottone (Read 337 times) previous topic - next topic

armandinok

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???


Code: [Select]


 
#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);
}
}

Patrick_M

#1
Nov 13, 2018, 11:27 pm Last Edit: Nov 13, 2018, 11:35 pm by Patrick_M
se non sbaglio ti basta spostare vecchio_val= val dentro all'if
Code: [Select]
  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
Code: [Select]
    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
Code: [Select]

 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;
  }
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

armandinok

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!!

Patrick_M

non ho capito molto bene che succede
per favore riposta il programma.... mi sa che ho dimenticato qualche cosa
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

armandinok

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


Code: [Select]



 
#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);
}
}




Patrick_M

prova a cambiare questo e occhio all'errore stato==0 ;)
Code: [Select]

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

in questo
Code: [Select]

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

e aggiungere curr=0
Code: [Select]

  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;
  }
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

Patrick_M

#6
Nov 15, 2018, 01:32 pm Last Edit: Nov 15, 2018, 01:38 pm by Patrick_M
ti do un paio di dritte...
Code: [Select]
Serial.print("Fase: "); Serial.println("DOWN");
essendo due stampe sul monitor seriale che non provengono da variabili.... puoi tranquillamente scrivere così:
Code: [Select]
Serial.println("Fase: DOWN");
risparmi una riga/istruzione :)

Code: [Select]
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è:
Code: [Select]
analogWrite(pin_down,   fade[(51 - i)]);
quindi è inutile ripetere 52 volte accendi pin_moon e tutto il resto quindi è più corretto scrivere:
Code: [Select]
    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:
Code: [Select]
analogWrite(pin_down, 0+(5*i));  // da 0 a 255 con step 5
nel SUN si complica la storia :)
nella prima riga basta fare
Code: [Select]
analogWrite(pin_down,255-(5*i));  // da 255 a 0 step 5
la seconda riga va studiata....
Code: [Select]
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
Code: [Select]
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 ;)

nel SUNSET di nuovo basta fare
Code: [Select]
analogWrite(pin_sunset, 0+(5*i)); //da 0 a 255 step 5
e nel MOON
Code: [Select]
analogWrite(pin_sunset, 255-(5*i));
(le parentesi nelle moltiplicazioni sono ridondanti.... ma si capisce meglio il calcolo ;)
quindi una volta risolta la questione del SUN l'array fade puoi buttarlo via ;)
per inserire (lo sketch) il programma, dall'IDE clicca modifica, clicca copia per il forum poi vieni qui e incolla nel tuo post (ctrl+v) ;)

armandinok

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

Go Up