JavaからUSBランプを光らせてみる(DL100B Dream Cheeky Generic Controller編)
2013/2/14追記: WindowsサービスでWebmail Notifierを制御するユーティリティを作ったけど半年以上忘れてたので紹介 - ka-ka_xyzの日記
前回、単色でしか発光しないWebMail Notifierを掴んでしまい、あわてて三色発光するタイプのものを買ったのですが、新たな問題が発生しました。
USBポートに接続すると、デバイス名が
DL100B Dream Cheeky Generic Controller
となっています。また、ベンダIDやプロダクトIDが前回使用したWebMail Notifierとは異なっていました、さらにlibusb-win32を使用してinfファイルを生成し、testlibusb-win.exe(libusb-win32の詳細と導入方法については前回の記事を参照)を実行してみると、USBデバイスの情報は下記のような結果となりました。
DLL version: 1.2.6.0
Driver version: 1.2.6.0bus/device idVendor/idProduct
bus-0/\\.\libusb0-0001--0x1d34-0x0004 1D34/0004
- Manufacturer : Dream Link
- Product : DL100B Dream Cheeky Generic Controller
bLength: 18
bDescriptorType: 01h
bcdUSB: 0110h
bDeviceClass: 00h
bDeviceSubClass: 00h
bDeviceProtocol: 00h
bMaxPacketSize0: 08h
idVendor: 1D34h
idProduct: 0004h
bcdDevice: 0002h
iManufacturer: 1
iProduct: 2
iSerialNumber: 0
bNumConfigurations: 1
wTotalLength: 34
bNumInterfaces: 1
bConfigurationValue: 1
iConfiguration: 0
bmAttributes: 80h
MaxPower: 250
bInterfaceNumber: 0
bAlternateSetting: 0
bNumEndpoints: 1
bInterfaceClass: 3
bInterfaceSubClass: 0
bInterfaceProtocol: 0
iInterface: 0
bEndpointAddress: 81h
bmAttributes: 03h
wMaxPacketSize: 8
bInterval: 10
bRefresh: 0
bSynchAddress: 0
前回のUSBデバイスは、エンドポイント(bEndpointAddress)の情報を、入力用および出力用の2つについて取得できていたのですが、今回のデバイス(DL100B Dream Cheeky Generic Controller)ではエンドポイント(in)の情報しか取得できません。
また、前回のソースではUSBライトをOn/Offするためにエンドポイントの情報が必要でしたが、今回はエンドポイント自体が存在していないようなので、ちょっと別のメソッドを叩く必要があります。
とりあえずサンプルソース。
import ch.ntb.usb.Device; import ch.ntb.usb.USB; import ch.ntb.usb.USBException; public class UsbMain { Device dev = null; public static void main(String[] args){ UsbMain usbMain = new UsbMain(); usbMain.firstLight(); } public UsbMain(){ /* * testlibusb-win.exe実行結果にあるベンダIDとプロダクトIDでUSBデバイスを指定 * ベンダID: 0x1d34 * プロダクトID: 0x0004 * */ dev = USB.getDevice((short) 0x1d34, (short) 0x0004); } public void firstLight(){ if(dev == null){ System.out.println("failed to open USB device!"); System.exit(1); } try { dev.open(1, 0, -1); //初期化 send(new byte[]{ 0x1f, 0x02, 0x00, 0x2e, 0x00, 0x00, 0x2b, 0x03 }); send(new byte[]{ 0x00, 0x02, 0x00, 0x2e, 0x00, 0x00, 0x2b, 0x04 }); //赤色 send(new byte[]{0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //緑色 send(new byte[]{0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //青緑〜黄色 send(new byte[]{0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //青色 send(new byte[]{0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //紫色 send(new byte[]{0x0f, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //水色 send(new byte[]{0x00, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //白 send(new byte[]{0x0f, 0x0f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x05}); sleep(1000); //Light Off send(new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05}); dev.close(); } catch (USBException e) { e.printStackTrace(); } } /** * USBデバイスへ信号を送信 * @param signal 信号を表すバイト配列. * */ private void send(byte[] signal) throws USBException{ dev.controlMsg( USB.REQ_TYPE_DIR_HOST_TO_DEVICE | USB.REQ_TYPE_TYPE_CLASS | USB.REQ_TYPE_RECIP_INTERFACE, 0x09, 0x0200, 0, signal, signal.length, 2000, false); } /** * 一定時間待機 * @param i 待機時間(ms). * */ private void sleep(long i){ try { Thread.sleep(i); } catch (InterruptedException e) { e.printStackTrace(); } } }
取り敢えず、長さ8のバイト配列の内先頭3つ分が各LEDランプに対応するようです。値は各LEDの発光強度を示しますが、"0xff"とかに設定しても"0x0f"と強度は同じのようです。天井がどのへんなのかは不明。