[PLC] PLC ST 언어에서 함수와 함수 블록을 활용한 서보 모터 제어 예시
PLC 프로그래밍을 하다 보면 여러 개의 서보 모터를 제어할 때 기본적인 로직은 동일하지만 입출력 주소나 동작 방식이 조금씩 다른 경우가 많습니다. 이런 경우, Structured Text(ST) 언어에서 함수(Function), 함수 블록(Function Block, FB), 그리고 Petri Net 을 활용하면 코드의 중복을 줄이고 유지보수성을 높일 수 있습니다. 이번 글에서는 이를 활용하는 방법을 소개하겠습니다.
1. 함수(Function) 활용
함수는 입력 값을 받아 처리한 후 결과를 반환하는 구조로, 입출력 주소가 다르지만 기본적인 제어 로직이 동일한 경우 유용합니다.
✅ 예제: 단순 서보 모터 제어 함수
FUNCTION ServoControl : BOOL
VAR_INPUT
StartCmd : BOOL;
StopCmd : BOOL;
END_VAR
VAR_OUTPUT
MotorStatus : BOOL;
END_VAR
BEGIN
IF StartCmd THEN
MotorStatus := TRUE;
ELSIF StopCmd THEN
MotorStatus := FALSE;
END_IF;
ServoControl := MotorStatus;
END_FUNCTION
✅ 사용법
Motor1_Status := ServoControl(Motor1_Start, Motor1_Stop);
Motor2_Status := ServoControl(Motor2_Start, Motor2_Stop);
➡️ 장점: 간단한 로직을 여러 개의 서보 모터에 쉽게 적용 가능
2. 함수 블록(Function Block, FB) 활용
함수 블록은 내부 변수 값을 유지할 수 있어, 서보 모터의 상태 저장이 필요한 경우 적합합니다. 각 서보 모터에 대해 인스턴스를 생성하여 독립적인 상태를 유지할 수 있습니다.
✅ 예제: 서보 모터 객체화
FUNCTION_BLOCK ServoMotor
VAR_INPUT
StartCmd : BOOL;
StopCmd : BOOL;
MotorID : INT;
END_VAR
VAR_OUTPUT
MotorStatus : BOOL;
END_VAR
VAR
Running : BOOL;
END_VAR
BEGIN
IF StartCmd THEN
Running := TRUE;
ELSIF StopCmd THEN
Running := FALSE;
END_IF;
MotorStatus := Running;
END_FUNCTION_BLOCK
✅ 사용법
VAR
Servo1, Servo2 : ServoMotor;
Servo1Status, Servo2Status : BOOL;
END_VAR
Servo1(StartCmd := Motor1_Start, StopCmd := Motor1_Stop, MotorID := 1);
Servo2(StartCmd := Motor2_Start, StopCmd := Motor2_Stop, MotorID := 2);
Servo1Status := Servo1.MotorStatus;
Servo2Status := Servo2.MotorStatus;
➡️ 장점: ✔ 상태 저장 가능 (모터의 현재 동작 상태 유지) ✔ 인스턴스를 활용하여 여러 서보 모터에 적용 가능 ✔ 코드 재사용성이 높아지고 유지보수가 용이함
3. Petri Net을 활용한 서보 모터 제어
Petri Net은 서보 모터의 동작 흐름을 모델링하고 분석할 수 있는 체계적인 방법을 제공합니다. 특히, 여러 개의 서보 모터가 동기적으로 동작해야 하는 경우나, 일련의 조건을 만족해야 다음 동작이 수행되는 경우 유용합니다.
✅ 예제: 두 개의 서보 모터가 순차적으로 동작하는 Petri Net
-
Place (상태)
-
P1
: 서보 모터 A가 준비됨 -
P2
: 서보 모터 A가 동작 중 -
P3
: 서보 모터 A가 완료됨 & 서보 모터 B 대기 중 -
P4
: 서보 모터 B가 동작 중 -
P5
: 서보 모터 B가 완료됨
-
-
Transition (전이)
-
T1
: 서보 모터 A 시작 -
T2
: 서보 모터 A 완료 → 서보 모터 B 시작 -
T3
: 서보 모터 B 완료
-
✅ Petri Net을 ST 언어로 구현
FUNCTION_BLOCK ServoPetriNet
VAR_INPUT
StartA, CompleteA, StartB, CompleteB : BOOL;
END_VAR
VAR_OUTPUT
MotorA_Run, MotorB_Run : BOOL;
END_VAR
VAR
P1, P2, P3, P4, P5 : BOOL; (* 상태 정의 *)
END_VAR
BEGIN
(* 초기 상태 *)
P1 := NOT P2 AND NOT P3 AND NOT P4 AND NOT P5;
(* Transition T1: 모터 A 시작 *)
IF StartA AND P1 THEN
P1 := FALSE;
P2 := TRUE;
MotorA_Run := TRUE;
END_IF;
(* Transition T2: 모터 A 완료, 모터 B 시작 *)
IF CompleteA AND P2 THEN
P2 := FALSE;
P3 := TRUE;
MotorA_Run := FALSE;
END_IF;
IF StartB AND P3 THEN
P3 := FALSE;
P4 := TRUE;
MotorB_Run := TRUE;
END_IF;
(* Transition T3: 모터 B 완료 *)
IF CompleteB AND P4 THEN
P4 := FALSE;
P5 := TRUE;
MotorB_Run := FALSE;
END_IF;
END_FUNCTION_BLOCK
➡️ 장점: ✔ 모터 간 순서 제어가 명확해짐 ✔ 병렬 프로세스 관리가 쉬워짐 ✔ 데드락(Deadlock) 방지 가능
4. 결론
PLC ST 언어에서 함수(Function), 함수 블록(Function Block, FB), Petri Net을 활용하면 중복 코드를 줄이고 유지보수를 용이하게 할 수 있습니다.
-
간단한 제어 로직:
FUNCTION
사용 -
서보 모터의 상태 저장 및 개별 인스턴스 활용:
FUNCTION_BLOCK
사용 -
복잡한 순차적/병렬 동작 논리 적용:
Petri Net
활용
이러한 방식을 적용하면 보다 효율적이고 확장성 있는 PLC 프로그램을 작성할 수 있습니다. 여러분의 프로젝트에서도 적극 활용해 보세요! 🚀
댓글
댓글 쓰기