본문 바로가기
PLC 전기제어 기술자료/PLC를 함수화 해보자!

[MELSEC] PLC 프로그램을 함수화 해보자 -3- (체크섬 생성)

by 위치결정 2022. 2. 28.
반응형

< XCALL을 활용한 체크섬 생성 함수 예제 >

 

PLC는 손쉽게 그림 그리듯 래더라는 언어를 이용하여 프로그램 할수 있는 뛰어난 자동화 제어장치입니다.

하지만 단점이 있으니 프로그램을 여러 유니트에 맞추어 어드레스를 변경해가며 일일이 복사해서 코딩을 해주어야 한다는 점입니다.

PLC에서도 간단한 기능들은 CALL이나 XCALL 문을 이용하여 함수화 할수 있으니 이를 활용하면 보다 프로그램이 간단해 질것입니다.

 

이번에는 세번째로 다뤄볼 기능으로 시리얼통신을 하다보면 은~그으은~히 스트레스가 되는 체크섬 Checksum 입니다.

이 기기, 저 기기 와 통신 프로토콜을 하다보면 가끔씩 튀어 나오는 존재라서 그때그때 프로그램하기 참 귀찮은 친구입니다.

 

그래서 체크섬 생성을 콜문형 함수화 해놓고 사용하기로 했습니다. 아주 편합니다.

 

checksum()_230301.gxw
0.89MB

 

< 함수 기능 설명 >

이번 함수는 데이터를 다루는 함수이기에 많은 워드가 필요합니다.

따라서 XCALL에서 파라미터로 활용할수 있는 로컬변수(FD0, FX1, FY2)를 사용하기가 애매합니다.

이를 극복하기 위해 유니트 프로그램의 끝부분에 해당하는 영역을 XCALL에서 활용할 어드레스 영역으로 지정하여 사용합니다.

[예제프로그램에서는 D5000번대를 통신프로그램영역으로 XCALL 함수영역은 D5900 번대 사용합니다.]

함수의 첫번째 파라미터 FD0 : 체크섬 생성시 문자열 참조 시작포인트

함수의 두번째 파라미터 FD1 : 체크섬 생성시 문자열 참조 종료포인트

 

ZR5900 : 원본 문자열 (입력값)

 

D5907 : 문자열의 추출 시작위치 포인트

D5909 : 원본 문자열의 길이 LEN

 

D5910 : 문자열을 바이트 캐릭터 단위로 분리 저장영역 (WTOB 버퍼)

 

D5992 : 체크섬 정수형 (출력값)

D5994 : 체크섬 문자열 (출력값)

D5996, D5997 : 체크섬 Byte캐릭터 (출력값)

 

 

< 프로그램 예제 #1 ::송신할 데이터에 체크섬을 구하여 프로토콜을 작성해야 하는 경우 >

 

어느 특정한 계측기에 "$STX :READ? <Checksum> $ETX" 라는 문자를 요청 프로토콜 전송하려고합니다.

 

XCALL문을 이용하여 함수를 호출하여 체크섬을 생성해보도록하겠습니다.

이때 체크섬은 "STX"를 포함하여 ":READ?" 까지 데이터를 참조하여 생성해야합니다.

시작 포인트는 1, 종료포인트는 LEN을 이용하여 문자끝 포인트를 지정해줍니다.

 

그리고 잘 동작하는게 맞는지 확인하기위해 체크섬를 직접 계산해봅니다.

각 문자의 16진수 코드는 다음과 같습니다.

STX 0x02

: 0x3A

R 0x52

E 0x45

A 0x41

D 0x44

? 0x3F

이를 다 합산하면 0x197 입니다. 여기서 상위 바이트를 버리고 남은 값이 바로 체크섬이죠.

0x97을 아스키형태로 돌려주면됩니다.

 

9는 0x39

7은 0x37

 

이를 송신데이터에 함께 보내주면 되는것이죠.

그럼 콜문을 실행하여 함수를 실행해봅니다.

체크섬이 D5990번대 영역에 잘 생성된것 같습니다.

그러면 송신 데이터에도 잘 합쳐졌는지 확인해봅니다.

처음에 보낼려던데로 "$STX :READ? <Checksum> $ETX" 형태로 잘 써진것 같습니다.

 

< 프로그램 예제 #2 ::수신데이터의 체크섬을 비교하여 벨리데이션 체크를 하는 경우 >

 

상대기기에서 "ST,100.00F2 $CR $LF" 라는 문자데이터를 수신받은 상황입니다.

이 값이 유효한 값인지 체크하기 위해 체크섬을 비교하여 동일하다면 정상값으로 처리할 예정입니다.

상대기기와의 프로토콜이 정형화 되어있어 어느자리에 어떤 데이터가 들어오는지 명확하다면 시작포인트와 종료포인트를 상수로 지정해도 될것입니다.

 

그런데 가변하는 경우 통상 종료코드 직전에 있는 데이터가 체크섬이죠.

이런 규칙을 이용하자면 LEN을 통해 문자열의 총 길이를 파악후 종료코드와 체크섬을 제외한 위치를 종료점으로 지정하여 체크섬을 생성하면 되겠습니다.

 

이번 경우에는 종료코드가 CR, LF 2바이트고, 체크섬도 2바이트기 때문에 LEN 명령어로 문자의 길이를 체크후 -4 를 한 값을 종료값으로 지정하였습니다.

그러면 1번문자부터 끝-4 문자까지 데이터를 참조하여 체크섬이 생설될것입니다.

 

정수형으로도, 문자열형태로도, 캐릭터 형태로도 생성이 잘 된것 같습니다.

그러면 이제 상황에 맞추어 이값들을 활용해 비교하여 일치여부만 체크하면 되겠네요.

 

잘 됩니다.

 

이제 스트레스를 좀 덜수 있을것 같습니다.

반응형

댓글