帰宅したときに部屋が暑すぎるのが嫌だったのでリモートからエアコンの電源を操作できたらいいなあ、という理由で USB 接続の赤外線リモコンを購入してみた。
購入したものはコレ。
USB接続 赤外線リモコンキット
半田付けするのはめんどうだったので、完成品を購入。
フリスクのケースにあうように作られているらしい。
届いてから色々と調べてみて Linux では hiddev ファイルに書き込めばいいらしいということがわかったのですが、スレッドの msg#1.2.1 と同じようなことになり使うことができなかった。
このリモコンキットはファームウェアのソースコードやWindowsのアプリのソースコードなどが公開されているので、それを参考にしつつプログラムを作ってみた。
app-misc/lirc とかのドライバとして作るのがほんとはいいのかも。
Linuxで操作するための手段としては
などがあるが、HIDのインターフェイスのことがよくわからず、Broken pipeばかりで解決できなかったので libusb を使うことにした。
このリモコンキットには4つのInterfaceDescriptorがありますが、使用するのは interfaceNumber 3 のみです。
購入したものはコレ。
USB接続 赤外線リモコンキット
半田付けするのはめんどうだったので、完成品を購入。
フリスクのケースにあうように作られているらしい。
届いてから色々と調べてみて Linux では hiddev ファイルに書き込めばいいらしいということがわかったのですが、スレッドの msg#1.2.1 と同じようなことになり使うことができなかった。
このリモコンキットはファームウェアのソースコードやWindowsのアプリのソースコードなどが公開されているので、それを参考にしつつプログラムを作ってみた。
app-misc/lirc とかのドライバとして作るのがほんとはいいのかも。
Linuxで操作するための手段としては
- hiddev インターフェイスを使う
- libhid を使う
- libusb を使う
などがあるが、HIDのインターフェイスのことがよくわからず、Broken pipeばかりで解決できなかったので libusb を使うことにした。
このリモコンキットには4つのInterfaceDescriptorがありますが、使用するのは interfaceNumber 3 のみです。
lsusbの結果
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Bus 003 Device 053: ID 22ea:001e | |
Device Descriptor: | |
bLength 18 | |
bDescriptorType 1 | |
bcdUSB 2.00 | |
bDeviceClass 0 (Defined at Interface level) | |
bDeviceSubClass 0 | |
bDeviceProtocol 0 | |
bMaxPacketSize0 8 | |
idVendor 0x22ea | |
idProduct 0x001e | |
bcdDevice 0.01 | |
iManufacturer 1 Bit Trade One LTD. | |
iProduct 2 USB IR REMOCON | |
iSerial 0 | |
bNumConfigurations 1 | |
Configuration Descriptor: | |
bLength 9 | |
bDescriptorType 2 | |
wTotalLength 123 | |
bNumInterfaces 4 | |
bConfigurationValue 1 | |
iConfiguration 0 | |
bmAttributes 0xe0 | |
Self Powered | |
Remote Wakeup | |
MaxPower 100mA | |
Interface Descriptor: | |
bLength 9 | |
bDescriptorType 4 | |
bInterfaceNumber 0 | |
bAlternateSetting 0 | |
bNumEndpoints 1 | |
bInterfaceClass 3 Human Interface Device | |
bInterfaceSubClass 1 Boot Interface Subclass | |
bInterfaceProtocol 2 Mouse | |
iInterface 0 | |
HID Device Descriptor: | |
bLength 9 | |
bDescriptorType 33 | |
bcdHID 1.11 | |
bCountryCode 0 Not supported | |
bNumDescriptors 1 | |
bDescriptorType 34 Report | |
wDescriptorLength 52 | |
Report Descriptors: | |
** UNAVAILABLE ** | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x81 EP 1 IN | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0004 1x 4 bytes | |
bInterval 8 | |
Interface Descriptor: | |
bLength 9 | |
bDescriptorType 4 | |
bInterfaceNumber 1 | |
bAlternateSetting 0 | |
bNumEndpoints 1 | |
bInterfaceClass 3 Human Interface Device | |
bInterfaceSubClass 1 Boot Interface Subclass | |
bInterfaceProtocol 0 None | |
iInterface 0 | |
HID Device Descriptor: | |
bLength 9 | |
bDescriptorType 33 | |
bcdHID 1.11 | |
bCountryCode 0 Not supported | |
bNumDescriptors 1 | |
bDescriptorType 34 Report | |
wDescriptorLength 31 | |
Report Descriptors: | |
** UNAVAILABLE ** | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x82 EP 2 IN | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0001 1x 1 bytes | |
bInterval 1 | |
Interface Descriptor: | |
bLength 9 | |
bDescriptorType 4 | |
bInterfaceNumber 2 | |
bAlternateSetting 0 | |
bNumEndpoints 2 | |
bInterfaceClass 3 Human Interface Device | |
bInterfaceSubClass 1 Boot Interface Subclass | |
bInterfaceProtocol 1 Keyboard | |
iInterface 0 | |
HID Device Descriptor: | |
bLength 9 | |
bDescriptorType 33 | |
bcdHID 1.11 | |
bCountryCode 0 Not supported | |
bNumDescriptors 1 | |
bDescriptorType 34 Report | |
wDescriptorLength 63 | |
Report Descriptors: | |
** UNAVAILABLE ** | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x83 EP 3 IN | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0008 1x 8 bytes | |
bInterval 8 | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x03 EP 3 OUT | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0008 1x 8 bytes | |
bInterval 8 | |
Interface Descriptor: | |
bLength 9 | |
bDescriptorType 4 | |
bInterfaceNumber 3 | |
bAlternateSetting 0 | |
bNumEndpoints 2 | |
bInterfaceClass 3 Human Interface Device | |
bInterfaceSubClass 0 No Subclass | |
bInterfaceProtocol 0 None | |
iInterface 0 | |
HID Device Descriptor: | |
bLength 9 | |
bDescriptorType 33 | |
bcdHID 1.11 | |
bCountryCode 0 Not supported | |
bNumDescriptors 1 | |
bDescriptorType 34 Report | |
wDescriptorLength 29 | |
Report Descriptor: (length is 29) | |
Item(Global): Usage Page, data= [ 0x00 0xff ] 65280 | |
(null) | |
Item(Local ): Usage, data= [ 0x01 ] 1 | |
(null) | |
Item(Main ): Collection, data= [ 0x01 ] 1 | |
Application | |
Item(Local ): Usage Minimum, data= [ 0x01 ] 1 | |
(null) | |
Item(Local ): Usage Maximum, data= [ 0x40 ] 64 | |
(null) | |
Item(Global): Logical Minimum, data= [ 0x00 ] 0 | |
Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 | |
Item(Global): Report Size, data= [ 0x08 ] 8 | |
Item(Global): Report Count, data= [ 0x40 ] 64 | |
Item(Main ): Input, data= [ 0x00 ] 0 | |
Data Array Absolute No_Wrap Linear | |
Preferred_State No_Null_Position Non_Volatile Bitfield | |
Item(Local ): Usage Minimum, data= [ 0x01 ] 1 | |
(null) | |
Item(Local ): Usage Maximum, data= [ 0x40 ] 64 | |
(null) | |
Item(Main ): Output, data= [ 0x00 ] 0 | |
Data Array Absolute No_Wrap Linear | |
Preferred_State No_Null_Position Non_Volatile Bitfield | |
Item(Main ): End Collection, data=none | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x84 EP 4 IN | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0040 1x 64 bytes | |
bInterval 8 | |
Endpoint Descriptor: | |
bLength 7 | |
bDescriptorType 5 | |
bEndpointAddress 0x04 EP 4 OUT | |
bmAttributes 3 | |
Transfer Type Interrupt | |
Synch Type None | |
Usage Type Data | |
wMaxPacketSize 0x0040 1x 64 bytes | |
bInterval 8 | |
Device Status: 0x0001 | |
Self Powered |
今回使う部分だけ抜粋すると下記の部分です。
逆にデバイスに書き込む際は EP Address 0x04 を渡せばいいようです。
Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 8 Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x04 EP 4 OUT bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0040 1x 64 bytes bInterval 8デバイスからデータを貰ってくるときは EP Address 0x84 を libusb_interrupt_transfer() に渡してあげれば良さそうです。
逆にデバイスに書き込む際は EP Address 0x04 を渡せばいいようです。
続いてリモコンキットの制御コードの部分。
これは〔ファームウェアソースコード(Ver2.1.0〕の中を参考にします。
アーカイブの中の main.c がファームウェアのソースコードのようです。
ProcessIO() の中に switch 文があり、そこに制御コードが書かれています。
赤外線をリモコンキットで受信する場合は
パケットサイズは 64 Bytes なので余った部分は 0xFF で埋めます。
これで受信待ちモードになったので、続いてデバイスからデータを読み出す制御コードを送りつけます。
これは〔ファームウェアソースコード(Ver2.1.0〕の中を参考にします。
アーカイブの中の main.c がファームウェアのソースコードのようです。
ProcessIO() の中に switch 文があり、そこに制御コードが書かれています。
制御コード | 説明 |
---|---|
0x56 | Get Firmware version |
0x80 | EEPROMにデータを設定(サイズ61) |
0x81 | EEPROMにデータを設定(サイズ10) |
0x82 | EEPROMからデータ読み出し(サイズ61) |
0x83 | EEPROMからデータ読み出し(サイズ10) |
0x40 | Echo back |
0x41 | Echo back |
0x50 | 赤外線受信データを送信(デバイス->Host) |
0x51 | 赤外線受信待ちモード設定(1=受信待ち, 0=解除) |
0x52 | 赤外線受信データを送信 拡張版(デバイス->Host, 65 octets) |
0x53 | 赤外線受信待ちモード設定 拡張版(1=受信待ち, 0=解除) |
0x60 | 赤外線出力データを受信する(7 Octets) |
0x61 | 赤外線出力データを受信する 拡張版(65 Octets) |
赤外線をリモコンキットで受信する場合は
0x53 0x01 0xFF 0xFF ....というパケットを EPAddress 0x04 に投げます。
パケットサイズは 64 Bytes なので余った部分は 0xFF で埋めます。
これで受信待ちモードになったので、続いてデバイスからデータを読み出す制御コードを送りつけます。
0x52 0xFF 0xFF 0xFF ....このパケットを繰り返しデバイスに送っておきつつ EPAddress 0x84 を読み込めば赤外線を受信したときにコードを取れます。
リモコンキットから赤外線を送信する場合は
0x61の後に続けて送りたいコードをつけて EPAddress 0x04 に投げつければ送信されます。
久々にブログ書いたけど、文章まとめるの難しい..