Using Arrays in structured text

Tony Hibbert picture Tony Hibbert · Mar 2, 2016 · Viewed 18.9k times · Source

I am using B&R Automation Studio on a simulation PLC. I am just playing around with some programs and have come across a problem.

I have a list of alarms for my system. If anyone of these alarms go off, I want there to be an alarm flag. This is simple enough to do by a simple OR statement made even easier because I only have 5 alarms.

However, what if I was to have 100 alarms, it would take a long time to enter these all in manually. My first thoughts are to put all the alarms into an array so then I can access any element easily, but in order to do this would I not need to type all these variables into the system anyway? so I wouldn't be saving a great deal of time? Is there a way or a function block I can utilize so that I can skip the manual process of entering 100+ variables into an array?

Answer

pboedker picture pboedker · Mar 2, 2016

I don't think there's any way around having to enter either the 100+ alarms or variables. As a minimum you will have to evaluate each alarm condition to set it's alarm.

One method I find useful is to define an enum list with all the alarms and then use this to set the individual alarm bits in an alarm array. If you only want to set one alarm flag, you can then iterate the complete array. Or if you have multiple flags, the enums could be grouped and iterated accordingly.

VAR
  arrAlarm: ARRAY [0 .. ALARM_SIZE] OF BOOL;
  bFlag: BOOL;
  bFlag1, bFlag2: BOOL;
  i: INT;
END_VAR

(* Example code for setting alarmbits. This could mean 100+ lines... *)
arrAlarm[ALARM_CircuitBreaker1] := IO_a;
arrAlarm[ALARM_CircuitBreaker2] := IO_b;
arrAlarm[ALARM_CircuitBreaker3] := IO_c;
arrAlarm[ALARM_Temperature1] := IO_d > 100;
arrAlarm[ALARM_Temperature2] := IO_e > 100;
arrAlarm[ALARM_Temperature3] := IO_f > 100;
arrAlarm[ALARM_EmergencyStop] := NOT IO_g;

(* Example code for setting alarm flags. This could be even simpler if only one flag *)
bFlag := FALSE;
FOR i := 0 to ALARM_SIZE - 1 DO
  IF arrAlarm[i] THEN
    bFlag := TRUE;
  END_IF;
END_FOR;
bFlag1 := FALSE;
FOR i := ALARM_Temperature1 to ALARM_Temperature3 DO
  IF arrAlarm[i] THEN
    bFlag1 := TRUE;
  END_IF;
END_FOR;
bFlag2 := FALSE;
FOR i := ALARM_CircuitBreaker1 to ALARM_EmergencyStop DO
  IF arrAlarm[i] THEN
    bFlag2 := TRUE;
  END_IF;
END_FOR;

(* Definition of alarms. These could be an extract from a definition file *)
TYPE E_ALARM :
(
  ALARM_Temperature1,
  ALARM_Temperature2,
  ALARM_Temperature3,
  ALARM_CircuitBreaker1,
  ALARM_CircuitBreaker2,
  ALARM_CircuitBreaker3,
  ALARM_EmergencyStop,
  ALARM_SIZE,
);
END_TYPE