0

我的项目是从我的汽车方向盘控件中读取按钮输入,并将它们(使用类似 Teensy 3.2 Arduino)转换为我选择的 android 系统操作(例如提高音量、下一曲目、OK Google)。

为了解决这个问题,我尝试了 Teensy 提供的几种不同模式,最初是作为键盘仿真,然后是操纵杆仿真,最后是 Raw HID 设备。所有这些模式都可以在 Windows 和 Linux 上完美运行,但不能在 android 上运行(我已经在运行 Android 4.1 的目标设备和 Android 5 设备上尝试过,两者都不起作用)。

我设法使这项工作最接近的方法是作为带有我编写的小应用程序的 RawHID 设备来解码数据包并转换为系统操作。这实际上有效......大约 2-5 按钮按下。然后什么都没有。为了让我的下一个 2-5 按钮按下,我必须拔下设备并重新启动程序。程序在thisConnection 上停止。requestWait ()永远。在旧版本中,我使用了 bulkTransfer,它具有类似的效果,在按下 2-5 次按钮后永久返回 -1 并且没有数据。

OpenConnection 的代码:

    public boolean OpenConnection(UsbManager pUsbManager)
    {

        if(ActiveDevice == null) return false;
        if(!hasPermission) return false;
        if(ActiveConnection != null && ActiveEndpoint != null) return true;

        if(hasAssociatedUsbDevice()) {

            ActiveInterface = ActiveDevice.getInterface(InterfaceIndex);
            ActiveEndpoint = ActiveInterface.getEndpoint(EndpointIndex);
            ActiveConnection = pUsbManager.openDevice(ActiveDevice);
            ActiveConnection.claimInterface(ActiveInterface, true);
            ActiveRequest = new UsbRequest();
            ActiveRequest.initialize(ActiveConnection,ActiveEndpoint);

            return true;
        }

        return false;
    }

设备循环代码(在单独的低优先级线程上运行)

private void deviceLoop(Config.HIDDevice pHIDDevice)
{

    try
    {
        if (!pHIDDevice.OpenConnection(mUsbManager)) return;


        ByteBuffer dataBufferIn = ByteBuffer.allocate(64);

        //String activeAppName = mAppDetector.getForegroundAppName(); //TODO: Refactor, causing excessive memory alloc


        String activeAppName = null;

        Config.AppProfile activeProfile = pHIDDevice.getAppProfile(activeAppName);

        while (!mExitDeviceThreads)
        {
            UsbDeviceConnection thisConnection = pHIDDevice.getActiveConnection();
            if (thisConnection == null) break; //connection dropped

            UsbRequest thisRequest = pHIDDevice.getActiveRequest();
            if (thisRequest == null) break; //connection dropped 

            thisRequest.queue(dataBufferIn, dataBufferIn.capacity());

            if (thisConnection.requestWait() == thisRequest)
            {
                byte[] dataIn = dataBufferIn.array();

                for (Config.ButtonPacketMapping thisButtonMapping : pHIDDevice.getButtonPacketMappings())
                {
                    if (thisButtonMapping.Update(dataIn))
                    {
                        for (Config.ButtonAction thisButtonAction : activeProfile.getButtonActions(thisButtonMapping.getName()))
                        {
                            if (thisButtonMapping.getLastValue() == false && thisButtonMapping.getValue() == true)
                            {
                                if (thisButtonAction.buttonAction == Config.ButtonAction.eButtonActionType.Press)
                                {
                                    thisButtonAction.Set();
                                }
                            }
                            else if (thisButtonMapping.getLastValue() == true && thisButtonMapping.getValue() == false)
                            {
                                if (thisButtonAction.buttonAction == Config.ButtonAction.eButtonActionType.Release)
                                {
                                    thisButtonAction.Set();
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                break; //Connection dropped or something went very wrong
            }
        }
    }
    finally
    {
        pHIDDevice.CloseConnection();
    }
}

所以我的问题更简洁的是:

有没有人设法让 Teensy Arduino 通过 USB 以任何方式与 Android 交互?我的 HID 方法有什么问题会导致这个“停滞”问题吗?

4

1 回答 1

0

最后,我切换到具有原生 USB 支持的Arduino Pro Micro,并使用“消费者设备”方法使用Project-HID 库。这适用于我尝试过的任何操作系统/硬件组合。

于 2017-10-05T12:28:28.117 回答