RS232C 付 DMM(デジタルマルチメータ) MS8226 を読んでみました (2017/05/06~12/10)
・2017/12/10 iOS (iPhone) のコード (Delphi 10.1) を追加しました。
MS8226 は MASTECH(中国)のデジタルマルチメータで、標準で RS232C ポートと専用ケーブルが付いています。
アマゾンで、¥4,950. で購入しました。中国から届きます。
TsDMMViewer の KAISE KU-2068 モード で接続すると、PC での計測値の表示、ロギングが可能になります。
通信は、1 秒に 1 回程度の間隔で、LCD 表示の 14 バイトのデータが送られてきます。
計測値は数値ではなく、7 セグメント x 4桁 のデータなので、解析が必要になります。
他にも、PCリンク(RS232C、Bluetooth、BLE ...)の DMM がありますが、通信データの内容は、LCD 表示なのではないかと思います。
■スクリーンショット

これを元に、RS-232C - WiFi 変換器を付けて、スマホ(iPhone、Android)に飛ばしています。
MS8226 は、DTR を ON にしないと、データを送信しません。(DTR をフォトカプラの電源として使用していると思われます。)
使用した RS-232C - WiFi 変換器(ラトックシステム社 REX-WF60) は、DTR には対応していないため、DC5V を MS8226 の 4 番ピンに接続する必要があります。

■Delphi 10.1 + ComPort LIB ソースコード
unit MS8226Unit;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, CPort, CPortCtl;
type
TForm2 = class(TForm)
ComPort1: TComPort;
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Edit13: TEdit;
ComComboBox1: TComComboBox;
Edit4: TEdit;
Edit5: TEdit;
Edit6: TEdit;
Label1: TLabel;
procedure Button1Click(Sender: TObject);
procedure ComPort1RxChar(Sender: TObject; Count: Integer);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure Button2Click(Sender: TObject);
private
{ Private 宣言 }
public
{ Public 宣言 }
GTicks : Cardinal;
GStrHex :string;
GStrBin :string;
procedure DispStrBin;
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
// ComPort オープン
procedure TForm2.Button1Click(Sender: TObject);
begin
ComPort1.BaudRate := TBaudRate.br2400;
ComPort1.DataBits := TDataBits.dbEight;
ComPort1.StopBits := TStopBits.sbOneStopBit;
ComPort1.FlowControl.FlowControl := TFlowControl.fcNone;
ComPort1.FlowControl.ControlDTR := TDTRFlowControl.dtrEnable;
ComPort1.Open;
GTicks := GetTickCount;
end;
// ComPort クローズ
procedure TForm2.Button2Click(Sender: TObject);
begin
if Comport1.Connected then begin
try
Comport1.Close;
Label1.Caption := '';
except
;
end;
end;
end;
// 1バイト整数を2進文字列に
function ByteToBin(x: Byte) : string;
var
i : integer;
begin
result := '';
for i := 1 to 8 do begin
if ((x and 1) = 1) then
result := '1' + result
else
result := '0' + result;
x := x shr 1;
end;
end;
// 1バイト16進文字列を2進文字列に
function HexToBin(const hex : string) : string;
var
x : integer;
begin
result := '';
x := StrToIntDef('$' + hex, -1);
if x >= 0 then
result := ByteToBin(x);
end;
// 7セグメントデータを数値に
function SevenSegToStr(const efadcgb : string): string;
var
s : string;
begin
result := '';
if efadcgb.Length = 7 then begin
s := efadcgb;
if s = '1111101' then result := '0'
else if s = '0000101' then result := '1'
else if s = '1011011' then result := '2'
else if s = '0011111' then result := '3'
else if s = '0100111' then result := '4'
else if s = '0111110' then result := '5'
else if s = '1111110' then result := '6'
else if s = '0010101' then result := '7'
else if s = '1111111' then result := '8'
else if s = '0111111' then result := '9'
else if s = '1101000' then result := 'L';
end;
end;
// 2進文字列をDMMデータとして表示
procedure TForm2.DispStrBin;
const
offset = 4;
var
s : string;
AcDc, Range, Tani : string;
begin
if GStrBin.Length = 14 * 8 then begin
// AC / DC
if GStrBin.Substring(offset + 0, 1) = '1' then AcDc := 'AC'
else if GStrBin.Substring(offset + 1, 1) = '1' then AcDc := 'DC'
else AcDc := '';
Edit1.Text := AcDc;
// Rnage
if GStrBin.Substring(offset + 2, 1) = '1' then Range := 'AUTO'
else Range := 'MANUAL';
Edit2.Text := Range;
// 単位(Unit)
if GStrBin.Substring(offset + 82, 1) = '1' then Tani := 'M'
else if GStrBin.Substring(offset + 81, 1) = '1' then Tani := '%'
else if GStrBin.Substring(offset + 80, 1) = '1' then Tani := 'm'
else if GStrBin.Substring(offset + 74, 1) = '1' then Tani := 'K'
else if GStrBin.Substring(offset + 73, 1) = '1' then Tani := 'n'
else if GStrBin.Substring(offset + 72, 1) = '1' then Tani := 'u'
else Tani := '';
if GStrBin.Substring(offset + 98, 1) = '1' then Tani := Tani + 'Hz'
else if GStrBin.Substring(offset + 97, 1) = '1' then Tani := Tani + 'V'
else if GStrBin.Substring(offset + 96, 1) = '1' then Tani := Tani + 'A'
else if GStrBin.Substring(offset + 89, 1) = '1' then Tani := Tani + 'Ω'
else if GStrBin.Substring(offset + 88, 1) = '1' then Tani := Tani + 'F'
else if GStrBin.Substring(offset + 105, 1) = '1' then Tani := Tani + '℃';
Edit3.Text := Tani;
if GStrBin.Substring(offset + 83, 1) = '1' then Edit4.Text := 'Beep'
else if GStrBin.Substring(offset + 75, 1) = '1' then Edit4.Text := 'Diode'
else Edit4.Text := '';
if GStrBin.Substring(offset + 91, 1) = '1' then Edit5.Text := 'HOLD'
else Edit5.Text := '';
if GStrBin.Substring(offset + 90, 1) = '1' then Edit6.Text := 'REL'
else Edit6.Text := '';
{
if GStrBin.Substring(offset + 3, 1) = '1' then Edit7.Text := 'RS232C'
else Edit7.Text := '';
}
// 測定値
s := '';
if GStrBin.Substring(offset + 8, 1) = '1' then s := s + '-' else s := s + ' ';
s := s + SevenSegToStr(GStrBin.Substring(offset + 9, 3) + GStrBin.Substring(offset + 9 + 7, 4));
if GStrBin.Substring(offset + 24, 1) = '1' then s := s + '.';
s := s + SevenSegToStr(GStrBin.Substring(offset + 25, 3) + GStrBin.Substring(offset + 25 + 7, 4));
if GStrBin.Substring(offset + 40, 1) = '1' then s := s + '.';
s := s + SevenSegToStr(GStrBin.Substring(offset + 41, 3) + GStrBin.Substring(offset + 41 + 7, 4));
if GStrBin.Substring(offset + 56, 1) = '1' then s := s + '.';
s := s + SevenSegToStr(GStrBin.Substring(offset + 57, 3) + GStrBin.Substring(offset + 57 + 7, 4));
Edit13.Text := s;
end;
end;
// ComPort から受信
procedure TForm2.ComPort1RxChar(Sender: TObject; Count: Integer);
var
s : string;
i : integer;
Ticks : Cardinal;
begin
if Count > 0 then begin
Ticks := GetTickCount;
ComPort1.ReadStr(s, Count);
if s.Length > 0 then begin
if Ticks - GTicks > 200 then begin
if GStrHex.Length = 28 then begin
GStrBin := '';
// 2進文字列に
for i := 0 to 28 div 2 -1 do
GStrBin := GStrBin + HexToBin(GStrHex.Substring(i * 2, 2));
if Label1.Caption <> '■' then Label1.Caption := '■'
else Label1.Caption := '';
//Memo1.Lines.Insert(0, GStrBin);
// 2進文字列をDMMデータとして表示
DispStrBin;
end;
GTicks := Ticks;
GStrHex := '';
end;
// 一時的に16進文字列に
for i := 0 to s.Length -1 do
GStrHex := GstrHex + IntToHex(Ord(s.Chars[i]), 2);
end;
end;
end;
// フォームクローズ
procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if Comport1.Connected then begin
try
Comport1.Close;
except
;
end;
end;
end;
end.
■Delphi 10.1 + Wi-Fi (Indy) ソースコード
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.Controls.Presentation, FMX.StdCtrls, FMX.Layouts, IdBaseComponent,
IdComponent, IdTCPConnection, IdTCPClient, IdUDPBase, IdUDPClient, IdUDPServer,
FMX.Edit, IdGlobal, FMX.ScrollBox,{ FMX.Memo,}
TTS.iOS,FMX.Platform, FMX.Objects,
System.Math.Vectors,UIConsts;
type
TForm2 = class(TForm)
ScaledLayout1: TScaledLayout;
Button1: TButton;
IdTCPClient1: TIdTCPClient;
Timer1: TTimer;
StyleBook1: TStyleBook;
PaintBox1: TPaintBox;
Label1: TLabel;
Button3: TButton;
Rectangle1: TRectangle;
procedure Button1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
private
{ private 宣言 }
function HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
public
{ public 宣言 }
cnt : Integer;
TTS: TTextToSpeech;
DMMValue : string;
AcDcStr : string;
UnitStr : string;
end;
var
Form2: TForm2;
implementation
{$R *.fmx}
{$R *.iPhone47in.fmx IOS}
// -----------------------------------------------------------------------------
var
SevenSegsData : array [0..43] of array [0..1] of Double =
(
// a
(-7.33526 , 13.9743) ,(-7.066240, 14.2) ,(-0.892448, 14.2),
(-0.785713, 14.0728) ,(-2.89844 , 12.3) ,(-5.93038 , 12.3),
// b
(-0.477173, 13.7051) ,(-0.254734, 13.44) ,(-1.1403 , 8.4177),
(-2.30772 , 7.43812) ,(-3.08004 , 8.35855),(-2.425590, 12.0702),
// c
(-2.36688 , 6.76188) ,(-1.59456 , 5.84146) ,(-2.49057 , 0.76),
(-2.82852 , 0.476423),(-4.18485 , 2.09283) ,(-3.53430 , 5.7823),
// d
(-3.19622 , 0.167884),(-3.39629 , 0.0) ,(-9.57008 , 0.0),
(-9.73467 , 0.19615) ,(-7.7041 , 1.9) ,(-4.64964 , 1.9),
// e
(-10.0432 , 0.56385) ,(-10.2078 , 0.76) ,(-9.32223 , 5.7823),
(-8.15483 , 6.76188) ,(-7.3825 , 5.84146) ,(-8.01264 , 2.2677),
// f
(-8.09565 , 7.43813) ,(-8.86797 , 8.35854) ,(-7.97197 , 13.44),
(-7.70297 , 13.6657) ,(-6.29808 , 11.9915) ,(-6.92823 , 8.4177),
// g
(-7.78711 , 7.07042) ,(-6.61969 , 8.05) ,(-3.44774 , 8.05),
(-2.67543 , 7.12958) ,(-3.84285 , 6.15) ,(-7.01480 , 6.15),
// dp
(-0.85000 , 0.85000) ,(1.2, 0.0)
);
function ToSevenSegsData(const src: string): string;
var
c: string;
begin
c := src.Substring(0, 1);
if c = '0' then result := '1111110'
else if c = '1' then result := '0110000'
else if c = '2' then result := '1101101'
else if c = '3' then result := '1111001'
else if c = '4' then result := '0110011'
else if c = '5' then result := '1011011'
else if c = '6' then result := '1011111'
else if c = '7' then result := '1110010'
else if c = '8' then result := '1111111'
else if c = '9' then result := '1111011'
else if c = '-' then result := '0000001'
else if c = '+' then result := '0110001'
else if c = '=' then result := '0001001'
else if c = '.' then result := '.'
else if c = 'a' then result := '0011101'//='o'
else if c = 'b' then result := '0011111'
else if c = 'c' then result := '0001101'
else if c = 'd' then result := '0111101'
else if c = 'e' then result := '1001111'//='E'
else if c = 'f' then result := '1000111'//='F'
else if c = 'g' then result := '1111011'
else if c = 'h' then result := '0010111'
else if c = 'i' then result := '0010000'
else if c = 'j' then result := '0111000'
else if c = 'k' then result := '0010111'//='h'
else if c = 'l' then result := '0110000'//='1'
else if c = 'm' then result := '0010101'//='n'
else if c = 'n' then result := '0010101'//='m'
else if c = 'o' then result := '0011101'//='a'
else if c = 'p' then result := '1100111'//='P'
else if c = 'q' then result := '1110011'
else if c = 'r' then result := '0000101'
else if c = 's' then result := '1011011'//='5'
else if c = 't' then result := '0001111'
else if c = 'u' then result := '0011100'
else if c = 'v' then result := '0011100'//='u'
else if c = 'w' then result := '0011100'//='u'
else if c = 'x' then result := '0011100'//='H'
else if c = 'y' then result := '0100111'//='Y'
else if c = 'z' then result := '1101101'//='2'
else if c = 'A' then result := '1110111'
//else if c = 'B' then result := '1111111'//='8'
else if c = 'B' then result := '0011111'
else if c = 'C' then result := '1001119'
//else if c = 'D' then result := '1111110'//='0'
else if c = 'D' then result := '0111101'
else if c = 'E' then result := '1001111'
else if c = 'F' then result := '1000111'
else if c = 'G' then result := '1010111'
else if c = 'H' then result := '0110111'
else if c = 'I' then result := '0110000'
else if c = 'J' then result := '0111100'
else if c = 'K' then result := '0110110'//='H'
else if c = 'L' then result := '0001110'
else if c = 'M' then result := '1110110'
else if c = 'N' then result := '1110110'
else if c = 'O' then result := '1111110'
else if c = 'P' then result := '1100111'
else if c = 'Q' then result := '1111110'//='0'
else if c = 'R' then result := '1110111'//='A'
else if c = 'S' then result := '1011011'//='5'
else if c = 'T' then result := '1000110'
else if c = 'U' then result := '0111110'
else if c = 'V' then result := '0111110'
else if c = 'W' then result := '0111110'
else if c = 'X' then result := '0110111'//='H'
else if c = 'Y' then result := '0100111'//='y'
else if c = 'Z' then result := '0101101'//='2'
else result := '';
end;
procedure DrawSevenSegsElement(const BitStr : string; dispX, dispY, scale: double; cv : TCanvas; co :TAlphaColor);
var
segdata : string;
i, j : integer;
pts : TPolygon ; // uses ,,, System.Math.Vectors;
dpX, dpY, dpR : double;
begin
cv.BeginScene;
try
// 輪郭
cv.Stroke.Kind := TBrushKind.Solid ;
cv.Stroke.Color := co;
// 塗りつぶし
cv.Fill.Kind := TBrushKind.Solid;
cv.Fill.Color := co;
if BitStr = '.' then begin
dpR := SevenSegsData[43, 0] * scale * 1.5;
dpX := SevenSegsData[42, 0] * scale + 10.2 * scale + dispX - dpR;
dpY := SevenSegsData[42, 1] * scale + 14.1 * scale + dispY - dpR;
cv.FillEllipse(RectF(dpX, dpY , dpX + dpR, dpY + dpR), 1.0);
cv.DrawEllipse(RectF(dpX, dpY , dpX + dpR, dpY + dpR), 1.0);
end
else begin
segdata := ToSevenSegsData(BitStr);
if segdata.Length = 7 then begin
SetLength(pts, 6);
for i := 0 to 6 do begin
if segdata.Substring(i, 1) = '1' then begin
for j := 0 to 5 do begin
pts[j] := PointF(
SevenSegsData[i * 6 + j, 0] * scale +10.2 * scale + dispX,
- SevenSegsData[i * 6 + j, 1] * scale +14.1 * scale + dispY
);
end;
cv.FillPolygon(pts, 1.0);
cv.DrawPolygon(pts, 1.0);
end;
end;
end;
end;
finally
cv.EndScene;
end;
end;
// 左上が基点
// 使用例:
// src := '-12.34567890';
// DrawSevenSegsText(src, 0, 0, 5.0, PaintBox1.Canvas, claBlue);
// uses ,,, UIConsts; for TAlphaColor;
procedure DrawSevenSegsText(const src : string; stX, stY, scale: double; cv : TCanvas; co :TAlphaColor);
var
s : string;
i : integer;
dispX, dispY: double;
begin
dispY := stY;
dispX := stX;
for i := 0 to src.Length -1 do begin
s := src.SubString(i, 1);
if s = '.' then begin
DrawSevenSegsElement(s, dispX- scale * 10, dispY, scale, cv, co);
end
else begin
DrawSevenSegsElement(s, dispX, dispY, scale, cv, co);
dispX := dispX + scale * 10.4;
end;
end;
end;
// -----------------------------------------------------------------------------
// FMX TApplicationEvents
// uses ,, FMX.Platform;
function TForm2.HandleAppEvent(AAppEvent: TApplicationEvent; AContext: TObject): Boolean;
begin
// ※ TimeChange,OpenURL は iOS のみサポート
case AAppEvent of
TApplicationEvent.FinishedLaunching:
;
TApplicationEvent.BecameActive:
;//
TApplicationEvent.WillBecomeInactive:
begin
;// バックグラウンドになる直前に呼ばれる
try
if IdTCPClient1.Connected then begin
IdTCPClient1.Disconnect;
Button1.Text := '接続';
end;
except
;
end;
end;
TApplicationEvent.EnteredBackground:
;// バックグラウンドになった直後に呼ばれる
TApplicationEvent.WillBecomeForeground:
;// フォアグラウンドになる直前に呼ばれる
TApplicationEvent.WillTerminate :
;
TApplicationEvent.LowMemory:
;
TApplicationEvent.TimeChange:
;
TApplicationEvent.OpenURL:
;
end;
Result := True;
end ;
procedure TForm2.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.Clear(claBlack);
//DrawSevenSegsText(DMMValue, 0, 72, 7.5, Canvas, claAqua);
DrawSevenSegsText(DMMValue, 0, 80, 12, Canvas, claYellow);
Canvas.BeginScene;
try
// 輪郭
Canvas.Stroke.Kind := TBrushKind.Solid ;
Canvas.Stroke.Color := claAqua;
// 塗りつぶし
Canvas.Fill.Kind := TBrushKind.Solid;
Canvas.Fill.Color := claAqua;
Canvas.Font.Size := 60;
Canvas.FillText(RectF(15, 15, 660, 60), AcDcStr, False, 1.0, [], TTextAlign.Leading, TTextAlign.Center);
Canvas.FillText(RectF( 0, 15, 640, 60), UnitStr, False, 1.0, [], TTextAlign.Trailing, TTextAlign.Center);
finally
Canvas.EndScene;
end;
end;
// 1バイト整数を2進文字列に
function ByteToBin(x: Byte) : string;
var
i : integer;
begin
result := '';
for i := 1 to 8 do begin
if ((x and 1) = 1) then
result := '1' + result
else
result := '0' + result;
x := x shr 1;
end;
end;
// 1バイト16進文字列を2進文字列に
function HexToBin(const hex : string) : string;
var
x : integer;
begin
result := '';
x := StrToIntDef('$' + hex, -1);
if x >= 0 then
result := ByteToBin(x);
end;
// 7セグメントデータを数値に
function SevenSegToStr(const efadcgb : string): string;
var
s : string;
begin
result := '';
if efadcgb.Length = 7 then begin
s := efadcgb;
if s = '1111101' then result := '0'
else if s = '0000101' then result := '1'
else if s = '1011011' then result := '2'
else if s = '0011111' then result := '3'
else if s = '0100111' then result := '4'
else if s = '0111110' then result := '5'
else if s = '1111110' then result := '6'
else if s = '0010101' then result := '7'
else if s = '1111111' then result := '8'
else if s = '0111111' then result := '9'
else if s = '1101000' then result := 'L';
end;
end;
procedure TForm2.Button1Click(Sender: TObject);
begin
if Button1.Text = '接続' then begin
IdTCPClient1.Host := '1.2.3.4';
IdTCPClient1.Port := 2000;
IdTCPClient1.ReadTimeout := 500;
IdTCPClient1.ConnectTimeout := 1000;
try
IdTCPClient1.Connect;
if IdTCPClient1.Connected then begin
Button1.Text := '切断';
end;
except
on E: Exception do begin
ShowMessage( E.ClassName + sLineBreak + E.Message);
end;
end;
end
else begin
Button1.Text := '接続';
if IdTCPClient1.Connected then begin
try
IdTCPClient1.Disconnect;
//Button1.Text := '接続';
except
on E: Exception do begin
ShowMessage( E.ClassName + sLineBreak + E.Message);
end;
end;
end;
end;
end;
procedure TForm2.Button3Click(Sender: TObject);
begin
if Button3.Text = '音声OFF' then
Button3.Text := '音声ON'
else
Button3.Text := '音声OFF';
end;
procedure TForm2.FormCreate(Sender: TObject);
var
SvcEvents : IFMXApplicationEventService; //uses ... FMX.Platform;
begin
Label1.Text := '';
// 画面を縦に固定
//Application.FormFactor.Orientations :=
// [TFormOrientation.Portrait, TFormOrientation.InvertedPortrait];
// ApplicationEvent
if TPlatformServices.Current.SupportsPlatformService
(IFMXApplicationEventService, IInterface(SvcEvents)) then
SvcEvents.SetApplicationEventHandler(HandleAppEvent);
// テキストスピーチ
TTS := TTextToSpeech.Create;
TTS.Speed := TTS.SpeedMin;
// インターバルタイマー
Timer1.Interval := 250;
Timer1.Enabled := True;
end;
procedure TForm2.FormDestroy(Sender: TObject);
begin
// テキストスピーチ解放
TTS.Free;
end;
// 小数点位置
function BinStrToDMMDecimalPoint(const BinStr: string): integer;
const
offset = 4;
var
i : integer;
begin
result := 0;
for i := 0 to 2 do begin
if BinStr.Substring(offset + 24 + i * 16, 1) = '1' then begin
result := 3 - i;
break;
end;
end;
end;
// 単位
function BinStrToDMMUnit(const BinStr: string): string;
const
offset = 4;
begin
// 単位(Unit)
if BinStr.Substring(offset + 82, 1) = '1' then result := 'M'
else if BinStr.Substring(offset + 81, 1) = '1' then result := '%'
else if BinStr.Substring(offset + 80, 1) = '1' then result := 'm'
else if BinStr.Substring(offset + 74, 1) = '1' then result := 'K'
else if BinStr.Substring(offset + 73, 1) = '1' then result := 'n'
else if BinStr.Substring(offset + 72, 1) = '1' then result := 'μ'
else result := '';
if BinStr.Substring(offset + 98, 1) = '1' then result := result + 'Hz'
else if BinStr.Substring(offset + 97, 1) = '1' then result := result + 'V'
else if BinStr.Substring(offset + 96, 1) = '1' then result := result + 'A'
else if BinStr.Substring(offset + 89, 1) = '1' then result := result + 'Ω'
else if BinStr.Substring(offset + 88, 1) = '1' then result := result + 'F'
else if BinStr.Substring(offset + 105, 1) = '1' then result := result + '℃';
end;
// テキストスピーチ用単位
function BinStrToDMMUnitMessage(const BinStr: string): string;
const
offset = 4;
begin
// 単位(Unit)
if BinStr.Substring(offset + 82, 1) = '1' then result := 'メガ'
else if BinStr.Substring(offset + 81, 1) = '1' then result := 'パーセント'
else if BinStr.Substring(offset + 80, 1) = '1' then result := 'ミリ'
else if BinStr.Substring(offset + 74, 1) = '1' then result := 'キロ'
else if BinStr.Substring(offset + 73, 1) = '1' then result := 'ナノ'
else if BinStr.Substring(offset + 72, 1) = '1' then result := 'マイクロ'
else result := '';
if BinStr.Substring(offset + 98, 1) = '1' then result := result + 'ヘルツ'
else if BinStr.Substring(offset + 97, 1) = '1' then result := result + 'ボルト'
else if BinStr.Substring(offset + 96, 1) = '1' then result := result + 'アンペア'
else if BinStr.Substring(offset + 89, 1) = '1' then result := result + 'オーム'
else if BinStr.Substring(offset + 88, 1) = '1' then result := result + 'ファラッド'
else if BinStr.Substring(offset + 105, 1) = '1' then result := result + 'ド';
end;
// AC / DC
function BinStrToDMMAcDc(const BinStr: string): string;
const
offset = 4;
begin
result := '';
if BinStr.Substring(offset + 0, 1) = '1' then result := 'AC'
else if BinStr.Substring(offset + 1, 1) = '1' then result := 'DC';
end;
// 測定値
function BinStrToDMMValue(const BinStr: string; UnitFlag: boolean):string;
const
offset = 4;
begin
result := '';
if BinStr.Length = 14 * 8 then begin
if BinStr.Substring(offset + 8, 1) = '1' then result := '-' else result := ' ';
result := result + SevenSegToStr(BinStr.Substring(offset + 9, 3) + BinStr.Substring(offset + 9 + 7, 4));
if BinStr.Substring(offset + 24, 1) = '1' then result := result + '.';
result := result + SevenSegToStr(BinStr.Substring(offset + 25, 3) + BinStr.Substring(offset + 25 + 7, 4));
if BinStr.Substring(offset + 40, 1) = '1' then result := result + '.';
result := result + SevenSegToStr(BinStr.Substring(offset + 41, 3) + BinStr.Substring(offset + 41 + 7, 4));
if BinStr.Substring(offset + 56, 1) = '1' then result := result + '.';
result := result + SevenSegToStr(BinStr.Substring(offset + 57, 3) + BinStr.Substring(offset + 57 + 7, 4));
if UnitFlag then
result := result + ' ' + BinStrToDMMUnit(BinStr);
end;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
var
res : string;
binstr : string;
svalue : string;
vbuf : TIdBytes;
i : integer;
dvalue : double;
dp : integer;
ttstr : string;
begin
try
if IdTCPClient1.Connected then begin
IdTCPClient1.IOHandler.ReadTimeout := IdTCPClient1.ReadTimeout;
try
IdTCPClient1.IOHandler.ReadBytes(vbuf, 14);
res := '';
binstr := '';
for i := 0 to Length(vbuf) -1 do begin
res := res + IntToHex(vbuf[i], 2);
binstr := binstr + ByteToBin(vbuf[i]);
end;
//for i := 0 to 28 div 2 -1 do
// binstr := binstr + HexToBin(res.Substring(i * 2, 2));
// 16進表示
Label1.Text := res;
// 測定値(表示そのまま)
svalue := BinStrToDMMValue(binstr, False);
DMMValue := svalue;
// 測定値
dvalue := StrToFloatDef(svalue, 10000);
dp := BinStrToDMMDecimalPoint(binstr);
if dvalue < 10000 then
ttstr := Format('%.' + dp.ToString + 'f', [dvalue])
else
ttstr := 'Overflow Lebel';//svalue;//'O.L.'; //'OverflowLebel';
//ttstr := StringReplace(ttstr, '.', 'テン',[]);
//DMMValue := ' ' + Label1.Text;
//DMMValue := DMMValue.Substring(DMMValue.Length-6, 5);
//PaintBox1.Repaint;
// 単位
UnitStr := BinStrToDMMUnit(binstr);
// AC / DC
AcDcStr := BinStrToDMMAcDc(binstr);
//AcDcStr := ttstr;
PaintBox1.Repaint;
// テキストスピーチ
Inc(cnt);
if (cnt >= 12) then begin
if Button3.Text = '音声OFF' then
TTS.Speak(ttstr + ' ' + BinStrToDMMUnitMessage(binstr));
cnt := 0;
end;
except
on E: Exception do begin
// Timeout Error
Label1.Text := E.ClassName;
end;
end;
end;
except
on E: Exception do begin
Label1.Text := E.ClassName;
end;
end;
end;
end.