从Android设备上的USB通信获取空数据

从Android设备上的USB通信获取空数据,android,usb,communication,Android,Usb,Communication,我正在开发Android应用程序,它应该通过USB与我的硬件通信。我已经建立了连接,但所有接收到的数据似乎都是空的,但长度正确(我的硬件输出应该没有问题,通过WiFi、BT、COM测试,一切正常)。有人看到我下面列出的代码有什么问题吗 try { UsbManager mUsbManager = (UsbManager) BoardActivity.ctx.getSystemService(Context.USB_SERVICE);

我正在开发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(),但结果相同,连接建立正确,数据流在预期的周期和长度内,但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);

通过USB进行通信并不是那么简单,如果没有细节,很难说问题出在哪里(我没有你的硬件)。然而,在这里我给出了部分代码(它是c#+xamarin)作为灵感,你需要解决什么问题

简而言之:您需要找到USBDevice获得许可证,设置ControlTransfer(为您的硬件提供正确的RequestType和波特率),开始通信并使用临时缓冲区,以便稍后快速读取和处理数据,以及进行大量调试和测试

在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;
专用UsbDevice UsbDevice=null;
专用UsbDeviceConnection USBConnection=null;
专用UsbEndpoint USBEndPointRead=null;
专用UsbEndpoint USBEndPointWrite=null;
私有对象InternalBufferReadLock=新对象();
私有对象TempBufferReadLock=新对象();
私有对象BufferReadLock=新对象();
私有对象WriteBufferLock=新对象();
私有字节[]InternalBufferRead=新字节[UsbPacketSize];
私有字节[]TempBufferRead=新字节[UsbPacketSize];
私有字节[]BufferRead=新字节[UsbBufferSize]//此缓冲区使用游标BufferReadWriteCursors或/BufferReadCursor
private int BufferReadWriteCursor=0;
私有int bufferReadCursor=0;
私有常量int UsbBaudRate=26;//波特率速度-hexa-int9600-0x4138-16696、19200-0x809C-32924、115200-0x001A-26、230040-0x000D-13460800-0x4006-16390921600-0x8003-32771
private const int UsbPacketSize=64;
私有常量int UsbBufferSize=65536;
private volatile bool ContinueCycle=false;
专用无效准备通信(UsbDevice pUsbDevice、bool pFromActivity)
{
Utils.MyLog(“USB”,“准备通信”,1,“pUsbDevice=“+pUsbDevice+”,pFromActivity=“+pFromActivity”);
如果(USBManager==null)
{
object obj=this.GetSystemService(Context.UsbService);
如果(obj!=null&&obj是UsbManager)
{
USBManager=(USBManager)obj;
Utils.MyLog(“USB”,“准备通信”,0,“USBManager正常”);
}
else Utils.MyLog(“USB”,“准备通信”,0,“未找到USBManager”);
}
如果(USBManager!=null)
{
if(pUsbDevice!=null)
{//如果我从BroadcastReceiver获得它,请连接android.hardware.usb.action.usb\u设备
Utils.MyLog(“USB”,“准备通信”,0,“来自广播连接USB的USB设备”);
USBDevice=pusbevice;
}
如果(USBDevice==null)
{//如果我没有,我会找到的
Utils.MyLog(“USB”,“PrepareCommunication”,0,“USBDevice为空,请尝试查找某人”);
如果(USBManager.DeviceList!=null&&USBManager.DeviceList.Count>0&&USBManager.DeviceList.Values!=null&&USBManager.DeviceList.Values.Count>0)
{
MyLog(“USB”,“PrepareCommunication”,0,“USBDevice DeviceList包含某些内容”);
ICollection deviceIterator=(ICollection)USBManager.DeviceList.Values;
如果(deviceIterator.Count>1)Utils.MyLog(“USB”,“PrepareCommunication”,0,“USBDevice DeviceList.Values.Count=“+USBManager.DeviceList.Values.Count”);
foreach(设备计数器中的USB设备TMP设备)
{
USBDevice=tmpUsbDevice;//Beru pouze prvni。
Utils.MyLog(“USB”,“准备通信”,0,“从设备计数器查找的USB设备”);
打破
}
}
else-Utils.MyLog(“USB”,“PrepareCommunication”,0,“设备列表中无USB设备”);
}
如果(USBDevice!=null)
{
如果(!USBManager.HasPermission(USBDevice))
{
Utils.MyLog(“USB”,“PrepareCommunication”,0,“USBDevice尚未获得发送请求权限”);
悬而未决的许可意向;
permissionIntent=pendingent.GetBroadcast(ApplicationContext,0,新Intent(“EVOAndroidUSBService.EVOAndroidUSBService.usbservice.UsbServiceUnit.USB_PERMISSION”),0);
USBManager.RequestPermission(USBDevice,permissionIntent);//用户确认权限,广播传递了意图,然后必须重新运行此方法。然后他将拥有权限
}
其他的
{
Utils.MyLog(“USB”,“PrepareCommunication”,0,“USBDevice尚未获得许可”);
if(USBConnection==null)
{
MyLog(“USB”,“PrepareCommunication”,0,“USBC连接为空,请尝试通过OpenDevice创建”);
USBConnection=USBManager.OpenDevice(USBDevice);
}
if(USBConnection!=null)
{//这是一个开放连接,因此我发现接口和端点。。。
UsbInterface UsbInterface=USBDevice.GetInterface(0);
if(usbInterface!=null)
{
UsbEndpoint UsbEndpoint 1=usbInterface.GetEndpoint(0);
UsbEndpoint UsbEndpoint 2=usbInterface.GetEndpoint(1);
if(usbEndpoint1!=null&&usbEndpoint1.Direction==usbadstoring.In)
{//输入端点
USBConnection.ControlTransfer((usbadstoring)64,0,0,0,null,0,0);//重置mConnection.ControlTransfer(0×40,0,1,0,null,0,0);//清除Rx
ControlTransfer((usbadTransfer)64,0,1,0,null,0,0);//清除Rx
ControlTransfer((usbadstoring)64,0,2,0,null,0,0);//清除Tx
ControlTransfer((usbadstoring)64,3,UsbBaudRate,0,null,0,0);//波特率速度hexa-
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++;
          }
        }
      }
    }
  }
}