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.
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 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.
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.
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.
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.
The model of this demonstration example is shown in the figure below.
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
.
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.
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.
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.
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
.
Let's load the described model:
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
.
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:
[ 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.
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:
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.
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.
{"id": "6e56e111-f6e8-451a-be42-0a61ebba7765", "data": [{"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"title": {"text": ""}}, "name": "Счётчик", "zmin": null, "yaxis": "y", "legendgroup": "Счётчик", "zmax": null, "line": {"color": "rgba(0, 154, 250, 1.000)", "shape": "linear", "dash": "solid", "width": 2}, "y": [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15], "type": "scatter", "x": [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 251, "currentCount": 251}}}, {"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"title": {"text": ""}}, "name": "Код светофоров", "zmin": null, "yaxis": "y", "legendgroup": "Код светофоров", "zmax": null, "line": {"color": "rgba(227, 111, 71, 1.000)", "shape": "linear", "dash": "solid", "width": 2}, "y": [33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 33, 33, 32, 32, 33, 33, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 4, 12, 12, 4, 4, 12, 12, 4, 4, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 33, 33, 32, 32, 33, 33, 32, 32, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 52, 52, 52, 52, 52, 52, 52, 52, 52, 52, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 4, 4, 12, 12, 4, 4, 12, 12, 4, 4, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 33, 32, 32, 33, 33, 32, 32, 33, 33, 32, 32, 34], "type": "scatter", "x": [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 251, "currentCount": 251}}}], "config": {"showlegend": true, "xaxis": {"showticklabels": true, "gridwidth": 0.5, "range": [-3.75, 128.75], "domain": [0.041102848255079226, 0.9956255468066492], "mirror": false, "tickangle": 0, "showline": true, "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "y", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "Время, сек", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 300, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "range": [-1.620000000000001, 55.620000000000005], "domain": [0.10108632254301551, 0.9868766404199475], "mirror": false, "tickangle": 0, "showline": true, "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "Значения", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "top", "xanchor": "left", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 0.07}, "width": 634.984375}}
{"id": "e4d62de9-6c41-4de5-ae18-8a2d2516ea52", "data": [{"showlegend": true, "mode": "lines", "xaxis": "x", "colorbar": {"title": {"text": ""}}, "name": "Код пешеходный светофор", "zmin": null, "yaxis": "y", "legendgroup": "Код пешеходный светофор", "zmax": null, "line": {"color": "rgba(0, 128, 0, 1.000)", "shape": "linear", "dash": "solid", "width": 2}, "y": [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2], "type": "scatter", "x": [0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 31, 32, 32, 33, 33, 34, 34, 35, 35, 36, 36, 37, 37, 38, 38, 39, 39, 40, 40, 41, 41, 42, 42, 43, 43, 44, 44, 45, 45, 46, 46, 47, 47, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 57, 58, 58, 59, 59, 60, 60, 61, 61, 62, 62, 63, 63, 64, 64, 65, 65, 66, 66, 67, 67, 68, 68, 69, 69, 70, 70, 71, 71, 72, 72, 73, 73, 74, 74, 75, 75, 76, 76, 77, 77, 78, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 88, 88, 89, 89, 90, 90, 91, 91, 92, 92, 93, 93, 94, 94, 95, 95, 96, 96, 97, 97, 98, 98, 99, 99, 100, 100, 101, 101, 102, 102, 103, 103, 104, 104, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119, 119, 120, 120, 121, 121, 122, 122, 123, 123, 124, 124, 125, 125], "zaxis": null, "z": null, "metadata": {"shouldEnableSmartZoom": false, "smartZoomParams": {"minCount": 25000, "maxCount": 251, "currentCount": 251}}}], "config": {"showlegend": true, "xaxis": {"tickangle": 0, "showline": true, "gridcolor": "rgba(0, 0, 0, 0.1)", "showticklabels": false, "gridwidth": 0.5, "visible": true, "ticks": "inside", "range": [-3.75, 128.75], "domain": [0.03122630504520268, 0.9956255468066492], "linecolor": "rgba(0, 0, 0, 1)", "showgrid": false, "zeroline": false, "type": "linear", "title": {"text": "Время, сек"}, "zerolinecolor": "rgba(0, 0, 0, 1)", "mirror": false, "anchor": "y"}, "paper_bgcolor": "rgba(255, 255, 255, 1.000)", "annotations": [], "height": 300, "margin": {"l": 0, "b": 20, "r": 0, "t": 20}, "plot_bgcolor": "rgba(255, 255, 255, 1.000)", "yaxis": {"showticklabels": true, "gridwidth": 0.5, "range": [0, 3], "domain": [0.06404928550597848, 0.9868766404199475], "mirror": false, "tickangle": 0, "showline": true, "zeroline": false, "tickfont": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "zerolinecolor": "rgba(0, 0, 0, 1)", "anchor": "x", "visible": true, "ticks": "inside", "tickmode": "array", "linecolor": "rgba(0, 0, 0, 1)", "showgrid": true, "title": {"text": "Значения", "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}}, "gridcolor": "rgba(0, 0, 0, 0.1)", "tickcolor": "rgb(0, 0, 0)", "type": "linear"}, "legend": {"yanchor": "top", "xanchor": "left", "bordercolor": "rgba(0, 0, 0, 1)", "bgcolor": "rgba(255, 255, 255, 1.000)", "borderwidth": 1, "tracegroupgap": 0, "y": 1, "font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 11}, "title": {"font": {"color": "rgba(0, 0, 0, 1)", "family": "sans-serif", "size": 15}, "text": ""}, "traceorder": "normal", "x": 0.07}, "width": 634.984375}}