TEMPORIZZATORI

Salve a tutti ,

Vengo subito al sodo;

Ho realizzato un piccolo circuito per testare il funzionamento di una scheda con 4 rele.

Ho utilizzato quindi 4 pulsanti che a loro volta comandano singolarmente i 4 rele , ma siccome l'appetito vien mangiando mi sono spinto un pelino oltre in quanto vorrei che il mio programma funzionasse in questo modo:

Per comodità prenderò in esame solo una canale

  1. premo il pulsante
  2. accendo il rele
  3. rilascio il pulsante
  4. attendo i secondi impostati
  5. spengo il rele

e tutto questo lo vorrei fare su ogni rele indipendentemente come se fossero dei temporizzatori singoli.

invece il mio test funziona in questo modo:

  1. premo il pulsante (qualche secondo di attesa)
  2. accendo il rele
  3. rilascio il pulsante
  4. attendo i secondi impostati
  5. spengo il rele

Per comodità prenderò in esame solo una canale

scusate gli errori ortografici (ma come dico sempre) le correzioni sono ad esclusivo carico di chi legge!

Grazie in anticipo

// Gestione di 4 ingressi e quattro uscite a rele di cui 2 temporizzate

const int buttonPin1 = 13;     // assegna indirizzo ingresso
  const int buttonPin2 = 12;     // assegna indirizzo ingresso
    const int buttonPin3 = 11;     // assegna indirizzo ingresso
      const int buttonPin4 = 10;     // assegna indirizzo ingresso

        const int ledPin1 =  7;      // assegna indirizzo uscita
      const int ledPin2 =  6;      // assegna indirizzo uscita
    const int ledPin3 =  5;      // assegna indirizzo uscita
  const int ledPin4 =  4;      // assegna indirizzo uscita

int buttonState1 = 0;         // azzera la variabile
  int buttonState2 = 0;         // azzera la variabile
    int buttonState3 = 0;         // azzera la variabile
      int buttonState4 = 0;         // azzera la variabile

// definizione uscite

void setup() {
  
  pinMode(ledPin1, OUTPUT);
   pinMode(ledPin2, OUTPUT);
    pinMode(ledPin3, OUTPUT);
     pinMode(ledPin4, OUTPUT);

// definizione ingressi
  
  pinMode(buttonPin1, INPUT);
   pinMode(buttonPin2, INPUT);
    pinMode(buttonPin3, INPUT);
     pinMode(buttonPin4, INPUT);
}

void loop() {
  
  buttonState1 = digitalRead(buttonPin1); // leggi lo stato del pin13
  
    if (buttonState1 == HIGH) {             // se il pulsante è alto
        delay(2000);                        // aspetta 2sec
        digitalWrite(ledPin1, HIGH);        // scrivi lo stato alto del pin7
              } else {                      // atrimenti
        digitalWrite(ledPin1, LOW);         // scrivi lo stato basso del pin7
  }
  
  buttonState2 = digitalRead(buttonPin2); 
  
  if (buttonState2 == HIGH) {
        delay(2000);
        digitalWrite(ledPin2, HIGH); 
              } else {
        digitalWrite(ledPin2, LOW);
  }
  
  buttonState3 = digitalRead(buttonPin3); 
  
  if (buttonState3 == HIGH) {
        delay(2000);
        digitalWrite(ledPin3, HIGH);
              } else {
        digitalWrite(ledPin3, LOW);
  }
  
   buttonState4 = digitalRead(buttonPin4); 
   
  if (buttonState4 == HIGH) {
        delay(2000);
        digitalWrite(ledPin4, HIGH);
              } else {
        digitalWrite(ledPin4, LOW);
  }
  
}

scusate ho commesso un errore nella spiegazione del funzionamento:

  1. premo il pulsante
    2.attendo i secondi impostati
  2. accendo il rele
  3. rilascio il pulsante
  4. spengo il rele

mentre funziona cosi:

  1. premo il pulsante
    2.attendo i secondi impostati
  2. accendo il rele
  3. rilascio il pulsante
    pausa du qualche secondo
  4. spengo il rele

hai messo le resistenze di pull-down sui pulsanti....

Il problema è il delay()...devi usare millis()...cambiando ovviamente l'impostazione del programma.

ORSO2001:
Il problema è il delay()...devi usare millis()...cambiando ovviamente l'impostazione del programma.

se il problema è sul ritardo nello spegnimento... non credo siano i delay presumo che il pin dell'interruttore non vada subito a zero quando rilasciato

ad ogni modo servirebbe anche lo schema elettrico

sicuramente serve che il tutto sia cablato a dovere (resistenze incluse)...però se ci pensi bene al rilascio del pulsante avrà sempre un effetto di ritardo di 2 secondi dato da delay()...perchè la prima cosa che fa è la verifica dell'if...se premuto aspetta 2 secondi ...la verifica se tasto ancora premuto o no lo fa dopo questi

Patrick_M:
hai messo le resistenze di pull-down sui pulsanti....

certo sotto il punto di vista elettrico non ho alcun problema , in una versione precedente di questo sketch, cioè quella con l'accensione ON OFF non ho alcun problema

ORSO2001:
sicuramente serve che il tutto sia cablato a dovere (resistenze incluse)...però se ci pensi bene al rilascio del pulsante avrà sempre un effetto di ritardo di 2 secondi dato da delay()...perchè la prima cosa che fa è la verifica dell'if...se premuto aspetta 2 secondi ...la verifica se tasto ancora premuto o no lo fa dopo questi

si certo.... hai ragione :grinning:

ORSO2001:
sicuramente serve che il tutto sia cablato a dovere (resistenze incluse)...però se ci pensi bene al rilascio del pulsante avrà sempre un effetto di ritardo di 2 secondi dato da delay()...perchè la prima cosa che fa è la verifica dell'if...se premuto aspetta 2 secondi ...la verifica se tasto ancora premuto o no lo fa dopo questi

assodato che tutto è stato cablato correttamente questa è un interessante considerazione ...... quindi?

di seguito un esempio che puoi provare per un pulsante collegato al pin 2 che, se premuto per più di due secondi accende il LED di arduino collegato al pin 13...se pulsante rilasciato si spegne subito:

#define PULS 2
#define RELE 13
unsigned long myMillis;


void setup() {
  pinMode(PULS, INPUT);
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, LOW);

}

void loop() {
  if (!digitalRead(PULS)) {
    myMillis = millis();
  }
  if (millis() - myMillis >= 2000) {
    digitalWrite(RELE, HIGH);
  }
  else {
    digitalWrite(RELE, LOW);
  }
}

ORSO2001:
di seguito un esempio che puoi provare per un pulsante collegato al pin 2 che, se premuto per più di due secondi accende il LED di arduino collegato al pin 13...se pulsante rilasciato si spegne subito:

#define PULS 2

#define RELE 13
unsigned long myMillis;

void setup() {
 pinMode(PULS, INPUT);
 pinMode(RELE, OUTPUT);
 digitalWrite(RELE, LOW);

}

void loop() {
 if (!digitalRead(PULS)) {
   myMillis = millis();
 }
 if (millis() - myMillis >= 2000) {
   digitalWrite(RELE, HIGH);
 }
 else {
   digitalWrite(RELE, LOW);
 }
}

ho provato il tuo codice ma fà quasi la stessa cosa .....

se hai provato esattamente il mio codice...cioè con un solo pulsante e facendo riferimenti al LED_BUILTIN di arduino (quello sulla scheda)...è impossibile che non si spenga subito al rilascio del pulsante...salvo problemi hardware/cablaggio...io l'ho testato con il PIN 2 impostato come INPUT_PULLUP e quindi devo chiudere il pulsante verso GND per cambio stato...e quindi la logica di lettura del PIN 2 è invertita...ma ti garantisco che funziona...controlla le pull down...pubblica lo schema di come hai cablato

con la scheda nuda :slight_smile:
cambia

pinMode(PULS, INPUT);

in pinMode(PULS, INPUT_PULLUP);

compila e trasferisci

collegando a gnd il pin 2 con un cavetto
e farà esattamente questo

  1. premo il pulsante
    2.attendo i secondi impostati
  2. accendo il rele
  3. rilascio il pulsante
  4. spengo il rele

come dice ORSO2001

edit no, fino a quando non rilascio il pulsante non parte il conteggio del tempo e il led non si accende... io l'ho modificato così

#define PULS 2
#define RELE 13

unsigned long myMillis;

boolean flag = false;

void setup() {
  pinMode(PULS, INPUT_PULLUP);
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, LOW);
}

void loop() {
  if (!digitalRead(PULS) && (flag==false)) {
    myMillis = millis();
    flag=true;
  }
  if ((millis() - myMillis >= 2000) && (flag==true)) {
    digitalWrite(RELE, HIGH);
    flag= false;
  }
  else if (digitalRead(PULS)){
    digitalWrite(RELE, LOW);
  }
}

non capisco...in questo caso il flag pulsante non serve...ragioniamo....:

millis avanza
pulsante NON premuto ->mioTempo = millis
è millis > di mioTempo di 2 secondi -> NO

millis avanza
pulsante premuto ->non salvo più millis in mioTempo
è millis > di mioTempo di 2 secondi -> se mantengo premuto il pulsante si

a me funziona alla grande...così:

#define PULS 2
#define RELE 13

unsigned long myMillis;

void setup() {
  pinMode(PULS, INPUT_PULLUP);
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, LOW);
}

void loop() {
  if (digitalRead(PULS) == HIGH) {
    myMillis = millis();
  }
  if (millis() - myMillis >= 2000) {
    digitalWrite(RELE, HIGH);
  }
  else {
    digitalWrite(RELE, LOW);
  }
}

Buongiorno, sono riuscito finalmente a venirne a capo ...... ho modificato qualcosa rispetto lo sketch di ORSO e ho cambiato qualcosa anche sul cablaggio.

#define PULS1 13 
#define PULS2 12
#define PULS3 11
#define PULS4 10

#define RELE1 7
#define RELE2 6
#define RELE3 5
#define RELE4 4

unsigned long myMillis1;
unsigned long myMillis2;
unsigned long myMillis3;
unsigned long myMillis4;

void setup() {
  
  pinMode(PULS1, INPUT);
  pinMode(PULS2, INPUT);
  pinMode(PULS3, INPUT);
  pinMode(PULS4, INPUT);
  
  pinMode(RELE1, OUTPUT);
  pinMode(RELE2, OUTPUT);
  pinMode(RELE3, OUTPUT);
  pinMode(RELE4, OUTPUT);
  
  digitalWrite(RELE1, LOW);
  digitalWrite(RELE2, LOW);
  digitalWrite(RELE3, LOW);
  digitalWrite(RELE4, LOW);

}

void loop() {
  
  if (!digitalRead(PULS1)) {
    
    myMillis1 = millis();
  }
  if (millis() - myMillis1 >= 2000) {
    digitalWrite(RELE1, LOW);
  }
  else {
    digitalWrite(RELE1, HIGH);
  }

if (!digitalRead(PULS2)) {
    
    myMillis2 = millis();
  }
  if (millis() - myMillis2 >= 2000) {
    digitalWrite(RELE2, LOW);
  }
  else {
    digitalWrite(RELE2, HIGH);
  }

if (!digitalRead(PULS3)) {
    
    myMillis3 = millis();
  }
  if (millis() - myMillis3 >= 2000) {
    digitalWrite(RELE3, LOW);
  }
  else {
    digitalWrite(RELE3, HIGH);
  }

if (!digitalRead(PULS4)) {
    
    myMillis4 = millis();
  }
  if (millis() - myMillis4 >= 2000) {
    digitalWrite(RELE4, LOW);
  }
  else {
    digitalWrite(RELE4, HIGH);
  }

 }

adesso il programma fà esattamente ciò che volevo

bene!
...comunque a me sembra esattamente quello che avevo postato la prima volta ripetuto per 4 pulsanti... :wink:

poi se vuoi si possono evitare tutti quegli if/else creando delle array e usando for().

ORSO2001:
non capisco...in questo caso il flag pulsante non serve...ragioniamo....:

millis avanza
pulsante NON premuto ->mioTempo = millis
è millis > di mioTempo di 2 secondi -> NO

millis avanza
pulsante premuto ->non salvo più millis in mioTempo
è millis > di mioTempo di 2 secondi -> se mantengo premuto il pulsante si

a me funziona alla grande...così:

#define PULS 2

#define RELE 13

unsigned long myMillis;

void setup() {
  pinMode(PULS, INPUT_PULLUP);
  pinMode(RELE, OUTPUT);
  digitalWrite(RELE, LOW);
}

void loop() {
  if (digitalRead(PULS) == HIGH) {
    myMillis = millis();
  }
  if (millis() - myMillis >= 2000) {
    digitalWrite(RELE, HIGH);
  }
  else {
    digitalWrite(RELE, LOW);
  }
}

Si hai ragione mi ha inganato il tuo discorso successivo riferito alla input_pullup per cui ragionavo al contrario :slight_smile:

usando la negazione nell'if e il pullup funziona anche il mio :slight_smile:
ovviamente è più semplice togliere la negazione e anche il flag...

ORSO2001:
bene!
...comunque a me sembra esattamente quello che avevo postato la prima volta ripetuto per 4 pulsanti... :wink:

poi se vuoi si possono evitare tutti quegli if/else creando delle array e usando for().

certo è esattamente il tuo codice ma se noti ho dovuto invertire gli stati del pulsante e del rele (ma forse è dovuto al cablaggio)

Lavorare per semplificare il codice è un lavoro che ho intenzione di fare ......