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.