Macchina a stati finiti e Arduino

by luca
29 comments

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:

Related Posts

29 comments

Ronald 1 ottobre 2013 - 01:35

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!!!

Reply
luca 1 ottobre 2013 - 19:46

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!

Reply
Beppe 2 ottobre 2013 - 10:02

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

Reply
luca 3 ottobre 2013 - 19:10

Ciao Beppe,

l’ora esatta è mantenuta dal CHIP RTC, che va pre-configurato… ho pronto un piccolo tutorial su come farlo!

Reply
Beppe 5 ottobre 2013 - 17:56

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

Reply
raffaele 7 novembre 2013 - 12:27

Buongiorno,
avrei dei progetti da realizzare con arduino , vorrei chiederle se è disposto a realizzarli o ha un nominativo al quale rivoelgermi

Reply
Patrick 15 aprile 2014 - 22:42

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

Reply
luca 27 aprile 2014 - 12:37

Ciao Patrick, l’intervallo di funzionanmento se ho capito bene è a cavallo della mezzanotte?

Reply
max 1 agosto 2014 - 07:34

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

Reply
Aristide 7 marzo 2015 - 12:17

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 ?

Reply
luca 8 marzo 2015 - 13:33

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.

Reply
Aristide 9 marzo 2015 - 16:29

ok grazie mille

Reply
Aristide 10 marzo 2015 - 10:28

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

Reply
luca 11 marzo 2015 - 20:18

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 eccitato

Reply
Aristide 12 marzo 2015 - 10:38

ok 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 .

Reply
luca 12 marzo 2015 - 20:50

modifica lo sketch, in alto ci sono orario di attivazione e di disattivazione del relè

Reply
Aristide 12 marzo 2015 - 21:06

Adesso ci provo . GRAZIE

Reply
Mario 24 aprile 2015 - 15:54

Ciao Luca,

innanzitutto ti ringrazio per i fantastici articoli scritti fin qui!
Come gestisci il cambio dell’ora legale/solare?
Grazie!

Reply
luca 24 aprile 2015 - 19:16

Ciao Mario, in questo semplice esempio non lo gestisco. In altri progetti, ho utilizzato ad esempio questa libreria.

Reply
Mario 26 aprile 2015 - 07:44

Grazie Luca,

prezioso… come sempre 🙂

Reply
Moises Lima 29 aprile 2015 - 00:19

I am newbie in Arduino and enjoyed this project, as put more of a time for execution.
may give light.
hugs and thanks

Reply
giovanni 14 agosto 2015 - 11:04

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

Reply
luca 14 agosto 2015 - 16:02

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.

Reply
giovanni 14 agosto 2015 - 16:31

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

Reply
Linus 21 settembre 2015 - 09:32

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.

Reply
luca 26 settembre 2015 - 10:24

Hi! looking forward to your sketch 😉

Reply
Domenico 24 settembre 2015 - 17:37

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

Reply
luca 26 settembre 2015 - 10:29

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

Reply
lui 22 marzo 2016 - 15:25

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

Reply

Leave a Comment