Delphi 10 で ApdComPort を使う (2019/02/20)
※ 2019/02/10 AdSelCom.IsPortAvailable() のサンプルコードを修正。
※ 2019/02/10 ApdDataPacket1.EndCond : ecStringにチェックを追記。IntToBin, IntToBunRev
を変更。
※ 2019/02/06 三菱 FX3S との通信サンプルを追加
※ 2017/05/18 TApdDataPacket、TApdSLController、TApdStatusLight コンポーネント、ログファイルのスクリーンショットを追加
※ 2017/05/21 日本語マニュアルがありました。TurboPower Async Professional リファレンス・ガイド 第2章
これまでは CPortLIB を使っていたのですが、GetIt からインストールできる ApdComPort を使ってみました。
ウェルカムページ で、「GetIt でアドオンを取得」 をクリックすると、GetIt パッケージマネージャ が開きます。
インストールすると、ツールパレットに APRO カテゴリが追加されます。
TApdComPort は、その中にあります。
データの受信は、ApdComPort1TriggerAvail(CP: TObject; Count: Word); イベントを使います。
終端文字が ETX、CRLF のように固定の場合は、TApdDataPacket コンポーネントを追加し、
ComPort プロパティを ApdComPort にします。
終端文字が CRLF の場合は、EndString を #13#10 (^M^J) に、StartCond を scAnyData に設定。
ApdDataPacket1.EndCond プロパティの ecString にチェックを付けておくと、(2019/02/10追加)
ApdDataPacket1StringPacket(Sender: TObject; Data: AnsiString); イベントで文字列として取得されます。
通信状態のランプは、TApdStatusLight コンポーネントを必要数追加、TApdSLController コンポーネントを1個追加し、
ApdSLController に ApdStatusLigh を登録。ApdSLController の ComPort プロパティに ApdComPort
を設定します。
ApdSLController1.Monitoring := True; にすると、動くようになります。
COM ポート番号が有効であるかを確認するには、uses 節に、AdSelCom を追加し、IsPortAvailable() を使います。
※2019/02/20 修正
AdSelCom.ShowPortsInUse := False;
for i := 0 to 32 do if AdSelCom.IsPortAvailable(i) thenComboBox4.Items.Add
(AdPort.ComName(i));
単体で、ログファイルの作成、追加ができます。
ASCII 表記
HEX 表記
// GetIt からアドオンを取得 // AsyncPro for VCL 1.3 var buf : string; // 送信 procedure TForm2.Button1Click(Sender: TObject); begin ApdComPort1.ComNumber := 5; // COM5 ApdComPort1.Baud := 2400; ApdComPort1.StopBits := 1; ApdComPort1.DataBits := 8; ApdComPort1.Parity := TParity.pNone; try ApdComPort1.Open := True; buf := ''; // 送信 ApdComPort1.Output := 'ABCDEFGHIJKLMNOPQRS'; ApdComPort1.PutString('1234678901324567890'); except ShowMessage('ERROR'); end; end; // 受信 //---------------------------------------------------------- // GetChar //---------------------------------------------------------- procedure TForm2.ApdComPort1TriggerAvail(CP: TObject; Count: Word); var i: Word; begin for i := 1 to Count do buf := buf + string(ApdComPort1.GetChar); Edit1.Text := buf; end; //---------------------------------------------------------- // Byte //---------------------------------------------------------- procedure TForm2.ApdComPort1TriggerAvail(CP: TObject; Count: Word); var i: Word; B: array [0..1024] of Byte; begin ApdComPort1.GetBlock(B, Count); for i := 0 to Count -1 do buf := buf + Char(B[i], 2); Edit1.Text := buf; end; //---------------------------------------------------------- // TBytes //---------------------------------------------------------- procedure TForm2.ApdComPort1TriggerAvail(CP: TObject; Count: Word); var B: TBytes; begin SetLength(B, Count); ZeroMemory(B, Count); ApdComPort1.GetBlock(B[0], Count); buf := buf + TEncoding.ANSI.GetString(B); Edit1.Text := buf; end;
・2019/02/06 FX3S との通信を追加
unit TX3SRS232ComTestUnit4; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs,AdSelCom, Vcl.StdCtrls, OoMisc, AdPort, Vcl.ComCtrls; type TForm4 = class(TForm) ApdComPort1: TApdComPort; ComboBox1: TComboBox; UpDown1: TUpDown; Edit1: TEdit; Edit2: TEdit; Button1: TButton; Button2: TButton; procedure FormCreate(Sender: TObject); procedure ApdComPort1TriggerAvail(CP: TObject; Count: Word); procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } rcvBuf : string; end; var Form4: TForm4; implementation {$R *.dfm} function IntToBin(x : Integer; bits : integer) : String; var i, k : integer; begin result := ''; k := x; for i := 0 to bits -1 do begin result := IntToStr(k and 1) + result; k := k shr 1; end; end; function IntToBinRev(x : Integer; bits : integer) : String; var i, k : Integer; begin result := ''; k := x; for i := 0 to bits - 1 do begin result := result + IntToStr(k and 1); k := k shr 1; end; end; procedure TForm4.ApdComPort1TriggerAvail(CP: TObject; Count: Word); // 文字列受信 var i: Word; begin for i := 1 to Count do rcvBuf := rcvBuf + string(ApdComPort1.GetChar); Edit2.Text := rcvBuf; end; procedure TForm4.Button1Click(Sender: TObject); // COM ポートオープン var s : string; begin with ApdComPort1 do begin if not Open then begin s := ''; with ComboBox1 do begin if ItemIndex >= 0 then begin s := Items[ItemIndex].Substring(4); end; end; if s <> '' then begin with ApdComPort1 do begin ComNumber := s.ToInteger; Baud := 19200; StopBits := 1; DataBits := 8; Parity := TParity.pNone; try Open := True; except ShowMessage('ERROR'); end; end; end; end; end; end; procedure TForm4.Button2Click(Sender: TObject); // WAV-5F2 255CH 再生テスト用 // Y0~Y4 = D0 ~ D4、Y5 = STB に使用 const STX = #$02; // テキスト開始 ETX = #$03; // テキスト終了 EOT = #$04; // テキスト終結 ENQ = #$05; // 問合せ ACK = #$06; // 肯定応答 CR = #$0D; // キャリッジリターン LF = #$0A; // 改行 CL = #$0C; // クリア NAK = #$15; // 否定応答 var s, cmd, head, term : string; begin // 左から若い順の2進文字列に s := IntToBinRev(UpDown1.Position, 8).Substring(0, 5); with ApdComPort1 do begin if Open then begin try rcvBuf := ''; head := ENQ +'00FFBW0'; term := CR + LF; cmd := 'Y0000'; // 5桁で指示:Y0000から cmd := cmd + '06'; // 6個書き込み cmd := cmd + s + '0'; PutString(head + cmd + term); // STB (Y5) ON PutString(head + 'Y0005011' + term); Sleep(50); // STB (Y5) OFF PutString(head + 'Y0005010' + term); cmd := 'Y0000'; // 5桁で指示:Y0000から cmd := cmd + '06'; // 6個書き込み cmd := cmd + '000000'; PutString(head + cmd + term); except end; end; end; end; procedure TForm4.FormCreate(Sender: TObject); // 使用可能な COM ポートを列挙 var i : integer; begin Edit2.Text := ''; with ComboBox1 do begin for i := 0 to 32 do begin if IsPortAvailable(i) then Items.Add('COM ' + i.ToString); end; if Items.Count > 0 then ItemIndex := 0; end; end; end.