Subroutine과 Function Block의 실행 구조 비교
자동화 제어의 심장 Subroutine과 Function Block 이해하기
산업 현장의 자동화 기계나 스마트 공장을 움직이는 것은 눈에 보이는 철제 프레임과 모터뿐만이 아닙니다. 그 장치들에게 언제 움직이고 언제 멈춰야 할지 명령을 내리는 보이지 않는 두뇌, 즉 PLC 프로그램이 핵심적인 역할을 담당합니다. 이 PLC 프로그램을 작성할 때 가장 기본적이면서도 중요한 두 가지 개념이 바로 서브루틴과 펑션 블록입니다.
처음 자동화 제어를 접하는 사람들은 이 두 용어의 차이를 명확히 이해하기 어려워합니다. 둘 다 코드를 재사용하고 프로그램을 깔끔하게 정리하는 데 도움을 주기 때문입니다. 하지만 내부적으로 메모리를 다루는 방식이나 데이터를 기억하는 능력에서 큰 차이를 보입니다. 이 차이를 정확히 이해하는 것은 효율적이고 오류 없는 제어 프로그램을 만드는 첫걸음이 됩니다.
서브루틴의 개념과 기본적인 작동 방식
서브루틴은 프로그램 전체에서 반복적으로 사용되는 특정 코드 조각을 하나의 독립된 구역으로 모아둔 것입니다. 일상생활에 비유하자면 스마트폰의 단축키 설정과 같습니다. 매번 길게 입력해야 하는 번거로운 작업을 하나의 버튼으로 해결하듯이 프로그램 내에서 특정 연산이 필요할 때마다 호출해서 사용하는 방식입니다.
서브루틴이 실행될 때는 메인 프로그램이 잠시 진행을 멈추고 서브루틴 내부의 명령들을 차례대로 수행한 뒤 다시 원래 자리로 돌아옵니다. 이 과정에서 임시 변수들을 사용할 수 있지만 서브루틴의 실행이 끝나면 그 내부의 데이터는 초기화되거나 사라지는 경우가 많습니다. 따라서 매번 새로운 조건에서 동일한 순서의 연산을 빠르게 처리해야 할 때 주로 활용됩니다.
펑션 블록의 특성과 데이터 유지 능력
펑션 블록은 서브루틴과 비슷해 보이지만 결정적인 차이점을 가지고 있습니다. 가장 큰 특징은 자신만의 고유한 메모리 공간, 즉 인스턴스를 가진다는 점입니다. 공장에 똑같은 모델의 컨베이어 벨트 제어기가 여러 대 설치되어 있다고 가정해 보겠습니다. 제어하는 로직은 모두 동일하지만 각각의 벨트가 작동한 총 시간이나 현재 실시간 상태는 서로 다를 것입니다.
이럴 때 펑션 블록이 빛을 발합니다. 하나의 펑션 블록 틀을 만들어 두고 이를 복제해서 컨베이어 벨트마다 하나씩 할당하면 각각의 벨트는 자신만의 독립된 데이터를 기억하며 작동합니다. A 벨트의 누적 가동 시간과 B 벨트의 누적 가동 시간이 섞이지 않고 안전하게 보존되는 이유가 바로 이 인스턴스 메모리 덕분입니다.
두 실행 구조의 결정적인 차이점 비교
서브루틴과 펑션 블록은 구조적으로 설계 목적과 활용 방향에서 뚜렷한 차이를 보입니다. 이 차이를 이해하면 어떤 상황에서 어떤 방식을 선택해야 할지 명확한 기준을 세울 수 있습니다.
- 메모리 관리 방식에서 서브루틴은 전역 변수나 임시 메모리를 공유하는 반면 펑션 블록은 호출될 때마다 고유의 메모리 영역을 할당받습니다.
- 코드의 재사용성 관점에서 서브루틴은 단순한 로직 반복에 유리하고 펑션 블록은 상태를 유지해야 하는 장비 제어에 적합합니다.
- 프로그램의 가독성 측면에서 서브루틴은 순차적인 흐름을 분산시킬 때 좋고 펑션 블록은 객체지향적인 설계를 가능하게 합니다.
- 디버깅 과정에서 서브루틴은 변수의 값이 덮어써지는 문제를 주의해야 하며 펑션 블록은 특정 블록의 내부 상태만 추적하면 되므로 대규모 시스템에서 유리합니다.
실생활과 산업 현장에서의 활용 사례
실제 제조 현장이나 빌딩 자동화 시스템에서 이 두 구조는 적재적소에 사용되어 시스템의 안정성을 높여줍니다. 온도 센서 값을 읽어와서 섭씨로 변환하는 간단한 수식 계산은 서브루틴으로 구현하는 것이 효율적입니다. 매번 계산할 필요 없이 필요할 때 불러와서 결과값만 쓱 받아오면 되기 때문입니다.
반면에 여러 개의 실린더와 밸브가 복잡하게 얽혀 있는 프레스 기계를 제어할 때는 펑션 블록이 필수적입니다. 프레스 기계가 동작하는 순서와 안전 감시 로직을 하나의 펑션 블록으로 묶어두고 공장에 이 기계가 세 대 있다면 블록을 세 번 호출하기만 하면 됩니다. 이렇게 하면 프로그램 코드가 엄청나게 짧아지고 나중에 수정 사항이 생겼을 때 원본 블록 하나만 고치면 세 대 모두에 적용되므로 유지보수 비용을 크게 아낄 수 있습니다.
흔히 발생하는 오해와 진실
PLC 프로그램을 처음 배울 때 서브루틴이 펑션 블록의 하위 개념이거나 단순히 구형 방식이라고 오해하는 경우가 많습니다. 하지만 이는 사실이 아닙니다. 두 기술은 우열을 가리는 관계가 아니라 해결하려는 문제가 다를 뿐입니다.
서브루틴이 구형 방식이라서 펑션 블록으로 모두 대체되어야 한다는 생각도 잘못된 것입니다. 단순한 조건 분기나 전체 프로그램의 스캔 순서를 제어하는 메인 흐름 제어에서는 여전히 서브루틴이나 점프 명령어가 가장 직관적이고 빠르게 동작합니다. 반대로 모든 것을 펑션 블록으로 만들려고 하면 오히려 메모리 낭비가 심해지고 프로그램이 복잡해질 수 있습니다.
비용 효율적인 프로그램 설계를 위한 조언
효율적인 제어 프로그램을 작성하는 것은 단순히 코드가 잘 작동하는 것을 넘어 향후 수정 비용과 유지보수 시간을 줄이는 것과 직결됩니다. 프로젝트를 시작하기 전에 제어하려는 대상의 특성을 꼼꼼히 분석하는 것이 중요합니다.
상태를 기억할 필요가 없는 단순 연산이나 일회성 데이터 처리는 서브루틴으로 작성하여 프로그램의 실행 속도를 높이고 스캔 타임을 단축하는 것이 좋습니다. 반면 반복해서 사용되는 장치 제어 로직, 예를 들어 모터 제어, 밸브 제어, PID 제어 등은 반드시 펑션 블록 형태로 만들어 라이브러리화해야 합니다.
이렇게 만들어둔 라이브러리는 다음 프로젝트에서도 그대로 재사용할 수 있으므로 엔지니어링 시간을 혁신적으로 단축하고 인건비와 개발 비용을 크게 절감해 줍니다.
초보자가 자주 묻는 질문
서브루틴 안에서 또 다른 서브루틴을 호출해도 괜찮은지 궁금해하는 사람들이 많습니다. 대부분의 현대적인 PLC에서는 다중 호출을 지원하지만 너무 깊은 단계로 들어가면 프로그램의 흐름을 파악하기 어렵고 스택 메모리 부족 현상이 발생할 수 있으므로 가급적 2단계 이내로 제한하는 것이 현명합니다.
펑션 블록 내부의 변수가 외부 프로그램에 영향을 주는지 걱정하는 경우도 종종 있습니다. 펑션 블록 내부의 변수는 기본적으로 은닉되어 외부에서 직접 접근할 수 없으며 오직 입력과 출력을 통해서만 데이터를 주고받습니다. 이 특성 덕분에 프로그램의 다른 부분에서 실수로 변수 값을 건드릴 위험이 사라져 시스템의 신뢰성이 크게 높아집니다.
서브루틴 호출 시 데이터를 전달하는 방법에 대해서도 혼동이 생기기 쉽습니다. 서브루틴은 별도의 입력 파인터가 명확히 정의된 경우가 드물기 때문에 주로 글로벌 메모리 영역을 공유하는 방식으로 데이터를 주고받습니다. 따라서 어떤 변수가 어디서 변경되는지 철저하게 관리하는 습관이 필요합니다.
댓글 0
첫 댓글을 남겨보세요.