使用光传感器数据

有两种建议的方法来解释和使用来自环境光传感器的照度数据。

  • 对数据应用转换,以便规范化光级别可以与程序行为或交互直接成比例使用。 例如,根据规范化数据 (或规范化数据范围(对应于户外)(例如) )直接改变程序中按钮的大小。 此方法提供最佳实现。
  • 处理照度数据的范围,并将程序行为和反应映射到这些照度数据范围的上限和下限阈值。 这是响应照明条件的简单方法,可能不会提供最佳用户体验。 但是,如果平滑转换不可行,此方法可以正常工作。

处理来自多个光传感器的数据

若要生成当前照明条件的最准确近似值,可以使用来自多个环境光传感器的数据。 由于环境光传感器可能部分或完全被覆盖传感器的阴影或物体遮盖,因此将多个传感器相隔一定距离可以提供比单个传感器更好的当前照明条件的近似值。

若要跟踪来自多个传感器的数据,可以使用以下两种方法:

  • 可以保留每个环境光传感器的最新数据值,以及每个读数的传感器数据报告中的时间戳。 可以保留针对每个传感器读数收到的最后 一个 ISensorDataReport ,并可以提供这两个值供以后参考。 通过引用每个传感器数据报表的时间戳,可以根据数据年限管理数据。 例如,如果数据超过 2 秒,则可省略它。 根据较新的传感器数据值,可以使用最高读数,因为假定相应的传感器不会被遮盖。
  • 可以使用报告的最后一个环境光传感器值。 此实现不是最佳方案,因为多个传感器的值不会相互比较以获得最准确的结果。 不建议使用此方法。

示例代码

以下示例代码演示 OnDataUpdated 事件的实现。 事件处理程序调用名为 UpdateUI 的帮助程序函数,该函数根据 lux 值更改用户界面。 编写 UpdateUI 的实现由你决定。

// Override of ISensorEvents::OnDataUpdated
// Part of an event sink implementation for ISensorEvents
STDMETHODIMP CALSEventSink::OnDataUpdated(
    ISensor* pSensor, 
    ISensorDataReport* pNewData)
{
    HRESULT hr = S_OK;
   
    if(pSensor == NULL ||
       pNewData == NULL)
    {
         return E_POINTER;
    }

    // Declare and initialize the PROPVARIANT
    PROPVARIANT lightLevel;
    PropVariantInit(&lightLevel);

    // Get the sensor reading from the ISensorDataReport object
    hr = pNewData->GetSensorValue(
        SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX, 
        &lightLevel);

    if(SUCCEEDED(hr))
    {
        if(lightlevel.vt == VT_R4)
        {
            // Extract the float value from the PROPVARIANT object
            float luxValue = lightLevel.fltVal;

            // Normalize the light sensor data
            double lightNormalized = ::log10(luxValue) / 5.0;

            // Handle UI changes based on the normalized LUX data
            // which ranges from 0.0 - 1.0 for a lux range of 
            // 0 lux to 100,000 lux. 
            UpdateUI(lightNormalized);
        }
    }

    // Release the variant.     
    PropVariantClear(&lightLevel);

    return hr;
}