Usage

Task Specific Alarms

  • Declare a Task Alarms type and a variable of that type. We recommend using the name of the task and _ as the prefix for the alarm names. This means creating a variable called _ and then adding the alarm names as members of the variable. You may use more substructures for organization. This structure CAN include other variables that are not alarms, but not that any strings in the structure will be populated by the varPopulateMemberNames call.

  • Calling varPopulateMemberNames will populate the required information for LaxAddAlarm to work.

  • Call the LaxAddAlarm function in the init routine to create the alarms.

  • Call any of the variations of LaxEdge or LaxLevel in the cyclic OR init routine to raise alarms.

(Local task type to define alarms)

TYPE
TaskAlarms_typ : 	STRUCT 
	ConfigurationInvalid : Lax_Alarm_typ;
	OpenFailed : Lax_Alarm_typ;
	CloseFailed : Lax_Alarm_typ;
	NoAirPressure : Lax_Alarm_typ;
END_STRUCT;
END_TYPE

(* Local task variables *)

VAR
name : STRING[80];
grp : UDINT;
_ : TaskAlarms_typ;
lowAirPressure : BOOL;
END_VAR
void _INIT ProgramInit(void)
{

	//Populate member names	
	ST_name(0,&name, &grp);
	brsstrcat(name,":_");
	varPopulateMemberNames(name,0);

	//Alarms can be raised in the init routine even before creation
	if( configurationIsInvalid ){
		LaxEdge(&_.ConfigurationInvalid);
	}


	// Create any task alarms in the init routine
	LaxAddAlarm(&gAlarmBuilder, LAX_ALARM_TYPE_EDGE,  
		&_.ConfigurationInvalid, ERR_ID_DOOR, ERR_SEVERITY_HIGH, 
		"Invalid configuration. PLease check configuration files", "See user guide", 0);
	LaxAddAlarm(&gAlarmBuilder, LAX_ALARM_TYPE_EDGE,  
		&_.OpenFailed, ERR_ID_DOOR, ERR_SEVERITY_MEDIUM, 
		"Door failed to open. Door: ", "See user guide", 0);
	LaxAddAlarm(&gAlarmBuilder, LAX_ALARM_TYPE_EDGE,  
		&_.CloseFailed, ERR_ID_DOOR, ERR_SEVERITY_MEDIUM, 
		"Door failed to close. Door: ", "See user guide", 0);
	LaxAddAlarm(&gAlarmBuilder, LAX_ALARM_TYPE_LEVEL, 
		&_.NoAirPressure, ERR_ID_DOOR, ERR_SEVERITY_HIGH, 
		"Doors cannot operate, Not enough air pressure", "Check estop and valve", 0);

}

void _CYCLIC ProgramCyclic(void)
{
	if( openDoors ){
		openDoors = 0;

		if( door1OpenFailed ){
			LaxEdgeSnippet(&_.OpenFailed, "Back Door");
		}
		if( door2OpenFailed ){
			LaxEdgeSnippet(&_.OpenFailed, "Front Door");
		}
	}
	if( closeDoors ){
		closeDoors = 0;

		if( door1CloseFailed ){
			LaxEdgeSnippet(&_.CloseFailed, "Back Door");
		}
		if( door2CloseFailed ){
			LaxEdgeSnippet(&_.CloseFailed, "Front Door");
		}
	}		

	LaxLevel(&_.NoAirPressure, lowAirPressure);
}

Global Alarms

Global alarms can be initialized the same way as task alarms. The only difference is that the variable is not local to a task.

Infrastructure

Tasks

We provide 2 tasks that are used to create and run the alarm system. These tasks are not required, but are recommended as a good base for your project. They can generally be used out of the box without modifications.

AlarmUI Task

This task is used to create the alarms and display alarms on the HMI. It should be the very last task in cyclic 8 to ensure that all alarms have been added before it creates them. We overload the AlarmUI task because it is fine for it to run in cyclic 8 and it is a good place to put the alarm creation code.

The Lax specific parts of this task are:

PROGRAM _INIT
	
	// Populate the system alarms
	varPopulateMemberNames('SysAlarms',0);

	// Set the default alarm core for alarms 
	//	that were not created with LaxAddAlarm 
	//	or that have no alarm core at creation	
	LaxSetDefaultAlarmCore(gAlarmXCore);

	// Create the default TMX file
	LaxCreateTmx(gAlarmBuilder);

	// Create the alarms XML and import it into the AlarmX system
	LaxCreateAlarms(gAlarmBuilder);

	// Add any alarms that were raised before the Alarms were created
	WHILE( NOT LaxDequeueAlarm( ADR(pAlarm) ) ) DO
		alarm ACCESS pAlarm;
		LaxEdge(alarm);	  
	END_WHILE

		
END_PROGRAM

AlarmCore

This task is meant to run the Alarm X system with or without Lax.

AlarmX Configuration

The AlarmX configuration is done in the AlarmX mapp component. The following settings are required:

  • 2 Alarm Cores

    • Static Alarm Core: This is the default alarm core for alarms that are not created with LaxAddAlarm. Mappings can be done here, as well as all the monitor/high/low settings.
    • Dynamic Alarm Core: This is a blank alarm core that is used to create alarms at runtime. It should be empty, since it will be overwritten by LaxCreateAlarms.
  • 2 Alarm Groups

    • Static Alarm Group: This is the main alarm group that is used to display alarms on the HMI. It should be mapped to the static alarm core.
    • Dynamic Alarm Group: This is a child alarm group to add the dynamic alarm core to the static alarm group. This ensures that the alarms from the dynamic alarm core are visible in the static alarm core.

Mapp Configuration

Text System

Lax uses the text system to display alarm messages on the HMI. This adds multi-language support to alarms. The tmx file needs to be added to the text system.

Text System

Default TMX

The default TMX file is provided as a starting point for your text system. It contains the alarm message provided by the add alarm functions and a placeholder for a snippet. By default, it is written to disk every boot and can be uploaded as needed. This TMX file can be added to the project and customized, or handed off to a translator for multilingual support.

For each alarm a message is added to the file with [AlarmName]_Text as the name. This is the message that will be displayed on the HMI. The message is set to “[Default Message][Alarm Snippet]”.

TMX