Engee documentation
Notebook

Code generation for Arduino (Crossroads)

In this example, we will develop a model in Engee to control two vehicular and one pedestrian traffic lights at one intersection on an Arduino-compatible board using the Engee Automata library.

Introduction

The purpose of this case study is to develop a control model for an intersection consisting of two vehicular and one pedestrian flows, which are controlled by two three-section and one two-section traffic lights, respectively. The section switching algorithm will be defined according to a timing diagram. The control algorithm will be realised by means of several blocks Chart, and the removal of input signals and generation of output signals will be realised by blocks C-Function.

In the control programme algorithm it is possible to select the operating or standby mode, switching of modes will be carried out by the input discrete signal from the target device.

This example is a development of the demo example "Code generation for Arduino (traffic lights on finite automata)". The peculiarities of this example in comparison with the previous one are: modelling and code generation of several interconnected blocks Chart and output of the data array to the periphery.

Hardware

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. The circuit simulates the operation of traffic lights: two three-section car traffic lights and one two-section pedestrian traffic light.

image.png

The input signal for switching on/off the standby mode is supplied by a pushbutton contact to digital contact 4 of the Arduino board. Output signals for switching on sections of traffic lights are output by digital contacts 8 - 13 to LEDs of the corresponding colours. Output signals of switching on sections of pedestrian traffic lights are given by digital contacts 6, 7. For the correct operation of the circuit, current limiting (330 Ohm) and shrinking (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 operation of traffic lights at the intersection according to the timing diagram below.

Three flows - two motor vehicles and one pedestrian are controlled asynchronously. At the same time, the traffic permit (green light) is formed only for one flow at a time and lasts for 10 seconds. After the end of the traffic authorisation of the vehicular flow, the flashing of the green section is switched on. The transition of the traffic light from the permissive signal to the prohibitive (red light) is accompanied by switching on the yellow section for 5 seconds, the reverse transition is accompanied by simultaneous switching on of the red and yellow sections for 5 seconds.

image_3.png

The duty cycle is described by two states of traffic lights:

  • yellow sections of the vehicle traffic lights are switched on for 1 second, sections of the pedestrian traffic lights are switched off;
  • during 1 second all sections of car and pedestrian traffic lights are switched off.

Model description

The model of this demonstration example is shown in the figure below.

image_2.png

The control algorithm is divided into functional parts - counter operation is reproduced in block Common_Counter, formation of control signal light for car traffic lights - in block Traffic_Lights, formation of control signal cross for pedestrian traffic lights - in block Crosswalk.

To transmit the mode selection signal to the model, block Digital Input is used, to output messages to the serial port of Arduino - block To Serial, and to output the codes of car and pedestrian traffic lights to the digital pins of Arduino - blocks Digital_Output_1 and Digital_Output_2 respectively.

For structured data output to the serial port the block of vector formation is used DataMux.

State diagrams

In the status diagram of the Common_Counter block, the state Counter and the transitions 2 and 3 are used to reproduce the operation of the incrementing counter with reset after 54 seconds. The state Service and the transition 1 are used to reset the counter to the value "-1" when the sleep mode for the intersection is set.

image_2.png

Depending on the value of the counter variable cntr in the state diagram of the block Traffic_Lights, the value of the variable lights, which encodes the states of the traffic light sections, is selected. In this case, all states except ninth and tenth reproduce the sequence of switching of sections in the operating mode. The diagram of states of the block Traffic_Lights is shown in the figure below.

image_2.png

In turn, depending on the value of the variable lights in the block Crosswalk, the value of the variable cross, which encodes the state of the pedestrian traffic light, is selected. The diagram of states of the block Crosswalk is shown in the figure below.

image.png

Signal tables are defined in the settings of each block state diagram Chart. Initial values of output variables:

  • block Common_Counter, variable mode = 0;
  • block Traffic_Lights, variable light = 33;
  • block Crosswalk, variable cross = 2.

Modelling results

Let's load the described model:

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

data = engee.run(m);

From the obtained model data we plot the counter variables counter, the coded states of the sections of the car traffic lights traffic_lights and the pedestrian traffic light crosswalk_lights.

In [ ]:
using Plots
plotlyjs()
plot(data["counter"].time, data["counter"].value,
    label="Счётчик", size=(900,300), lw=2, st=:step)
plot!(data["traffic_lights"].time, data["traffic_lights"].value,
    label="Код светофоров", size=(900,300), lw=2, st=:step,
    legend=:topleft)
xlabel!("Время, сек")
ylabel!("Значения")
Out[0]:
In [ ]:
plot(data["crosswalk_lights"].time, data["crosswalk_lights"].value,
    label="Код пешеходный светофор", size=(900,300), lw=2, st=:step, color=:green,
    ylims = (0,3), xticks=:none, legend=:topleft )
    xlabel!("Время, сек")
ylabel!("Значения")
Out[0]:

The graph shows the change of variables. The calculation period in the model is set to 1 second. Changes in the state variables of the sections of traffic and pedestrian traffic lights traffic_lights and crosswalk_lights by values and duration correspond to the time diagram

Uploading code to Arduino

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

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

Plug-in files were generated in the specified directory arduino_crossroad_code. Also in the directory of the demo example arduino_crossroad there is a pre-written Arduino sketch with the name of this directory arduino_crossroad.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_crossroad and load the sketch arduino_crossroad.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_4.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 push-button contact, the traffic lights of the intersection switch to standby mode, and the following messages are output to the serial port:

image_2.png

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

Conclusion

In this demo, a model of an intersection with two three-section vehicular traffic lights and one two-section pedestrian traffic light was 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 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, the lit sections of the three traffic lights and the current operating time.

Blocks used in example