산업 자동화 시스템에서 안정적이고 신뢰할 수 있는 통신은 장비 협력 제어의 핵심 요소입니다. 여러 개의 Modbus 부스터 장치를 관리할 때 효율적인 퍼블리싱 스케줄링 메커니즘 설계는 공학자들이 가져야 하는 핵심 기술 중 하나입니다. 본 문서에서는西门子 S7-1200 PLC에서의 Modbus RTU 퍼블리싱 구현 방법을 깊이 있게 탐구하며, TIA Portal의 고급 특성과 실제 프로젝트에서 발생하는 일반적인 통신 트래픽에 대한 해결책을 제공합니다.
1. 하드웨어 구성 및 기본 통신 설정
프로그래밍 시작 전에 올바른 하드웨어 구성은 통신 성공의 첫 번째 조건입니다. S7-1200 시리즈 PLC는 다양한 통신 모듈을 지원하며, CM1241 RS485와 CB1241 RS485 통신보드가 가장 일반적인 Modbus RTU 통신 하드웨어입니다.
- CM1241 RS485 모듈 (6ES7241-1CH32-0XB0): 최대 32개의 부스터 장치를 지원
- CB1241 RS485 보드: CPU 소프트웨어 버전 V2.0 이상 필요
- TIA Portal V15 이상 버전 추천
실제 프로젝트에서 가장 자주 발생하는 한 가지 트래픽은 RS485 접지 극성을 오해한 것입니다. 많은 엔지니어들은 A를 A, B를 B로 연결하곤 하지만, 각 장비의 RS485 인터페이스 정의는 다를 수 있습니다. 예를 들어, CB1241 보드의 B가 양극 (+), A가 음극 (-)이므로, 신호 극성을 올바르게 연결해야 합니다.
통신 파라미터 설정은 부스터 장치와 완벽하게 일치해야 합니다. TIA Portal에서 모듈 매개변수를 설정할 때, 중요한 오류는 모듈 속성에서 설정된 스톱 비트가 Modbus 통신에 영향을 미치지 않는다는 것입니다. 이는 `MB_COMM_LOAD` 명령의 배경 DB의 `STOP_BITS` 정적 변수를 수정하여 변경해야 합니다.
// 통신 초기화 예시
#MB_COMM_LOAD(
REQ := #FirstScan, // 첫 번째 스캔 트리거
PORT := 269, // 하드웨어 식별자
BAUD := 9600, // 비트레이트
PARITY := 2, // 짝수 검증
FLOW_CTRL := 0, // 흐름 제어 없음
RTS_ON_DLY := 0, // RTS 열기 지연
RTS_OFF_DLY := 0, // RTS 닫기 지연
RESP_TO := 1000, // 응답 시간 초과 1000ms
MB_DB := #MB_DB_Inst); // 배경 데이터 블록
2. 퍼블리싱 스케줄링 메커니즘 설계 및 구현
퍼블리싱 메커니즘의 핵심은 여러 부스터 장치 간에 통신 시간을 적절히 분배하여 각 장치가 즉시 서비스를 받으면서 PLC의 전체 실행 성능에 영향을 미치지 않도록 하는 것입니다.
2.1 기본 퍼블리싱 프레임워크
SCL 언어를 사용하여 퍼블리싱 논리를 구현하면 더 나은 가독성과 유연성이 가능합니다. 다음은 일반적인 다 부스터 퍼블리싱 구조의 예시입니다.
// 퍼블리싱 상태 머신 변수 선언
VAR
PollingState : INT := 0; // 퍼블리싱 상태
CurrentSlave : INT := 1; // 현재 부스터 주소
MaxSlaves : INT := 8; // 최대 부스터 수
PollingTimer : TON; // 퍼블리싱 타이머
ResponseTimeout : TON; // 응답 시간 초과 타이머
LastPollTime : TIME := T#0ms; // 마지막 퍼블리싱 시간
END_VAR
// 퍼블리싱 스케줄링 로직
CASE PollingState OF
0: // 유휴 상태, 퍼블리싱 간격 대기
IF PollingTimer.Q THEN
PollingState := 10;
PollingTimer(IN := FALSE);
ELSE
PollingTimer(IN := TRUE, PT := T#50ms); // 50ms 퍼블리싱 간격
END_IF
10: // Modbus 요청 발송
#MB_MASTER(
REQ := TRUE,
MB_ADDR := CurrentSlave,
MODE := 4, // 유지 보관 레지스터 읽기
DATA_ADDR := 40001, // 시작 주소
DATA_LEN := 10, // 10개의 단위 읽기
DATA_PTR := #DataBuffer[CurrentSlave],
MB_DB := #MB_DB_Inst);
PollingState := 20;
ResponseTimeout(IN := TRUE, PT := T#200ms); // 200ms 응답 시간 초과
20: // 응답 대기 또는 시간 초과
IF #MB_MASTER.DONE THEN
// 성공 응답 처리
PollingState := 30;
ELSIF #MB_MASTER.ERROR THEN
// 통신 오류 처리
PollingState := 40;
ELSIF ResponseTimeout.Q THEN
// 시간 초과 처리
PollingState := 40;
END_IF
30: // 성공 처리
CurrentSlave :