lampeggio led di un cancello scorrevole

salve a tutti,
sto progettando un cancello scorrevole in scala da presentare agli esami di terzo superiore.
mi servirebbe aiuto per programmare un lampeggio (uguale a quello di tutti i cancelli) che cominci quando il cancello si aziona e termini quando il cancello ritorni nella posizione di origine.
lo sketch per ora è questo

#include <IRremote.h> // use the library

int receiver = 12; // pin 1 of IR receiver to Arduino digital pin 11
IRrecv irrecv(receiver); // create instance of 'irrecv'
decode_results results;
int finecorsa;
int finecorsa2;
void setup()
{
  Serial.begin(9600); // for serial monitor output
  irrecv.enableIRIn(); // Start the receiver
  pinMode(8, OUTPUT);
  pinMode(2,  INPUT);
  pinMode(6, OUTPUT);
  pinMode(9,  INPUT);
  pinMode(7,OUTPUT);
 
}
void loop()
{
finecorsa=digitalRead(2);
finecorsa2=digitalRead(9);
  
  if (irrecv.decode(&results))
  { Serial.println(results.value, HEX); 
    irrecv.resume();
    if ( results.value == 5 || results.value == 805 )
    { digitalWrite(8, HIGH); 
    
    } 
    if ( results.value == 2 || results.value == 802 ) 
    { digitalWrite(6, LOW); 
    }  
  }
  if (finecorsa==HIGH)
  { digitalWrite(8, LOW);
  delay(5000);
  digitalWrite(6, HIGH);
  }
if (finecorsa2==HIGH){
  digitalWrite(6,LOW);
  digitalWrite(8,LOW);
}  

}

ps l'output 7 dovrebbe essere il led che deve lampeggiare

La tua soluzione si chiama ... millis() ...
... puoi studiarti QUESTO primo articolo e poi QUESTO altro.

Poi c'è anche QUESTO tutorial ...

Se studi bene i primi due link ... non avrai alcun problema a fare ciò che vuoi :wink:

Guglielmo

l'ho capito però non sò come utilizzarlo nel mio sketch

O magari questo:
http://forum.arduino.cc/index.php?topic=220669.msg1608184#msg1608184

@ferri, a me questo funziona.

già lo avevo provato ma ti ho già detto che rimane sempre acceso, tu mi hai risposto che avevi i pulsanti sempre in high mentre io ce l'ho in low

ferrif97:
già lo avevo provato ma ti ho già detto che rimane sempre acceso, tu mi hai risposto che avevi i pulsanti sempre in high mentre io ce l'ho in low

Si ma il codice che ti ho messo l'ho cambiato per te, mica ti ho dato il mio originale. Logico che non potevo darti il mio.

ferrif97:
l'ho capito però non sò come utilizzarlo nel mio sketch

Prima di tutto ti occorre una variabile che usi come un indicatore per ricordarti se devi far lampeggiare o meno il LED. Se la metti a false il led NON dovrà lampeggiare, se la metti a true il LED dovrà lampeggiare.

Una volta che hai questa, all'interno del IF dove la verificherai ... userai un'ulteriore variabile che ogni tot millis() invertirai e ... il suo utilizzo su un pin digitale accenderà e spegnerà il LED.

Questi sono i punti base su cui devi lavorare ...
... se hai veramente studiato i link che ti ho dato .. puoi farlo senza problemi :wink:

Guglielmo

Sempre più programmatori provetti hanno difficoltà ad usare la funzione millis(), forse perché non la comprendono.
Noi umani non siamo bravi a fare conteggi di tempo e questo si sa.

Se guardo l'orologio continuamente sto controllando in loop l'orario.
Su un foglio di carta, scrivo a matita il nome del timer che voglio controllare e accanto il valore.
myTimer =
Per me umano MyTimer = significa che ancora non ho preso il tempo di inizio, quindi posso considerare nullo o
zero MyTimer.

If (myTimer == 0)
myTimer = millis(); // equivale a leggere l'orario dall'orologio che ho al polso e scriverlo nel pezzo di carta.

Per cui nel pezzo di carta aggiorno il valore di myTimer:
myTimer = 10000 (diecimila)

Adesso myTimer non è più nullo o zero per cui myTimer = millis(); non viene più eseguito, e mi pare ovvio,
io prendo il tempo dal mio orologio una sola volta, ma sto sempre guardando l'orologio al polso.

L'orario scorre e millis() adesso restituisce un tempo maggiore a quello che ho scritto prima sul pezzo di carta.
La sottrazione di millis() - myTimer = ??. Il risultato dipende da quanto tempo è passato, supponiamo siano passati 1001 millesimi di secondo, quindi il calcolo millis() - myTimer = 1001.

Se io voglio compiere una azione ogni secondo, nel mentre che guardo l'orologio eseguo continuamente un controllo logico basato su un calcolo.
if ( ( millis() - myTimer ) > 1000)
; //eseguo l'azione perché sono passati più di 1000 millesimi di secondo (cioè 1 secondi)

Il calcolo (la sottrazione) lo eseguo prima della condizione logica > (magiore di), infatti notate le parentesi evidenziate:
( millis() - myTimer )
Supponiamo che la sottrazione l'abbia già eseguita:
if (1001 > 1000)
; eseguo l'azione.

Ci vuole un millesimo di secondo a valutare la condizione logica, basta uno sguardo e sappiamo che
1001 è maggiore di 1000 per cui il test è vero e quindi:
if (vero)
; eseguo l'azione.

Una delle prime cose da fare quando si esegue l'azione è quella di azzerare la variabile del timer, per cui
if ( (millis() - myTimer)) > 1000) { // uso le graffe per aprire un blocco di codice necessario quando ci sono più
istruzioni nel corpo della if.
myTimer = 0; Equivale a cancellare il valore dal pezzo di carta e al suo posto scriverci zero.
// qui scrivi il tuo codice corrispondente alla/e azione/i
}

Ricapitolando:
// Dichiaro una variabile di tipo unsigned long con nome a scelta, es. myTimer (usate il nome che preferite)

unsigned long myTimer;  /* es. il timer usato per la tastiera (in questo caso è meglio cercare un nome migliore di
                                                    myTimer*/

#define MYTIMER_ELAPSED      1000

void loop() {

    if (myTimer == 0) // è molto efficiente perché esiste una istruzione assembly equivalente a if (variabile == 0) salta
        myTimer = millis();  // mi annoto il tempo nel pezzo di carta
        // nota come non ho usato le graffe. Non servono e sono opzionali se c'è una solo istruzione nel blocco della if
        // Sostanzialmente equivale a dire che il blocco implicito della if è grande una sola istruzione, se voglio
        // estendere tale blocco devo usare le graffe {}. 

    if ( (millis()  - myTimer) > MYTIMER_ELAPSED ) {
        myTimer = 0;   // azzero il mio timer
        // qui scrivi il codice corrispondente alle azioni da intraprende. Nota l'uso delle graffe

    }
     
}

Spero sia di aiuto a chi si confonde davanti a millis e finisce per usare delay, che può essere usato
con valori di pochi millesimi di secondo senza avere effetti disastrosi. Valori di delay accetabili vanno da 1 a
200, però se nel codice ci sono 20 delay(200) la cpu sta a contare per 4 secondi e allora conviene ricorrere a millis()

Ciao.

Grazie Maurotec,
la tua spiegazione mi ha aiutato un pò nella comprensione, ora cerco di convertire le tue spiegazioni nel mio sketch

non riesco a mettere la funzione millis nel mio sketch.

Hai letto QUESTO mio post ?

Hai dichiarato una variabile che indica se il led deve o non deve lampeggiare e l'hai gestita ?
Hai dichiarato una variabile che indica se il led è acceso o spento (per il lampeggio) ?

Hai messo a vero o falso la variabile che indica se il led deve lampeggiare o meno nei giusti punti ?

Hai nel loop() fatto un IF che verifica se quella variabile è vera (deve lampeggiare) o falsa (non deve lampeggiare) ?

All'interno di quel IF non dovrai fare altro che ...
... guardare se sono passati N millisecondi, se NO, non fare nulla, se SI, azzerare il contatore e invertire la condizione del led (se on va a OFF e viceversa).

Quando hai buttato giù, in modo ordinato il tutto, posta il codice e vediamo di correggere cosa non va ...

Guglielmo

Ti do una mano anch'io, in pseudo-codice:

lampeggio = 0 //lampeggio oppure no?
led = 0 //stato led
tempo = 0 //tempo del lampeggio
cancello = 0 //cancello fermo
ciclo:
if cancello = 1 //ho acceso il cancello
  if lampeggio  = 0 //ho acceso il lampeggio? no
    lampeggio = 1
    led = 1
    tempo = millis
  end if
else //il cancello si è fermato
  if lampeggio = 1 //il lampeggio è ancora acceso? sì
    led = 0 //spengo il led
    lampeggio = 0 //fermo il lampeggio
  end if
end if

if lampeggio = 1 //devo far lampeggiare il led? sì
  if millis - tempo > intervallo //devo cambiare stato al led
    inverto led //inverto lo stato del led
    tempo = millis //mi risalvo il tempo
  end if
end if

Sono le 7:50, non è un codice vero, l'ho buttato giù di getto, ma dovrebbe fare quel che ti serve. Ovviamente lo devi trasformare in codice arduinico :wink: