ネタキリラボ
ネタキリラボ[ラボ]

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個のビットを、ただチャート表示する単純なソフトです。信号を解析する機能は付いていません。

RS-Analyzer

使い方は、PC-OP-RS1を差したCOMポートを選択し、「接続」ボタンを押してください。「受信」ボタンを押し5秒以内にPC-OP-RS1の受光部に向かってリモコンを押してください。チャートに信号が表示されます。あとの機能はおまけみたいなもんです。

ソースが付いているので改造も自由です。ただし改造したものを公開する場合は、GPLv2ライセンスに従ってください。

リモコン信号表示例

NECフォーマット

NEC_RB-73Aのパルス位相変調信号(リピート2回)。リピートコードを二回とらえています。

NEC_RB-73A

最初の信号を拡大したもの。

NEC_RB-73A

信号拡大

※リモコン信号はLIRC設定ファイル置き場から、適当に拾ってきてWinLIRCから信号を発信したものです。

SONYフォーマット

Sony_RMT-V767のパルス位相変調信号(リピート2回)。

Sony_RMT-V767

最初の信号を拡大したもの。

Sony_RMT-V767

信号拡大

※リモコン信号はLIRC設定ファイル置き場から、適当に拾ってきてWinLIRCから信号を発信したものです。

おまけ(日立製エアコン)

家で使っている日立製エアコンの信号。長すぎて全部とらえられないようです。PC-OP-RS1の最長は192ms。

日立エアコン

信号拡大

環境

注意点

参考

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.

ダウンロード

ソフト+ソースファイル [Down]


Copyright 2003-2010 yhira All Rights Reserved`
[Server] [Delphi Tips]
最終更新:2010/08/19 23:30:36