Dopo la pubblicazione dei miei sketch, ricevo spesso domande sul perché al loro interno vada a definire degli stati e più in generale su cosa sia una macchina a stati finiti. In questo tutorial, spiegherò come utilizzare tale modello per realizzare un semplice timer.
SimpleTimer
Utilizzeremo Arduino per realizzare un timer giornaliero, con un solo orario di accensione e spegnimento. Collegheremo Arduino ad un RTC (real-time clock) per avere l’ora corrente e ad un relay per controllare una lampadina.
Ho scelto di utilizzare due breakout board, una per l’integrato DS1307 (RTC) e una per il relay, così collegate ad Arduino:
L’integrato DS1307 ha una interfaccia i2c, utilizziamo quindi i PIN A4 (SDA) e A5 (SCL), mentre il modulo relay richiede un solo PIN digitale (nell’esempio il PIN 2).
RTC e Arduino
Per leggere l’orario dal modulo RTC, ho scelto la libreria RTCLib fornita da Adafruit, già usata in un precedente post.
Il suo utilizzo è semplice: per prima cosa dobbiamo includere nello sketch due files:
#include <Wire.h> #include "RTClib.h" |
Quindi definiamo un nuovo oggetto RTC_DS1307:
RTC_DS1307 RTC; |
All’interno del setup(), inizializziamo la libreria Wire (i2c) e l’oggetto RTC:
Wire.begin(); RTC.begin(); |
Per leggere l’orario corrente, è quindi sufficiente chiamare il metodo now(), che restituisce un oggetto DateTime. Questo oggetto ha poi metodi per recuperare le varie parti (giorno, ora, minuto…) di data e ora:
DateTime now = RTC.now(); int hour = now.hour(); [...] |
MSF
Una macchina a stati finiti è un modello che descrive il comportamento di un sistema. Il sistema può avere un numero finito di stati e in ogni istante può essere in un solo di essi, lo stato corrente. Il sistema può passare da uno stato all’altro in base ad eventi e/o condizioni: tale passaggio si chiama transizione.
Nel nostro esempio, il sistema potrà avere solo due stati:
- luce accesa (= relay attivo)
- luce spenta (= relay disattivo)
Il passaggio da uno stato all’altro dipende dall’orario corrente e dai due orari impostati di accensione e spegnimento. Una MSF si può visivamente definire tramite il suo diagramma degli stati:
All’interno dello sketch, definiamo due costanti che indicano i due diversi stati possibili:
#define STATE_OFF 0 #define STATE_ON 1 |
e una variabile che memorizzerà lo stato corrente:
int fsm_state; |
Nel setup() è importante definire lo stato iniziale:
fsm_state = STATE_OFF; |
All’interno del loop(), utilizziamo lo statement Switch per identificare lo stato attuale e verificare se ci sono le condizioni per una transizione di stato:
switch(fsm_state) { case STATE_OFF: if(now > START_TIME && now < END_TIME) { [...] fsm_state = STATE_ON; } break; case STATE_ON: if(now > END_TIME) { [...] fsm_state = STATE_OFF; } break; } |
Funzionamento
Lo sketch completo è disponibile nel mio repository su Github, ecco un paio di foto del progetto funzionante:
Buongiorno Sig. Luca!
Sono Ronald, mi trovo alle prime armi con Arduino, non ho problemi con l’hardware, essendo quadrista e anche un po’ di piu (faccio dei circuiti elettronici, è una passione) ma purtroppo come software, non conosco il linguaggio DELLA PROGRAMMAZIONE, volevo controllare dal cellulare (Android) via rete certe 0/1 del quadro di casa…
volevo sapere da lei, visto la sua notevole conoscenza dell’argomento,
quale software scaricare sul telefono (anche a pagamento) purche sia
semplice nel futuro uso e che disponga di almeno 8 o 10 comandi apri/chiudi contatto, quindi molto semplice,
rinominabili a piacere… e magari se si trovano degli sketch, come comunica android/rete – rete/scheda ethernet di Arduino…
La ringrazio davvero per l’attenzione e spero di ricevere una risposta!!!
A presto! GRAZIE MILLE!!!
Ciao Ronald,
visto che non hai molta esperienza di programmazione, ti consiglio di andare su una soluzione “chiavi in mano”, ad esempio il progetto Arduino Commander ti mette a disposizione una app per Android e il relativo sketch per Arduino, anche con shield Ethernet come serve a te. Buon divertimento!
Buongiorno Luca.
Ho eseguito il tuo codice, ma non riesco a capire come impostare l’ora del timer, e neanche come faccia il programma a recuperare l’ora esatta, devo impostarla io?
Ad esempio i minuti corrispondono con l’ora del PC, ma le ore sono otto ore avanti.
Il problema e mio in quanto neofita, ti ringrazio lo stesso e ti faccio i complimenti per i tuoi tutorial.
saluti
Beppe
Ciao Beppe,
l’ora esatta è mantenuta dal CHIP RTC, che va pre-configurato… ho pronto un piccolo tutorial su come farlo!
Ciao Luca.
Grazie per aver risposto.
Ho capito come fare per configurarlo,solo che adesso mi da soltanto ff ff ff come risultato, mi sa che ho cimito l’rtc , non so cosa puo essere successo. Ne prendero un altro e provero di nuovo.
Grazie
Saluti Beppe
Buongiorno,
avrei dei progetti da realizzare con arduino , vorrei chiederle se è disposto a realizzarli o ha un nominativo al quale rivoelgermi
Ciao sto utilizzando questo sketch utilissimo e lo sto riadattando alle mie esigenza ma purtroppo non riesco a configurare orari notturni dopo le 23.59 come vanno scritti? ti ringrazio in anticipo
Ciao Patrick, l’intervallo di funzionanmento se ho capito bene è a cavallo della mezzanotte?
Buongiorno Luca, complimenti per il validissmo aiuto che dai agli sviluppatori.
Mi accodo alla richiesta di Patrick, rimasta inevasa: se il mio spegnimento è dopo la mezzanotte, come mi devo comportare?
Stavo cercando qualche via d’uscita, ma per il momento non ho trovato nulla di elegante!
Max
Ciao Luca ti chiedevo ma riesco collegare ad arduino tre rele’ invece di uno perche volevo far eccitare i tre rele in orari diversi del giorno . Riesci a spiegarmi come posso collegari e poi penso che devo modificare lo sketch che ho scaricato per un solo rele giusto o no ?
ciao, ogni relè si collega ad un diverso PIN di Arduino. Il modo per collegarli è identico… per il resto dovrai immagino gestire 3 diversi orari per i 3 relè nello sketch e modificarlo di conseguenza.
ok grazie mille
Ciao Luca ho montato il progetto come hai fatto tu e cioe macchina stati finiti . Ma nel monitor seriale mi esce la scritta SimpleTimer running …… e basta l orario non ce e il rele’ rimane eccitato . Come mai ho fatto qualche errore da premettere che ho usato lo skecht com e’ senza modifica
ciao! penso ci sia qualche problema su come hai collegato i componenti: lo sketch nel setup fa
digitalWrite(RELAY_PIN, LOW);
quindi il rele all’inizio deve essere NON eccitatook grazie .E per il fatto dell ora come posso fare per regolare un orario tanto per vedere se funziona tipo non so esempio inizio 13.30 fine 13.35 .
modifica lo sketch, in alto ci sono orario di attivazione e di disattivazione del relè
Adesso ci provo . GRAZIE
Ciao Luca,
innanzitutto ti ringrazio per i fantastici articoli scritti fin qui!
Come gestisci il cambio dell’ora legale/solare?
Grazie!
Ciao Mario, in questo semplice esempio non lo gestisco. In altri progetti, ho utilizzato ad esempio questa libreria.
Grazie Luca,
prezioso… come sempre 🙂
I am newbie in Arduino and enjoyed this project, as put more of a time for execution.
may give light.
hugs and thanks
Ciao, grazie per condividere la Tua conoscenza con tutti noi, in merito a questo progetto avevo la necessità di aggiungere un sensore PIR, nello specifico la mia esigenza nasce per le luci di ingresso e vorrei fare che le stesse si accendessero tipo, dalle 19:00 alle 23:00 e successivamente 23:01 alle 03:00 solo tramite sensore PIR, ho trovato diversi sketch in rete ma nessuno ha entrambe le funzioni, vorrei partire dal tuo progetto, grazie anticipatamente e buon lavoro
Ciao Giovanni, la cosa è abbastanza semplice: se usi un RTC (chip che fa da orologio) puoi scrivere uno sketch che verifica lo stato del sensore PIR, se questo rileva movimento, legge l’ora corrente da RTC e se ricade nel range che ti serve accendi per tot secondi le luci.
infatti, sto cercando di scriverlo, ma non riesco a far comunicare il tutto! cmq arduino è bello per quello, ci sbatto la testa finché non va’, pensavo che avessi qualcosa di simile da adattare… Ciao Luca
Hi there
I want to control an 8 channel relay module using an Arduino Uno R3, RTC DS1302 and internet. I would like to ” ON ” & ” OFF ” individual relays at a set time of the day and over the internet.
Hi! looking forward to your sketch 😉
Ciao Luca,
Ho notato che non hai dato una risposta per la gestione degli orari dopo mezzanotte; presumo che la soluzione — if(now > START_TIME && now START_TIME) — risolvo il problema dell’accensione, ma si spegnerebbe subito perchè now sarà sempre maggiore END nel case STATE_ON:
La soluzione che a me viene subito è quello di mettere — if(now = START_TIME) — e if(now = END_TIME).
Ma sono sicuro che tu hai in mente un approccio più efficace.
Saluti
Ciao Domenico, la cosa più facile è fare un controllo ulteriore verificando a monte se start_time > end_time… in questo caso significa che l’intervallo di ON è a cavallo di mezzanotte e quindi inverti la logica.
bye
Salve qualcuno ha già usato la DMBoard? ne ho sentito parlare bene in riferimento alla semplicità per la programmazione proprio in relazione agli stati finiti. cosa ne pensate?
Sono indeciso se prenderla o orientarmi su arduino. Io di programmazione ne sono poco anzi nulla.
http://www.dmboard.it