【问题标题】:Retrieving info from multiple sensors using Windows Sensor API使用 Windows Sensor API 从多个传感器检索信息
【发布时间】:2019-06-17 11:39:42
【问题描述】:

我正在使用 Windows Sensor API 从各种传感器(包括加速度计和陀螺仪)获取信息。 (https://docs.microsoft.com/en-us/windows/desktop/sensorsapi/sensor-api-programming-guide)

我的加速度计传感器驱动程序的初始实现工作正常 - 我可以异步获取该传感器的值。

单个传感器(加速度计)的工作初始化代码如下所示:

void initialize1(AccelerometerCallBack callBack) {

    HRESULT hr = S_OK;
    CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);

    ISensorManager* pSensorManager = NULL;
    ISensorCollection* pSensorColl = NULL;
    ISensor* accelerometer = NULL;

    hr = CoCreateInstance(CLSID_SensorManager,
        NULL, CLSCTX_INPROC_SERVER,
        IID_PPV_ARGS(&pSensorManager));

    if (SUCCEEDED(hr))
    {
        printf("Succeeded getting Sensor...\n");
        ULONG ulCount = 0;
        // Verify that the collection contains
        // at least one sensor.
        hr = pSensorColl->GetCount(&ulCount);
        if (SUCCEEDED(hr))
        {
            if (ulCount < 1)
            {
                wprintf_s(L"\nNo sensors of the requested category.\n");
                hr = E_UNEXPECTED;
            }
        }
    }
    else {
        printf("Failed to get Sensor...\n");
    }

    if (SUCCEEDED(hr))
    {
        // Get the first available sensor.
        hr = pSensorColl->GetAt(0, &accelerometer);

        BSTR name = 0;
        hr = accelerometer->GetFriendlyName(&name);
        wprintf(L"%s\n", name);
    }

    AccelerometerEvent* pEventClass = NULL;
    ISensorEvents* pMyEvents = NULL;
    if (SUCCEEDED(hr))
    {
        // Create an instance of the event class.
        pEventClass = new(std::nothrow) AccelerometerEvent();
        pEventClass->globalCallBack = callBack;
    }

    if (SUCCEEDED(hr))
    {
        // Retrieve the pointer to the callback interface.
        hr = pEventClass->QueryInterface(IID_PPV_ARGS(&pMyEvents));
    }

    if (SUCCEEDED(hr))
    {
        // Start receiving events.
        hr = accelerometer->SetEventSink(pMyEvents);
    }

    MSG msg;
    BOOL bRet;
    while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
    {
        if (bRet == -1)
        {
        // handle the error and possibly exit
        }
        else
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
}

现在我想同时获取陀螺仪,所以我添加了类似的初始化代码:

void initialize2(GyroscopeCallBack callBack);,其作用与上述类似。

现在我的 C# 层会像这样触发这些代码:

internal void Start()
{
    AccelerometerCallBack myCallBack1 = new AccelerometerCallBack(onAccelerometerDataChanged);
    initialize1(myCallBack1);

    GyroscopeCallBack myCallBack2 = new GyroscopeCallBack(onGyroscopeDataChanged);
    initialize2(myCallBack2);
}

但是,只有加速度计信息是通过回调接收的,而不是陀螺仪的。

  • 我已确认我的设备具有正确类型的两个传感器
  • 我已经确认我的回调函数和 C# 到 C++ 接口都可以正常工作

使用 Windows 传感器 API“获取”多个传感器(而不是一个)的正确方法是什么?

官方网站上没有关于这样做的示例,唯一相关的SO帖子(Exposing multiple sensors on a single device to Windows Sensor API)也没有帮助。谢谢!

【问题讨论】:

  • 如果只加载陀螺仪,是否有效?尝试使用传感器诊断工具来验证它不是硬件限制。传感器可以一起加载。
  • 您所展示的只是创建ISensorManager COM 对象的代码,而不是任何实际使用它的代码,或设置各个传感器及其事件接收器,或处理其事件的代码.请提供一个 minimal reproducible example 来证明您的问题在行动中。
  • 代码“在这里做更多”是什么?里面有没有类似while(true) 或其他循环的东西?你能确保程序实际运行到new GyroscopeCallBack()这一行吗?
  • @Michael 如果我只加载陀螺仪,它确实可以工作。
  • @JohnW 您根本不应该在传感器初始化函数中调用CoInitializeEx。这属于您的应用程序启动代码。但主要问题是,您甚至在触摸陀螺仪之前就已经为加速度计完成了所有工作。这很容易解决,只需将代码分解一下即可。创建 1 个 SensorManager,然后为其中的两个传感器设置事件接收器,然后运行消息循环。您的初始化函数不仅仅是初始化,还需要将消息循环从它们中取出并单独处理。

标签: c++ winapi com sensors


【解决方案1】:

成功了!解决方案是删除消息泵并为Coinitializine() 使用COINIT_MULTITHREADED 选项。感谢大家的帮助。

【讨论】:

    猜你喜欢
    • 2020-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多