Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 팁&트릭
Delphi Programming Tip&Tricks
[312] [팁]Comport를 이용하여 STX, ETX를 제거하고 수신하는 방법입니다
상어밥 [tonetel] 11327 읽음    2013-09-12 11:23

시리얼통신의 시장이 이전만큼은 못한거 같지만 아직도 현장에서는 볼 수 있습니다

시리얼 프로그램 관련해서 수신부분에 질문이 많은것 같아서 검색하여 찾은 자료를 가지고 팁을 드리려고 합니다

참고로 365일 돌려도 수신부분의 문제는 발생하지 않고 있습니다(데이터량 엄청납니다만^^ 이상없음)

통신프로토콜은 STX와 ETX가 있다는 가정하여 자신합니다 ^_^

그림으로 만들었는데 운영자님한테 혼나지 않을까 염려됩니다만 저같은 초보를 위하여 시간내서 편집했습니다

1. TComport를 Form에 붙입니다.

2. Events에서 OnRxChar를 더블클릭합니다

 

3. 코딩을 합니다.

 

3. 전역변수를 정의합니다.

 

4.TMemo1을 화면에 올립니다.

 

5. Object Inspector에서 시리얼포트를 설정합니다

 

6. Connected를 True로 설정하면 끝입니다.

F9을 눌러서 동작이 되는지 봅니다



카피신공을 하시는분들을 위하여

procedure TMain_Form.ComPort1RxChar(Sender: TObject; Count: Integer);
var
  i : integer;
  Str : String;    // Sbuffer : string;  // 전역변수로 지정 한다.
begin //
    Comport1.ReadStr(Str, Count);   //Serial포트로 데이터를 받는다

/////////////////////////////////////////////////////////////////////////////
//  02FF8082808303 데이터이면 FF80828083 STX와 ETX를 제거한다
/////////////////////////////////////////////////////////////////////////////
      for i := 1 to Length(Str) do begin
       if Str[i] = Chr(2) then
        begin
          Sbuffer := '';   // STX 스타트비트가  (02)
          end else
            if Str[i] = Chr(3) then begin  // ETX   END비트가 (03)
               MemoRxHex.Text := (Sbuffer);
             end else begin

////////////////////////////////////////////////////////////////////////////
// 이부분은STX와 ETX를 제거하고 데이터만 FF0203같이 붙어서 옵니다 ' '를 줘서 FF 02 03으로 나중에
// 공백으로 데이터를 대입하기 편하게 했습니다
// 그리고 대부분 STX(02)와 ETX(03)안에 02 또는 03이 붙을때가 발생하는데 이럴때는
// 대부분 데이터를 FF 80(0) 82(2) 80(0) 83(3)으로 표기합니다
// 이런 데이터를 대입할때 귀찮아서 아래와 같이 80이면 FF 8082 8083 로
// 붙도록 만들었습니다 ^^

         if Str[i] = #$80 then
          begin
            Sbuffer := Sbuffer + IntToHex(Integer(Str[i]), 2);
          end else
       Sbuffer := Sbuffer + IntToHex(Integer(Str[i]), 2) + ' ';
    end;
  end;
end;

팁을 하나더 드리자면 8082, 8083 16진수를 10진수로 바꿔쓸때가 가끔 있습니다
투박하지만 참고해서 보십시오
///////////////////////////////////////////////////////////////////////////////////
// 8082 또는 8083으로 들어오는 16진수를 10진수로...(정수이기때문에 앞 0이 없다) 
// 즉 8082는 16진수 02 이고 8083은 16진수 03 이라고 가정할때 쓴다   
//////////////////////////////////////////////////////////////////////////////////
function HexToInteger(hex: String): Integer;
begin
  if hex = '' then
    begin
      Result := 0;
      end else begin

  if hex =  '8082' then
   begin
      hex := '$' + '02';
      Result := StrToInt(hex);
      exit;
      end else

  if hex =  '8083' then
   begin
     hex := '$' + '03';
     Result := StrToInt(hex);
     exit;
     end else
     hex := '$' + hex;
     Result := StrToInt(hex);
  end;
end;

시험해보는 방법은
Edit2.Text := IntToStr(HexToInteger(Edit1.Text));

////////////////////////////////////////////////////////////////////////////////////////////////////
// 여기까지 수신 받는 팁이었습니다
// 프로그래머마다 각기 생각이 다르기 때문에 다른방법도 무궁무진하겠지요
// 저도 개발할때 마다 다르게 수신받는 방법을 이용하고 있습니다
///////////////////////////////////////////////////////////////////////////////////////////////////

그럼 다음으로 어떻게 02 FF 10 8082 04 03 16진수를 대입하는가 인데요
이번에는 CommaText를 이용해 보았는데 나름 편했습니다 ^^

Edit1.Text 를 Form에 올려 놓습니다 그리고 Text에 임의 16진수 02 FF 10 8082 04 03 를 입력합니다

procedure TForm2.Button1Click(Sender: TObject);
var
  RX_Text:  TStringList;
  a, b, c, d, e, f: String;
begin
RX_Text := TStringList.Create;
RX_Text.CommaText := Edit1.Text;

a := RX_Text.Strings[0];   //02
b := RX_Text.Strings[1];  // FF
c := RX_Text.Strings[2];  //10
d := RX_Text.Strings[3];  // 8082
// 8082를 10진수로 바꾸어서 대입하고자 한다면
// d := IntToStr(HexToInteger(RX_Text.Strings[3]));  // 십진수 2가 표기 되겠지요
e := RX_Text.Strings[4];  // 04
f  := RX_Text.Strings[5];  // 03  이 들어있겠지요

ShowMessage(b);    // FF가 보이면 OK입니다 아마도 보일겁니다!
                                 // 테스트시 무한루프에 빠질때를 대비해서 이런방법도 Edit1.Text :=  RX_Text.Strings[1];  // FF

end;

Comport를 이용해서 수신받는 방법을 대략 적어보았습니다
처음 접하시면 또 모르는 부분이 생길지는 모르겠습니다.

프로그램을 개발하다보면 간단한 부분에서 몇일 또는 몇주를 고민하는 경우가 있는데 더 딜레마에 빠질 경우가 있습니다
이때 델파이관련 사이트에 질문을 해보면 가끔은 더 기발한 방법을 알려주시는 고마운분들이 계신데
덕분에 저도 먹고 살고 있습니다 ^^ 감사합니다

마지막으로 전 Comport를 유료로 구매해서도 써보았습니다만 지금은 Delphi XE2에 공개용 Comport411f를
이용하고 있습니다 공개용으로 Comport를 이용하게 해주신분들께도 진심 감사드립니다.
gomsun2 [vhrvnd723]   2013-09-13 09:36 X
아 사진이 보이지 않네요..
멀더 [borlandforum]   2013-10-11 13:32 X
먼저 저도 ComPort (CPort 4.11버전) 사용중입니다만.. 델XE 버전에서는 신호를 제대로 받지 못해서 통신용 프로그램은 델7 에서만 개발하고 있습니다. 같은 소스와 동일한 버전의 CPort 컴포넌트로 컴파일만 달리해봤지만...수신되는 값이 달라서요..

위에서...이해가 않되는 부분이..다른 값들을 보아하니 char 형 값으로 Hex 값을 각각 받은것이 기재된것으로 보입니다.
그런데 하나의 Char 값인데... 8082, 8083 이라는 값은 뭘 말하는건지 이해가 되지 않는데요?? 어떤값이죠?
상어밥 [tonetel]   2013-10-20 00:21 X
8082  8083 은 약속되지 않았다면 무시하시면 됩니다
상어밥 [tonetel]   2013-10-20 22:31 X
하드웨어팀과 소프트웨어 팀이 따로 작업하다보면 정말 사소한것에서 우를 범할수 있습니다
하드웨어를 제어하다보면  가정하여  02 00 FF 03 03 이라는 프로토콜이 발생할 수 있습니다 이럴경우 문제가 되지요...
소프트웨어는 "02" STX와 "03"이라는 ETX를 가지고 데이터를 추출하여 이용하는데 데이터 안에 02 또는 03이 있으면 어쩔방법이 없습니다
그래서 데이터에 포함된 02 또는 03이라는 16진값을 재정의해서 데이터가 02 또는 03일때 8082 또는 8083으로 표기하던지
아니면 다른방법을 찾아봅니다 ( 예외상황일때 입니다) 
그리고 XE던지 Delphi6던지 수신받을때 달라지는것을 저는 경험해 보지 못해서 어떻게 말씀드릴수 없지만 위 소스를 대입해서
문제가 되면 언제든지 고민을 같이 해드리겠습니다 이제는 C#으로 넘어가는중이라서 매일 공부를 해야합니다만.... 시간이 허락되면요
파이어몽끼 [begin]   2014-01-11 17:17 X
님과 달라 올립니다.
참고용입니다.
....
ReceivedText : AnsiString;

procedure TMDIChild.ComPort1RxBuf(Sender: TObject; const Buffer; Count: Integer);
var
  s: AnsiString;
begin
  SetLength(s, Count);
  System.Move(Buffer, s[1], Count);
  ReceivedText := ReceivedText + s;
  if (POS(STX, ReceivedText) <> 0) and (POS(ETX, ReceivedText) <> 0) and (Length(ReceivedText) > 10) then
    Proc(ReceivedText);
end;

+ -

관련 글 리스트
312 [팁]Comport를 이용하여 STX, ETX를 제거하고 수신하는 방법입니다 상어밥 11327 2013/09/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.