시리얼 통신 하기[6]
출처: melsec PLC 동호회(http://cafe.daum.net/melsec)의 회색늑대 (grizlupo)님의 초보 통신 이야기 연재글 입니다.
회색늑대 (grizlupo)님의 초보 통신 이야기중 시리얼 통신에 관련하여 전반적으로 이해 할 수 있는 좋은 글입니다. 총 7회 분량의 글 입니다.
5. 바이트와 워드
앞서 바이트와 워드와의 관계와 PLC는 워드를 기본으로 하는데 비해 통신은 바이트를 기본으로 한다는 말씀을 드렸습니다. 그리고 앞서의 예제를 다루면서도 우리는 워드 단위로 송신할 문자의 수를 통신 모듈에 알려 주었습니다. 하지만 3개의 문자만을 송신해야 하는 경우에는 어떻게 해야 하는 걸까요?
시리얼 통신 모듈을 만든 사람도 이것이 걱정스러웠던 모양입니다. 바이트 단위로 하라고 하려니 워드 단위에 워낙에 익숙한 PLC 프로그래머들이 반발을 할지도 모른다는 걱정. 그렇다고 워드 단위로만 전송 크기를 설정하는 것으로 하려니 3개의 문자만을 송신해야 하는 따위의 문제에 대응하지 못하는 문제가 생기니 참 많이 고민스러웠던 모양입니다.
그래서 어떻게 했을 것 같습니다. 답은 “네 마음대로 하세요”입니다. 사용하는 사람이 선택을 할 수 있도록 되어 있습니다. 기본값은 워드 단위로 하는 것입니다만 바이트 단위로 하고 싶다면 그렇게 할 수 있도록 배려해 두었습니다.
통신 모듈의 버퍼 메모리 150과 310에 0을 기록하면 워드 단위가 되고, 1을 기록하면 바이트 단위가 됩니다. 150은 채널 1에 적용되고, 310은 채널 2에 적용됩니다. 물론 저는 MOV K1 U2\G150 이나 MOV K1 U2\G310을 사용해서 바이트 단위로 사용하는 것을 선호합니다.
바이트 단위로 하고, 전용해야 할 문자에 <NUL>이 없어 널종료 문자열 형태로 송신할 문자가 기록되어 있다면 이런 형태를 코드를 사용할 수 있습니다.
MOV K1 D2000
MOV K0 D2001
LEN D1000 D2002
G.OUTPUT H2 D2000 D1000 M1000
앞서 본 것과의 차이라면 문자열의 길이를 직접 계산하지 않고, LEN이라는 명령으로 대신했다는 것입니다. 이렇게 해 두면 D1000에 전송하고 싶은 문자를 널종료 문자열 형태가 되도록 기록만 하면 길이는 자동으로 설정되기 때문에 사소하지만 또 하나의 편리함을 추구할 수 있게 됩니다.
6. 수신하기
OUTPUT 이라는 전용명령 하나면 송신이 이루어졌던 것처럼 INPUT 전용명령 하나면 수신이 이루어집니다. 하지만 수신은 송신하고 조금 다른 면을 가지고 있습니다. 송신에는 자신이 보내고 싶은 때라는 것이 있을 수 있습니다. 그래서 그 때에 OUTPUT 이라는 명령을 수행하면 됩니다. 하지만 수신에서는 이 때를 내가 결정하는 것이 아니라 상대방이 결정하게 됩니다. 즉, 상대방이 송신을 한 때에 반드시 수신을 해야 합니다. 이미 상대방이 송신한 것은 이미 내뱉은 말과 같은 것이여서 지금은 바빠서 들을 수 없다고 내 마음대로 나중에 들을 수 있는 그런 성질의 것이 아닙니다.
이런 까닭에 기본적으로 시리얼 통신 모듈은 모든 수신을 자신이 알아서 해 버립니다. 즉, 상대방이 하는 말을 무조건 녹음해 버리는 전화기라고 생각하시면 됩니다. 이렇게 함으로써 송신에서처럼 내가 수신을 하고 싶을 때, 그 때 INPUT이라는 명령을 사용하더라도 상대의 송신을 놓치는 일은 없습니다. 하지만 여전히 기본적인 수신은 시리얼 통신 모듈이 하더라도, 언제 이 INPUT 명령을 사용할 것인가? 하는 것은 여전히 문제입니다.
가장 먼저 생각해 볼 수 있고 가장 흔하게 사용하는 방법은 INPUT 명령을 아무 생각없이 계속해서 사용하는 것입니다. INPUT 명령을 사용해서 수신이 없으면 그만이고, 있으면 그에 맞는 적절한 조치를 취하면 되는 것입니다. 정말 무식해 보이는 이런 방법을 사용할까? 싶겠지만 정말 그렇게 합니다.
물론 약간의 보완이 있습니다. 즉, 시리얼 통신 모듈은 수신이 있는 경우에 수신이 있다는 사실을 I/O를 통해 알려 주기 때문에 최종적인 수신 프로그램은 이 수신 확인 접점을 조건으로 해서 INPUT 명령이 사용되는 형태입니다. 뭐야! 이건 무식하게 INPUT 명령을 사용하는 것이 아니지 않느냐? 라고 하시는 분이 분명 계실 겁니다. 하지만 관점의 차이 이겠지만 수신 확인 접점을 확인하는 것이나 INPUT 명령을 직접적으로 사용하는 것이나 매 스캔마다 계속해서 뭔가를 검사 한다는 것에서는 둘이 동일한 개념이라는 것을 말씀 드리고 싶습니다. 모든 PLC 프로그램은 이런 개념으로 만들어 집니다. 그런데 왜 이런 당연해 보이는 말을 주절주절 늘어 놓는 것인가? 그것은 이렇게 하지 않는 다른 방법도 있기 때문입니다.
또 다른 방법, 그것은 인터럽트를 사용하는 형태입니다. 하지만 여기서 인터럽트에 대한 말씀을 드리지는 않겠습니다. 인터럽트라는 것 자체만으로도 너무 많은 말을 해야 하고, 시리얼 통신 모듈은 내부적으로 이미 이러한 인터럽트 개념을 사용해서 수신을 스스로 잘 하고 있기 때문에 굳이 CPU에서 다시 인터럽트를 사용해야 할 이유를 느끼지 않기 때문입니다. 그래서 인지 개인적으로 인터럽트을 이용한 수신을 한 번도 해 보지 않았습니다. 때문에 사용 설명서에 있는 내용 그 이상을 말씀 드릴 수가 없습니다. 그러니 궁금하시거나 필요하다고 생각되시는 분은 사용설명서를 참조 하십시요.
7. INPUT 명령어
이제 정말 수신을 해 보겠습니다. 실제 수신은 이미 시리얼 통신 모듈이 하고, 수신이 있다는 것을 알리는 접점이 있다고 했습니다. 따라서 문제는 간단합니다. 그냥 이 수신 확인 접점에 INPUT 명령을 연결하시면 됩니다. 수신 확인 접점은 사용설명서 ‘3.8 PLC CPU에 대한 입출력 신호 일람’에 나와 있습니다. 채널 1은 X3, 채널 2는 XA로 되어 있습니다. 우리는 시리얼 통신 모듈의 시작 I/O가 H20인 것으로 계속 가정하고 있으니까? X23과 X2A가 될 것입니다.
MOV K1 D2100
MOV K0 D2101
MOV K0 D2102
MOV K10 D2103
G.INPUT U2 D2100 D1100 M1100
X23을 조건으로 이 같은 명령을 수행하면 D1100 워드 디바이스 쪽으로 수신된 문자들이 옮겨집니다. 송신을 할 때처럼 아무런 특별할 것이 없습니다. 역시 허탈한 그 무엇입니다. 여기서도 OUTPUT에서 처럼 D2100부터 4워드가 컨트롤 데이터가 됩니다. 첫번째 D2100은 역시 채널을 선택해 주는 부분입니다. 그리고 두번째 D2101은 이상이 있는 경우 0이외의 값이 기록되는 곳입니다. 세번째는 INPUT을 통해 D1100으로 수신된 문자의 수입니다(.실제로는 워드 단위인지 바이트 단위인지에 따라 다릅니다). D2101과 D2102는 INPUT 명령을 수행하는 시스템에 의해 기록되는 값입니다. 여기서는 그냥 0으로 값을 지운 것에 불과합니다. 마지막 D2103은 D1100에 수신된 문자를 얼마나 기록할 수 있는지 표시하는 값입니다. 즉, 최대로 수신할 수 있는 수를 기록하면 됩니다. 물론 그 만큼의 D1100 이후의 디바이스가 다른 용도로 사용되지 않도록 해 주어야 합니다. 최대 수신은 어디까지나 최대로 수신할 수 있는 양이고, 실제 수신이 이 보다 작으면 그 만큼만 수신됩니다.
M1100은 INPUT에서와 같은 의미입니다. 즉, M1100은 INPUT 명령이 완료된 경우 한 스캔동안 ON하고, M1101은 명령이 완료된 시점에 이상이 있었다면 역시 한 스캔 동안 On합니다.
8. 수신 확인 접점
앞서는 그냥 수신이 된 경우 알려주는 접점이 있다고만 했습니다. 하지만 수신이 된다는 것은 정확하게 무엇인가? 하는 의미이 있을 수 있습니다. 단 한 문자라도 수신되면 바로 바로 접점이 살면서 통보를 할 것인가? 하나는 너무 작으니 10개나 20개 정도로 할 것인가? 뭐 이런 것에 대한 의문이 생깁니다.
시리얼 통신 모듈이 수신이라고 인식하는 방법은 두 가지 입니다. 1개, 10개 100개 처럼 문자의 갯수를 지정하는 방법이 그 하나이고, 수신 되는 문자 중에 지정된 문자기 있으면 갯수에 상관없이 그 순간을 수신으로 인식하는 방법입니다.
시리얼 통신 모듈의 기본 설정은 최대 511개의 문자가 수신되거나 <CR><LF>가 수신 되는 경우입니다. 이들은 버퍼 메모리 164와 165에 각각 설정됩니다. 둘 중에 어느 것이라고 만족하면 수신으로 간주합니다. 즉, <CR><LF>가 수신되면 511개의 문자가 아니어도 수신으로 처리하고, 설사 <CR><LF>가 수신되지 않더라도 511개의 문자가 수신되면 수신으로 처리되는 것입니다.
수신 종료 코드가 <CR><LF>인 경우는 특별한 경우이고, 사용자가 지정하는 경우에는 0에서 255사이의 한 문자만을 지정할 수 있습니다. 만약 이렇게 수신의 끝이라고 지정할 만한 것이 하나도 없다면 어쩔 수 없습니다. 수신 종료 데이터 수를 1로 시정해서 단 1문자라도 수신되면 접점이 살도록 해서 죽이 되든 밥이 되든 래더 프로그램으로 어떻게 해 보는 수 밖에 다른 도리가 없습니다. 그런 상황이 없기를 바라는 수 밖에요.
9. 수신 고장
설명서에는 수신 확인 접접, 정확하게는 수신 읽기 요구 신호와 함께 수신 고장 검출 신호라는 것이 있습니다. 이것은 INPUT 명령을 수행하는 동안 문제가 생겼다는 것이 아니라 내부적으로 수신 처리를 하는 중에 이상이 생겼다는 것을 알리는 신호입니다. 가장 많게는 패리티가 이상하다거나 뭐 그런 이상이 있을 수 있습니다. 즉, 뭔가 수신을 하기는 했는데 이상하다. 뭐 이런 정도의 의미인데, 이상이 있는 문자들을 분석할 필요는 없을 것입니다. 그러니 이런 상황에서 우리의 선택은 하나 뿐입니다. 버리는 것입니다. 버린다고 뭐 특별한 방법이 있는 것은 아니고, INPUT 명령을 수행해서 읽은 후 아무 처리도 하지 않으면 됩니다. 물론 버퍼 메모리를 직접 조작해서 처리하는 방법이 있을 수도 있겠습니다만 해보지도 않았고, 버퍼 메모리에 대한 지식은 최소한으로 가져 가고 싶은 욕심에 전용명령을 사용하는 것이니까 그냥 INPUT 명령으로 읽어서 버리는 방법을 권하는 것입니다.
'PLC 프로그래밍 > MELSEC PLC ' 카테고리의 다른 글
MX-Link 사용하기 [1] (0) | 2019.03.24 |
---|---|
시리얼 통신 하기[7] (0) | 2019.03.09 |
시리얼 통신 하기[5] (0) | 2019.03.08 |
시리얼 통신 하기[4] (0) | 2019.03.07 |
시리얼 통신 하기[3] (0) | 2019.03.07 |
댓글