Design Embedded Software using Finite State Machines

I have been planning for a while, to share some of my experiences as a developer and a couple of projects I have developed during my spare time. To start off with, last weekend I developed a simple application using Arduino Uno, and I decided to use state machines to design the software. I believe that knowing how to use state machines to design embedded software’s, is one of the good practices every embedded developer should know. Hence I’d like to take the time to present a simple use case of finite state machines, for designing an embedded software application.

As it goes by the quote from an old Chinese proverb –

I hear and I forget; I see and I remember; I do and I understand.

So, let’s design and build some stuff using state machines. But before doing so, it is necessary to understand the application of the system and its use case to go ahead with the state machine design. This is going to be a small interesting project, that will give you a good understanding of how to use state machines.

Auto Lighting System (ALS)

Sorry about the lame name I have given this system, as I could not think of any other better names at that moment. Though it’s not a big deal, yet If you could suggest some better names, please do let me know and I will change it. But for now, let’s proceed with ALS.

I shall present one use case of the system, that we will be developing. That is:

Auto Lighting System (ALS) : In many apartments, villas and independent houses (not automated), there would be small light bulbs or LED lighting’s in the corridors of the apartments, or outdoors of the villas, probably near the entrance or in the back yard, or maybe in the parking lot, depending on the plan and architecture. I have observed that most of the owners would prefer to keep these lights switched ON during the night and they switch it off during the daytime. Maybe for some security reasons or may be because Scooby is there wandering in the back yard. Our device is going to take care of this, by automatically switching on and off the lights at the desired timings, with no involvement of any humans or necessity of manual switching

The above is a simple use case of the device. The functionalities can definitely be extended further which I shall discuss at the end of this post.

Introduction to Finite State Machines

Finite State machines are used to design computer programs. I have seen a lot of people think it is some kind of complex or boring topic, and even wonder where and how is it applied, however, it is quite simple to use and is applied in developing robust embedded programs. The complexity lies in the engineering problem one is trying to solve, and state machines can be used to solve these problems effectively by breaking them down into logical states.

Finite State Machine: A finite state machine is a mathematical model of a computer program. A computer program can have finite number of states and each state is designed to perform a set of operations, and monitor certain parameters. At any given time, the embedded device can only be in one state known as the current state of the device. The device will change its state from the current one to another state depending on the inputs from the previous states, and parameters being monitored in the current state. The change in the state is known as state transition.

Circuit Diagram of ALS

Purpose of each component in the system:Fig 1 shows the circuit diagram of the system along with the components used for the developments.

– Arduino UNO: It consists of the ATMEL328P micro controller, that is the brain of the system, which handles all the functions.

– RTC DS1307: It is real time clock that is used to keep a track of the current time and date. The RTC uses the I2C interface for communication with the information of time and date. The I2C interface consists of a data line as SDA (Pin A4) and clock line as the SCL (Pin A5).

Note: I haven’t shown the pull resistors for the SDA and SCL lines in the above Fig, as they are generally present on most of the RTC modules.

–10K Pot (R2): The 10 K pot is connected to the analogue input (Pin A1) of the Arduino. It’s connected to a 10 bit in-built ADC. So when the resistance of the pot is zero, then the output of the ADC is 0 that corresponds to 0 Volts, and if the resistance of the pot is maximum, then the output of ADC is 1023 that corresponds to 5 Volts.

– LED (L1): The LED is controlled by the GPIO (Pin 13) depending on the values of the Pot and time.

Hardware Setup of ALS

Fig 2. Hardware Set Up for the ALS

Fig 2 shows the hardware set up of the system as per the circuit diagram is shown in Fig 1. On the RTC module, you can see that there is an additional EEPROM IC which we are currently not using to minimise the number of components in the system, Instead, we will be using the inbuilt EEPROM within the ATMEL 328P.

What is the software supposed to do?

Enabling and Disabling the Auto – Lighting: The user can enable or disable this feature. Technically, this feature gets enabled only when the ADC value corresponding to the 10 K pot, is set to 1023. For the rest of values, it’s disabled.

Setting Auto – Lighting Timings: The user can set on and off time range, for e.g. If he/she sets on time as 7:30 PM and off time as 6:30 AM, the light/LED will remain ON within the set range of time every day and OFF when out of range. Currently the system can handle controlling the light for just one range of time, however, it can be extended to handle the control of light for multiple time ranges.

State Machine Design – Auto Lighting System (ALS)

Fig 3. State Machine Design for ALS

Fig 3 shows the state machine design of ALS. In this design, we will have 3 states as shown in the Fig above i.e. CHECK_ADC_STATE, CHECK_ON_STATE and CHECK_OFF_STATE.

CHECK_ADC_STATE: This state checks if the auto lighting feature has been enabled or disabled. If it is enabled, then the device transits to the CHECK_ON_STATE state. If it’s not disabled, the device remains in the CHECK_ADC_STATE state until its enabled. The auto lighting feature is enabled when the ADC value is set to 1023 by using the 10 K Pot, else it is disabled for the rest of the values.

CHECK_ON_STATE: This state keeps monitoring for ON time, provided the auto lighting feature has been enabled. If the RTC time matches the set ON time, then the LED/light is triggered ON and the device transits to the CHECK_OFF_STATE. In case the auto lighting feature is disabled while the LED is ON, then the device turns the LED OFF and goes back to the CHECK_ADC_STATE state.

CHECK_OFF_STATE: Once the light/LED has been triggered, this state keeps monitoring for OFF time. If the RTC time matches the set OFF time, then the LED is triggered OFF and the device transits back to the CHECK_ON_STATE provided the auto lighting feature is enabled. In case the auto lighting feature is disabled in this state, then the device goes back to CHECK_ADC_STATE state.

Software Implementation of the State Machine Design

In this section, I have shared the cream of the software, in which the state machine design is converted into an algorithm that will guide the MCU, to executing the implementation logic of the ALS. You can clone or download the complete source code for the Auto Lighting System from here.

You can notice in the code the way I have implemented the state machine logic i.e. by simply using the switch and case statements. The cases represent the states of the device and the switch statement is used for switching between the states depending on the inputs and parameters being monitored. So, it’s as simple as that. Similarly, you can develop computer programs to solve much more complex problems by using state machines.

I am sure that there are much better ways of implementation than the above piece of code. It may be possible to eliminate one of the states and tightly couple the logic using just two states, or reduce the number of lines in the code etc., so, these improvements I leave it to you. The main idea of the above code was to demonstrate the use of state machines to develop programs, and I think it serves that purpose, however, if you do come up with some improvements or better ways of implementation, please share your ideas with us by commenting below.

I found a nice and simple RTC DS1307 code here, which I used for interfacing the RTC to Arduino UNO.

The below video will show the working demo of the Auto Lighting System and how the device transits from one state to another.

How can we make the system better and improve user experience?

A 16×2 segment display can be interfaced, for displaying the LED trigger ON and OFF set times including the current time and date.

A keypad can be used to give the ability for users to set the LED trigger ON and OFF times. Currently, we are hard coding these values in the software.

In case if you are facing any issues, please comment below and I will be happy to help. In the next article, I will guide you on setting up QT and touch display libraries with Beagle Bone Black + 4D Touch Display on Linux. Till then be in sync with Deeply Embedded.