none
Retrieving custom sensor values through a Win8/win8.1 desktop applications RRS feed

  • Question

  • Hi,

    I am trying to develop an windows desktop application to retrieve and display the data values of a custom sensor.The values are being displayed in SDT (Sensor diagnostics tool perfectly) but not in my application.

    The Sensor manager is detecting the custom sensor, sensor collection is also fine, but sensor report returns property not found when i execute the following code

    "hr = pReport->GetSensorValue(SENSOR_DATA_TYPE_CUSTOM_VALUE1, &var);"

    I am also putting my full code(removed a few debug statements) here:

    "

    #include "stdafx.h"
    #include <initguid.h>
    #include "Sensorsapi.h"
    #include "Sensors.h"


    #include <iostream>
    using namespace std;

    ISensorManager* pSensorManager; 
    ISensorCollection* pSensorColl;
    ISensor* pSensor; 
    ISensorDataReport* pReport;


    int _tmain(int argc, _TCHAR* argv[])
    {
    CoInitialize(NULL);
    HRESULT hr = CoCreateInstance(CLSID_SensorManager, 
    NULL, CLSCTX_INPROC_SERVER,
    IID_PPV_ARGS(&pSensorManager));
    cout<<hr<<endl;
    //printf("%0x",hr);
    if(hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DISABLED_BY_POLICY))
    {
    // Unable to retrieve sensor manager due to 
    // group policy settings. Alert the user.
    cout<<"error!1"<<endl;
    return hr;
    }
    cout<<hr<<endl;
    if(FAILED(hr)){
    return hr;
    }

    //hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_ACCELEROMETER_3D, &pSensorColl);
    //hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_GYROMETER_3D, &pSensorColl);
    hr = pSensorManager->GetSensorsByType(SENSOR_TYPE_CUSTOM, &pSensorColl);
    cout<<hr<<endl;
    if (FAILED(hr))
    {
    printf("No Custom Sensor");
    return hr;
    }
    ULONG ulCount = 0;
    hr = pSensorColl->GetCount(&ulCount);

    if (FAILED(hr))
    {
    printf("No Custom Sensor");
    return hr;
    }



    hr = pSensorColl->GetAt(0, &pSensor);

    if(SUCCEEDED(hr)){
    hr = pSensor->SetEventSink(NULL);
    }
    else
    {
    printf("failed here first\n");
    }

    hr = pSensor->GetData(&pReport);
    cout<<hr<<endl;

    if(SUCCEEDED(hr))
    {
    PROPVARIANT var = {};

    hr = pReport->GetSensorValue(SENSOR_DATA_TYPE_CUSTOM_VALUE1, &var);
    cout<<hr<<endl;
    //cout<<"the error value for not found is  :"<<HRESULT_FROM_WIN32(ERROR_NOT_FOUND)<<endl;
    if(SUCCEEDED(hr))
    {
    printf("Custom sensor data is %f\n",var.dblVal);//var.dblVal);
    }
    else
    {
    printf("failed\n");
    }
    PropVariantClear(&var);
    hr = pReport->GetSensorValue(SENSOR_DATA_TYPE_CUSTOM_VALUE2, &var);
    cout<<hr<<endl;
    if(SUCCEEDED(hr))
    {
    printf("%f",var.dblVal);
    cout<<"custom data is "<<var.dblVal<<endl;
    }

    PropVariantClear(&var);
    hr = pReport->GetSensorValue(SENSOR_DATA_TYPE_CUSTOM_VALUE3, &var);
    cout<<hr<<endl;

    if(SUCCEEDED(hr))
    {
    printf("%f",var.dblVal);
    cout<<"custom data is "<<var.dblVal<<endl;
    }
    }

    CoUninitialize();
    return 0;
    }

    Note: I am also having other sensors on board, and i am able to read their data values properly.

    • Edited by ArMD Thursday, December 19, 2013 4:22 AM
    Wednesday, December 18, 2013 6:12 AM

Answers

  • The behavior of synchronous reads for dynamic data fields (for any sensor including custom) is undefined and a known limitation in Windows 8. It has been fixed in Windows 8.1.

    This posting is provided AS IS with no warranties, and confers no rights.

    Tuesday, January 7, 2014 7:29 PM

All replies

  • Your code looks correct for retrieving the property.  Do you have tracing for the driver for your custom sensor?  Have you verified that you are always populating the data?  You might also want to make sure that the sensor state is SENSOR_STATE_READY before reading data.

    This posting is provided "AS IS" with no warranties, and confers no rights.

    Wednesday, December 18, 2013 6:46 PM
  • ISensor::GetData synchronously queries the latest data from the driver and will ultimately call ISensorDriver::OnGetSupportedDataFields then ISensorDriver::OnGetDataFields. Is it possible OnGetSupportedDataFields is not returning SENSOR_DATA_TYPE_CUSTOM_VALUE1 or OnGetDataFields is not populating the value? The SensorDiagnosticTool uses asynchronous data events, which the driver may populate differently before calling ISensorClassExtension::PostEvent. Note you can issue a synchronous data request from SDT using Refresh Data -> Execute to see if all expected data fields are present.

    This posting is provided AS IS with no warranties, and confers no rights.

    • Marked as answer by Doron Holan [MSFT] Tuesday, December 24, 2013 5:00 AM
    • Unmarked as answer by ArMD Saturday, January 4, 2014 4:55 AM
    Wednesday, December 18, 2013 7:16 PM
  • "SDT" is reading the data properly,so i cannot doubt my custom sensor driver. Again if the sensor states are not appropriate,SDT would have not read the data.

    There is some issue in my application with regard to custom sensor. As I am able to call the data fields of all the other sensors on board (for instance, Accelerometer, i am able to retrieve its data fields).


    • Edited by ArMD Thursday, December 19, 2013 6:36 AM
    Thursday, December 19, 2013 6:34 AM
  • The SDT is reading the data from an asynchronous report, which may trigger a different code path in your driver.  Have you tried to read the data multiple times?  Does it eventually populate with data?  I definitely recommend adding code to check the sensor state using this API:

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd318878(v=vs.85).aspx


    This posting is provided "AS IS" with no warranties, and confers no rights.


    Thursday, December 19, 2013 10:01 PM
  • I checked the sensor state,its fine(pstate is sensor ready).

    The only supported datafield it is showing is time-stamp, when i do a check for supported data fields.

    Tuesday, December 24, 2013 4:36 AM
  • Even i believe this is the issue. I am trying to read data asynchronously, but how to check if an event has happened is not clear from:

    http://msdn.microsoft.com/en-us/library/windows/desktop/dd319014(v=vs.85).aspx

    I am still trying to implement it, but as of now i am still getting some error while trying to retrieve data.

    Tuesday, December 24, 2013 4:46 AM
  • Your application must implement ISensorEvents (http://msdn.microsoft.com/en-us/library/windows/desktop/dd318944(v=vs.85).aspx) and call ISensor::SetEventSink to request event updates. When the sensor driver posts a data event, OnDataUpdated will be called. The link you shared above illustrates the required code.

    This posting is provided AS IS with no warranties, and confers no rights.

    Thursday, January 2, 2014 5:55 PM
  • Is there anyway we can get data from custom sensor by reading synchronously?

    I am able to get data asynchronously but when i try to do synchronously it gets only time stamp.

    Friday, January 3, 2014 8:41 AM
  • Yes, it sounds like there is a bug in the custom sensor driver. Please see the earlier responses in this thread for how to debug the problem and query data synchronously.

    This posting is provided AS IS with no warranties, and confers no rights.

    Friday, January 3, 2014 5:04 PM
  • But with the same sensor device and same application, i am able to read synchronously from Win 8.1 but its failing in Win8.0, so i dont doubt the sensor driver.

    From HID sensor Usages document:

    http://msdn.microsoft.com/en-us/library/windows/hardware/hh975383.aspx

    The document says the following -

    "Like the optional datafield, these dynamic datafields are not actually available at the API until an input report bearing the data for a dynamic datafield defined in the input report descriptor is actually received by the driver. When such an input report is received by the driver, that datafield is added to the list of datafields supported by the driver for that sensor and is then available at the API. "For custom sensors all fields are optional fields, since i am using SENSOR_DATA_TYPE_CUSTOM_VALUE.

    So does this mean i can read custom sensors only aynchronously(Win 8.0 scenario)? But then, how is synchronous read working for Win8.1?

    Could you please clarify?

    • Edited by ArMD Tuesday, January 7, 2014 6:41 AM
    Saturday, January 4, 2014 4:54 AM
  • There were a number of improvements made to the HID Sensor Class Driver in Windows 8.1, including how custom input reports are handled. Synchronous read works as expected in 8.1 (as you have observed).

    This posting is provided AS IS with no warranties, and confers no rights.

    Monday, January 6, 2014 6:11 PM
  • Thanks Andrew.

    Could you please clarify if synchronous reads will work for custom sensor input report (which has all optional fields) in Win8.0?

    • Edited by ArMD Tuesday, January 7, 2014 6:42 AM
    Tuesday, January 7, 2014 6:41 AM
  • The behavior of synchronous reads for dynamic data fields (for any sensor including custom) is undefined and a known limitation in Windows 8. It has been fixed in Windows 8.1.

    This posting is provided AS IS with no warranties, and confers no rights.

    Tuesday, January 7, 2014 7:29 PM
  • Thanks for the confirmation.

    Wednesday, January 8, 2014 6:39 AM