ここではDelphiからAVC300を操作するサンプルを載せています。卓上リモコンAVC300サンプルプログラムソース
に付属しているVBソースを元に書きました。
このサンプルは、AVC300の根幹機能といえる接続(Connect)、システム情報取得(ReadSys)、システム情報保存(SaveSysdata)、ステータス情報取得(GetStatus)、リモコンコマンド送信(RemoconCMD)、リモコンコマンド学習(LearningCMD)を解析すべく作りました。
他の機能(SetReserveList、GetReserveInfo、Getrimodata、、GetMailInfo、GetDeviceInfoなど)は盛り込んでいません。予約機能などはアプリケーション側で実装できますし、他のメール機能は特にいらないかなと。というか、面倒くさかったのが一番の理由です。そのうちやる気が出たら、ここのソースを元に全機能を含んだラッパーなどを作れればと思います。
Connect→ReadSysの後に他のボタンが使用できます。右側にログが表示され、AVC300が返してきた返信(返ってきたバッファの1番目)や返信バッファ数なども見ることが出来ます。
unit Globals;
interface
const
DEVICE_MAX_NO = 4;
KEY_MAX_NO = 40; //1デバイス当のリモコンの操作キーの個数
BUF_SIZE = 670;
KEYCODE_BUFSIZE = 12000;
END_DATA = $FF;
LEARNING_TIMEOUT = 10000; //msec Data登録時のタイムアウト
MAX_RESERVATION = 100;
AVC300_RUNNING = 2;
DATA_LENGTH_MIN = 20; //リモコンデータの最小サイズ
PULSE_WIDTH_MIN = 3; //パルスの最小幅
PULSE_WIDTH_CORRECTION = 2; //パルス幅補正
DEVICE_LEN = 12; //デバイスの名前のサイズ
KEY_LEN = 24; //キーの名前のサイズ
WEB_PASSWORD_LENGTH = 9;
DEFAULT_WEB_PASSWORD = 'rimo';
//COMMAND
SET_CONDITION = 'S';
TRANSMIT_MODE = 'T';
RECEIVING_MODE = 'R';
REGISTER_MODE = 'r';
SET_MODE = 2;
RESET = 7;
NO_RES = 3;
NO_DATA = 4;
ENQ = 5;
ACK = 6;
NACK = 21;
DATA_REQ = 16;
DEVICE_INFO = 9; //Device ,KeyのListを送信してSYSへ保存
GET_DEVICE_INFO = 10; //SYSから読み出して転送
RIMO_OK = 17; //赤外線照射のACK
SET_TIME = 18; //時刻を設定
SET_RESERVE = 19; //予約実行
STP_RESERVE = 20; //予約実行
GET_RESERVE_INFO = 25; //予約情報の取得FromAVC300
GET_INFO = 26; //時刻、予約、マクロ、温度、明度の実行状態
GET_MAIL_INFO = 29;
SET_MAIL = 30;
SEND_MAIL_TST = 31;
GET_RIMO_DATA = 32;
SAVE_RIMO_DATA = 33;
LEARNING = 13;
REMOCON = 14;
WRITE_ERROR = 2; //WriteUsb error
RECIVE_DATA = 46;
DEFAULT_PACKET_SIZE = 192;
DEFAULT_TRANSMIT_PACKET_SIZE = 192;
//温度計測
KELVIN_CONST = 3300; //カルビン定数
R25 = 500; //25度の抵抗
ABSTMP = 273; //絶対温度
RC = 510; //分割抵抗
VCC = 5; //基準電圧
SYS_PASSWORD = 'AVC';
//明度
BRIGHT = 230; //眩
LIGHT = 180; //明
DIME = 128; //照明
DARK = 82; //薄暗
NIGHT = 35; //暗
BLACK = 0; //闇
type
TReceivedData = array of Byte;
TTransmitData = TReceivedData;
//今回未使用
TRecevingData = (rdNone, rdSystemData, rdStatusInfo);
TDeviceData = record
LedCh: Byte;
CarrierClock: Byte;
DeviceName: array[0..11] of Char;
end;
TKeyData = record
DeviceNo: Byte;
KeyNo: Byte;
KeyName: array[0..23] of Char;
end;
TSystemData = record
SysPassWord: array[0..2] of Char;
TransmitFrq: Byte;
CarrierClock: Byte;
SYSReserv1: Byte;
TransmitInterval: Byte;
TmpOffset: Byte;
LocalIP: array[0..3] of Byte;
GateWayIP: array[0..3] of Byte;
PortNo: Word;{array[0..1] of Byte;} //UDPプロトコルのポート
SYSReserv2: array[0..8] of Byte;
CurrentDeviceNo: Byte;
CurrentLedCh: Byte;
CurrentCarrierClock: Byte;
SYSReserv3: array[0..19] of Byte;
Password: array[0..8] of Char;
//明度計測;
Bright: Byte; //= 230 "眩"
Light: Byte; // = 180 "明"
Dime: Byte; // = 128 "照明"
Dark: Byte; // = 82 "薄暗"
Night: Byte; // = 35 "暗"
Black: Byte; // = 0 "闇"
LampMode: Byte;
PacketSize: Byte; //パケット単位64BYTE AVCの受信
TransmitPacketSize: Byte; //パケット単位64BYTE AVCの送信
WebPortNo: Word;{array[0..1] of Byte;} //WebBrousser用サーバのポート
SYSReserv4: array[0..29] of Byte;
Device: array[0..3] of TDeviceData;
Keyname: array[0..179] of TKeyData;
end;
TReserveData = record
Year: Byte; //西暦-2000
Month: Byte;
Day: Byte;
Hour: Byte;
Minute: Byte;
Sec: Byte;
Week: Byte; //0:当日のみ 1:毎日 2:月から金 3:以上は曜日指定
//3:Sun 4:Mon 5:Tue:,,9:sat
DeviceNo: Byte;
KeyNo: Byte;
end;
TStatusInfo = record
Year: Byte; //西暦-2000
Month: Byte;
Day: Byte;
Hour: Byte;
Minute: Byte;
Seconde: Byte;
Week: Byte; //0:当日のみ 1:毎日 2:月から金 3:以上は曜日指定
//3:Sun 4:Mon 5:Tue:,,9:sat
Luminosityc: Byte;
Temperature: Byte;
end;
implementation
end.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics,
Controls, Forms, Dialogs, StdCtrls, IdUDPServer,
IdBaseComponent, IdComponent, IdUDPBase, IdUDPClient,
IdSocketHandle, Globals, ComCtrls, ExtCtrls, Spin;
type
TForm1 = class(TForm)
Bevel1: TBevel;
ButtonPanel: TPanel;
CHRadioGroup: TRadioGroup;
ConnectButton: TButton;
DeviceNoSpinEdit: TSpinEdit;
GetStatusButton: TButton;
IdUDPClient1: TIdUDPClient;
IdUDPServer1: TIdUDPServer;
KeyNoSpinEdit: TSpinEdit;
Label1: TLabel;
LearningCMDButton: TButton;
LogPanel: TPanel;
Memo1: TMemo;
Panel1: TPanel;
ReadSysDataButton: TButton;
RemoconCMDButton: TButton;
SaveSysdataButton: TButton;
SetModeRadioGroup: TRadioGroup;
Splitter1: TSplitter;
Splitter2: TSplitter;
StatusInfoListView: TListView;
StatusInfoPanel: TPanel;
SystemDataListView: TListView;
SystemDataPanel: TPanel;
procedure ConnectButtonClick(Sender: TObject);
procedure IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
procedure ReadSysDataButtonClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure GetStatusButtonClick(Sender: TObject);
procedure SaveSysdataButtonClick(Sender: TObject);
procedure RemoconCMDButtonClick(Sender: TObject);
procedure LearningCMDButtonClick(Sender: TObject);
procedure SetModeRadioGroupClick(Sender: TObject);
private
{ Private 宣言 }
FStartTime: Cardinal;
FSystemData: TSystemData;
FStatusInfo: TStatusInfo;
procedure Log(s: string);
procedure StartTime;
function StopTime: Cardinal;
procedure SendData(cmd: Byte; const Buffer: TTransmitData;
Count: Word);
procedure SendCommand(cmd: Byte; Text: string);
function TransmitByteData(cmd: Byte; Data: TTransmitData;
Count: Word): Boolean;
procedure SetStatusInfo(const Value: TStatusInfo);
procedure SetSystemData(const Value: TSystemData);
function AddIntItem(LV: TListView; AName: string;
AValue: Integer): TListItem;
function AddStrItem(LV: TListView; AName,
AValue: string): TListItem;
procedure LogResAndSize(ARes, ASize: Integer);
procedure CheckButtonEnabled;
public
{ Public 宣言 }
IsReceving: Boolean; //データ取得中かどうか
RecevedMs: TMemoryStream; //取得したデータ格納用
TotalDataSize, //トータル取得データ
TmpTotalDataSize: Word; //トータル取得データ計算用
SystemDataExist: Boolean; //SystemDataを取得したかどうか
RecevingData: TRecevingData; //今回未使用
property StatusInfo: TStatusInfo read FStatusInfo
write SetStatusInfo;
property SystemData: TSystemData read FSystemData
write FSystemData;
procedure Connect;
procedure ReadSysData;
procedure GetStatus;
procedure SaveSysdata;
function TransmitSystemData(sd: TSystemData): Boolean;
function RemoconCMD(DeviceNo, KeyNo, CarrierClock,
CH: Byte): Boolean;
function LearningCMD(DeviceNo, KeyNo, CarrierClock,
CH, TrasmitFrq: Byte): Boolean;
end;
var
Form1: TForm1;
const
//環境に合わせて設定してください
PASSWORD = 'rimo';
DEFAULT_LOCAL_IP = '192.168.0.145';
DEFAULT_PORT = 6000;
SEP = '------------------';
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Clear;
CheckButtonEnabled;
RecevedMs := TMemoryStream.Create;
IsReceving := False;
TotalDataSize := 0;
SystemDataExist := False;
RecevingData := rdNone;
//Indy設定
with IdUDPClient1 do begin
Active := True;
Host := DEFAULT_LOCAL_IP;
Port := DEFAULT_PORT;
ReceiveTimeout := 100;
end;
with IdUDPServer1 do begin
Active := True;
DefaultPort := DEFAULT_PORT;
end;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
RecevedMs.Free;
end;
procedure TForm1.SendData(cmd: Byte; const Buffer: TTransmitData; Count: Word);
//サム計算
function GetSum(cmd: Byte; const Buffer; Count: Word): Byte;
var i: Integer; sum: Word;
buf: array of Byte; //len: Word;
begin
sum := cmd;
SetLength(buf, Count);
CopyMemory(Pointer(buf), Pointer(Buffer), Count);
for i := Low(buf) to High(buf) do begin
sum := sum + buf[i];
end;
Result := sum and $FF;// LoByte(sum)
end;
var ms: TMemoryStream; len: Word; tmp: Byte; i: Integer;
begin
ms := TMemoryStream.Create;
try
Log(SEP);
len := Count + 7; //+7:Datalength(2)+cmd+0+endData+endData+sum
tmp := LoByte(len);
ms.WriteBuffer(tmp, 1); //データ数LoByte
tmp := HiByte(len);
ms.WriteBuffer(tmp, 1); //データ数HiByte
ms.WriteBuffer(cmd, 1); //コマンド
tmp := 0;
ms.WriteBuffer(tmp, 1); //0(予備)
for i := 0 to Count-1 do begin
tmp := Buffer[i];
ms.WriteBuffer(tmp, 1); //データ配列
end;
tmp := END_DATA;
ms.WriteBuffer(tmp, 1); //endData(255)
ms.WriteBuffer(tmp, 1); //endData(255)
tmp := GetSum(cmd, Buffer, Count);
ms.WriteBuffer(tmp, 1); //SUM(1BYTEサムチェックコード)
ms.Position := 0;
//UDP送信
IdUDPServer1.Bindings[0].SendTo(
DEFAULT_LOCAL_IP, DEFAULT_PORT, ms.Memory^, len);
finally
ms.Free;
end;
end;
procedure TForm1.SendCommand(cmd: Byte; Text: string);
var buf: TTransmitData; len: Word;
begin
len := Length(Text);
SetLength(buf, len);
CopyMemory(Pointer(buf), Pointer(text), len);
SendData(cmd, buf, len);
end;
procedure TForm1.ConnectButtonClick(Sender: TObject);
begin
Connect;
end;
procedure TForm1.Log(s: string);
begin
Memo1.Lines.Add(s);
end;
procedure TForm1.LogResAndSize(ARes, ASize: Integer);
begin
Log('RES:' + IntToStr(ARes) + #9 + 'SIZE:' + IntToStr(ASize));
end;
procedure TForm1.IdUDPServer1UDPRead(Sender: TObject; AData: TStream;
ABinding: TIdSocketHandle);
function GetResult(ms: TMemoryStream): Byte;
var res: Byte;
begin
Result := NACK;
if ms.Size > 0 then begin
ms.Position := 0;
ms.Read(res, 1);
Result := res;
ms.Position := 0;
end;
end;
procedure SendDataReq;
var req: Byte;
begin
req := DATA_REQ;
IdUDPServer1.Bindings[0].SendTo(DEFAULT_LOCAL_IP, DEFAULT_PORT, req, 1);
end;
var ms: TMemoryStream; res, sum: Byte;
buf: TReceivedData; i: Integer; tmpsum: Cardinal;
sd: TSystemData; si: TStatusInfo; //p: PByte; psi: ^TStatusInfo;
begin
ms := AData as TMemoryStream;
res := GetResult(ms); //msのバッファの先頭の数字を取得
LogResAndSize(res, ms.Size);
if not IsReceving then begin
case res of
ACK: ;
NACK: Exit;
// 4: Log(SEP);
//ステータス取得
GET_INFO: begin
RecevedMs.Clear;
RecevingData := rdStatusInfo;
SetLength(buf, ms.Size);
//GET_INFOの内容を見るデバック用
//ms.SaveToFile('GetInfo.dat');
ms.ReadBuffer(buf[0], ms.Size);
//CopyMemory(@si, @buf[1], ms.Size-1);
//↑何故かエラーになるから↓の方法
with si do begin
Year := buf[1];
Month := buf[2];
Day := buf[3];
Hour := buf[4];
Minute := buf[5];
Seconde := buf[6];
Week := buf[7];
Luminosityc := buf[8];
Temperature := buf[9];
end;
SetStatusInfo(si);
Log('ステータス情報を取得しました。');
end;
//システムデータ取得
RECIVE_DATA : begin
IsReceving := True;
TotalDataSize := 0;
RecevedMs.Clear;
RecevingData := rdSystemData;
TmpTotalDataSize := ms.Size;
ms.Read(TotalDataSize, 2); //全体のサイズ取得
ms.Position := 0;
RecevedMs.Position := 0;
//RecevedMsにデータ取得開始
RecevedMs.WriteBuffer(ms.Memory^, ms.Size);
SendDataReq;
end;
else IsReceving := False;
end;
end else begin
//全体のサイズをTmpTotalDataSizeが超えたら終了処理へ
if TotalDataSize > TmpTotalDataSize then begin
TmpTotalDataSize := TmpTotalDataSize + ms.Size;
ms.Position := 0;
//TotalDataSizeになるまでデータ取得
RecevedMs.WriteBuffer(ms.Memory^, ms.Size);
SendDataReq;
end else begin
//RECIVE_DATA終了処理
IsReceving := False;
TmpTotalDataSize := 0;
//RECIVE_DATAの内容を見るデバック用
//RecevedMs.SaveToFile('ReceveData.txt');
RecevedMs.Position := 0;
RecevedMs.ReadBuffer(TotalDataSize, 2);
Log('TOTAL:'#9 + IntToStr(TotalDataSize));
SetLength(buf, TotalDataSize);
RecevedMs.ReadBuffer(buf[0], TotalDataSize);
RecevedMs.ReadBuffer(sum, 1);
//チェックサム
tmpsum := 0;
for i := 0 to TotalDataSize-1 do begin
tmpsum := tmpsum + buf[i]; //サム計算
end;
tmpsum := tmpsum mod 256;
Log('SUM:'#9 + IntToStr(sum));
Log('CHKSUM:'#9 + IntToStr(tmpsum));
if sum = tmpsum then begin
Log('サムが一致しました。');
end else begin
Log('サムが一致しません。');
Exit;
end;
//データのコピー
CopyMemory(@sd, @buf[0], SizeOf(TSystemData));
SetSystemData(sd);
RecevingData := rdNone;
SystemDataExist := True;
Log('システムデータを取得しました。');
CheckButtonEnabled;
end;
end;
end;
procedure TForm1.StartTime;
begin
FStartTime := GetTickCount;
end;
function TForm1.StopTime: Cardinal;
begin
Result := GetTickCount - FStartTime;
end;
procedure TForm1.ReadSysDataButtonClick(Sender: TObject);
begin
ReadSysData;
end;
function TForm1.AddStrItem(LV: TListView; AName, AValue: string): TListItem;
begin
Result := LV.Items.Add;
with Result do begin
Caption := AName;
SubItems.Add(AValue);
end;
end;
function TForm1.AddIntItem(LV: TListView; AName: string; AValue: Integer): TListItem;
begin
Result := AddStrItem(LV, AName, IntToStr(AValue));
end;
procedure TForm1.SetStatusInfo(const Value: TStatusInfo);
//温度変換
function CnvrtToTmp(Value: Double): Double;
var v, R: Double;
TmpOffset: Integer;
begin
if (Value <= 0) or (Value >= 200) then begin
Result := -ABSTMP; //Error
Exit;
end;
v := Value;
v := v * VCC / 256;
R := RC * v / (VCC - v);
Result := 1 / (Ln(R/R25) / KELVIN_CONST + 1 / (25 + ABSTMP));
TmpOffset := SystemData.TmpOffset - 128; //Byteのため128をゼロとする
Result := Result - ABSTMP + (TmpOffset / 10);
end;
begin
FStatusInfo := Value;
with Value do begin
StatusInfoListView.Items.BeginUpdate;
StatusInfoListView.Clear;
AddStrItem(StatusInfoListView, '日付', IntToStr(Year + 2000) + '/' +
IntToStr(Month) + '/' + IntToStr(Day));
AddStrItem(StatusInfoListView, '時刻', IntToStr(Hour) + ':' +
IntToStr(Minute) + ':' + IntToStr(Seconde));
AddIntItem(StatusInfoListView, '明度', Luminosityc);
AddStrItem(StatusInfoListView, '温度',
FormatFloat('0.00', CnvrtToTmp(Temperature)) + '℃');
StatusInfoListView.Items.EndUpdate;
end;
end;
procedure TForm1.SetSystemData(const Value: TSystemData);
var i: Integer; s: string;
begin
FSystemData := Value;
with Value do begin
SystemDataListView.Items.BeginUpdate;
SystemDataListView.Clear;
AddStrItem(SystemDataListView, 'SysPassWord', SysPassWord);
AddIntItem(SystemDataListView, 'TransmitFrq', TransmitFrq);
AddIntItem(SystemDataListView, 'CarrierClock', CarrierClock);
AddIntItem(SystemDataListView, 'TransmitInterval', TransmitInterval);
AddIntItem(SystemDataListView, 'TmpOffset', TmpOffset);
AddStrItem(SystemDataListView, 'LocalIP',
IntToStr(LocalIP[0]) + '.' + IntToStr(LocalIP[1]) + '.' +
IntToStr(LocalIP[2]) + '.' + IntToStr(LocalIP[3]));
AddStrItem(SystemDataListView, 'GateWayIP',
IntToStr(GateWayIP[0]) + '.' + IntToStr(GateWayIP[1]) + '.' +
IntToStr(GateWayIP[2]) + '.' + IntToStr(GateWayIP[3]));
AddIntItem(SystemDataListView, 'PortNo', PortNo);
AddIntItem(SystemDataListView, 'CurrentDeviceNo', CurrentDeviceNo);
AddIntItem(SystemDataListView, 'CurrentLedCh', CurrentLedCh);
AddIntItem(SystemDataListView, 'CurrentCarrierClock', CurrentCarrierClock);
AddStrItem(SystemDataListView, 'PassWord', PassWord);
AddIntItem(SystemDataListView, 'Bright', Bright);
AddIntItem(SystemDataListView, 'Light', Light);
AddIntItem(SystemDataListView, 'Dime', Dime);
AddIntItem(SystemDataListView, 'Dark', Dark);
AddIntItem(SystemDataListView, 'Night', Night);
AddIntItem(SystemDataListView, 'Black', Black);
AddIntItem(SystemDataListView, 'LampMode', LampMode);
AddIntItem(SystemDataListView, 'PacketSize', PacketSize);
AddIntItem(SystemDataListView, 'TransmitPacketSize', TransmitPacketSize);
AddIntItem(SystemDataListView, 'WebPortNo', WebPortNo);
for i := 0 to 3 do begin
s := 'Device[' + IntToStr(i) + '].';
AddIntItem(SystemDataListView, s + 'LedCh', Device[i].LedCh);
AddIntItem(SystemDataListView, s + 'CarrierClock', Device[i].CarrierClock);
AddStrItem(SystemDataListView, s + 'DeviceName', Device[i].DeviceName);
end;
for i := 0 to 179 do begin
s := 'Keyname[' + IntToStr(i) + '].';
AddIntItem(SystemDataListView, s + 'DeviceNo', Keyname[i].DeviceNo);
AddIntItem(SystemDataListView, s + 'KeyNo', Keyname[i].KeyNo);
AddStrItem(SystemDataListView, s + 'KeyName', Keyname[i].KeyName);
end;
SystemDataListView.Items.EndUpdate;
end;
end;
procedure TForm1.GetStatusButtonClick(Sender: TObject);
begin
GetStatus;
end;
procedure TForm1.Connect;
begin
SendCommand(ENQ, PASSWORD);
end;
procedure TForm1.ReadSysData;
begin
SendCommand(GET_DEVICE_INFO, '');
end;
procedure TForm1.GetStatus;
begin
SendCommand(GET_INFO, '');
end;
procedure TForm1.SaveSysdata;
var sd: TSystemData;
begin
sd := FSystemData;
//試しにデバイス名などを変えてみてください
//sd.Device[0].DeviceName := 'test_001';
{***************************************
どのシステムデータも変更することが出来ますが
下手に弄ると繋がらなくなるので慎重に!
システムデータがおかしくなった場合は
AVC300ヘルプの「AVC300の初期化法」参照
***************************************}
if TransmitSystemData(sd) then begin
SetSystemData(sd);
end;
end;
function TForm1.TransmitByteData(cmd: Byte; Data: TTransmitData;
Count: Word): Boolean;
var ms: TMemoryStream; len, last, packet, leftover: Word; buf, pacbuf: TTransmitData;
sum, l: Cardinal; i, sendCount: Integer;
retry: Byte; rcv: array[0..9] of Byte;
begin
Result := False;
ms := TMemoryStream.Create;
try
//SUM(1BYTEサムチェックコード)サムの範囲はコマンドからendDataの前まで
sum := cmd;
for i := 0 to Count-1 do
sum := sum + Data[i];
sum := sum and $FF;
len := Count + 7; //+7:Datalength(2)+cmd+0+endData+endData+sum
Log(SEP);
Log('TOTAL:'#9 + IntToStr(len));
Log('DATA:'#9 + IntToStr(Count));
Log('SUM:'#9 + IntToStr(sum));
SetLength(buf, len);
buf[0] := LoByte(len); //全データ数LoByte
buf[1] := HiByte(len); //全データ数HiByte
buf[2] := cmd; //コマンド
buf[3] := 0; //0(予備)
CopyMemory(@buf[4], Pointer(Data), Count); //データ配列
last := len - 1;
buf[last-2] := END_DATA; //endData(255)
buf[last-1] := END_DATA; //endData(255)
buf[last] := sum; //SUM
packet := SystemData.TransmitPacketSize * 64;
leftover := len mod packet; //余り
sendCount := (len div packet) + 1; //送る回数を計算
SetLength(pacbuf, packet);
l := 0;
rcv[0] := 0;
for i := 0 to sendCount-1 do begin
retry := 0;
repeat
if (retry > 3) or (rcv[0] = NACK) then begin
Log('データ送信に失敗しました。');
Exit;
end;
ms.Clear;
if i <> (sendCount-1) then begin
ms.WriteBuffer(buf[packet*i], packet);
ms.Position := 0;
IdUDPClient1.SendBuffer(ms.Memory^, packet);
end else begin
ms.WriteBuffer(buf[packet*i], leftover);
ms.Position := 0;
IdUDPClient1.SendBuffer(ms.Memory^, leftover);
end;
l := IdUDPClient1.ReceiveBuffer(rcv, 1);
LogResAndSize(rcv[0], l);
Inc(retry);
until (rcv[0] = ACK) or (rcv[0] = DATA_REQ);
end;
//リモコン学習の場合
StartTime;
if cmd = LEARNING then begin
while True do begin
if StopTime > 5000 then begin
Log('タイムアウト。');
Exit;
end;
//1秒後から取得
//AVC300がデータを送っていないのに受信割込みが動作しないためらしい
if StopTime > 1000 then begin
l := IdUDPClient1.ReceiveBuffer(rcv, 2);
len := rcv[1];
len := len * 256 + rcv[0];
//受信すると2BYTE返ってくるので次の処理に行く
if (l >= 2) and (len >= 10) then Break;
end;
end;
LogResAndSize(len, l);
if len < 10 then begin
Log('登録が未完了です。(' + IntToStr(len) + ')');
end else begin
if len = $FFFF then begin
Log('登録できませんでした。(' + IntToStr(len) + ')');
end else begin
if len >= BUF_SIZE - 3 then begin
Log('データが長すぎます。液晶TV、直射日光等の他からの' +
'赤外線に注意して下さい(' + IntToStr(len) + ')');
end else begin
Log('登録しました。(' + IntToStr(len) + ')');
Result := True;
end;
end;
end;
Exit;
end;
Result := True;
Log('データ送信を完了しました。');
finally
ms.Free;
end;
end;
function TForm1.TransmitSystemData(sd: TSystemData): Boolean;
var buf: TTransmitData; len, all: Word;
begin
len := SizeOf(TSystemData);
all := len + 3; //+3 datalen(2) + $00
SetLength(buf, all);
//データ作成
buf[0] := LoByte(len); //データ数LoByte
buf[1] := HiByte(len); //データ数HiByte
buf[2] := $00; //0
CopyMemory(@buf[3], @sd, len); //data copy
Result := TransmitByteData(DEVICE_INFO, buf, all);
end;
procedure TForm1.SaveSysdataButtonClick(Sender: TObject);
begin
SaveSysdata;
end;
function TForm1.RemoconCMD(DeviceNo, KeyNo, CarrierClock,
CH: Byte): Boolean;
var buf: TTransmitData; len: Word;
begin
len := 4;
SetLength(buf, len);
buf[0] := CH + 2; //CH3がCH1に対応するため
buf[1] := CarrierClock;
buf[2] := DeviceNo;
buf[3] := KeyNo;
Result := TransmitByteData(REMOCON, buf, len);
end;
procedure TForm1.RemoconCMDButtonClick(Sender: TObject);
var DeviceNo, KeyNo, CH: Byte;
begin
//リモコン操作テスト
DeviceNo := DeviceNoSpinEdit.Value;
KeyNo := KeyNoSpinEdit.Value;
CH := CHRadioGroup.ItemIndex;
RemoconCMD(DeviceNo, KeyNo,
FSystemData.Device[DeviceNo].CarrierClock, CH);
end;
function TForm1.LearningCMD(DeviceNo, KeyNo, CarrierClock, CH,
TrasmitFrq: Byte): Boolean;
var buf: TTransmitData; len: Word;
begin
len := 7;
SetLength(buf, len);
buf[0] := TrasmitFrq;
buf[1] := CH;
buf[2] := CarrierClock;
buf[3] := DATA_LENGTH_MIN;
buf[4] := PULSE_WIDTH_MIN +
PULSE_WIDTH_CORRECTION * $10; //上位4bitはセンサーLowpulse幅補正
buf[5] := DeviceNo;
buf[6] := KeyNo;
Result := TransmitByteData(LEARNING, buf, len);
end;
procedure TForm1.LearningCMDButtonClick(Sender: TObject);
var DeviceNo, KeyNo, CH: Byte; success: Boolean;
begin
//リモコン学習テスト
DeviceNo := DeviceNoSpinEdit.Value;
KeyNo := KeyNoSpinEdit.Value;
CH := CHRadioGroup.ItemIndex;
success := LearningCMD(DeviceNo, KeyNo,
FSystemData.Device[DeviceNo].CarrierClock,
CH, SystemData.TransmitFrq);
if not success then begin
MessageDlg('AVC300からの応答がありません。',
mtWarning, [mbOK], 0);
Exit;
end;
end;
procedure TForm1.SetModeRadioGroupClick(Sender: TObject);
begin
case SetModeRadioGroup.ItemIndex of
0: SendCommand(SET_MODE, REGISTER_MODE);
1: SendCommand(SET_MODE, TRANSMIT_MODE);
2: SendCommand(SET_MODE, RECEIVING_MODE);
end;
CheckButtonEnabled;
end;
procedure TForm1.CheckButtonEnabled;
begin
GetStatusButton.Enabled := SystemDataExist;
SaveSysdataButton.Enabled := SystemDataExist;
RemoconCMDButton.Enabled := SystemDataExist
and (SetModeRadioGroup.ItemIndex = 1);
LearningCMDButton.Enabled := SystemDataExist
and (SetModeRadioGroup.ItemIndex = 0);;
end;
end.