Air-Fuel Ratio Control System with Stateflow Charts

Generate code for an air-fuel ratio control system designed with Simulink® and Stateflow®.

Figures 1, 2, and 3 show relevant portions of the sldemo_fuelsys model, a closed-loop system containing a plant and controller. The plant validates the controller in simulation early in the design cycle. In this example, you generate code for the relevant controller subsystem, "fuel_rate_control". Figure 1 shows the top-level simulation model.

Use the command rtwdemo_fuelsys to open model sldemo_fuelsys. Then, and compile model to see the signal data types.

rtwdemo_fuelsys
sldemo_fuelsys([],[],[],'compile');
sldemo_fuelsys([],[],[],'term');

Figure 1: Top-level model of the plant and controller

The air-fuel ratio control system is comprised of Simulink® and Stateflow®. The control system is the portion of the model for which you generate code.

open_system('sldemo_fuelsys/fuel_rate_control');

Figure 2: The air-fuel ratio controller subsystem

The control logic is a Stateflow® chart that specifies the different modes of operation.

open_system('sldemo_fuelsys/fuel_rate_control/control_logic');

Figure 3: Air-fuel rate controller logic

Close these windows.

close_system('sldemo_fuelsys/fuel_rate_control/airflow_calc');
close_system('sldemo_fuelsys/fuel_rate_control/fuel_calc');
close_system('sldemo_fuelsys/fuel_rate_control/control_logic');
hDemo.rt=sfroot;hDemo.m=hDemo.rt.find('-isa','Simulink.BlockDiagram');
hDemo.c=hDemo.m.find('-isa','Stateflow.Chart','-and','Name','control_logic');
hDemo.c.visible=false;
close_system('sldemo_fuelsys/fuel_rate_control');

Configure and Build the Model with Simulink® Coder™

The code generator produces generic ANSI® C code for Simulink® and Stateflow® models When model configuration parameter System target file is set to grt.tlc (Generic Real-Time (GRT)). You can set the System target file parameter programmatically.

rtwconfiguredemo('sldemo_fuelsys','GRT');

For this example, build only the air-fuel ratio control system. Once the code generation process is complete, the code generator displays an HTML report that details the generated code. The main body of the code is located in fuel_rate_control.c.

rtwbuild('sldemo_fuelsys/fuel_rate_control');
### Starting build procedure for: fuel_rate_control
### Successful completion of build procedure for: fuel_rate_control

Configure and Build the Model with Embedded Coder®

To configure and build production ANSI® C/C++ code for the model, set model configuration parameter System target file to ert.tlc (Embedded Real-Time (ERT)). You can set the System target file parameter programmatically.

rtwconfiguredemo('sldemo_fuelsys','ERT');

Repeat the build process and inspect the generated code. You can navigate to the relevant code segments interactively by using Previous and Next buttons. From the chart context menu (right-click the Stateflow® block), select Code Generation > Navigate to Code. Programmatically, use the rtwtrace utility.

rtwbuild('sldemo_fuelsys/fuel_rate_control');
rtwtrace('sldemo_fuelsys/fuel_rate_control/control_logic')
### Starting build procedure for: fuel_rate_control
### Successful completion of build procedure for: fuel_rate_control

View the air-fuel ratio control logic in the generated code.

rtwdemodbtype('fuel_rate_control_ert_rtw/fuel_rate_control.c',...
    '/* Function for Chart:','case IN_Warmup:',1,0);
/* Function for Chart: '<S1>/control_logic' */
static void Fueling_Mode(const int32_T *sfEvent)
{
  /* This state interprets the other states in the chart to directly control the fueling mode. */
  switch (rtDW.bitsForTID0.is_Fueling_Mode) {
   case IN_Fuel_Disabled:
    rtDW.fuel_mode = DISABLED;

    /* The fuel is completely shut off while in this state. */
    switch (rtDW.bitsForTID0.is_Fuel_Disabled) {
     case IN_Overspeed:
      /* Inport: '<Root>/sensors' */
      /* The speed is dangerously high, so shut off the fuel. */
      if ((rtDW.bitsForTID0.is_Speed == 2) && (rtU.sensors.speed < 603.0F)) {
        if (rtDW.bitsForTID0.is_Fail != 1) {
          rtDW.bitsForTID0.is_Fuel_Disabled = IN_NO_ACTIVE_CHILD;
          rtDW.bitsForTID0.is_Fueling_Mode = IN_Running;
          switch (rtDW.bitsForTID0.was_Running) {
           case IN_Low_Emissions:
            rtDW.bitsForTID0.is_Running = IN_Low_Emissions;
            rtDW.bitsForTID0.was_Running = IN_Low_Emissions;
            rtDW.fuel_mode = LOW;
            switch (rtDW.bitsForTID0.was_Low_Emissions) {
             case IN_Normal:
              rtDW.bitsForTID0.is_Low_Emissions = IN_Normal;
              rtDW.bitsForTID0.was_Low_Emissions = IN_Normal;
              break;

Close the model and code generation report.

clear hDemo;
rtwdemoclean;
close_system('sldemo_fuelsys',0);

Related Examples

For related fixed-point examples that use sldemo_fuelsys, see