Engee documentation
Notebook

Code generation for Arduino (Traffic lights on finite automata)

In this example, we will develop a model in Engee to control a three-section traffic light for Arduino-compatible boards using the Finite Automata library.

Introduction

The purpose of this example is to develop a control model for a three-section traffic light according to a timing diagram. The control algorithm will be realised using the block Chart, and the input signal removal and output signal generation will be realised using the blocks C-Function.

For complex demonstration of the capabilities of the library of Engee **Engee automata, including the subsequent generation of code, the traffic light control algorithm will organise the work of two modes - working (sections are switched on alternately) and duty (yellow light section is switched on and off). Switching of modes will be carried out by the input discrete signal from the target device.

Hardware part

This demo uses the controller from Amperka's Iskra Neo. The controlled circuit is assembled from radio components - LEDs, pushbutton contact, resistors and connecting wires on a solderless breadboard as shown in the layout diagram below.

plate_2.JPG

The input signal for switching on/off the standby mode is given by a pushbutton contact to digital contact 4 of the Arduino board. Output signals for switching on the traffic light sections are given by digital contacts 10 - 12 to LEDs of corresponding colours. For correct operation of the circuit, current limiting (330 Ohm) and pull-down (10 kOhm) resistors are also used. The circuit is powered by the Arduino board itself.

Timing diagram

The algorithm to be implemented will reproduce the traffic light operation according to the following timing diagram.

At the beginning of the operating mode cycle, the red section of the traffic light is lit for 10 seconds. During the last 3 seconds of its operation, the yellow section lights up in parallel. After this time has elapsed, the green section lights up for 10 seconds. After the green section flashes for 5 seconds, with periods of switching on and off lasting for 1 second each. After the flashing ends, the yellow section illuminates for 3 seconds. The operating mode cycle then starts again.

For clarity, the diagram described is shown in the figure below.

worktimediagram_2.png

The duty cycle is described by two traffic light states:

  • yellow section on for 1 second,
  • all sections are switched off for 1 second.

Model description

The model of this demo consists of five blocks as shown in the model screenshot below.

image.png

The control algorithm, as stated earlier, is reproduced by the block Chart. This block has one input mode for the operating mode switching signal and two outputs cnt and light for outputting the traffic light counter signal and the code of illuminated sections respectively. The periphery of the controller is initialised and controlled by means of blocks C Function: Digital Input - to transfer the state of the digital input of the controller to the model, Digital Output - to output the state of the sections to the digital outputs of the controller, To Serial - to output data through the serial port of the controller. Detailed description of the principles of operation of these blocks is given in the comments of their code.

For successful generation of the code of Digital Input block it is necessary to pass an input signal to it. In the example, the block Constant is used for this purpose.

State diagram

The state diagram of the Chart block contains six states: five for the operating mode (Red, RedAndYellow, Green, Blink, Yellow) and one for the service mode (BlinkOn).

image_2.png

In each state the counter cnt is decremented and the state of the traffic light sections is set light. Setting the counter and checking the conditions for changing the state of the traffic light sections takes place in the transitions between the states Chart.

Below is the table of signals of the block Chart.

image.png

The variable light transmits the binary state of the output contacts of the target device. Bit number 0 in this variable corresponds to the green section of the traffic light, bit number 1 to the yellow section and bit number 2 to the red section. For example: at light = 4 = 0b0110, where bits numbered 1 and 2 take the value "1", the red and yellow sections of the traffic light will be switched on.

The traffic light mode changes between the states Red and BlinkOn depending on the value of the input variable mode.

The variable service is local to the block Chart and serves for switching the state BlinkOn

Modelling results

Let's load the described model:

In [ ]:
if "arduino_traffic_lights" in [m.name for m in engee.get_all_models()]
    m = engee.open( "arduino_traffic_lights" );
else
    m = engee.load( "$(@__DIR__)/arduino_traffic_lights.engee" );
end

data = engee.run(m);

From the obtained model data, plot the counter variables cnt and the traffic light section status code light:

In [ ]:
using Plots
plotlyjs();
plot(data["Chart.cnt"].time, data["Chart.cnt"].value,
    label="Counter", size=(900,300), lw=2, st=:step)
plot!(data["Chart.light"].time, data["Chart.light"].value,
    label="Light", size=(900,300), lw=2, st=:step)
xlims!(0.0,40.0)
Out[0]:

The plotted graph shows the change of variables. The calculation period in the model is set to 1 second. The change of the variable of the state of traffic light sections light by value and duration corresponds to the time diagram.

Uploading the code to Arduino

To transfer the developed model to the target device, let's generate C code:

In [ ]:
engee.generate_code( "$(@__DIR__)/arduino_traffic_lights.engee",
                     "$(@__DIR__)/arduino_traffic_lights_code" )
[ Info: Generated code and artifacts: /user/start/examples/codegen/arduino_traffic_lights/arduino_traffic_lights_code

Plug-in files were generated in the specified directory arduino_traffic_lights_code. Also in the directory of the demo example arduino_traffic_lights there is a pre-written Arduino sketch with the name of this directory arduino_traffic_lights.ino. In it, the header file obtained during code generation is connected, global variables are initialised, the model calculation loop is defined, and the model calculation functions are called. A detailed description of the sketch is given in the code comments.

To execute the code on Arduino, download the directory arduino_traffic_lights and load the sketch arduino_traffic_lights.ino from Arduino IDE to the target device.

Executing the code on Arduino

After successful compilation and loading the sketch into the target device, the digital outputs of the debug board will generate signals to switch on the traffic light sections (LEDs on the breadboard). To make sure that the model works correctly, let's open the serial port monitor in Arduino IDE.

image.png

It can be seen that the messages prescribed in the To Serial block are output to the serial port in the required format with a periodicity of 1 second.

When pressing the button contact with the red LED lit, the traffic light switches to the standby mode, and the following messages are output to the serial port:

image.png

The required message is output to the serial port with a periodicity of 1 second. Consequently, the operation of the traffic light in the standby mode is also correct, which confirms the operability of the model and code.

Conclusion

In this demo, a three-section traffic light model has been developed for Arduino-compatible platforms. The control algorithm is recreated using a finite automata library. The model reproduces the operation of the traffic light in two modes, ensuring not only the switching of the sections, but also their flashing. The algorithm was tested on the target device, the resulting code not only controls the LED sections, but also sends messages to the serial port about the current mode, lit sections and remaining time of the section.

Blocks used in example