Ritardo comando arduino

Salve a tutti, sono di nuovo qua per chiedere il vostro prezioso aiuto. Ho scritto questo sketch:

int led= 53;
int pulsante = 40;
int val=0;


void setup(){
  pinMode(53, OUTPUT);
  pinMode(40,INPUT);
}


void loop()
  {
    val = digitalRead(pulsante);
    if (val == HIGH) {
      delay(5000);
      digitalWrite(led , HIGH);
    }
    else if (val== LOW){
      digitalWrite(led, LOW);
    }
  }

edit by mod: per favore includi il codice usando gli appositi tag

Perchè vorrei che quando premo il pulsante il LED si accendesse dopo 5 sec. e si spegnesse subito dopo aver rilasciato il pulsante. Ma purtroppo con lo sketch da me scritto si accende dopo 5 sec. ma si spegne anche dopo 5 sec. . Qualcuno di voi mi può aiutare ?

Grazie mille a tutti.

Ciao, due cose devi tenere presente ...

  1. I pulsanti hanno sempre dei rimbalzi, quindi nel tuo codice devi implementare una tecnica anti rimbalzo per evitare che una pressione o un rilascio vengano letti come N pressioni e N riasci. Vedi QUI come.

  2. Non usare la funzione delay() che è bloccante e non ti permette il continuare l'esecuzione del tuo ciclo per il tempo di delay(). Guarda QUI invece come usare, per lo stesso scopo, la millis() in modo non bloccante.

Prova quindi a modificare il codice seguendo queste due indicazioni (... e facendoti un diagrammino logico di come vorresti che funzionasse, prima di scrivere il codice in C) e poi vediamo come va ... ;)

Guglielmo

P.S. : Cortesemente puoi racchiudere il codice all'interno degli appositi tag CODE (il bottoncino con il simbolo # che vedi quando editi il messaggio)

Grazie mille per la risposta, ora provo poi vi faccio sapere come va.

Salve, ho fatto svariate prove ma non riesco a raggiungere il mio scopo. Cioè quando premo il pulsante riesco a farlo accendere dopo 5 sec .ma non riesco a farlo spegnere appena rilascio il pulsante, passano sempre questi benedetti 5 sec. Mi aiutate? Grazie

Metti il nuovo codice che hai scritto (racchiudilo tra i tag CODE e correggi anche il tuo primo messaggio ... o prima o poi arriva il moderatore e ...) e vediamo cosa c'è che non va ... ;)

Guglielmo

gpb01: ( ... o prima o poi arriva il moderatore e ...)

]:D

salve a tutti, chiedo scusa al moderatore ma sono ancora un po’ nuovo nel forum e non sono ancora molto pratico. Ora posto il mio codice:

int led = 53;
int pulsante = 40;
int time;

void setup()
{
  pinMode( led, OUTPUT);
  pinMode(pulsante, INPUT);
  time = millis();
  
}

void loop()
{
  if(digitalRead(pulsante) == HIGH)
  if((time+5000)<millis()){
  
    digitalWrite(led, HIGH);
    time = millis();
  }
  if(digitalRead(pulsante) == LOW)
  {
    digitalWrite(led, LOW);
    time = millis();
  }
  
}

ho provato con questo sketch ma purtroppo dopo alcune pressione del pulsante non funziona più. Sapete come aiutarmi?
Grazie mille ancora a tutti per l’aiuto.

Hai un’Arduino Mega?

time deve essere dichiarato unsigned long.

const byte led = 53;
const pulsante = 40;
unsigned long time;

void setup()
{
  pinMode( led, OUTPUT);
  pinMode(pulsante, INPUT);
  time = millis();
}

void loop()
{
  if(digitalRead(pulsante) == HIGH)
    if((time+5000)<millis()){

      digitalWrite(led, HIGH);
      time = millis();
    }
  if(digitalRead(pulsante) == LOW)
  {
    digitalWrite(led, LOW);
    time = millis();
  }
}

Ridefiniamo le tue esigenze ... ... "vorrei che quando premo il pulsante il LED si accendesse dopo 5 sec. e si spegnesse subito dopo aver rilasciato il pulsante." ... e, da quanto hai detto, si capisce che tu vuoi :

  1. alla pressione di un pulsate si comincia a contare il tempo.
  2. se si tiene premuto il pulsante dopo 5 secondi il LED deve accendersi e rimanere acceso.
  3. se si rilascia il pulsante il LED si deve spegnere.

... e se si rilascia il pulsante prima dei 5 secondi ??? Non si deve accendere affatto ? Oppure ???

Dettaglia ESATTAMENTE le tue esigenze e vediamo come aiutarti a modificare quel codice ;)

Guglielmo

P.S. : Non vedo routines per il debouncing nel tuo codice ... P.S.2 : Come ti ha indicato PaoloP, la funzione millis() ritorna un unsigned long, non un int !!!

Ora mi spiego meglio.Vorrei far si che quando un sensore di posizione rileva la posizione di un oggetto che arriva da un nastro trasportatore dopo circa 5sec. fermi il nastro. Naturalmente al momento volevo simulare il tutto con un pulsante e un led. Spero di essermi spiegato meglio questa volta e mi scuso, ma sono alle prime armi con arduino. Grazie ancora a tutti voi.

P.S si ho un arduino mega

Ok, quindi hai un nastro trasportatore, quando arriva un oggetto e passa difronte ad un sensore, si aspettano 5 secondi e si ferma il nastro ... ... ma l'oggetto in questione già non è più davanti al sensore (... ha continuato a camminare per 5 secondi).

Tornando al tuo esempio del bottone de del LED, ora ci stai dicendo che [u]spingi e rilasci il bottone/u e che dopo 5 secondi si deve accendere il LED ( = dopo 5 secondi devi fermare il nastro).

E' giusto così ???

Guglielmo

Salve, il sensore ha un range di azione non regolabile, quindi devo dare almeno 5sec di range prima di far frmare il nastro. Perche l'oggetto si deve posizionare in un preciso punto e questo e garantito dal comando di ritardo del sensore sul motore. Appena mi e possibile posto delle foto del mio progetto. Grazie ancora per la sua disponibilita'.

lilosnow: Salve, il sensore ha un range di azione non regolabile, quindi devo dare almeno 5sec di range prima di far fermare il nastro. Perche l'oggetto si deve posizionare in un preciso punto e questo e garantito dal comando di ritardo del sensore sul motore. ...

... si, ma non hai risposto alla domanda ... quando l'oggetto si ferma, oramai ha lasciato l'area del sensore, giusto ? Ovvero, nel tuo esercizio con pulsante e LED, il pulsante viene premuto [u]e poi rilasciato[/u] e, a cinque secondi dalla pressione si accende il LED ... corretto ?

Guglielmo

Il tuo problema è simile a quello affrontato qui: http://forum.arduino.cc/index.php?topic=190328.0

Vedi se quel codice può esserti d'aiuto.

Ho avuto la tua stessa necessità e ho usato un Interrupt e un Timer, precaricato usando istruzioni C puro pur essendo in ambito IDE Arduino, o meglio, il C su base AVR.

Nel momento che schiacci il pulsante parte il Timer 16 bit, il quale dopo tot tempo alza l'Interrupt, si resetta e riparte con il nuovo tempo per il rilascio.

Il Timer a 16 bit non consente di avere tempi così lunghi in una sola iterazione, così, prima di sollevare l'interrupt, conto almeno una decina di passaggi per lo zero.

Se usi il delay potresti avere la sorpresa che i tempi non sono super-precisi, invece con il timer non ho avuto problemi di jitter misurabili, ovvero minimi ritardi tra input e output dovuti alle istruzioni che cmq un Interrupt impiega..

salve,

... si, ma non hai risposto alla domanda ... quando l'oggetto si ferma, oramai ha lasciato l'area del sensore, giusto ? Ovvero, nel tuo esercizio con pulsante e LED, il pulsante viene premuto e poi rilasciato e, a cinque secondi dalla pressione si accende il LED ... corretto ?

Guglielmo

l'oggetto quando si ferma non ha lasciato il sensore. La squenza e la segunte:

l'oggetto arriva sul nastro trasportatore entra ne raggio di azione del sensore dopo 5 sec ferma il nastro e l'oggetto si trova perfettamente davanti al sensore

Tutto questo perchè davanti al sensore si trova un pistoncino ad aria che deve pressare l'oggetto.

Come già detto in precedenza appena riesco inseriro delle foto del progetto per darvi maggior chiarezza.

Un ringraziamento a tutti per la vostra cortese disponibilità nel cercare di aiutarmi.

Ciao,

l'anomalia da te riscontrata nel codice del post originale, dipende ovviamente dall'uso della delay. Infatti, ad ogni ciclo, se il pulsante è HIGH il programma si ferma per 5 secondi. Se tu lasci il pulsante durante questi 5 secondi, il programma se ne accorgerà soltanto alla fine del delay. Quindi in realtà ho la sensazione che il led non si spegne dopo 5 secondi ma dopo un tempo variabile tra 0 e 5 secondi in base al tempo trascorso dall'ultima invocazione della delay.

Ciò premesso, proverei a modificare il tuo codice usando la millis, in questo modo:

int led= 53;
int pulsante = 40;
int val=0;
unsigned long highTime;

void setup()
{
     pinMode(53, OUTPUT);
     pinMode(40,INPUT);
     
     highTime = 0;
}


void loop()
{
     unsigned long now = millis();
     val = digitalRead(pulsante);

     if (highTime == 0)
     {
          if (val == HIGH) 
          {
               highTime = now;
               digitalWrite(led , HIGH);
          }
     } 
     else if (now - highTime >= 5000)
     {
          if (val == LOW) 
          {
               digitalWrite(led, LOW);
               highTime = 0;
          }
     }
}

highTime conserva l'istante in cui il pulsante è diventato HIGH e all'inizio vale 0. In questo stato ad ogni ciclo si entra nel primo if e si controlla se il pulsante è HIGH. Quando questa condizione si avvera conservo tale istante in highTime e accendo il led.

In questo stato ad ogni ciclo si comincia ad entrare nell'else che controlla se sono passati i 5 secondi (now - highTime >= 5000). Quando questa condizione si avvera ad ogni ciclo cominciamo a controllare che il pulsante sia LOW. Appena si avvera anche questa condizione, spengo il led e resetto highTime. Il ciclo ricomincia dal principio.

Ovviamente non ho testato il codice e può senz'altro essermi sfuggito qualcosa. Consideralo solo un punto di partenza per chiarire il concetto.

Ciao. V.

Salve a tutti inserisco delle foto del mio progetto per farvi capire meglio che cosa ho intenzione di fare e le foto del quadro di comando. Naturalmente nel post parlavo di pulsanti e led solo perchè prima voglio provare lo sketch su una breadboed .
Grazie ancora a tutti del vostro aiuto che risulta sempre molto prezioso

Salve a tutti, ho fatto le mie prove e funziona tutto perfettamente. Grazie mille a tutti per la vostra enorme disponibilità ad aiutare un principiante come me. :D :D :D :D