我正在开发Android应用程序,它应该通过USB与我的硬件进行通信。我已经建立了连接,但所有收到的数据似乎都是空的,但是长度正确(我的硬件输出应该没有问题,通过WiFi,BT,COM测试,一切运行良好)。有人在我下面列出的代码中看到任何问题吗?
try {
UsbManager mUsbManager = (UsbManager) BoardActivity.ctx.getSystemService(Context.USB_SERVICE);
UsbInterface intf = device.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = mUsbManager.openDevice(device);
connection.claimInterface(intf, true);
byte[] bytes = new byte[2048];
//UsbRequest usbRequest = new UsbRequest();
//usbRequest.initialize(connection, endpoint);
//ByteBuffer bytesBuff = ByteBuffer.wrap(bytes);
while (true) {
//usbRequest.queue(bytesBuff, bytes.length);
//connection.requestWait();
int len = connection.bulkTransfer(endpoint, bytes, bytes.length, 0);
//Log.d("USB_TEST", Util.bytesToHex(bytes, bytes.length));
Log.d("USB_TEST", Util.bytesToHex(bytes, len));
Thread.sleep(1000);
}
} catch (Exception e) {}
;
我也尝试过来自GitHub的库FTDriver(https://github.com/ksksue/FTDriver),但结果相同,连接建立正确,数据以预期的时间和长度流动,但bytebuffer中的每个值都为零。
FTDriver mUSBSerial = new FTDriver((UsbManager) BoardActivity.ctx.getSystemService(Context.USB_SERVICE));
mUSBSerial.usbAttached(intent);
boolean connOk = mUSBSerial.begin(FTDriver.BAUD115200);
Log.i(TAG_USB, "Connestion result " + connOk);
答案 0 :(得分:0)
通过USB进行通信并不是那么简单,没有细节,很难确切地说出问题所在(我没有你的硬件)。但是,在这里我给出了部分代码(它是c#+ xamarin),以获得所有你需要解决的灵感。
简而言之:您需要找到USBDevice获取许可证,设置ControlTransfer(为您的硬件正确使用RequestType和BaudRate),开始通信并使用临时缓冲区以便以后快速读取和处理数据以及大量调试和测试。< / p>
在Res.xml.device_filter.xml
中<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- POZOR, aby proslo buildem, musim v properties tohoto souboru nastavit BuildAction na AndroidResource -->
<!--<usb-device vendor-id="0403" product-id="6001" /> FTDI FT232R UART in hexa-->
<usb-device vendor-id="1027" product-id="24577" />
<!--FTDI FT232R UART in decimal-->
</resources>
代码
private UsbManager USBManager = null;
private UsbDevice USBDevice = null;
private UsbDeviceConnection USBConnection = null;
private UsbEndpoint USBEndPointRead = null;
private UsbEndpoint USBEndPointWrite = null;
private Object InternalBufferReadLock = new Object();
private Object TempBufferReadLock = new Object();
private Object BufferReadLock = new Object();
private Object WriteBufferLock = new Object();
private byte[] InternalBufferRead = new byte[UsbPacketSize];
private byte[] TempBufferRead = new byte[UsbPacketSize];
private byte[] BufferRead = new byte[UsbBufferSize];//This buffer used cursor BufferReadWriteCursor/BufferReadReadCursor
private int BufferReadWriteCursor = 0;
private int BufferReadReadCursor = 0;
private const int UsbBaudRate = 26;// baudrate speed-hexa-int9600-0x4138-16696, 19200-0x809C-32924, 115200-0x001A-26, 230040-0x000D-13,460800-0x4006-16390,921600-0x8003-32771
private const int UsbPacketSize = 64;
private const int UsbBufferSize = 65536;
private volatile bool ContinueCycle = false;
private void PrepareCommunication(UsbDevice pUsbDevice, bool pFromActivity)
{
Utils.MyLog("USB", "PrepareCommunication", 1, "pUsbDevice=" + pUsbDevice + ", pFromActivity=" + pFromActivity);
if (USBManager == null)
{
object obj = this.GetSystemService(Context.UsbService);
if (obj != null && obj is UsbManager)
{
USBManager = (UsbManager)obj;
Utils.MyLog("USB", "PrepareCommunication", 0, "USBManager OK");
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "USBManager NOT FINDED");
}
if (USBManager != null)
{
if (pUsbDevice != null)
{//If I get it from BroadcastReceiver intent android.hardware.usb.action.USB_DEVICE_ATTACHED
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice from broadcast ATTACHED USB");
USBDevice = pUsbDevice;
}
if (USBDevice == null)
{//If I have not I'll find
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice is null, try find someone");
if (USBManager.DeviceList != null && USBManager.DeviceList.Count > 0 && USBManager.DeviceList.Values != null && USBManager.DeviceList.Values.Count > 0)
{
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice DeviceList contains something");
ICollection<UsbDevice> deviceIterator = (ICollection<UsbDevice>)USBManager.DeviceList.Values;
if (deviceIterator.Count > 1) Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice DeviceList.Values.Count=" + USBManager.DeviceList.Values.Count);
foreach (UsbDevice tmpUsbDevice in deviceIterator)
{
USBDevice = tmpUsbDevice;//Beru pouze prvni.
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice FINDED from deviceIterator");
break;
}
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice NOTHING in DeviceList");
}
if (USBDevice != null)
{
if (!USBManager.HasPermission(USBDevice))
{
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice HAS NOT PERMISSION YET send request permission");
PendingIntent permissionIntent;
permissionIntent = PendingIntent.GetBroadcast(ApplicationContext, 0, new Intent("EVOAndroidUSBService.EVOAndroidUSBService.UsbServiceUnit.USB_PERMISSION"), 0);
USBManager.RequestPermission(USBDevice, permissionIntent);//User confirm permission and the broadcast delivered the intent and than must re-run this method. Then he will have permission
}
else
{
Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice HAS PERMISSION YET");
if (USBConnection == null)
{
Utils.MyLog("USB", "PrepareCommunication", 0, "USBConnection is null, try create by OpenDevice");
USBConnection = USBManager.OpenDevice(USBDevice);
}
if (USBConnection != null)
{//It is an open connection, so I find the interface and EndPoint ...
UsbInterface usbInterface = USBDevice.GetInterface(0);
if (usbInterface != null)
{
UsbEndpoint usbEndpoint1 = usbInterface.GetEndpoint(0);
UsbEndpoint usbEndpoint2 = usbInterface.GetEndpoint(1);
if (usbEndpoint1 != null && usbEndpoint1.Direction == UsbAddressing.In)
{//input endpoint
USBConnection.ControlTransfer((UsbAddressing)64, 0, 0, 0, null, 0, 0);// reset mConnection.controlTransfer(0×40, 0, 1, 0, null, 0, 0);//clear Rx
USBConnection.ControlTransfer((UsbAddressing)64, 0, 1, 0, null, 0, 0);// clear Rx
USBConnection.ControlTransfer((UsbAddressing)64, 0, 2, 0, null, 0, 0);// clear Tx
USBConnection.ControlTransfer((UsbAddressing)64, 3, UsbBaudRate, 0, null, 0, 0);// baudrate speed-hexa-int 115200-0x001A-26, 9600-0x4138-16696, 19200-0x809C-32924, 230040-0x000D-13
USBConnection.ControlTransfer((UsbAddressing)64, 2, 0, 0, null, 0, 0);// flow control none
USBConnection.ControlTransfer((UsbAddressing)64, 4, 8, 0, null, 0, 0);// data bit 8, parity none, stop bit 1, tx off
USBEndPointRead = usbEndpoint1;//Zkusim prvne bez spozdeni rovnou.
}
if (usbEndpoint2 != null && usbEndpoint2.Direction == UsbAddressing.Out)
{//output endpoint
USBEndPointWrite = usbEndpoint2;
}
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "usbInterface IS NULL");
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "USBConnection IS STILL NULL");
}
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "USBDevice IS STILL NULL");
}
else Utils.MyLog("USB", "PrepareCommunication", 0, "USBManager IS STILL NULL");
if (USBEndPointRead != null && USBConnection != null && USBDevice != null)
{//StartCommunication in other thread
if (!ContinueCycle) ThreadPool.QueueUserWorkItem(o => StartCommunication());
}
}
private void StartCommunication()
{
ContinueCycle = true;
while (ContinueCycle)
{
if (USBEndPointRead != null && USBConnection != null)
{
int rxlen;
lock (InternalBufferReadLock)
{//only quickly read and save to TempBufferRead
rxlen = USBConnection.BulkTransfer(USBEndPointRead, InternalBufferRead, InternalBufferRead.Length, 0);
Array.Copy(InternalBufferRead, TempBufferRead, rxlen);
}
if (rxlen > 2)//FTDI chip keeps sending 2 status byte, regardless of whether or not the data (if the data is the same as at the beginning of status byte ...) with an interval of approx. 16ms
{//if it is more than 2 bytes than the data exists
lock (BufferReadLock)
{//Put data into MainBuffer
for (int i = 2; i < rxlen; i++)
{
BufferRead[BufferReadWriteCursor] = TempBufferRead[i];//and then once a while (eg. the timer) you read data from MainBufferu and process .
BufferReadWriteCursor++;
}
}
}
}
}
}