Accendere pin dopo tot secondi di un evento

Avrei la necessità di fare quanto segue:

leggo lo stato alto su un pin (x) se non ne segue un altro dopo tot secondi, sempre sul pin x, attivare un altro pin (y).

Qualche suggerimento?

Ho fatto una cosa simile utilizzando due cicli while dai un'occhiata al mio topic .

tonid:
Ho fatto una cosa simile utilizzando due cicli while dai un'occhiata al mio topic .

se ci mettevi un link magari :roll_eyes:
http://arduino.cc/forum/index.php/topic,128862.0.html

Hai ragione ma gli ho risposto appena ha fatto la domanda ed i due topic erano uno sotto l'altro :wink:

Si infatti l'avevo trovato.
Grazie lo stesso pablos

Ci ho provato ma non ci sono riuscito o non ho capito come fare dal topic che mi avete segnalato o mi sono spiegato male io.
Ricapitolo quello che devo fare.

Impulso sul pin x
Allo spegnimento del primo impulso controllo che non arrivi un altro impulso sul pin x in s millisecondi (da poter regolare)
Se arriva all'interno dell'intervallo s attivo pin y altrimenti ricomincio da capo.
Se arriva un altro impulso sul pin x quando il pin y è attivo disattivo pin y.

Spero di essermi spiegato.

Ma l'hai guardato l'esempio che ti hanno linkato?

Un ciclo while imbriglia l'esecuzione in un loop da cui se ne può uscire solo al verificarsi di un evento.
Tu vuoi controllare che arrivi un impulso, attivare un contatore e poi controllare prima del timeout che non arrivi un altro impulso. Se entrambe le condizioni si verificano, attivi un altro pin.
Come vedi sono 2 condizioni annidate quindi un while dentro l'altro. E' ciò che ha fatto tonid nel suo codice.

Sisi ma non sono riuscito ad impiegarlo per il mio scopo.
Ritenterò.

Intanto questo è il codice che ho scritto.
Se qualcuno ha voglia di darci un'occhiata.... :stuck_out_tongue:

byte x = 8;
byte y = 13;
byte xVal = LOW; 
byte yVal = LOW;

boolean xAccesa = false;
boolean appo = false;
unsigned long interval=200000;
unsigned long tempoSpenta;

void setup()  
{
  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  Serial.println("Pronti");

  pinMode(x, INPUT); 
  pinMode(y, OUTPUT); 
  digitalWrite(y, LOW); // Spengo il led L sulla scheda
}

void loop()
{  
  xVal = digitalRead(x);  // Leggo lo stato del pin x, finchè è off non faccio nulla.
  xAccesa=xVal;

  // Quando è on blocco l'esecuzione del loop finchè non diventa off
  while(xAccesa){
    yVal=LOW;
    digitalWrite(y, yVal);

    xVal = digitalRead(x);  // read input value
    xAccesa=xVal;
    appo=true;
    Serial.println("qui");
  }
  
  // Uscito dal loop prendo il tempo di uscita
  tempoSpenta=millis();

  if ( appo ){
	// Se è entrato nel while precedente vuol dire che c'è stato un impulso
    appo=false;

	// Attendo per vedere se c'è un secondo impulso
    while(millis()<(tempoSpenta + interval)){
      xVal = digitalRead(x);  // read input value
      xAccesa=xVal;
      Serial.println("qui1");
      if ( xAccesa ){
        yVal=LOW;
        break;
      }
      else{
        yVal=HIGH; 
      }
    }
  }

  digitalWrite(y, yVal);
}

Nessuno? =(

erpomata:
Intanto questo è il codice che ho scritto.
Se qualcuno ha voglia di darci un'occhiata.... :stuck_out_tongue:

La domanda è: ti funziona? Fa cioè quello che volevi tu?

E no altrimenti....

erpomata:
Sisi ma non sono riuscito ad impiegarlo per il mio scopo.
Ritenterò.

Ok non mi volete aiutare.
=(

erpomata:
Ok non mi volete aiutare.
=(

Forse confondi il forum con il corso di informatica :stuck_out_tongue:
Qui nessuno ti insegna a programmare, devi farlo da solo. Se hai un problema puoi pubblicare il tuo sketch, dire cosa fa e cosa invece dovrebbe fare.

Ti sono stati dati dei link, ti è stato dato un codice corrispondente a quello che devi fare tu, se non ho capito male, e poi ti sono state date delle dritte.
Hai pubblicato un tuo programma e chiedi se va bene. Alla mia domanda se il codice funziona, hai risposto citando un tuo post in cui dici che non ti funziona. E cos'è che non funziona? Siamo al cane che si morde la coda.

Non chiedo un corso, ma una idea per la soluzione.
Ho letto il topic che mi avete suggerito, però, secondo me non centra nulla col mio problema.

erpomata:
Avrei la necessità di fare quanto segue:

leggo lo stato alto su un pin (x) se non ne segue un altro dopo tot secondi, sempre sul pin x, attivare un altro pin (y).

Qualche suggerimento?

Ripartiamo da qui.

In pseudo-codice:

loop
--leggo il pin
--è HIGH?
----sì - chiamo checkPin

checkPin
--prendo il tempo
--inizio un ciclo
----se il pin non è più HIGH, esco
----quanto è passato? 5 secondi?
----no, torno su
----esco
--quanto tempo è passato? 5 secondi?
----sì, allora accendo il pin Y

Ciao a tutti.

Forse ho inteso male la richiesta ma io ho capito che alla prima pressione di un pulsante comincio a contare un tempo. Se trascorso un certo ritardo non ricevo una seconda pressione, accendo il led. Se invece ricevo una seconda pressione entro il ritardo prefissato, non succede nulla e si riparte da zero.

In generale non condivido dei cicli che bloccano il loop principale. Questo perchè impedirebbero l'esecuzione di altre funzioni in contemporanea. Magari non è questo il caso ma lo dico solo per esprimere un concetto generale.

Io farei così:

int led = 13;
int button = 12;
unsigned long startTime;
unsigned long delay = 5000;
bool firstClick;

void setup() 
{                
	firstClick = true;
	pinMode(button, INPUT);     
	pinMode(led, OUTPUT);     
}

void loop() 
{
	if (digitalRead(button) == HIGH)
	{
		if (firstClick) startTime = millis();
		
		firstClick = !firstClick;
	}
	
	if (!firstClick)
	{
		unsigned long elapsedTime =  millis() - startTime
		if (elapsedTime > delay)
		{
			firstClick = true;
			digitalWrite(led, HIGH);
		}
	}

              // qui posso inserire altro codice che viene comunque eseguito ad ogni ciclo
}

All'inizio firstClick vale true e sono in attesa della prima pressione. Se il pin va HIGH e sono in attesa della prima pressione (firstClick=true), faccio partire il tempo impostando startTime al valore attuale di millis(). In ogni caso cambio il valore di firstClick. In questo modo se era true parte il tempo, altrimenti vuol dire che ho ricevuto la seconda pressione e devo ripartire da zero.

Poi controllo se firstClick è false (vuol dire che sono in attesa della seconda pressione). In questo caso vedo quanto tempo è trascorso (millis() - startTime). Se il tempo trascorso è maggiore del ritardo richiesto (delay = 5000, 5 secondi perchè espresso in millisecondi), accendo il led e rimetto firstClick a true per ripartire da capo.

Come dicevo, dove ho inserito il commento è possibile inserire altro codice che viene eseguito ad ogni ciclo dato che il loop principale gira sempre.

A proposito, non ho capito chi spegne il led...

Non ho provato il codice e magari mi è sfuggito qualcosa. Nel caso, parliamone.

Ciao.
Vittorio.

Grazie per le soluzioni vedrò di implementarle.
Ma il problema è che il primo click come i successivi possono durare indefinitivamente quindi io ho ragionato sul passaggio da alto a basso, cioè sul rilascio del pulsantino.
Se dopo x secondi non arriva un secondo click accendo il led.

Il led si spegne se arriva un altro click dopo x secondi, cioè dopo che si è acceso.