AKI-232C を Android で使う (2018/04/01)
秋月電子のRS232Cラインモニタキット AKI-232C (リンクはこちら)用のモニタツールの Android 版です。
※ラインモニタキットに付属しているモニタツールは、Windows 2000 / XP 用ですが、
こちらの環境では、Windows 8.1 (64bit) でも動いています。
・OTG (USB-Host) に対応した Android 端末でのみ使用できます。
・タブレット端末 Nexus 7 での動作を確認しています。
・7 インチを基準にしているため、スマホ端末では、画面全体が縮小されます。
・通信速度が速い場合、データの取りこぼしが発生する場合があります。
・データ表示はリアルタイムではありません。1024バイト以上受信、または [STOP] ボタンをタップ後に表示されます。
■ダウンロード
APK本体のみ(ダウンロードは、こちら)
※USB - RS232C 通信には、CSD 社の Uni232C コンポーネントを使用しています。(リンクはこちら)
AKI-232C 添付ツールのソースコードを参考にしています。

■ソースコード
Delphi 10.2 Tokyo + Uni23C コンポーネント
unit Unit2;
interface
uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Layouts,
Uni232C, FMX.Edit, FMX.Controls.Presentation, FMX.StdCtrls, FMX.ListBox,
FMX.ScrollBox, FMX.Memo, System.Rtti, FMX.Grid.Style, FMX.Grid, System.UIConsts,
Androidapi.JNIBridge, AndroidApi.JNI.Media,
System.IOUtils, System.IniFiles;
type
TRxData = record
Tick : Byte;
Data : Byte;
end;
TComReadThread = class(TThread)
private
{ Private 宣言 }
procedure ComRead;
protected
procedure Execute; override;
public
constructor Create; virtual;
end;
TForm2 = class(TForm)
ScaledLayout1: TScaledLayout;
Uni232C1: TUni232C;
Button1: TButton;
ComboBox1: TComboBox;
ComboBox2: TComboBox;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
StringGrid1: TStringGrid;
StringColumn1: TStringColumn;
StringColumn2: TStringColumn;
StringColumn3: TStringColumn;
StringColumn4: TStringColumn;
StringColumn5: TStringColumn;
StringColumn6: TStringColumn;
StringColumn7: TStringColumn;
StringColumn8: TStringColumn;
StringColumn9: TStringColumn;
StringColumn10: TStringColumn;
StringColumn11: TStringColumn;
StringColumn12: TStringColumn;
StringColumn13: TStringColumn;
StringColumn14: TStringColumn;
StringColumn15: TStringColumn;
StringColumn16: TStringColumn;
StringColumn17: TStringColumn;
StringColumn18: TStringColumn;
StringColumn19: TStringColumn;
StringColumn20: TStringColumn;
StringColumn21: TStringColumn;
StringColumn22: TStringColumn;
StringColumn23: TStringColumn;
StringColumn24: TStringColumn;
StringColumn25: TStringColumn;
StringColumn26: TStringColumn;
StringColumn27: TStringColumn;
StringColumn28: TStringColumn;
StringColumn29: TStringColumn;
StringColumn30: TStringColumn;
StringColumn31: TStringColumn;
StringColumn32: TStringColumn;
StringColumn33: TStringColumn;
Button3: TButton;
Button4: TButton;
Button5: TButton;
GroupBox1: TGroupBox;
CheckBox1: TCheckBox;
CheckBox2: TCheckBox;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure StringGrid1DrawColumnCell(Sender: TObject; const Canvas: TCanvas;
const Column: TColumn; const Bounds: TRectF; const Row: Integer;
const Value: TValue; const State: TGridDrawStates);
procedure Button5Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure CheckBox1Change(Sender: TObject);
procedure CheckBox2Change(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ private 宣言 }
public
{ public 宣言 }
procedure DispRxData;
end;
var
Form2: TForm2;
// モニタバイト数の2倍
RxDataAry : array [0..2047] of TRxData;
RxDataIndex : integer;
GTicks : Cardinal;
Gloopflag : boolean;
GStartIndex{, GEndIndex} : integer;
GCmdMode : integer;
ThComRead : TComReadThread;
ControlCode : array of string = [
'NUL', 'SOH', 'STX', 'ETX', 'EOT', 'ENQ', 'ACK', 'BEL', 'BS', 'HT',
'LF', 'VT', 'FF', 'CR', 'SO', 'SI', 'DLE', 'DC1', 'DC2', 'DC3',
'DC4', 'NAK', 'SYN', 'ETB', 'CAN', 'EM', 'SUB', 'ESC', 'FS', 'GS',
'RS', 'US', 'DEL']; //DEL = $7E
implementation
{$R *.fmx}
procedure Beep(typ : integer);
// ブザー音
// uses ... Androidapi.JNIBridge, AndroidApi.JNI.Media;
var
ToneGenerator: JToneGenerator;
toneType : integer;
begin
ToneGenerator := TJToneGenerator.JavaClass.init(
TJAudioManager.JavaClass.STREAM_ALARM,
TJToneGenerator.JavaClass.MAX_VOLUME);
//https://developer.android.com/reference/android/media/ToneGenerator.html
if typ = 1 then
toneType := TJToneGenerator.JavaClass.TONE_PROP_BEEP
else if typ = 2 then
toneType := TJToneGenerator.JavaClass.TONE_PROP_BEEP2
else
toneType := TJToneGenerator.JavaClass.TONE_PROP_ACK;
ToneGenerator.startTone(toneType);//, 1000);
end;
function CheckRxData:string;
var
i, k: integer;
temp : array [0 ..2047] of TRxData;//Byte;
a, b : Byte;
ngcnt : integer;
res : string;
begin
res := '';
for i := 0 to 2047 do begin
temp[i].Data := 0;
temp[i].Tick := 0;
end;
i := 0;
k := 0;
ngcnt := 0;
while true do begin
a := RxDataAry[i].Data shr 4;
b := RxDataAry[i + 1].Data shr 4;
if ((a = $8) and (b = $9)) or ((a = $A) and (b = $B)) then begin
temp[k] := RxDataAry[i];
temp[k + 1] := RxDataAry[i + 1];
k := k + 2;
i := i + 2;
end
else begin
temp[k] := RxDataAry[i];
temp[k + 1] := RxDataAry[i];
k := k + 2;
Inc(i);
Inc(ngcnt);
res := res + ((k + 1) div 2).ToString + ',';
end;
if k > 2047 then break;
if i > 2047 then break;
if i >= RxDataIndex then break;
end;
for i := 0 to 2047 do RxDataAry[i] := temp[i];
if ngcnt > 0 then
result := 'NG = '+ ngcnt.ToString + ' : '+ Copy(res, 1, res.Length -1);
end;
function RateMesure: string;
// ボーレート計測
var
DataCount : integer;
Baud : array [0..99] of integer;
m, n : integer;
BaudRate : integer;
bps : string;
begin
result := '計測失敗';
if RxDataIndex > 100 then begin
DataCount := RxDataIndex;
m := 0;
for n := 0 to DataCount div 2 - 1 do begin
Baud[m] := RxDataAry[n * 2 + 1].Data;
Baud[m] := Baud[m] * 256;
Baud[m] := Baud[m] + RxDataAry[n * 2].Data + 15;
Baud[m] := Trunc(Baud[m] * 108.459); // nsec 108.459=1/9.22MHz
Inc(m);
if m = 100 then Break;
end;
BaudRate := 5000000; // nsec
for n := 0 to 50 -1 do begin
if Baud[n] <> 0 then begin
if Baud[n] < BaudRate then BaudRate := Baud[n];
end;
end;
if (3333332 * 0.85 < BaudRate) and (BaudRate < 3333332 * 1.15) then bps := '300bps'
else if (1666666 * 0.85 < BaudRate) and (BaudRate < 1666666 * 1.15) then bps := '600bps'
else if ( 833333 * 0.85 < BaudRate) and (BaudRate < 833333 * 1.15) then bps := '1200bps'
else if ( 416666 * 0.85 < BaudRate) and (BaudRate < 416666 * 1.15) then bps := '2400bps'
else if ( 208332 * 0.85 < BaudRate) and (BaudRate < 208332 * 1.15) then bps := '4800bps'
else if ( 104166 * 0.85 < BaudRate) and (BaudRate < 104166 * 1.15) then bps := '9600bps'
else if ( 69444 * 0.85 < BaudRate) and (BaudRate < 69444 * 1.15) then bps := '14400bps'
else if ( 52083 * 0.85 < BaudRate) and (BaudRate < 52083 * 1.15) then bps := '19200bps'
else if ( 34722 * 0.85 < BaudRate) and (BaudRate < 34722 * 1.15) then bps := '28800ps'
else if ( 26041 * 0.85 < BaudRate) and (BaudRate < 26041 * 1.15) then bps := '38400bps'
else if ( 17361 * 0.85 < BaudRate) and (BaudRate < 17361 * 1.15) then bps := '57600bps'
else if ( 8680 * 0.85 < BaudRate) and (BaudRate < 8680 * 1.15) then bps := '115200bps'
else if ( 4340 * 0.85 < BaudRate) and (BaudRate < 4340 * 1.15) then bps := '230400bps'
else if ( 2170 * 0.85 < BaudRate) and (BaudRate < 2170 * 1.15) then bps := '460800bps'
else if ( 1085 * 0.85 < BaudRate) and (BaudRate < 1085 * 1.15) then bps := '921600bps';
result := bps;
end;
end;
procedure TForm2.DispRxData;
var
i, j: integer;
a, b, c, d: Byte;
cnt : integer;
nth, idx, k : integer;
begin
if RxDataIndex >= 2 then begin
idx := 0;
cnt := 0;
nth := 0;
with StringGrid1 do begin
BeginUpDate;
for i := GStartIndex div 2 to RxDataIndex div 2 - 1 do begin
k := nth * 6;
a := RxDataAry[i * 2].Data shl 4;
b := RxDataAry[i * 2 + 1].Data and $0F;
c := RxDataAry[i * 2].Data shr 4;
d := RxDataAry[i * 2 + 1].Data shr 4;
if (c = $A) and (d = $B) then begin
Cells[1 + idx, k + 2] := IntToHex(a + b, 2);
Cells[1 + idx, k + 3] := Char(a + b);
if Cells[1 + idx, k + 4] <> '' then Cells[1 + idx, k + 4] := '';
if Cells[1 + idx, k + 5] <> '' then Cells[1 + idx, k + 5] := '';
end
else if (c = 8) and (d = 9) then begin
if Cells[1 + idx, k + 2] <> '' then Cells[1 + idx, k + 2] := '';
if Cells[1 + idx, k + 3] <> '' then Cells[1 + idx, k + 3] := '';
Cells[1 + idx, k + 4] := IntToHex(a + b, 2);
Cells[1 + idx, k + 5] := Char(a + b);
end
else begin
for j := 2 to 5 do
if Cells[1 + idx, k + j] <> '' then Cells[1 + idx, k + j] := '';
end;
// アイドルタイム
if RxDataAry[i * 2].Tick > 0 then
Cells[1 + idx, k + 1] := RxDataAry[i * 2].Tick.ToString
else if RxDataAry[i * 2 + 1].Tick > 0 then
Cells[1 + idx, k + 1] := RxDataAry[i * 2 + 1].Tick.ToString
else
if Cells[1 + idx, k + 1] <> '' then Cells[1 + idx, k + 1] := '';
Inc(idx);
Inc(cnt);
if idx >= 32 then begin
idx := 0;
Inc(nth);
end;
if cnt >= 64 then Break;
end;
// 余白を消す
if cnt < 64 then begin
for i := cnt to 64 - 1 do begin
if i < 32 then begin
k := 0;
idx := i;
end
else begin
k := 6;
idx := i - 32;
end;
for j := 1 to 5 do
if Cells[1 + idx, k + j] <> '' then Cells[1 + idx, k + j] := '';
end;
end;
EndUpDate;
end;
end;
end;
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
var
IniFile: TMemIniFile;
begin
IniFile := TMemIniFile.Create(System.IOUtils.TPath.Combine(
System.IOUtils.TPath.GetDocumentsPath, 'AKI232AND.ini'), TEncoding.UTF8);
with IniFile do begin
try
WriteInteger('ComboBox', 'BaudRate', ComboBox1.ItemIndex);
WriteInteger('ComboBox', 'J1<->J2', ComboBox2.ItemIndex);
WriteBool('CheckBox', 'Bit8', CheckBox1.IsChecked);
WriteBool('CheckBox', 'Bit8+1', CheckBox2.IsChecked);
finally
Free;
end;
end;
end;
procedure TForm2.FormCreate(Sender: TObject);
var
IniFile: TMemIniFile;
begin
Label1.Text := '';
Label2.Text := '';
// 横画面に固定
Application.FormFactor.Orientations :=
[TFormOrientation.Landscape, TFormOrientation.InvertedLandscape];
IniFile := TMemIniFile.Create(System.IOUtils.TPath.Combine(
System.IOUtils.TPath.GetDocumentsPath, 'AKI232AND.ini'), TEncoding.UTF8);
with IniFile do begin
try
ComboBox1.ItemIndex := ReadInteger('ComboBox', 'BaudRate', 6);
ComboBox2.ItemIndex := ReadInteger('ComboBox', 'J1<->J2', 0);
CheckBox1.IsChecked := ReadBool('CheckBox', 'Bit8', True);
CheckBox2.IsChecked := ReadBool('CheckBox', 'Bit8+1', False);
finally
Free;
end;
end;
end;
procedure TForm2.StringGrid1DrawColumnCell(Sender: TObject;
const Canvas: TCanvas; const Column: TColumn; const Bounds: TRectF;
const Row: Integer; const Value: TValue; const State: TGridDrawStates);
// セル描画
var
s: string;
c: Cardinal;
ARect : TRectF;
begin
if Column.Index = 0 then begin
end
else begin
// データ番号
if (Row = 0) or (Row = 6) then begin
if Column.Index > 0 then begin
ARect := Bounds;
ARect.Left := Bounds.Left - 2;
ARect.Right := Bounds.Right + 2;
if (StringGrid1.Cells[Column.Index, Row + 2] = '') and
(StringGrid1.Cells[Column.Index, Row + 4] = '') then
Canvas.Fill.Color := TAlphaColorRec.Grey
else
Canvas.Fill.Color := TAlphaColorRec.Silver;//.Darkcyan;
Canvas.FillRect(ARect, 0, 0, AllCorners, 1, TCornerType.Round );
Canvas.DrawRect(Bounds, 0, 0, AllCorners, 1);
if Column.Index + GStartIndex div 2 <= RxDataIndex div 2 then begin
if Row = 0 then
s := IntToStr(Column.Index + GStartIndex div 2)
else
s := IntToStr(32 + Column.Index + GStartIndex div 2);
Canvas.Font.Size := 11;
Canvas.Fill.Color := TAlphaColorRec.White;
Canvas.FillText(Bounds, s, False, 1.0, [], TTextAlign.Center);
end;
end;
end
// アイドル時間(100ms単位)
else if (Row = 1) or (Row = 7) then begin
s := StringGrid1.Cells[Column.Index, Row];
if s <> '' then begin
Canvas.Fill.Color := claOrange;
Canvas.FillRect(Bounds, 0, 0, AllCorners, 1, TCornerType.Round );
Canvas.Fill.Color := claBlack;
Canvas.Font.Size := 12;
Canvas.FillText(Bounds, s, False, 1.0, [], TTextAlign.Leading);
end;
end
// 16進表示を色分け
else if Row mod 2 = 0 then begin
if not Value.IsEmpty then s := Value.ToString
else s := '';
if s <> '' then begin
c := StrToInt('$' + s);
if (c < $20) or (c = $7E) then Canvas.Fill.Color := claRed
else begin
if (Row = 2) or (Row = 8) then Canvas.Fill.Color := claLime
else Canvas.Fill.Color := claCyan;
end;
// 透過で塗りつぶし
Canvas.FillRect( Bounds, 0, 0, AllCorners, 0.4, TCornerType.Round );
end;
end
// 制御コードを表示
else begin
s := StringGrid1.Cells[Column.Index, Row - 1];
if s <> '' then begin
c := StrToInt('$' + s);
if (c < $20) or (c = $7E) then begin
Canvas.Fill.Color := claYellow;
Canvas.FillRect(Bounds, 0, 0, AllCorners, 1, TCornerType.Round );
Canvas.Fill.Color := claBlack;
if c < $20 then s := ControlCode[c]
else s := ControlCode[$20];
Canvas.Font.Size := 11;
Canvas.FillText(Bounds, s, False, 1.0, [], TTextAlign.Center);
end;
end;
end
end;
end;
// -----------------------------------------------------------------------------
procedure TComReadThread.ComRead;
var
ret : integer;
AData : TBytes;
i : integer;
Ticks : Cardinal;
idl : integer;
res : string;
begin
GloopFlag := True;
// ボーレート計測
if GCmdMode = 101 then begin
while not Terminated and GloopFlag do begin
if Form2.Uni232C1.Connect then begin
SetLength(AData, 64);
ret := Form2.Uni232C1.Read(64, @AData[0]);
if ret > 0 then begin
for i := 0 to ret -1 do begin
RxDataAry[RxDataIndex].Data := AData[i];
Inc(RxDataIndex);
end;
{
Synchronize(procedure begin
Form2.Label2.Text := 'Read Data = ' + RxDataIndex.ToString;
end);
}
if RxDataIndex > 100 then
GLoopFlag := False;
end
else begin
//Sleep(1);
Synchronize(procedure begin
if Form2.Label2.Text <> (RxDataIndex div 2).ToString then
Form2.Label2.Text := (RxDataIndex div 2).ToString;
end);
end;
end
else
GloopFlag := False;
end;
end
// モニタリング
else begin
while not Terminated and GloopFlag do begin
if Form2.Uni232C1.Connect then begin
SetLength(AData, 64);
ret := Form2.Uni232C1.Read(64, @AData[0]);
if ret > 0 then begin
Ticks := TThread.GetTickCount;
if RxDataIndex > 0 then begin
idl := (Ticks - GTicks) div 100;
if idl > 255 then idl := 255;
RxDataAry[RxDataIndex].Tick := idl;
end;
GTicks := Ticks;
for i := 0 to ret - 1 do begin
RxDataAry[RxDataIndex].Data := AData[i];
Inc(RxDataIndex);
if RxDataIndex >= 2048 then begin
GloopFlag := False;
break;
end;
end;
{
Synchronize(procedure begin
Form2.Label2.Text := (RxDataIndex div 2).ToString;
end);
}
end
else begin
//Sleep(1);
Synchronize(procedure begin
if Form2.Label2.Text <> (RxDataIndex div 2).ToString then
Form2.Label2.Text := (RxDataIndex div 2).ToString;
end);
end;
end
else
GloopFlag := False;
end;
end;
Synchronize(procedure begin
if Form2.Label2.Text <> (RxDataIndex div 2).ToString then
Form2.Label2.Text := (RxDataIndex div 2).ToString;
end);
// モニタリング、ボーレート計測終了
if Form2.Uni232C1.Connect then begin
SetLength(AData, 64);
AData := TEncoding.ANSI.GetBytes('E');
Form2.Uni232C1.Write(1, @AData[0]);
Sleep(100);
Form2.Uni232C1.Close;
if GCmdMode = 101 then begin
if RxDataIndex > 100 then begin
Synchronize(procedure begin
ShowMessage(RateMesure);
end);
end;
end;
end;
if GCmdMode = 101 then begin
Synchronize(procedure begin
Form2.Button5.Text := 'ボーレート計測';
end);
end
else begin
res := CheckRxData;
if res <> ''then
Synchronize(procedure begin
Form2.Label2.Text := Form2.Label2.Text + ' (' + res + ')';
end);
end;
Synchronize(procedure begin
Form2.DispRxData;
Form2.Button1.Enabled := True;
Form2.Button5.Enabled := True;
end);
GCmdMode := 0;
Beep(3);
end;
constructor TComReadThread.Create;
begin
// スレッドを生成、直ちに実行
inherited Create(False);
// スレッド終了時、スレッドオブジェクトを破棄
FreeOnTerminate := True;
end;
procedure TComReadThread.Execute;
begin
ComRead;
end;
procedure TForm2.Button1Click(Sender: TObject);
// [START]
var
AData : TBytes;
ret : integer;
i: Integer;
begin
GCmdMode := 0;
Label1.Text := '';
SetLength(AData, 64);
Uni232C1.BaudRate := 115200;
Uni232C1.ByteSize := Bit8;
Uni232C1.StopBits := StopBit1;
Uni232C1.ParityBits := ParityNone;
Uni232C1.Open ;
Sleep(100);
if Uni232C1.Connect then begin
Button1.Enabled := False;
Button5.Enabled := False;
Beep(1);
{ [ BaudRate ];
'0' 600bps
'1' 1200bps
'2' 2400bps
'3' 4800bps
'4' 9600bps
'5' 14400bps
'6' 19200bps
'7' 28800bps
'8' 38400bps
'9' 57600bps }
// ボーレート
AData := TEncoding.ANSI.GetBytes(ComboBox1.ItemIndex.ToString);
Uni232C1.Write(1, @AData[0]);
Sleep(100);
SetLength(AData, 64);
Uni232C1.Read(64, @AData[0]);
// 'V' ファームウエアのバージョンデータ要求
SetLength(AData, 64);
AData := TEncoding.ANSI.GetBytes('V');
Uni232C1.Write(1, @AData[0]);
Sleep(100);
SetLength(AData, 64);
ret := Uni232C1.Read(64, @AData[0]);
if ret > 0 then begin
SetLength(AData, ret);
Label1.Text := TEncoding.ANSI.GetString(AData);
end;
SetLength(AData, 64);
// 8Bit / 8+1Bit (Parity)
if CheckBox1.IsChecked then AData := TEncoding.ANSI.GetBytes('d')
else AData := TEncoding.ANSI.GetBytes('D');
Uni232C1.Write(1, @AData[0]);
Sleep(100);
SetLength(AData, 64);
Uni232C1.Read(64, @AData[0]);
// モニタリング開始
case ComboBox2.ItemIndex of
0 : AData := TEncoding.ANSI.GetBytes('G'); // 双方向
1 : AData := TEncoding.ANSI.GetBytes('A'); // J2->J1
2 : AData := TEncoding.ANSI.GetBytes('B'); // J1->J2
end;
Uni232C1.Write(1, @AData[0]);
Sleep(100);
SetLength(AData, 64);
Uni232C1.Read(64, @AData[0]);
RxDataIndex := 0;
// データ表示の開始データ位置
GStartIndex := 0;
for i := 0 to 2047 do RxDataAry[i].Tick := 0;
ThComRead := TComReadThread.Create;
end;
end;
procedure TForm2.Button2Click(Sender: TObject);
// [STOP]
begin
GLoopFlag := False;
end;
procedure TForm2.Button3Click(Sender: TObject);
// [<]ボタン
begin
Button3.Enabled := False;
if GStartIndex > 0 then begin
GStartIndex := GStartIndex - 64;
if GSTartIndex < 0 then GStartIndex := 0;
DispRxData;
end;
Button3.Enabled := True;
end;
procedure TForm2.Button4Click(Sender: TObject);
// [>] ボタン
begin
Button4.Enabled := False;
if GStartIndex < RxDataIndex - 64 then begin
GStartIndex := GStartIndex + 64;
DispRxData;
end;
Button4.Enabled := True;
end;
procedure TForm2.Button5Click(Sender: TObject);
// ボーレート計測
var
AData : TBytes;
ret : integer;
i : integer;
begin
if Button5.Text <> '計測中止' then begin
Label1.Text := '';
if Button1.Enabled then begin
Uni232C1.BaudRate := 115200;
Uni232C1.ByteSize := Bit8;
Uni232C1.StopBits := StopBit1;
Uni232C1.ParityBits := ParityNone;
Uni232C1.Open;
Sleep(100);
if Uni232C1.Connect then begin
Beep(1);
Button1.Enabled := False;
Button5.Text := '計測中止';
// 'V' ファームウエアのバージョンデータ要求
SetLength(AData, 64);
AData := TEncoding.ANSI.GetBytes('V');
Uni232C1.Write(1, @AData[0]);
Sleep(100);
SetLength(AData, 64);
ret := Uni232C1.Read(64, @AData[0]);
if ret > 0 then begin
SetLength(AData, ret);
Label1.Text := TEncoding.ANSI.GetString(AData);
end;
RxDataIndex := 0;
GStartIndex := 0;
SetLength(AData, 64);
AData := TEncoding.ANSI.GetBytes('M');
Uni232C1.Write(1, @AData[0]);
Sleep(100);
for i := 0 to 2047 do RxDataAry[i].Tick := 0;
GCmdMode := 101;
ThComRead := TComReadThread.Create;
end;
end;
end
else begin
if Uni232C1.Connect then begin
GloopFlag := False;
end;
end;
end;
procedure TForm2.CheckBox1Change(Sender: TObject);
begin
if CheckBox1.IsChecked and CheckBox2.IsChecked then
CheckBox2.IsChecked := False
else if not CheckBox1.IsChecked and not CheckBox2.IsChecked then
CheckBox2.IsChecked := True;
end;
procedure TForm2.CheckBox2Change(Sender: TObject);
begin
if CheckBox1.IsChecked and CheckBox2.IsChecked then
CheckBox1.IsChecked := False
else if not CheckBox1.IsChecked and not CheckBox2.IsChecked then
CheckBox1.IsChecked := True;
end;
end.