domenica 31 ottobre 2010

Arduino: semaforo (versione 2)

Vi ricordate il semaforo visto ieri? Il circuito mostrato sopra ne estende le capacità aggiungendo adesso un bottone (collegato al pin 3) per l'attraversamento dei pedoni. L'interazione è come sempre gestita attraverso il software. Qui trovate il codice sorgente per l'IDE di Arduino.
Per questo sketch ho usato la libreria Metro per Arduino. All'interno del programma mi occorreva qualcosa che mi liberasse dal conteggio del tempo per dedicarmi alla gestione del bottone. La libreria Metro fa proprio questo! Qui trovate la pagina che spiega come installarla e utilizzarla all'interno dell'IDE. Fondamentalmente, una volta importato l'header (Metro.h) occorre creare una variabile per il conteggio con l'omonimo costruttore Metro(interval), dove interval è un unsigned long ed esprime l'intervallo di conteggio (in millisecondi) per la variabile dichiarata. In altre parole la variabile, appena viene dichiarata, fa scorrere il tempo fino all'intervallo di tempo impostato. Con il metodo reset() è possibile far ripartire il conteggio. Esiste un secondo costruttore che prevede come secondo argomento un valore logico che, se settato a true, fa ripartire il conteggio automaticamente.
Il metodo più importante offerto dalla libreria, a mio avviso, è il metodo check(). Questa funzione ritorna true se l'intervallo di tempo impostato nel costruttore è passato, altrimenti restituisce false. Se abbiamo bisogno di modificare l'intervallo di tempo da conteggiare va usato il metodo interval(new_interval), dove new_interval è un unsigned long che esprime (in millisecondi) il nuovo intervallo di tempo.
Dopo aver dichiarato dove sono mappati i led ed il bottone, ho dichiarato le costanti di tempo usate per le pause nel corso del programma. Ogni nuova costante di tempo per la durata di un led va quindi modificata nella parte iniziale del codice. Il programma usa due variabili globali, una per segnare lo stato del bottone e una per la presenza di pedoni. In realtà lo stato delle due variabili coincidono: se il bottone è stato premuto è evidente che ci sono pedoni! Tuttavia, per facilitare la gestione del codice ho deciso di tenere separate le due variabili, i cui stati sono gestiti in diversi istanti del ciclo di funzionamento.
La variabile Metro è dichiarata solo in una funzione (green_light()), a livello locale quindi, sicché nessun'altra funzione può interferire con il conteggio. La stessa funzione fa quindi partire il timer (variabile timer) e accende la luce verde. L'istruzione per verificare lo stato del bottone (button_stat=digitalRead(BUTTON)) è inserita in un ciclo do-while() la cui condizione di uscita è la verifica del timer con timer.check(). Tale ciclo può allora terminare per due motivi: per la fine del conteggio, per un cambiamento di stato del bottone. Quest'ultimo evento viene eventualmente segnato nella variabile globale people, in questo modo la funzione red_light() saprà se aggiungere un ulteriore tempo alla sosta delle macchine (per permettere a più pedoni di attraversare).

4 commenti:

  1. Volendo mettere 2 semafori, come posso impostare il programma?, sempre utilizzando un bottone per il passaggio pedonale?

    RispondiElimina
  2. L'ideale, perché secondo me più vicino alla realtà, sarebbe gestire i due semafori con due schede Arduino che si sincronizzano tra di loro, attraverso dei segnali.
    Sfruttando, invece, il codice già scritto per questo esempio si potrebbe seguire la soluzione che sintetizzo di seguito:

    1) Nella funzione green_light applicare questa sequenza di istruzioni:
    accendi_R2
    accendi_V1
    spegni_V1

    2) Nella funzione red_light applicare questa sequenza di istruzioni:
    accendi_R1
    accendi_V2
    wait T2_V
    accendi_G2
    wait T2_G
    spegni_R1
    spegni_G2

    Dove: G1, R1, e V1 sono le luci del primo semaforo e G2, R2 e V2 quelle del secondo semaforo. T2_V e T2_G sono, rispettivamente, la durata della luce verde e gialla del secondo secondo semaforo.

    RispondiElimina
  3. come posso allungare i tempi del semaforo!

    RispondiElimina
  4. Nell'intestazione del codice, oltre ai pin della scheda usati come output, sono state definite delle costanti di tempo (in secondi):

    #define RED_TIME 20
    #define YELLOW_TIME 5
    #define GREEN_TIME 30

    per regolare gli intervalli di tempo da applicare ai tempi del semaforo ;)

    RispondiElimina