Q&A

  • 아래에 comport 질문한 거 다시 묻겠습니다.
안녕하세요?
델초보인데 얼마전 부서를 옮기고 델파이를 시작하면서 OJT 과제로
작은 프로젝트를 받아서요 comport 2.64로 작업중인데요,
시리얼 통신 채팅프로그램 같은 거 만들고 있거든요.

일단 프로그램 띄우고 양쪽에서 connect 시켜주고 텍스트 입력해서 보내면
상대방에 텍스트가 뜹니다.

문제는요 두 번 정도 왔다갔다하고나면 그담부턴 더 이상 내용이 전달되지 않습니다.
그래서 자꾸 연결이 끊어진다고 생각했었거든요.

근데, 연결이 끊어지는 게 아닌 것 같습니다.
텍스트가 전달이 안되서 양쪽에서 다시 connect를 시켜줘도
마찬가지로 전달이 되지 않네요.
프로그램을 종료시키고 다시 띄워서 양쪽에서 connect해주고나면
다시 텍스트 전송이 되지만 두어줄 보내고나면 마찬가지로 전송이 되지 않습니다.

그래서, 연결이 끊어지는 게 아니고 어딘가에서 딴짓을하는 게 아닐까(무한루프라던지.. 뭐 그런 거)
소스 좀 봐주세요.

그리고 한 가지 더 묻자면

R_str : array[1..100] of char;  이렇게 변수선언하고

ComPort.ReadStr(R_str,count);

이런식으로 컴포트에서 read한 파일을 char배열에 넣으려고하니까
array와 string의 type이 맞지 않는다는 에러가 뜨는데요,
이거 원래 가능한 거잖아요. char로 된 배열에 string 문자 넣고 읽고 하는 거 다 되는건데
기존에 다른 소스에서도 많이 썼었는데 안되네요.

======== 소스내용입니다 ===================
unit ComPort;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, CPort, CPortCtl, ExtCtrls;

type
  TForm1 = class(TForm)
    ComPort: TComPort;
    RichEdit1: TRichEdit;
    Edit1: TEdit;
    ConnBtn: TButton;
    ClearBtn: TButton;
    ExitBtn: TButton;
    EnterBtn: TButton;
    DisConnBtn: TButton;
    Memo1: TMemo;
    procedure ConnBtnClick(Sender: TObject);
    procedure DisConnBtnClick(Sender: TObject);
    procedure ClearBtnClick(Sender: TObject);
    procedure ExitBtnClick(Sender: TObject);
    procedure EnterBtnClick(Sender: TObject);
    procedure ComPortRxChar(Sender: TObject; Count: Integer);
    procedure Edit1KeyPress(Sender: TObject; var Key: Char);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.ConnBtnClick(Sender: TObject);
begin
  if ComPort.Connected then exit
  else
    ComPort.Open;
  ConnBtn.Caption := '연결중';
  Edit1.SetFocus;
end;

procedure TForm1.DisConnBtnClick(Sender: TObject);
begin
  if ComPort.Connected then
    ComPort.Close
  else exit;
  MessageDlg('연결 해제되었습니다', mtInformation, [mbOK], 0);
  ConnBtn.Caption := '&Connect';
end;

procedure TForm1.ClearBtnClick(Sender: TObject);
begin
  RichEdit1.Lines.Clear;
  Edit1.SetFocus;
end;

procedure TForm1.ExitBtnClick(Sender: TObject);
begin
  Close;
end;

procedure TForm1.EnterBtnClick(Sender: TObject);
var T_str : string;
begin
  if ComPort.Connected then
    begin
      T_str := Edit1.Text;
      if copy(T_str, length(T_str), 1) <> #13 then T_str := T_str + #13;
      ComPort.WriteStr(T_str);
      RichEdit1.Lines.Add('[송신] ' + T_str);
      Edit1.Clear;
      Edit1.SetFocus;
    end
  else if MessageDlg('연결되지 않았습니다' + #10#13 + '연결하시겠습니까?',
          mtWarning,[mbYes,mbNo],0) = mrYes then ComPort.Open
       else begin
         Edit1.SetFocus;
         Exit;
       end;
end;

procedure TForm1.ComPortRxChar(Sender: TObject; Count: Integer);
var
  R_str : string;
begin
  ComPort.ReadStr(R_str, Count);
  if copy(R_str, count, 1) <> #13 then Memo1.Text := Memo1.Text + R_str
  else
    begin
      RichEdit1.Lines.Add('[수신] '+ Memo1.Text + R_str);
      Memo1.Clear;
      Edit1.SetFocus;
    end;
end;

procedure TForm1.Edit1KeyPress(Sender: TObject; var Key: Char);
begin
  if Key = #13 then EnterBtnClick(nil);
end;

end.
4  COMMENTS
  • Profile
    이동규 2006.11.15 18:56
    님의 코드 중에서 송신, 수신 부분을 가져와서 사용했는데 이상없었습니다.
    저는 컴이 하나라 serial port를 loop시켜서 했습니다. (2, 3번 핀 loop)
    송신, 수신 모두 이상이 없었습니다.
    그럼 수고하세요.
  • Profile
    정계순 2006.11.16 02:09
    오늘 안 사실인데요, 한글이 깨져서 그렇게 되더라고요
    스트링의 끝에 #13을 인식해서 #13이 붙어있으면 그 동안 모아놓은  memo의 내용을
    화면에 뿌려주게 코딩해놓으니까, 한글이 깨져버린 경우 스트링 끝에 #13이 인식이 안되서
    그걸 계속 모아놓기만 하지 화면에 뿌리질 못하더군요.
    영문하고 숫자로 주고받으면 전혀 문제없이 잘 되더라고요.

    여기까진 알아냈는데, 한글이 깨지는 현상을 어떻게 처리해야 하는지가 남아있네요.
    그거 알아내서 고쳐보려고 오늘 하루가 다 갔습니다. ㅠ.ㅠ

    근데, 정말 이상한 건 디버깅하면서 한 문장씩 수행하면요,
    한글이 전혀 깨지지 않고 잘 전해지고 잘 받아진다는 거죠.
    애국가 1절부터 4절까지 보내봐도 전혀 안 깨지더라고요.
    근데, 실행파일만 만들면 한글이 깨지면서 화면상으로 멈추는 거죠.

    이것도 좀 도와주삼~~
  • Profile
    정계순 2006.11.16 03:46
    위에 질문 올려놓고 얼마 안되서 문제가 해결됐어요.
    전 해결됐는데, 혹시 같은 일로 고생하시는 분 있다면 참고하시라고...

    Comport.ReadStr 메소드 대신 ComPort.Read 메소드를 이용해서 버퍼에 자료를 넣고요,
    받은 문자의 끝을 찾을 때 스트링의 마지막 글자를 copy 함수를 이용해서 확인하는 대신에
    배열을 이용해서 첫번째 칸부터 하나씩 비교하면서 #13이 아니면 Memo.text에 추가하고
    #13이 나오면 Memo.text를 화면에 뿌려주는 식으로 바꾸니까 되네요.

    문제가 해결돼서 맘편히 퇴근해서 지금 소스가 없으니 올려주지는 못하고..

    전역변수로
    var
      buff : array[0.,1000] of char;
      j : integer

    이렇게 선언해두고

    Comport.Read(R_str, count);
    for i :=0 to count-1 do  //i는 이 프로시저에서 선언한 integer이고요
      if R_str[i] <> #13 then
        begin
          buff[j] := R_str[i];
          inc(j);
        end
      else
        begin
          RichEdit.Lines.Add(buff);
          buff := '';
          j := 0;
        end;

    이런 식으로 했던 것 같습니다.
    배열로 한 바이트씩 차곡차곡 받아서 한꺼번에 처리하니까
    한글이 깨지지도 않고, 깨진 글자가 없으니 #13도 잘 인식해서
    화면에 깨끗이 잘 뿌려지더군요.

    누군가에게 도움이 되었으면 좋겠습니다.
    열 프!!      
  • Profile
    이동규 2006.11.16 18:04
    ㅎㅎ