Finite-state machine and Arduino

by luca
29 comments

When I post my sketches, I often receive questions about the reason why I define state constants and, more generally, about the meaning of a finite-state machine. In this tutorial you’ll learn how to use that model to create a simple timer.

SimpleTimer

You’re going to use Arduino as a daily timer, setting a time to turn on and turn off the load. Arduino will be connected to an RTC (real-time clock) to get the actual time and to a relay to control the load (for example a lamp).

I chose to use two breakout boards, one for the DS1307 IC (RTC) and one for the relay, connected to Arduino in the following way:

DS1307 IC provides an i2c interface, I therefore used PIN A4 (SDA) and A5 (SCL), while the relay module requires only one digital PIN (in my example, PIN 2).

RTC and Arduino

I installed the RTCLib library provided by Adafruit to get the actual time from the RTC chip; I’ve already used it in a previous post.

It’s usage is very simple: first include two libraries in your sketch:

#include <Wire.h>
#include "RTClib.h"

Then, define a new object of the RTC_DS1307 class:

RTC_DS1307 RTC;

In the setup(), initialize the Wire (i2c) library and the RTC object:

Wire.begin();
RTC.begin();

To get the actual time, now just call the now() method, that returns a DateTime object. This object provides several methods to retrieve the different parts (day, hour, minute…) of date and time:

DateTime now = RTC.now();
int hour = now.hour();
[...]

FSM

A finite-state machine is a model that describes the behavior of a system. The system has a finite number of states and can be in only one of them at a time, the current state. The system can change from one state to another on triggers and/or conditions: the change is called transition.

In my example, the system has only two possible states:

  • light on (= relay activated)
  • light off (= relay deactivated)

The change from one state to the other depends on the actual time and the start and end time set in the sketch. A FSM can be represented using a state diagram:

In the sketch, define two constants that represent the two possible states:

#define STATE_OFF  0
#define STATE_ON   1

and a variable to store the actual state:

int fsm_state;

In the setup() it’s very important to define the initial state:

fsm_state = STATE_OFF;

In the loop(), use the Switch statement to identify the actual state, perform the operations and check if the conditions are good for a change of state:

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;
}

Working

The sketch is available in my Github’s repository, here are a couple of photos about the project working:

Related Posts

29 comments

Ronald Tuesday October 1st, 2013 - 01:35 AM

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 Tuesday October 1st, 2013 - 07:46 PM

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 Wednesday October 2nd, 2013 - 10:02 AM

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 Thursday October 3rd, 2013 - 07:10 PM

Ciao Beppe,

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

Reply
Beppe Saturday October 5th, 2013 - 05:56 PM

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 Thursday November 7th, 2013 - 12:27 PM

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

Reply
Patrick Tuesday April 15th, 2014 - 10:42 PM

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 Sunday April 27th, 2014 - 12:37 PM

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

Reply
max Friday August 1st, 2014 - 07:34 AM

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 Saturday March 7th, 2015 - 12:17 PM

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 Sunday March 8th, 2015 - 01:33 PM

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 Monday March 9th, 2015 - 04:29 PM

ok grazie mille

Reply
Aristide Tuesday March 10th, 2015 - 10:28 AM

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 Wednesday March 11th, 2015 - 08:18 PM

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 Thursday March 12th, 2015 - 10:38 AM

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 Thursday March 12th, 2015 - 08:50 PM

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

Reply
Aristide Thursday March 12th, 2015 - 09:06 PM

Adesso ci provo . GRAZIE

Reply
Mario Friday April 24th, 2015 - 03:54 PM

Ciao Luca,

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

Reply
luca Friday April 24th, 2015 - 07:16 PM

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

Reply
Mario Sunday April 26th, 2015 - 07:44 AM

Grazie Luca,

prezioso… come sempre 🙂

Reply
Moises Lima Wednesday April 29th, 2015 - 12:19 AM

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 Friday August 14th, 2015 - 11:04 AM

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 Friday August 14th, 2015 - 04:02 PM

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 Friday August 14th, 2015 - 04:31 PM

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 Monday September 21st, 2015 - 09:32 AM

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 Saturday September 26th, 2015 - 10:24 AM

Hi! looking forward to your sketch 😉

Reply
Domenico Thursday September 24th, 2015 - 05:37 PM

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 Saturday September 26th, 2015 - 10:29 AM

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 Tuesday March 22nd, 2016 - 03:25 PM

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

11 − one =