Introduction
The Sensor API is a simple Windows 7 ActiveX interface that allows you to communicate with sensors. Sensors can detect light, temperature, electricity, location (GPS), motion and so on. (The supported list of categories is available in MSDN).
You need
Where to Find Sensors?
In the SDK, there is a Virtual Light Sensor that can simulate a light sensor. As Windows 7 is released, more and more devices will support the Sensors abstraction API.
In my site, I've also created a GPS Sensor Driver that reads actual GPS data from a COM port. Read more here.
Overview
The sample here provides code for both full (explorer) sensor capabilities and also a simple SENSOR
namespace that implements sensors in a library you can use. The steps for the full explorer are:
- Call
CoCreateInstance()
to instantiate an ISensorManager
. - Call
ISensorManager::GetSensorsByCategory
using the requested category (all categories in MSDN). - From the returned
ISensorCollection
, call GetCount()
to get the number of sensors in that category, then call GetAt()
to retrieve an ISensor
. - Use
ISensor
methods to learn about the sensor properties, type, ID etc. - To get the supported data fields, call
ISensor::GetSupportedDataFields()
. - Use
GetCount()
and GetAt()
from the returned IPortableDeviceCollection
to get the data fields. - Use
ISensor::GetData()
to retrieve the current data in a ISensorDataReport
. - Use
ISensorDataReport::GetSensorValue
to get a specific value, use ISensorDataReport::GetTimestamp
to return the time at which the data was collected.
Sensors are disabled by default, so you may have to call ISensorManager::RequestPermissions
if you get an access denied error when retrieving the sensor state.
All this stuff is used in main.cpp.
Sensor Manager Events
The Sensor Manager can notify you when something occurs. Implement an ISensorManagerEvents
, then pass it to ISensorManager::SetEventSink
. Currently, this interface implements the OnSensorEnter()
function which is called when a sensor is available.
Sensor Events
The Sensor can notify you when something occurs. Implement an ISensorEvents
, then pass it to ISensor::SetEventSink
, then call ISensor::SetEventInterest
to indicate the types of notifications you want to receive. Currently, ISensorEvents
implements four member functions which notify you when an event occurs, when data is changed, when state is changed, and when the sensor is disabled.
Using an Actual Sensor
The Virtual Light sensor is OK for testing purposes, but we need real data. I've created a small sample driver project, GPSDirect, which can read and parse actual GPS information from a COM port (Bluetooth, USB etc.). This driver currently supports parsing GGA and RMC sentences to provide position information.
SensorLib
In case you just want a simple interface, you can use my senslib* project and the SENSOR
namespace. This currently implements a SENSOR
and a LIGHTSENSOR
class to be used as follows:
INT_PTR CALLBACK D_DP(HWND hh,UINT mm,WPARAM ww,LPARAM ll)
{
HWND hT = GetDlgItem(hh,701);
HWND hL2 = GetDlgItem(hh,902);
static SENSOR::LIGHTSENSOR* ls = 0;
switch(mm)
{
case WM_INITDIALOG:
{
SetClassLongPtr(hh,GCLP_HICONSM,(LONG_PTR)hIcon1);
SetClassLongPtr(hh,GCLP_HICON,(LONG_PTR)hIcon1);
if (!SENSOR::InitializeSensorManager())
{
EndDialog(hh,-1);
break;
}
ls = new SENSOR::LIGHTSENSOR(hh,WM_USER);
break;
}
case WM_USER:
{
if (ww == 0)
{
SENSOR::SENSOR_DATA* data = (SENSOR::SENSOR_DATA*)ll;
if (data)
{
for(unsigned int i = 0 ; i < data->Num ; i++)
{
if (data->keys[i] == SENSOR_DATA_TYPE_LIGHT_LEVEL_LUX)
{
TCHAR x[100];
_stprintf(x,_T("Lux: %f"),data->data[i].fltVal);
SetDlgItemText(hh,701,x);
}
}
}
}
return 0;
}
case WM_CLOSE:
{
delete ls;
SENSOR::FreeSensorManager();
EndDialog(hh,0);
return 0;
}
}
return 0;
}
To-do...
History
- 28 - 9 - 2009: Library update and GPS Sensor.
- 2 - 5 - 2009: First release.