필자도 처음에 RS-485를 대할때.... 개념의 이해에 애를 많이 먹었다..
모두 자료부족으로 인한... 배울 기회가 전혀없이 그야말로 맨땅에 헤딩한 격이었으니..ㅠ.ㅠ
오늘 필자와 같이 처음으로 RS-485를 대하며 오리무중에 빠진 분들을 위해..
아는 만큼만 서술하려고 한다.
1. 개념과 하드웨어적 개요
일반적으로 시리얼 통신에서 가장 많이 쓰는 것은 당연히 RS-232C 이다.
PC에 연결하기 위해서는 RS-422을 통해서든, RS-485를 통해서든
좌우지당간 RS-232C로 변환되어야만 하는 것이다.
이를 위하여 등장한 것이 RS422,RS485와 RS232C간 컨버터이다...
아시다시피 RS232C는 3가닥 통신이며 RS422은 4가닥 통신이지만 RS485는 2가닥으로
통신한다...
RS232는 특별한 경우가 아니라면 RX,TX,SG 만으로 통신이 가능하며,
RS422의 경우는 RX+,RX-, TX+,TX-로 통신을 하고 있다...
결선도에 대해서는 홈피 상단의 결선도 메뉴를 참조하시라..
특이하게도 RS-485의 경우는 2가닥통신을 한다...
RX,TX라는 개념없이 오로지 데이터 통신은 한가닥으로만 하는 것이다...
편의상 한가닥을 A로 나머지 한가닥을 B라고 한다면
A로는 데이터 송수신을, B로는 데이터 송수신을 위한 Control 신호를 잡아주기 위한
용도로 사용하는 것이다...
RS422,485 <-> 232C간 컨버터는 여러가지 모델이 있으며 보통은 대부분 RS422,485겸용이다...
이것은 RS422이 전이중이고 485가 반이중이라는 차이점외에 전기적으로 형태는 같기 때문이다..
RS422의 경우 RX+는 TX+로 RX-는 TX-로 서로 교차연결함으로써 통신을 하게 된다...
결과적으로 +신호끼리 -신호끼리 서로 교차연결되어 있는 것인데...
RX+,TX+를 점퍼링해서 묶어버린다면 뭉떵거려서 어쨋든 +신호가 되고
RX-,TX-를 점퍼링해서 묶는다면 -신호가 되어버린다..
이러한 형태는 곧 RX485가 요구하는 형태와 같다...
따라서 컨버터의 모델에 따라 결선법이 다르겠지만 어떤 기종의 경우는
RS-485통신을 하기 위해서는 컨버터의 접속단자에 선을 연결할 시...
+신호끼리, -신호끼리 점퍼링할 것을 요구한다...
그러면 왜 굳이 RS232C와 같이 일반적이고 대중화된 결선법을 채택하지 않고...
RS-422A 혹은 RS-485와 같은 특별한 결선법을 사용하는 것인가....에 대해
생각해 볼 수 있다...
RS-232C의 메뉴얼상 통신거리는 15M이다...(허나 본인은 50M도 해봤다..ㅡ.ㅡ)
RS-422,485는 메뉴얼상 통신거리가 1.2KM이다...
이유를 알 수 있을 것이다...
어떤 특정 구역내에서 장거리 통신을 하기 위한 방법으로 신호를 증폭시켜서 보다 멀리 통신을 하기 위한
방법인 것이다...
그러면 RS-422과 485의 차이점은 뭔가...
485가 2가닥인 이유로 비용의 절감이 예상된다..ㅡ.ㅡ 유용하고 간편하다...
보다 근본적인 이유는 +신호끼리, -신호끼리 한가닥 씩만 연결함으로써 통신이 가능한 것이다.
422은 크로스연결을 요구하지만 485는 그냥 병렬로 쭈욱 연결하면 끝이다...
422은 4개씩의 접속단자를 요구하지만 485는 2개만 있으면된다.
멀티드롭을 굳이 422로 하려고 한다면 4개씩 8개의 접속단자가 있어야하지만
485로 한다면 4개만 준비하면된다...
이러한 연유로 많은 컨트롤러에서 422A과함께 485를 지원하며 특히 병렬연결을 필요로 하는 장비는
422을 아예 지원하지 않는 경우가 있다.
2. 전이중(Full Duplex), 반이중(Half Duplex)통신이란 무엇인가?
RS-422은 전이중이며 485는 반이중이라 했다...
전이중 통신은 전화를 연상하면 된다...
반이중 통신은 무전기를 연상하면 된다...
전화는 상대방의 말을 듣는 와중에도 자신이 말을 할 수 있으며...
상대방 역시... 마찬가지이다...
+신호와 -신호 그리고 RX,TX가 구분되어 있으므로 이것이 가능한 것이다...
이번엔 무전기를 생각해보라...
오로지 일방향 통신인 것이다.
한사람이 무전기의 송신 스위치를 누른 상태에서 말을 해야하며...
'오버'라는 말과 함께 송신 스위치를 뗀다...
이것은 곧 수신 준비가 되었다는 뜻이다...
그래야만 상대방이 자신에게 송신할 수 있게된다.
상호간 대화는 A신호로 주고 받는다 치자면 무전기의 스위치는 B신호로 치고 이 버튼을 이용하여
무전기상의 어떤 통신을 위한 제어권을 넘겨주기 위한 용도로 사용하는 것이다.
그러므로 전이중 통신인 RS-232C, RS-422A와는 달리 RS-485를 제대로, 원래대로...
또는 본격적인 의미로 제어하기 위해서는 문제의 제어권 컨트롤을 해줘야 한다는 것이다.
이를 위하여 PC상에 달려있는 RS-232C 포트, COM1, COM2의 RTS(Receive To Send) 핀과
CTS(Clear To Send) 핀이 활용되고 있다.
3. RTS/CTS의 제어에 대해 알아보자...
우선 용어사전에서는 머라고 설명을 해놨는지 보자...
기대하지는 말라...
RTS/CTS:
송신 요구/송신 가능(RTS/CTS:request to send/clear to send) 방법이 있다.
이것은 시스템(컴퓨터)과 모뎀, 또는 통신 장치 간에 전기 신호와 논리 회로를 사용하여
데이터의 흐름을 제어한다.
텔레넷(Telenet)과 미국 이외의 나라들에서 데이터 통신망과 같은 부가 가치 통신망(VAN)에
이 기법을 많이 사용한다.>
DTR:
<컴퓨터와 외부 장치 간 직렬 통신에 사용되는 신호의 일종으로,
컴퓨터 또는 데이터 단말 장치(DTE)가 데이터 전송 준비가 완료된 상태에 있다는 것을
표시하기 위해 컴퓨터나 DTE에서 모뎀이나 데이터 회선 종단 장치(DCE)로 전달되는
인터페이스 제어 신호.
데이터 단말 준비 완료(DTR)는 RS-232C 인터페이스에서 20번선으로 전달되는 하드웨어 신호이다. >
라고...한다...ㅡ.ㅡ
컨버터 내부를 자세히 뜯어보거나 구조를 살펴보진 않아서 2가닥의 선들이 어떤식으로
RS232핀에 연결되어있는지...잘은 모르겠다.
422,485<->232간 컨버터는 통신의 제어권에 따라 분명히 232포트의 RTS와 CTS핀에 연결해놓은 것은
틀림이 없다... 이것은 어찌보면 국제적인 규약이며 약속일 것이다...
RTS와 CTS핀은 232같은 전이중환경에서도 반이중 통신을 할 수 있게 해준다...
하지만 노력해서 굳이.... 전이중통신을 안쓰고 반이중통신 방식을 채택하는 경우는
한번도 못봤다. 그럴 이유가 전혀 없다는 말이다...
또 이러한 흐름제어를 위하여 20번핀 DTR(Data-Terminal-Ready)핀을 사용하기도 한다.
DTR신호는 모뎀에서 주로 사용을 하고 있다.
다른 한가닥은 분명 데이터 수신과 송신상태에 따라 232포트의 9핀 중 RX(2번핀)인지, TX(3번핀)을
살려주거나 죽여줄 것이다.
누가 이분야에 정통하다면 보다 정확한 내부 결선정보를 알려주기 바란다... ㅡ.ㅡ
어쨋든 485통신상에서 통신제어권을 넘겨주느냐, 그렇지 않느냐는 9핀중 7번핀인 RTS핀을
주로 사용하게 된다.
앞서 485통신은 무전기를 연상하면 된다고 했다.
한가지 더 중요하게 고려해야 할 점이 있다면 데이터 송,수신시 반이중이라는 통신상 제약으로 인하여
약간의 통신 딜레이를 감안해야한다는 것이다.
무전기를 예를 들어 설명하면
통신제어권을 주고 받는 과정에서 송신 스위치를 누르는 동안의 시간...
대화를 마치고 '오버'를 외치고 송신 스위치를 떼는 동안의 시간, 대화가 오가는 시간,
대화를 처리하여 무전기의 스피커를 울리게 하는 시간들이 있게 마련이다.
RS-485통신에서 이러한 조건은 똑같다...
송신준비완료, 수신준비완료는 RTS신호가 살아있냐, 죽어있냐에 따라 결정되므로...
RTS신호를 살린 후에 송신하며 송신이 모두 완료되면 RTS를 죽이면 되는 것이다.
RTS(송신요구)신호는 곧 CTS와도 관련이 있고 RTS와 CTS(송신가능)는 서로 연동되어 작동한다.
RTS(송신요구)신호 이후 얼마간의 딜레이는 바로 CTS(송신가능)핀의 작동을 의미하게된다.
바로 이 딜레이타임은 중요한 화두가 된다.
일부 컨버터는 이러한 흐름제어를 자동으로 해준다...
전이중 통신에만 경험이 있다면 반이중 통신은 새롭고 어렵게 다가온다.
그러한 이유로 컨버터 회사들은 이러한 통신제어권을 스스로 알아서 처리하는 컨버터들을
만들어 낸 것이다.
그럼에도 불구하고 이러한 자동컨버터들이 통신의 안정성에 대해 보장하는 것은 아니다.
대상 장비가 어떤 조건, 규격을 따라서 제작되었느냐에 따라 다르기 때문이다.
어떤 통신대상장비는 통신제어권을 넘겨주고 받는 시간, 즉 딜레이 설정이 다를 수 있으며
이것이 정확하지 않으면 통신이 안되는 경우가 또 있는 것이다.
자동은 정해진 대로의 환경이 존재할 때만 그 혜택을 준다....
조금이라도 그 환경조성이 안된다면 혜택은 바로 무로 돌아가는 것이다.
그러므로 현장에서 수많은 중,소 장비를 대하게 될 경우...
485통신을 위한 모든 준비를 완료했음에도 불구하고 통신이 안된다면
RTS/CTS제어에 대해 강력한 의심을 품어야한다.
컨버터뿐만 아니라 해당 장비가 어떠한 방식으로 RTS/CTS제어를 하는지...
얼마만큼의 딜레이를 요구하는지에 대해 자세하고 정확하게 알아내야하는 것이다.
4. 델파이에서의 응용
자..................................
그러면 델파이에서는 어떻게 이 짓을 할 것인가...
FAOpenVCL 내에서는 공개용 통신라이브러리인 ComPort를 사용한다.
Comport 의 프로퍼티 중에서는 RTS관련 프로퍼티가 있지만 이러한 세팅은 모두 무시하자..
모두 Disable로 설정한다. 물론 FlowControl이라는 프로퍼티 내부에 존재하며 DTR 역시
Disable로 설정하도록 하자...
우리는 자동으로 RTS제어하는 것을 믿지 않는다.
그러면 어떻게 제어할 것인가..
Comport의 메쏘드 중에...
SetRTS(Boolean) 가 존재한다.
인자에 True/False를 줌으로써 RTS핀을 �하거나 해제하게 되는 것이다.
FAOpenVCL의 TModbusMast에서는 RS-485를 위한 딜레이타임과 설정유무를 결정하는 프로퍼티가 있다
그 내부코드를 보자.
// 데이터를 보내기전에 RTS를 �하고 딜레이를 주는 함수이다...
procedure TModbusMast.Rs485_Packet_SendReady;
var
Tick : DWORD;
begin
if FRS485 then
begin
//Tick := GetTickCount();//Tick을 써볼라고 했으나 CPU를 점유하는 관계로 막았다...
FCOMDriver.SetRTS(True);//RTS를 �한다.
Sleep(FRS485_PacketStart_ms);//설정한 만큼 딜레이를 준다.
//while Tick + FRS485_PacketStart_ms >= GetTickCount() do ;
end;
end;
// 데이터 송신완료후 딜레이를 주고 RTS를 해제하는 함수이다.
procedure TModbusMast.Rs485_Packet_SendFinish;
var
Tick : DWORD;
begin
if FRS485 then
begin
//Tick := GetTickCount();
//while Tick + FRS485_PacketEnd_ms >= GetTickCount() do ;
Sleep(FRS485_PacketEnd_ms);
FCOMDriver.SetRTS(False);
end;
end;
// 위 2가지 함수를 이용해서 데이터를 송신하는 함수이다.
procedure TModbusMast.r_request_data;
var
S, SendStr : string;
i, Crc16 : WORD;
begin
if (csDesigning in ComponentState) then exit;
SetLength(SendStr, 6);
FillChar(SendStr[1], 6, 0);
SendStr[1] := Chr(FTag^.SlaveId);
case FTag^.FuncID of
ftRIS: SendStr[2] := Chr($02);
ftRIR: SendStr[2] := Chr($04);
end;
SendStr[3] := Chr(Hi(FTag^.MemAddr));
SendStr[4] := Chr(Lo(FTag^.MemAddr));
SendStr[5] := Chr(Hi(FTag^.count));
SendStr[6] := Chr(Lo(FTag^.count));
Crc16 := calcCRC16(sendstr, Length(sendstr));
sendstr := sendstr + chr(hi(crc16)) + chr(lo(crc16));
FCOMDriver.ClearBuffer(True, True);
////////////////////////////////////////////////////////////////////////
if FDebug then FPrintf.Trace('RTS on...');
RS485_Packet_SendReady;
FCOMDriver.Write(SendStr[1], Length(SendStr));
if FDebug then FPrintf.Trace('요구패킷 송신.....');
RS485_Packet_SendFinish;
if FDebug then FPrintf.Trace('RTS Off...');
////////////////////////////////////////////////////////////////////////
S := '';
for i := 1 to Length(SendStr) do
S := S + Format('[%.2x]', [Byte(SendStr[i])]);
if FDebug then FPrintf.Trace('Request Data :' + S);
if FDebug then FPrintf.Trace('응답대기중...');
end;
위 함수를 자세히 살펴보면 Ready와 Finish 동작의 2가지 함수가 있고
이를 순서대로 사용한다는 것을 알 수 있다...
485에서의 데이터 송신은 위와 같이 어떤 RTS를 � 한 직후 일정한 시간동안은
데이터를 보내면 안된다.
즉 상대장비가 수신완료상태가 될 때까지의 시간을 벌어줘야하는 것이다.
그 시간이 일정하지 않고 규칙도 없다...
다만 장비의 성능, 메카니즘, 내부에 박힌 프로그램에 따라 다른 것이다...
하지만 머..대충.. 정해서 해보면 곧 답이 나올것이다...ㅡ.ㅡ
이것에서 컨버터에 의존한 RTS제어가 잘될 때가 있고 안될 때가 있는 이유를 알게되었을 것이다.
간략하게 순서를 나열하면 다음과 같다.
RTS SET(데이터송신요구) -> Delay(대기) -> DATA PACKET 송신 -> Delay(대기) -> RTS 해제
RTS SET이후의 대기시간은 길수도 짧을 수도 있다..
대략 10ms 에서 100ms 사이이다.
DATA PACKET 송신 직후의 대기시간은 매우 짧다. 10ms 정도이다.
이것은 데이터를 완전하게 보내고 수신측에서 데이터를 버퍼에 쌓아놓을 시간을 벌어주는
안전을 위한 하드웨어적인 요구일 것으로 생각된다.
대상장비의 RS-485의 메커니즘에 따라 데이터 송신직후의 대기시간은 무시될 수 있다.
필자는 RS-485를 대하면서 위와 같은 코드를 생성했으며 RS-485제작진과의 협의에 따라
정확한 딜레이 타임에 대한 정보를 얻어낼 수 있었다.
그 장비는 컨버터가 자동으로 해결해주는 딜레이타임으로는 데이터 수신을 위한 준비를
하지 못하는 것이다.
아니 그렇게 하기로 내부적인 약속을 한 것인지 모른다...
아니면 하드웨어적인 제약성 어쩔 수 없는 조건이었는지도 모른다...
어떤 이유에서건 대략 50ms 정도의 시간이 필요하다는 것이다.
또 데이터 송신직후의 딜레이타임 역시 장비가 데이터를 수신하는 메커니즘에서 요구하는
최소한의 처리시간을 요구하는 것이다.
마지막으로 RTS의 해제는 더이상의 데이터송신요구가 없다는 뜻으로 �하는 것이되겠다.
이러한 송신과정은 매번 패킷을 보낼때마다 반복되어져야한다.
결과적으로 매우 우수한 통신 상태를 얻을 수 있었다.
50ms 라 할지라도 이것은 매우 짧은 시간이다. 통신속도 역시 매우 빠르다.
5. 맺음말
아직도 PID컨트롤러, 전력전산계 등등...소형 계측장비나 컨트롤러 등에서는 경제적인 이유
하나만으로도 시리얼 통신을 채택할 수 밖에 없으며 거리상 제약으로 인하여
또 단자수의 축소를 위하여 RS-485의 채택은 필수사항이라고 생각한다.
그러므로 프로젝트시 MMI로는 도저히 해결이 안되는 컨트롤러를 분명히 대하게 될 것이며...
이글은 그럴때 RS-485에 대한 이해를 돕게 될 것이다.
필자가 그렇다고 RS-485의 처음과 끝에 대해서 정통한 것은 아니다..
다만 몇몇 장비를 대하고 고생하면서 머리속에 남았던 것들을 이 기회에 한번 정리해 본 것일 뿐...
시리얼 통신에 대한 메카니즘적인 이해는 연구소에 짱박힌 해당분야의 전문 프로그래머가 아니면...
그 구조를 자세히 알 방도가 별로 없을 것이다...
누군가 속 시원히 보다 더 자세한 정보를 기록해주었으면 좋으련만..
출처 : 라르코님 홈페이지 http://www.cyworld.com/embe/504269
'知 > Delphi' 카테고리의 다른 글
파일 정보 알아내기 (0) | 2008.08.23 |
---|---|
한글 안깨지게 자르기 (0) | 2008.08.23 |
GRF 파일 저장 문제 (0) | 2008.07.25 |
[바코드] EAN-13 체크 디지트 구하는 루틴 (0) | 2008.07.18 |
델파이 문법 (0) | 2008.06.06 |