我有这个USB Relay,我想从Android手机控制 .
(有一个类似的帖子here,但它解释了如何从Linux shell . 通过查看该代码我认为我能够解决它 - 显然不是 . )
设备在lsusb中列出:
Bus 002 Device 011: ID 16c0:05df VOTI
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x16c0 VOTI
idProduct 0x05df
bcdDevice 1.00
iManufacturer 1
iProduct 2
iSerial 0
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 34
bNumInterfaces 1
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 20mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 22
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 0x0008 1x 8 bytes
bInterval 20
我觉得很奇怪,终点被定义为“EP IN” . 在我看来它应该是“EP OUT”,因为方向应该是“host-> device” .
无论如何,我使用Android USB管理器创建连接,然后初始化USbRequest以获得基于中断的 endpoints . Android权限和所有处理权限,以便设备成功连接 .
用于发送数据的代码段 . 它遵循Android准则在单独的线程中运行:
UsbRequest request = new UsbRequest();
synchronized (mUsbLock) {
if (mUsbConnection != null && mUsbEndPointIn != null) {
if (!request.initialize(mUsbConnection, mUsbEndPointIn)) {
Log.e(TAG, "Unable to initialize UsbRequest. Thread exits");
return;
} else {
if (DEBUG) {
Log.d(TAG, String.format("Usb request is initialized"));
}
}
} else {
Log.e(TAG, "Usb communication is not up and running. The worker thread should never be started.");
return;
}
}
mRunning.set(true);
while (mRunning.get()) {
if (DEBUG) {
Log.d(TAG, String.format("Waiting for data to be sent to end point"));
}
WorkPackage wp = mWorkQueue.take();
// send the package.
byte[] data = wp.getData();
if (!request.queue(ByteBuffer.wrap(data), data.length)) {
Log.e(TAG, "Unable to queue to send data on UsbRequest.");
continue;
} else {
if (DEBUG) {
Log.d(TAG, String.format("Usb request is queued on end point, ep=%s", printUsbEndpoint(mUsbEndPointIn)));
}
}
}
似乎一切都很好,没有错误发生,请求在终点排队,但没有任何事情发生 . 我没有得到任何消息,请求已被处理 .
由于供应商不会发布开/关命令,我尝试了基于Linux帖子的变种(上图) . 似乎没有工作 . 供应商仅发布Windows二进制库 .
发送8字节包(根据最大包):
public static byte[] SET_RELAY_ON = {(byte) 0xff, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
public static byte[] SET_RELAY_OFF = {(byte) 0xfd, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00};
帮助赞赏 .
1 回答
所以,我想出了如何做到这一点 . 我会在这里写解决方案以防其他人遇到类似的问题 .
我不得不窥探USB流量以了解实际发送的内容 . 事实证明,根本没有使用定义的中断终点 . 因此,与设备的通信不是基于中断的,而是使用 endpoints 0上的控制传输类型 .
因此,使用Android USB API可转换为:
打开设备(设备 - >主机方向):
打开继电器“1”(主机 - >设备方向) .
注意,缓冲区中的第二个参数(0x01)是继电器编号(如果板上有> 1个继电器) . 我只有一个 .
关闭继电器'1'(主机 - >设备方向):