RS-Analyzer
RS-Analyzer
RS-Analyzerとは
RS-Analyzerとは、BUFFALO PC用学習リモコンキット PC-OP-RS1 からPCに送られて来るリモコン信号データを、チャート化して分析するためのソフトです。チャートは拡大することもでき、画像としても残せるようになっています。
PC-OP-RS1は、リモコンの信号を0.1ms(100μs)ごとにサンプリングして、データ長240Byte固定、240×8=1,920bitsのデータを送ってきます。その送られてきた、1,920個のビットを、ただチャート表示する単純なソフトです。信号を解析する機能は付いていません。

使い方は、PC-OP-RS1を差したCOMポートを選択し、「接続」ボタンを押してください。「受信」ボタンを押し5秒以内にPC-OP-RS1の受光部に向かってリモコンを押してください。チャートに信号が表示されます。あとの機能はおまけみたいなもんです。
ソースが付いているので改造も自由です。ただし改造したものを公開する場合は、GPLv2ライセンスに従ってください。
リモコン信号表示例
NECフォーマット
NEC_RB-73Aのパルス位相変調信号(リピート2回)。リピートコードを二回とらえています。
最初の信号を拡大したもの。
※リモコン信号はLIRCの設定ファイル置き場から、適当に拾ってきてWinLIRCから信号を発信したものです。
SONYフォーマット
Sony_RMT-V767のパルス位相変調信号(リピート2回)。
最初の信号を拡大したもの。
※リモコン信号はLIRCの設定ファイル置き場から、適当に拾ってきてWinLIRCから信号を発信したものです。
おまけ(日立製エアコン)
家で使っている日立製エアコンの信号。長すぎて全部とらえられないようです。PC-OP-RS1の最長は192ms。
環境
- BUFFALO PC-OP-RS1
- Borland Delphi 7 Professional
- Windows XP Professional
注意点
- 当方のサンプルを使用したいかなる結果に対しても、責任は持てません。あくまで自己責任で。
- 人身事故や火災などの重大事故が発生する可能性のある機器や装置には使用しないでください。
- 作者はリモコンの素人です。またシリアル通信プログラムは今回が初めてなので、間違ってたらごめんなさい。
参考
- Project C3 - PC-OP-RS1
- PC-OP-RS1操作オブジェクト作成
- スーの道具箱 - PC-OP-RS1
- PC-OP-RS1操作コマンド、リモコンコードのビット変更方法など
- FUTABA HOME - 赤外線リモコンについて
- リモコンコードの仕組みなど
- FUTABA HOME + BLOG - KURO-RS デバイス
- モードキャンセルコマンドなど
ソフトウェアライセンス
ソースを参考にさせて頂いたPC-OP-RS1 DLLがGPLv2ライセンスの元リリースされているので、GPLv2ライセンスで公開しています。
サンプルソース
フォーム
特にこれといって変わったものは使っていません。

RemoteStation.pas PC-OP-RS1操作オブジェクトと定数
unit RemoteStation;
interface
uses
Windows, SysUtils;
const
DEV_PCOPRS1_RET_OK = 0;
DEV_PCOPRS1_RET_ERR = 1;
DEV_PCOPRS1_RET_NOT_OPENED = 2;
DEV_PCOPRS1_RET_OUT_OF_RANGE = 3;
DEV_PCOPRS1_RET_TIMEOUT = 4;
DEV_PCOPRS1_RET_UNKNOWN = 5;
MODULE_MAJOR_VERSION = 1;
MODULE_MINOR_VERSION = 2;
REMOCON_CODE_COUNT = 240;
type
TRemoconCode = array[0..REMOCON_CODE_COUNT-1] of Char;
TPCOPRS1 = class
private
bOpened: Boolean;
hComm: THandle;
FComPort: Integer;
FReceiving: Boolean;
function WaitForReplyFromDevice(ExpectedCode: Char;
CodeGotten: PChar): Integer;
function SendCommand(cmd: Char): Integer;
function DataReceiveFromDevice(Buf: PChar; Len: Cardinal): Integer;
function DataTransmitToDevice(Buf: PChar; Len: Cardinal): Integer;
function GetConnecting: Boolean;
procedure ErrorPrevention;
public
constructor Create;
destructor Destroy; override;
function Open(PortNo: Integer): Integer;
function Close: Integer;
function LedFlash: Integer;
function SetTimeOut(TimeoutTime: Cardinal): Integer;
function Receive(RemoconCode: PChar): Integer;
function ModeCancel: Integer;
function Transmit(Ch: Integer; RemoconCode: PChar): Integer;
// function GetModuleVersion(var MajorVer: Cardinal; var
// MinerVer: Cardinal): Integer;
property Connecting: Boolean read GetConnecting;
property Receiving: Boolean read FReceiving;
end;
implementation
{ TPCOPRS1 }
constructor TPCOPRS1.Create;
begin
bOpened := False;
FComPort := 0;
FReceiving := False;
end;
destructor TPCOPRS1.Destroy;
begin
if bOpened then Close;
inherited;
end;
function TPCOPRS1.Open(PortNo: Integer): Integer;
var dcb: TDCB; res: LongBool; Errors: DWORD;
comport_name: string;
begin
Result := DEV_PCOPRS1_RET_OK;
if not bOpened then begin
// Open specified COM port
comport_name := Format('\\.\COM%d', [PortNo]);
hComm := CreateFileA(PChar(comport_name),
GENERIC_READ or GENERIC_WRITE,
0,
nil,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0);
if hComm = INVALID_HANDLE_VALUE then begin
Result := DEV_PCOPRS1_RET_ERR;
end else begin
// Configure the conditions of COM port
GetCommState(hComm, dcb);
with dcb do begin
BaudRate := 115200;
ByteSize := 8;
Parity := NOPARITY;
Flags := Flags or (1 shl 1);
StopBits := ONESTOPBIT;
end;
res := SetCommState(hComm, dcb);
FComPort := PortNo;
bOpened := True;
if res then begin
ClearCommError(hComm, Errors, nil);
end else begin
Result := DEV_PCOPRS1_RET_ERR;
end;
end;
end else begin
// Device is already opened so that the retvalue is ERROR.
Result := DEV_PCOPRS1_RET_ERR;
end;
end;
function TPCOPRS1.Close: Integer;
var res: LongBool;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
res := CloseHandle(hComm);
if res then begin
bOpened := False;
end else begin
Result :=DEV_PCOPRS1_RET_ERR;
end;
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED
end;
end;
function TPCOPRS1.LedFlash: Integer;
var res: Integer; receivecode: Char;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
SendCommand('i');
res := WaitForReplyFromDevice('O', @receivecode);
if res <> DEV_PCOPRS1_RET_OK then begin
if receivecode = 'Y' then begin
// If the device internal state was initialized with this
// command, then the LED is not flash.
// But the request for this method is to flash LED,
// so call LedFlash recursively for Flash LED instead.
LedFlash;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
end;
end;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
end;
end;
function TPCOPRS1.SetTimeOut(TimeoutTime: Cardinal): Integer;
var tmo: TCommTimeouts;
begin
Result := DEV_PCOPRS1_RET_OK;
GetCommTimeouts(hComm, tmo);
with tmo do begin
ReadTotalTimeoutConstant := TimeoutTime;
WriteTotalTimeoutConstant := TimeoutTime;
end;
SetCommTimeouts(hComm, tmo);
end;
function TPCOPRS1.Receive(RemoconCode: PChar): Integer;
var res: Integer;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
ErrorPrevention;
FReceiving := True;
// LedFlash;
SendCommand('r'); //receive mode
res := WaitForReplyFromDevice('Y', nil);
if res = DEV_PCOPRS1_RET_OK then begin
res := WaitForReplyFromDevice('S', nil);
if res = DEV_PCOPRS1_RET_OK then begin
Sleep(500); //あまり早く読み込ませすぎると失敗するっぽい
res := DataReceiveFromDevice(RemoconCode, REMOCON_CODE_COUNT);
if res = DEV_PCOPRS1_RET_OK then begin
res := WaitForReplyFromDevice('E', nil);
if res <> DEV_PCOPRS1_RET_OK then begin
Result := DEV_PCOPRS1_RET_ERR;
end;
end else if res = DEV_PCOPRS1_RET_TIMEOUT then begin
Result := DEV_PCOPRS1_RET_TIMEOUT;
ModeCancel;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
ModeCancel;
end;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
ModeCancel;
end;
end;
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED;
end;
FReceiving := False;
end;
function TPCOPRS1.Transmit(Ch: Integer; RemoconCode: PChar): Integer;
var res: Integer; code: TRemoconCode;
begin
Result := DEV_PCOPRS1_RET_OK;
CopyMemory(@code[0], RemoconCode, REMOCON_CODE_COUNT);
if bOpened then begin
ErrorPrevention;;
if not (Ch >= 0) and (ch <= 3) then begin
Result := DEV_PCOPRS1_RET_ERR;
end else begin
SendCommand('t'); //transmit mode
res := WaitForReplyFromDevice('Y', nil);
if res = DEV_PCOPRS1_RET_OK then begin
SendCommand(Char(IntToStr(1 + Ch)[1]));
res := WaitForReplyFromDevice('Y', nil);
if res = DEV_PCOPRS1_RET_OK then begin
DataTransmitToDevice(code ,REMOCON_CODE_COUNT);
res := WaitForReplyFromDevice('E', nil);
if res <> DEV_PCOPRS1_RET_OK then begin
Result := DEV_PCOPRS1_RET_ERR;
end;
end else if res = DEV_PCOPRS1_RET_TIMEOUT then begin
Result := DEV_PCOPRS1_RET_TIMEOUT;
ModeCancel;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
ModeCancel;
end;
end else begin
Result := DEV_PCOPRS1_RET_ERR;
ModeCancel;
end;
end;
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED;
end;
end;
//function TPCOPRS1.GetModuleVersion(var MajorVer,
// MinerVer: Cardinal): Integer;
//begin
// Result := DEV_PCOPRS1_RET_OK;
//
// MajorVer := MODULE_MAJOR_VERSION;
// MinerVer := MODULE_MINOR_VERSION;
//end;
function TPCOPRS1.SendCommand(cmd: Char): Integer;
var writtensize: DWORD;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
WriteFile(hComm, cmd, 1, writtensize, nil);
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED;
end;
end;
function TPCOPRS1.WaitForReplyFromDevice(ExpectedCode: Char;
CodeGotten: PChar): Integer;
var ReadSize: DWORD; buf: array[0..0] of Char;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
buf[0] := ExpectedCode;
ReadFile(hComm, buf, 1, ReadSize, nil);
if buf[0] <> ExpectedCode then begin
Result := DEV_PCOPRS1_RET_ERR;
end;
if CodeGotten <> nil then begin
CodeGotten^ := buf[0];
end;
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED;
end;
end;
function TPCOPRS1.DataReceiveFromDevice(Buf: PChar;
Len: Cardinal): Integer;
var ReadSize: DWORD; b: TRemoconCode;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
ReadFile(hComm, b, Len, ReadSize, nil);
CopyMemory(@Buf[0], @b[0], REMOCON_CODE_COUNT);
if ReadSize <> Len then begin
Result := DEV_PCOPRS1_RET_TIMEOUT;
end;
end else begin
Result := DEV_PCOPRS1_RET_NOT_OPENED;
end;
end;
function TPCOPRS1.DataTransmitToDevice(Buf: PChar;
Len: Cardinal): Integer;
var writtensize: DWORD;
begin
Result := DEV_PCOPRS1_RET_OK;
if bOpened then begin
WriteFile(hComm, Buf, Len, writtensize, nil);
if writtensize <> Len then begin
Result := DEV_PCOPRS1_RET_TIMEOUT;
end;
end else begin
Result :=DEV_PCOPRS1_RET_NOT_OPENED;
end;
end;
function TPCOPRS1.GetConnecting: Boolean;
begin
Result := bOpened;
end;
function TPCOPRS1.ModeCancel: Integer;
var res: Integer;
begin
Result := DEV_PCOPRS1_RET_OK;
SendCommand('c');
res := WaitForReplyFromDevice('Y', nil);
if res = DEV_PCOPRS1_RET_OK then begin
Result := DEV_PCOPRS1_RET_OK;
end;
end;
procedure TPCOPRS1.ErrorPrevention;
begin
if bOpened then begin
Close;
Open(FComPort);
end;
end;
end.
Main.pas フォームの実装
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls,
Forms, Dialogs, StdCtrls, RemoteStation, ExtCtrls, ComCtrls,
TeEngine, Series, TeeProcs, Chart, Menus, ActnList, Clipbrd,
StrUtils, IniFiles;
type
TRSAnalyzerForm = class(TForm)
AboutButton: TButton;
BinaryToClipAction: TAction;
C1: TMenuItem;
ChartPopupMenu: TPopupMenu;
ChartSaveDialog: TSaveDialog;
ClearCodeAction: TAction;
CodeListBox: TListBox;
CodePopupMenu: TPopupMenu;
CodeToClipAction: TAction;
COMPortComboBox: TComboBox;
DeleteCodeAction: TAction;
DeleteCodeAction2: TMenuItem;
Label1: TLabel;
Label2: TLabel;
LED1: TMenuItem;
LEDAction: TAction;
LEDButton: TButton;
MainMenu: TMainMenu;
N1: TMenuItem;
N2: TMenuItem;
N3: TMenuItem;
N4: TMenuItem;
N5: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N9: TMenuItem;
N10: TMenuItem;
N11: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
N14: TMenuItem;
N15: TMenuItem;
N16: TMenuItem;
N17: TMenuItem;
N18: TMenuItem;
OpenAction: TAction;
OpenAtStartUpCheckBox: TCheckBox;
OpenButton: TButton;
OutputComboBox: TComboBox;
Panel1: TPanel;
Panel2: TPanel;
ReceiveAction: TAction;
ReceiveButton: TButton;
SaveChartAction: TAction;
Series1: TFastLineSeries;
StatusBar1: TStatusBar;
TheActionList: TActionList;
TheChart: TChart;
TransmitAction: TAction;
TransmitButton: TButton;
UndoZoomAction: TAction;
Splitter1: TSplitter;
AboutAction: TAction;
TableToClipAction: TAction;
N19: TMenuItem;
N20: TMenuItem;
ChartToClipAction: TAction;
N21: TMenuItem;
procedure BinaryToClipActionExecute(Sender: TObject);
procedure ChackConnecting(Sender: TObject);
procedure ChackEmptyList(Sender: TObject);
procedure ChackSelectListItem(Sender: TObject);
procedure ClearCodeActionExecute(Sender: TObject);
procedure CodeListBoxClick(Sender: TObject);
procedure CodeToClipActionExecute(Sender: TObject);
procedure COMPortComboBoxChange(Sender: TObject);
procedure DeleteCodeActionExecute(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure LEDActionExecute(Sender: TObject);
procedure OpenActionExecute(Sender: TObject);
procedure OpenActionUpdate(Sender: TObject);
procedure ReceiveActionExecute(Sender: TObject);
procedure SaveChartActionExecute(Sender: TObject);
procedure TransmitActionExecute(Sender: TObject);
procedure TransmitActionUpdate(Sender: TObject);
procedure UndoZoomActionExecute(Sender: TObject);
procedure AboutActionExecute(Sender: TObject);
procedure TableToClipActionExecute(Sender: TObject);
procedure ChartToClipActionExecute(Sender: TObject);
private
{ Private 宣言 }
function CodeToBynary(Code: TRemoconCode): string;
function CodeToTable(Code: TRemoconCode): string;
function CodeToHex(Code: TRemoconCode): string;
procedure HexToCode(h: string; var Code: TRemoconCode);
procedure MakeChart(Code: TRemoconCode);
public
{ Public 宣言 }
PCOPRS: TPCOPRS1;
IniFile: TIniFile;
end;
var
RSAnalyzerForm: TRSAnalyzerForm;
implementation
{$R *.dfm}
const
CODE_FILENAME = 'code.txt';
procedure TRSAnalyzerForm.FormCreate(Sender: TObject);
var i: Integer;
begin
Caption := Application.Title;
//作成
PCOPRS := TPCOPRS1.Create;
IniFile := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
//初期設定
COMPortComboBox.Clear;
COMPortComboBox.Style := csDropDownList;
for i := 0 to 255 do begin
COMPortComboBox.Items.Add('COM' + IntToStr(i));
end;
OutputComboBox.Clear;
OutputComboBox.Style := csDropDownList;
for i := 0 to 3 do begin
OutputComboBox.Items.Add(IntToStr(i));
end;
//INI
with IniFile do begin
//フォーム位置
Left := ReadInteger('Form', 'Left', Left);
Top := ReadInteger('Form', 'Top', Top);
Width := ReadInteger('Form', 'Width', Width);
Height := ReadInteger('Form', 'Height', Height);
WindowState := TWindowState(
ReadInteger('Form', 'WindowState', Ord(WindowState)));
CodeListBox.Height := ReadInteger('Form',
'CodeListBox.Height', CodeListBox.Height);
//設定
COMPortComboBox.ItemIndex := ReadInteger('Config', 'ComPort', 0);
OutputComboBox.ItemIndex := ReadInteger('Config', 'OutputPort', 0);
ChartSaveDialog.FilterIndex := ReadInteger('Config', 'FilterIndex', 1);
OpenAtStartUpCheckBox.Checked :=
ReadBool('Config', 'OpenAtStartup', False);
end;
if OpenAtStartUpCheckBox.Checked then
OpenAction.Execute;
//データ読込
if FileExists(ExtractFilePath(ParamStr(0)) + CODE_FILENAME) then
CodeListBox.Items.LoadFromFile(
ExtractFilePath(ParamStr(0)) + CODE_FILENAME);
end;
procedure TRSAnalyzerForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
//データ保存
CodeListBox.Items.SaveToFile(
ExtractFilePath(ParamStr(0)) + CODE_FILENAME);
//INI
with IniFile do begin
//フォーム位置
WriteInteger('Form', 'WindowState', Ord(WindowState));
if WindowState = wsNormal then begin
WriteInteger('Form', 'Left', Left);
WriteInteger('Form', 'Top', Top);
WriteInteger('Form', 'Width', Width);
WriteInteger('Form', 'Height', Height);
end;
WriteInteger('Form',
'CodeListBox.Height', CodeListBox.Height);
//設定
WriteInteger('Config', 'ComPort', COMPortComboBox.ItemIndex);
WriteInteger('Config', 'OutputPort', OutputComboBox.ItemIndex);
WriteInteger('Config', 'FilterIndex', ChartSaveDialog.FilterIndex);
WriteBool('Config', 'OpenAtStartup', OpenAtStartUpCheckBox.Checked);
end;
end;
procedure TRSAnalyzerForm.FormDestroy(Sender: TObject);
begin
PCOPRS.Free;
IniFile.Free;
end;
function TRSAnalyzerForm.CodeToHex(Code: TRemoconCode): string;
var i: Integer;
begin
Result := '';
for i := Low(Code) to High(Code) do begin
Result := Result + IntToHex(Ord(Code[i]), 2);
end;
end;
procedure TRSAnalyzerForm.HexToCode(h: string; var Code: TRemoconCode);
var i, len, strIdx: Integer; s: string;
begin
ZeroMemory(@Code[0], REMOCON_CODE_COUNT);
len := Length(h);
for i := 0 to REMOCON_CODE_COUNT-1 do begin
strIdx := (i*2)+1;
if (strIdx + 1) > len then Exit;
s := Copy(h, strIdx, 2);
Code[i] := Char(StrToInt('$' + s));
end;
end;
function TRSAnalyzerForm.CodeToBynary(Code: TRemoconCode): string;
var i, j: Integer;
begin
Result := '';
for i := 0 to REMOCON_CODE_COUNT-1 do
for j := 0 to 7 do
if (Ord(Code[i]) and (1 shl j)) <> 0 then
Result := Result + '1'
else
Result := Result + '0';
end;
procedure TRSAnalyzerForm.MakeChart(Code: TRemoconCode);
var i, l: Integer; binary: string; tmpX, tmpY:Double;
begin
Series1.Clear;
binary := CodeToBynary(Code);
l := Length(binary);
tmpX := 0;
for i := 1 to l do begin
tmpY := StrToInt(binary[i]);
with Series1 do begin
AddXY(tmpX, tmpY);
AddXY(tmpX + 0.1, tmpY);
tmpX := tmpX + 0.1; //+100μs
end;
end;
end;
procedure TRSAnalyzerForm.COMPortComboBoxChange(Sender: TObject);
begin
OpenAction.Enabled := True;
PCOPRS.Close;
end;
procedure TRSAnalyzerForm.CodeListBoxClick(Sender: TObject);
var code: TRemoconCode;
begin
if CodeListBox.ItemIndex = -1 then Exit;
HexToCode(CodeListBox.Items[CodeListBox.ItemIndex], code);
MakeChart(code);
end;
procedure TRSAnalyzerForm.CodeToClipActionExecute(Sender: TObject);
begin
Clipboard.AsText := CodeListBox.Items[CodeListBox.ItemIndex];
end;
procedure TRSAnalyzerForm.BinaryToClipActionExecute(Sender: TObject);
var code: TRemoconCode;
begin
HexToCode(CodeListBox.Items[CodeListBox.ItemIndex], code);
Clipboard.AsText := CodeToBynary(code);
end;
procedure TRSAnalyzerForm.TableToClipActionExecute(Sender: TObject);
var code: TRemoconCode;
begin
HexToCode(CodeListBox.Items[CodeListBox.ItemIndex], code);
Clipboard.AsText := CodeToTable(code);
end;
function TRSAnalyzerForm.CodeToTable(Code: TRemoconCode): string;
var i: Integer; s: string;
begin
s := '[TABLE] 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F';
for i := Low(Code) to High(Code) do begin
if ((i mod 16) = 0) then s := s + #13#10 + Format(' %.6x', [i]);
s := s + ' ' + IntToHex(Ord(Code[i]), 2);
end;
Result := s;
end;
procedure TRSAnalyzerForm.OpenActionExecute(Sender: TObject);
begin
if PCOPRS.Open(COMPortComboBox.ItemIndex) = DEV_PCOPRS1_RET_OK then begin
StatusBar1.SimpleText := '接続成功';
end else begin
Beep;
StatusBar1.SimpleText := '接続失敗';
end;
OpenAction.Enabled := not PCOPRS.Connecting;
end;
procedure TRSAnalyzerForm.LEDActionExecute(Sender: TObject);
begin
if PCOPRS.LedFlash = DEV_PCOPRS1_RET_OK then begin
StatusBar1.SimpleText := 'LED点灯成功';
end else begin
Beep;
StatusBar1.SimpleText := 'LED点灯失敗';
end;
end;
procedure TRSAnalyzerForm.ReceiveActionExecute(Sender: TObject);
var ret: Integer; code: TRemoconCode;
s: string;
begin
PCOPRS.SetTimeOut(5000); //5sec
StatusBar1.SimpleText := '受信待機中...';
ret := PCOPRS.Receive(code);
if ret = DEV_PCOPRS1_RET_OK then begin
StatusBar1.SimpleText := '受信成功';
s := CodeToHex(code);
MakeChart(code);
CodeListBox.Items.Insert(0, s);
CodeListBox.ItemIndex := 0;
end else if ret = DEV_PCOPRS1_RET_TIMEOUT then begin
Beep;
StatusBar1.SimpleText := '受信タイムアウト';
end else begin
Beep;
StatusBar1.SimpleText := '受信失敗';
end;
end;
procedure TRSAnalyzerForm.TransmitActionExecute(Sender: TObject);
var code: TRemoconCode;
begin
HexToCode(CodeListBox.Items[CodeListBox.ItemIndex], code);
if PCOPRS.Transmit(OutputComboBox.ItemIndex, code) = DEV_PCOPRS1_RET_OK then begin
StatusBar1.SimpleText := '送信成功';
end else begin
Beep;
StatusBar1.SimpleText := '送信失敗';
end;
end;
procedure TRSAnalyzerForm.ChackSelectListItem(Sender: TObject);
begin
TAction(Sender).Enabled := CodeListBox.ItemIndex <> -1;
end;
procedure TRSAnalyzerForm.ChackEmptyList(Sender: TObject);
begin
ClearCodeAction.Enabled := CodeListBox.Items.Count <> 0;
end;
procedure TRSAnalyzerForm.ChackConnecting(Sender: TObject);
begin
TAction(Sender).Enabled := PCOPRS.Connecting;
end;
procedure TRSAnalyzerForm.OpenActionUpdate(Sender: TObject);
begin
TAction(Sender).Enabled := not PCOPRS.Connecting;
end;
procedure TRSAnalyzerForm.TransmitActionUpdate(Sender: TObject);
begin
TAction(Sender).Enabled := PCOPRS.Connecting and
(CodeListBox.ItemIndex <> -1);
end;
procedure TRSAnalyzerForm.ClearCodeActionExecute(Sender: TObject);
begin
CodeListBox.Clear;
Series1.Clear;
end;
procedure TRSAnalyzerForm.DeleteCodeActionExecute(Sender: TObject);
begin
CodeListBox.Items.Delete(CodeListBox.ItemIndex);
Series1.Clear;
end;
procedure TRSAnalyzerForm.UndoZoomActionExecute(Sender: TObject);
begin
TheChart.UndoZoom;
end;
procedure TRSAnalyzerForm.SaveChartActionExecute(Sender: TObject);
begin
with ChartSaveDialog do begin
if Execute then begin
if FilterIndex = 1 then begin
DefaultExt := 'bmp';
TheChart.SaveToBitmapFile(FileName);
end else begin
DefaultExt := 'wmf';
TheChart.SaveToMetafileEnh(FileName);
end;
end;
end;
end;
procedure TRSAnalyzerForm.ChartToClipActionExecute(Sender: TObject);
begin
TheChart.CopyToClipboardBitmap;
end;
procedure TRSAnalyzerForm.AboutActionExecute(Sender: TObject);
begin
MessageDlg(Application.Title + ' v.1.0.0' + #13#10#13#10 +
'yhira'#13#10 +
'http://netakiri.net/',
mtInformation, [mbOK], 0);
end;
end.
