Relè temporizzato dopo il rilascio del pulsante

Buona sera a tutti, in pratica vorrei realizzare uno sketch che facesse questa funzione :
Tengo pigiato un pulsante per un ora che mi eccita un relè, al mio rilascio se non ripigio il tasto il relè si diseccita dopo 5 seconti, ma se ripremo il pulsante prima dei 5 secondi acontinua a lasciare il relè eccitato. Grazie in anticipo

Bravo, inizia a buttare giù il codice e se hai dubbi e/o problemi postalo qui ( Regolamento punto 16 ) che ti aiutiamo.
Nel prossimo post con il codice che non funziona magari dettaglia meglio cosa deve fare il progetto nella realtà (nei limiti del possibile e del regolamento), Es. un ora deve essere un dato preciso o se premo per 1 secondo o per 1 ora non cambia devo solo aspettare 5 secondi prima di diseccitare il relè, ecc.

# define TASTO1 7
# define LED1   8

int Stato1 = 0;    

void setup() 
{ pinMode(LED1, OUTPUT);      
pinMode(TASTO1, INPUT);}

void loop(){

Stato1 = digitalRead(TASTO1);

if (Stato1 == HIGH)
{ digitalWrite(LED1, LOW);  
delay(1000);} 
else {digitalWrite(LED1, HIGH);}
}

QUESTO E LO SKETCH
il problema e che mi fa la funzione inversa ovvero aspetta tot secondi prima di accendere un led[/code]

>pep123456: ti ricordo che in conformità al regolamento, punto 7, devi editare il tuo post (quindi NON scrivendo un nuovo post, ma utilizzando il bottone More → Modify che si trova in basso a destra del tuo post) e racchiudere il codice all’interno dei tag CODE (… sono quelli che in edit inserisce il bottone con icona fatta così: </>, tutto a sinistra).

In pratica, tutto il tuo codice dovrà trovarsi racchiuso tra due tag: [code] _il _tuo_ codice_ [/code] così da non venire interpretato e non dare adito alla formazione di caratteri indesiderati o cattiva formattazione del testo. Grazie.

Guglielmo

in primis fai come chiesto da Guglielmo…dopo di che…sei un po’ lontano dal fare quello che vuoi…permettimi di dire che hai un po’ di confusione su come funziona l’if-else…e poi lascia stare il delay() e studiati l’uso di millis() che in questo caso fa al caso tuo…ti do un suggerimento di pseudo codice:

se pulsante premuto
    metto a true una variabile boolean per indicare che il pulsante è stato premuto
    salvo millis() attuale in una variabile di tipo congruo 
    accendo il LED

se pulsante non premuto && il pulsante era stato premuto
    se millis() attuale meno variabile salvata prima  >= dei 5 secondi
        spengo il LED
        metto a false la variabile boolean

e pure il mio funzionava abbastanza bene solo che funzionava all incontraruio

ciao...si dice che l'esperienza è la somma degli errori/sbagli che uno fa...quindi è giusto riflettere sui propri...dato che il tuo programma non fa quello che vuoi vuol dire che è sbagliato...ti suggerisco di ragionare bene su cosa fanno l'if() e l'else...la capisci perchè fa il contrario di quello che ti aspetti.

#define ledPin 13                   // Rinomina il pin 13 come ledPin
#define pulsantePin 2               // Rinomina il pin 2 come pulsantePin


int pulsanteState = 0;            // Variabile per leggere lo stato del pulsante


void setup() {
  pinMode(ledPin, OUTPUT);          // Imposta il ledPin come OUTPUT 
  pinMode(pulsantePin, INPUT);        // Imposta il pulsantePin come INPUT
}


void loop(){
  pulsanteState = digitalRead(pulsantePin);  // Leggi lo stato del pulsante
  if (pulsanteState == HIGH) {             // Se il pulsantePin è HIGH accendi il led 
    digitalWrite(ledPin, HIGH);        
  } 
  else {                                 
    digitalWrite(ledPin, LOW);           // Sennò spegni il led
  }
}

questa e un altra guida ma anchessa funziona all incontrario della sua descrizione

a questo punto voglio sapere esattamente come hai collegato il led :smiley:

2 casi

  1. il negativo del led è collegato direttamente a gnd e il positivo del led al pin di arduino (con la resistenza in serie o da una parte o dall'altra non importa)

  2. il positivo del led collegato direttamente al +5V e il negativo del led al pin di arduino (sempre con la solita resistenza)

se al contrario parliamo del led incluso sulla scheda quindi collegato come nel caso 1
definisci esattamente come hai collegato il pulsante
:wink:

  1. il negativo del led è collegato direttamente a gnd e il positivo del led al pin di arduino

il pulsante tra ground e pin 2

quindi quando premi il pulsante lo colleghi a massa.... quindi LOW quando è premuto :wink:

allora nel pinMode il pulsante non deve essere INPUT ma INPUT_PULLUP

ed ecco perchè funziona al contrario...

pep123456:
il pulsante tra ground e pin 2

pic001.png

Il sospetto di un cablaggio strano c'era...comunque il suo programma non farà quello che si aspetta...cioè premo e si accende il led...rilascio e dopo 1 secondo si spegne...

Vorrei proporre una soluzione postando il codice, sono poche righe. Tutti avrebbero potuto postare la soluzione ma volevano farti arrivare da solo a una soluzione! Io penso invece che anche scrivendo 4 righe e commentandole si possa imparare, e spesso avrei voluto che qualcuno si comportasse cosi con me "avrei imparato più velocemente " :slight_smile:

unsigned long tempo=0;
byte stato=0;
byte statopulsante=0;

void loop(){

    if(digitalRead(PULSANTE, HIGH)){
    
        digitalWrite(RELE,HIGH); //Se il pulsante è premuto tengo attivo il rele
        statopulsante=1; // il pulsante è stato premuto

    }else if(digitalRead(PULSANTE,LOW)&& statopulsante==1){ 
    //Se il pulsante è rilasciato e prima era premuto comincio il conteggio di 5 secondi
   
        tempo=millis();
        statopulsante=0; /*In questo modo questo codice viene eseguito una sola volta al rilascio del pulsante */
        while(millis()-tempo>=5000){// Il ciclo continua fino a che non sono passati 5 secondi
  
             if(digitalRead(PULSANTE,HIGH){ // Se in 5 secondi viene premuto il pulsante

                    stato=1; // Se premo il pulsante stato vale 1 e esco dal while
                    break; 
              }else
                    stato=0; // altrimenti stato è uguale a zero
   
        }// end while

        digitalWrite(RELE,stato); 
        /* Esco dal while perché sono passati 5 secondi o perché è stato premuto il pulsante
            se sono passati 5 secondi senza premere il pulsante stato è zero e disattiva il RELE, 
            se ho premuto il pulsante stato è uno e il RELE è attivato
            questo evita che il rele si distacchi, se non ci fosse stato ma low, il rele si stacca per poi tornare
            acceso, con la variabile stato evitiamo questo distacco */


   }// end else if()

}// end loop

torn24:
Vorrei proporre una soluzione postando il codice, sono poche righe. Tutti avrebbero potuto postare la soluzione ma volevano farti arrivare da solo a una soluzione! Io penso invece che anche scrivendo 4 righe e commentandole si possa imparare, e spesso avrei voluto che qualcuno si comportasse cosi con me "avrei imparato più velocemente " :slight_smile:

unsigned long tempo=0;

byte stato=0;
byte statopulsante=0;

void loop(){

if(digitalRead(PULSANTE, HIGH)){
   
        digitalWrite(RELE,HIGH); //Se il pulsante è premuto tengo attivo il rele
        statopulsante=1; // il pulsante è stato premuto

}else if(digitalRead(PULSANTE,LOW)&& statopulsante==1){
    / Se il pulsante è rilasciato e prima era premuto comincio il conteggio di 5 secondi
 
        tempo=millis();
        statopulsante=0; /*In questo modo questo codice viene eseguito una sola volta al rilascio del pulsante */
        while(millis()-tempo>=5000){// Il ciclo continua fino a che non sono passati 5 secondi
 
            if(digitalRead(PULSANTE,HIGH){ // Se in 5 secondi viene premuto il pulsante

stato=1; // Se premo il pulsante stato vale 1 e esco dal while
                    break;
              }else
                    stato=0; // altrimenti stato è uguale a zero
 
        }// end while

digitalWrite(RELE,stato);
        /* Esco dal while perché sono passati 5 secondi o perché è stato premuto il pulsante
            se sono passati 5 secondi senza premere il pulsante stato è zero e disattiva il RELE,
            se ho premuto il pulsante stato è uno e il RELE è attivato
            questo evita che il rele si distacchi, se non ci fosse stato ma low, il rele si stacca per poi tornare
            acceso, con la variabile stato evitiamo questo distacco */

}// end else if()

}// end loop

lo sai si che il tuo programma funzionerà al contrario col suo circuito... :wink:

Non ho guardato il circuito :slight_smile: Magari però è in grado di cambiare HIGH con LOW :slight_smile:

pep123456:

# define TASTO1 7

define LED1  8

int Stato1 = 0;

void setup()
{ pinMode(LED1, OUTPUT);     
pinMode(TASTO1, INPUT);}

void loop(){

Stato1 = digitalRead(TASTO1);

if (Stato1 == HIGH)
{ digitalWrite(LED1, LOW); 
delay(1000);}
else {digitalWrite(LED1, HIGH);}
}




QUESTO E LO SKETCH 
il problema e che mi fa la funzione inversa ovvero aspetta tot secondi prima di accendere un led

pep123456:

#define ledPin 13                   // Rinomina il pin 13 come ledPin

#define pulsantePin 2              // Rinomina il pin 2 come pulsantePin

int pulsanteState = 0;            // Variabile per leggere lo stato del pulsante

void setup() {
  pinMode(ledPin, OUTPUT);          // Imposta il ledPin come OUTPUT
  pinMode(pulsantePin, INPUT);        // Imposta il pulsantePin come INPUT
}
void loop(){
  pulsanteState = digitalRead(pulsantePin);  // Leggi lo stato del pulsante
  if (pulsanteState == HIGH) {            // Se il pulsantePin è HIGH accendi il led
    digitalWrite(ledPin, HIGH);       
  }
  else {                               
    digitalWrite(ledPin, LOW);          // Sennò spegni il led
  }
}



questa e un altra guida ma anchessa funziona all incontrario della sua descrizione

pare di no :smiley:

quindi vedi che se non ti rendi conto di come funziona... diventa solo un copia/incolla... senza polemiche neh... :smiley:

Non capisco cosa intendi ma non voglio approfondire :slight_smile:

Ha comunque un pulsante e un relè, premetto che di elettronica ho nozioni nulle, appunto per questo non capisco le difficoltà di cambiare un pulsante da pull up a pull down o cambiare il codice del programma.
Nel senso se non esiste nessun problema per me che non so nulla di elettronica, il problema deve essere veramente insignificante :slight_smile: :wink:

:smiley: dipende sempre da come affronti il problema, anch’io ho poche nozioni di elettronica… o per lo meno me le sono fatte strada facendo studiando gli argomenti che mi interessavano ovviamente

ma il fatto di aver realizzato un circuito :smiley: (messo un pulsante su una breadboard e averlo collegato tra gnd e un pin di arduino) senza capire prima cosa succede quando premo il pulsante
e poi aver caricato un programma di esempio e constatare che non funziona come uno si aspetta.
A questo punto bisogna fermarsi e ragionare… è davvero il programma che non funziona (visto che anche un altro programma simile va allo stesso modo) o c’è qualcosa di sbagliato nelle operazioni che compio?

e’ normale per un principiante (o come vuoi chiamarlo) potersi imbattere in queste cose apparentemente inspiegabili e concordo con te che è una cosa insignificante ma se non riesce a venirne fuori con il ragionamento, sarà complicato procedere con altri step, per questo dico che fornirgli il programma funzionante non serve, il programma che gli hai scritto è esattamente lo stesso di quelli che ha provato e continuerà a funzionare al contrario se non rivede il circuito o se non capisce che deve invertire la logica del pulsante
tutto qui :slight_smile:

pep123456:
...
Tengo pigiato un pulsante per un ora che mi eccita un relè, al mio rilascio se non ripigio il tasto il relè si diseccita dopo 5 seconti, ma se ripremo il pulsante prima dei 5 secondi acontinua a lasciare il relè eccitato. ...

Come sempre premetto che non essendo un programmatore, posso dare aiuto limitato ... ma credo che prima di tutto, dovresti chiarirci un'attimo questo ...

Allora ... finche' tieni premuto il pulsante, il rele' resta eccitato, e fin qui mi sembra chiaro ... nel momento in cui lo lasci, il rele' rimane eccitato per altri 5 secondi prima di diseccitarsi, ed anche qui mi sembra chiaro ...

...ma se ripremo il pulsante prima dei 5 secondi acontinua a lasciare il relè eccitato. ...

qui invece cosa intendi esattamente ... che se lo ripremi prima dei 5 secondi, il ciclo ricomincia da zero (cioe' rimane eccitato per tutto il tempo che lo ritieni premuto, piu i 5 secondi finali dopo che l'hai lasciato, e cosi via), OPPURE che se lo premi prima che scadano i 5 secondi, il rele' rimane sempre eccitato anche se poi lo rilasci ? ... perche' sono due casi diversi ...

Comunque, se e' il primo caso, forse puo funzionare cosi (da provare, e nel caso adattare)

unsigned long tempo=0;
byte stato=0;
//definire anche rele' e pulsante ovviamente

void loop()
  {
  if(digitalRead(PULSANTE, HIGH)) //se pulsante premuto
    {
    digitalWrite(RELE,HIGH);  // accendi rele', metti stato ad 1 e setta tempo a millis
    stato=1;                  // operazioni che anche se ripetute in continuazione non                       
    tempo = millis();         // interferiscono con il funzionamento del tutto
    }
  if(digitalRead(PULSANTE,LOW) && (stato == 1)) //pulsante rilasciato e rele' acceso
    {
    if (millis() - tempo >= 5000) // conteggio dei 5 secondi
      {
      digitalWrite(RELE,LOW); //spegne rele' dopo 5 secondi, ovviamente qui se si ripreme
      stato = 0;              //il pulsante prima che siano passati, il rele' rimane acceso
      }                       //ed il valore di tempo viene nuovamente settato a millis
    }                         //per cui il tutto riparte automaticamente dallo stato iniziale 
  }
}