ModeManagerLib provides a simple initialization system for Omron's NX/NJ controllers. A set of programs is called a mode, and the program to be launched is determined by selecting a mode. For details, please check "Sysmac Studioで簡単な初期化システムを作る".
By defining a mode as shown below and executing the mode activation POU, the program specified in the mode will be started.
IF P_First_Run THEN
SPEC_USE_MQTT := TRUE;
SPEC_USE_KINTONE := TRUE;
ModeManager_init(Context:=iModeManager,
// The name of the program under which the mode manager runs.
Name:='ProgramLoader',
// Whether the mode manager should terminate the running program on successful mode activation.
// The default is TRUE (stop).
OnSuccessStop:=TRUE,
// Whether the mode manager should terminate the running program on failed mode activation.
// The default is TRUE (stop).
OnFailStop:=FALSE,
// Whether to leave an alarm log in the controller on failed mode activation.
// The default is FALSE (No logs).
OnFailAlarm:=TRUE,
// User log alarm code.
// The default is 1.
AlarmCode:=1);
ModeSet(Context:=iModeManager);
Mode(Context:=iModeManager,
// Mode identifier.
Name:='modeselect',
// Whether this is the default mode.
// The default is FALSE (not default).
Default:=TRUE);
ModeUnit(Context:=iModeManager,
// The name of the program that is the mode unit.
Name:='DeviceIn',
// Whether to enable P_First_Run.
// The default is TRUE (enabled).
FirstRun:=TRUE,
// Whether to stop the program on failed mode activation.
// The default is TRUE (stop).
OnFailStop:=TRUE);
ModeUnit(Context:=iModeManager, Name:='DeviceOut');
ModeUnit(Context:=iModeManager, Name:='TelnetService');
Mode(Context:=iModeManager, Name:='setup');
ModeUnit(Context:=iModeManager, Name:='DeviceIn');
ModeUnit(Context:=iModeManager, Name:='DeviceOut');
ModeUnit(Context:=iModeManager, Name:='Machine1Setup');
ModeUnit(Context:=iModeManager, Name:='Machine2Setup');
ModeUnit(Context:=iModeManager, Name:='TelnetService');
Mode(Context:=iModeManager, Name:='run');
ModeUnit(Context:=iModeManager, Name:='DeviceIn');
ModeUnit(Context:=iModeManager, Name:='DeviceOut');
ModeUnit(Context:=iModeManager, Name:='Machine1Ctrl');
ModeUnit(Context:=iModeManager, Name:='Machine2Ctrl');
IF SPEC_USE_MQTT THEN
ModeUnit(Context:=iModeManager, Name:='MqttMachineStatSender');
END_IF;
IF SPEC_USE_KINTONE THEN
ModeUnit(Context:=iModeManager, Name:='KintoneClientService');
ModeUnit(Context:=iModeManager, Name:='KintoneAlarmCollector');
END_IF;
Mode(Context:=iModeManager, Name:='diagnosis');
ModeUnit(Context:=iModeManager, Name:='DeviceIn');
ModeUnit(Context:=iModeManager, Name:='DeviceOut');
ModeUnit(Context:=iModeManager, Name:='DiagnosisCtrl');
ModeUnit(Context:=iModeManager, Name:='Machine1Diagnosis');
ModeUnit(Context:=iModeManager, Name:='Machine2Diagnosis');
ModeUnit(Context:=iModeManager, Name:='DiagnosisReporter');
ModeUnit(Context:=iModeManager, Name:='TelnetService');
IF SPEC_USE_MQTT THEN
ModeUnit(Context:=iModeManager, Name:='MqttMachineStatSender');
END_IF;
IF SPEC_USE_KINTONE THEN
ModeUnit(Context:=iModeManager, Name:='KintoneClientService');
ModeUnit(Context:=iModeManager, Name:='KintoneAlarmCollector');
END_IF;
ModeSetClose(Context:=iModeManager);
// Select the mode.
ModeManager_selectMode(Context:=iModeManager, Name:=RUN_MODE);
END_IF;
// Activates the selected mode.
ModeManager_activate(Context:=iModeManager);
// When you output logs to the controller yourself.
(*
IF ModeManager_activate(Context:=iModeManager) THEN
IF ModeManager_hasError(Context:=iModeManager) THEN
ModeManager_getAlarmInfo(Context:=iModeManager,
ErrorID=>iErrorID,
RunMode=>iRunMode);
SetAlarm(Code:=1, Info1:=iErrorID, Info2:=iRunMode);
END_IF;
END_IF;
*)
In the controller task settings, set the program that contains the code to activate the mode to Enable, and the program that you want to start to Stop, as shown below.
ProgramLoader
is the program POU that executes the mode activate POU.
If you set the RUN_MODE
global variable to "diagnosis" and run it in the simulator, only the program in the mode specified as follows will be launched.
If mode activation fails, the following error occurs.
ErrorID | Description |
---|---|
0x0000..0x0FFF | The program specified in the mode unit Name does not exist. |
0x2000 | The program specified by Name in the mode manager does not exist. |
0x8000 | The mode manager was initialized with a Name of an empty string. |
0x81** | Defined a mode whose Name is an empty string. |
0x82** | Defined a mode unit whose Name is an empty string. |
If you have specified that an alarm log should be left when mode activation fails, a log of the specified alarm code will be left and the Error ID will be recorded in additional information 1.
ModeManagerLib has a limited function to deactivate currently active modes. When using, please keep the following in mind.
- Dependencies are not taken into account.
- Deactivate in the same order as activated.
- When a mode unit (program) in a mode fails to stop, subsequent mode units will not stop.
As long as you can determine that each is an independent program and can be stopped, there is no problem in deactivating the mode.
To deactivate the mode, use the following POU, which is similar to ModeManager_activate
.
FUNCTION ModeManager_deactivate(ModeManagerContext) : BOOL;
Below is an example of using ModeManager to dynamically switch programs in manual testing on an actual device. It monitors changes in the mode value and switches the running program.
CASE iState OF
// STATE_INIT
0:
Clear(iRunMode);
Clear(iPrevRunMode);
ModeManager_init(Context:=iContext,
Name:='Test_ManualTest',
OnSuccessStop:=FALSE,
OnFailStop:=FALSE,
OnFailAlarm:=FALSE);
ModeSet(iContext);
// NOP is to not start any programs.
Mode(Context:=iContext, Name:='NOP', Default:=TRUE);
Mode(Context:=iContext, Name:='EdgeFunction');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_EdgeFunction');
Mode(Context:=iContext, Name:='Rpc');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Rpc');
Mode(Context:=iContext, Name:='Select');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Select');
Mode(Context:=iContext, Name:='Insert');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Insert');
Mode(Context:=iContext, Name:='BulkInsert_json');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_BulkInsert_json');
Mode(Context:=iContext, Name:='BulkInsert_csv');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_BulkInsert_csv');
Mode(Context:=iContext, Name:='Update');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Update');
Mode(Context:=iContext, Name:='Upsert_json');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Upsert_json');
Mode(Context:=iContext, Name:='Upsert_csv');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Upsert_csv');
Mode(Context:=iContext, Name:='SingleUpsert_json');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_SingleUpsert_json');
Mode(Context:=iContext, Name:='SingleUpsert_csv');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_SingleUpsert_csv');
Mode(Context:=iContext, Name:='Delete');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Worker_Delete');
Mode(Context:=iContext, Name:='ServiceKeyAccess');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Check_ServiceKeyAccess');
Mode(Context:=iContext, Name:='ServiceKeyAccessWithKey');
ModeUnit(Context:=iContext, Name:='Test_ManualTest_Check_ServiceKeyAccessWithKey');
ModeSetClose(iContext);
iState := STATE_ACTIVE;
// STATE_ACTIVE
10:
IF iRunMode <> iPrevRunMode
AND iRunMode <> ''
THEN
iPrevRunMode := iRunMode;
IF ModeManager_selectMode(
Context:=iContext,
Name:=iRunMode)
THEN
Inc(iState);
END_IF;
END_IF;
11:
IF ModeManager_activate(Context:=iContext) THEN
IF ModeManager_hasError(Context:=iContext) THEN
iState := STATE_ERROR;
ELSE
Inc(iState);
END_IF;
END_IF;
12:
IF iRunMode <> iPrevRunMode THEN
Inc(iState);
END_IF;
13:
IF ModeManager_deactivate(
Context:=iContext,
IfActive:=TRUE)
THEN
iState := STATE_ACTIVE;
END_IF;
END_CASE;
The following environment is required to use this project.
Sysmac Studio | The latest version is recommended. |
This project was built in the following environment.
Sysmac Studio | Ver.1.62 |
The sample program (POU/Program/ProgramLoader) is used in the following steps.
Run the simulator and change to Program mode.
In the Watch window, set the startup mode to the RUN_MODE
global variable.
Switch the simulator to operation mode and confirm that the program for the specified mode is running.