The combination of good sensors and simplicity of tapping into the Windows 8 sensor APIs are really going to open the doors to some great apps. In this final review I'll touch on the core sensors, how they fared, and how to tap into each of them.
I've received a few pieces of hardware and software over the years for review purposes. Unfortunately, some of the hardware I receive falls far short of my expectations and hardly ever gets used again. This is definitely not the case with the Intel IvyBridge Ultrabook running Windows 8 Pro that I received. My experience with it over that time has left me extremely impressed for speed, portability, touch and a broad array of sensors.
From what I can tell, the machine itself is not one that we'll see in stores, but instead its simply just a model Intel used as a sample to show what OEM’s can create for Windows 8. Mine is not branded and has stickers all over its bottom saying that its not for retail. However, the Intel components inside this device will be showing up in devices you can purchase.
You can read my initial impressions of the IvyBridge Ultrabook here and my follow up on my 2 week reaction here. This ultrabook is easily portable and has many ports built in so I do not need a ton of dongles. That’s key when you travel and present like me. I can easily slip it into my bag and carry it around for presentations and get a lot of work done on it.
It’s fast. I live in Visual Studio 2012 and several other development tools. Speed and power are not “nice to have” for me; they are essentials. This ultrabook covers those areas despite its lower RAM and CPU than I usually get. I like an i7 but I admit with this ultrabook the i5 has been more than enough (perhaps its Windows 8 and its claimed efficiency or perhaps its just the super fast 180 GB SSD). Whatever it is, I’m very happy with the speed of this IvyBridge ultrabook.
In October I used this device to test some Windows 8 course material Dan Wahlin and I authored for Pluralsight. I was using quite a bit at the same time including Visual Studio 2012, Powerpoint, and OneNote. It all went very smooth on this device. You can learn more about this Introduction to Windows 8 course by clicking the image below.
Sensors
Windows 8 exposes a variety of APIs to access the device sensors. The Windows team made several examples available so you can test the sensors. You can find APIs for sensors including (but not limited to) these APIs:
- Accelerometer ( acceleration along 3 axes)
- Compass (orientation and position)
- Gyrometer (angular velocity)
- Inclinometer (angle of incline)
- LightSensor (ambient lighting)
- OrientationSensor (combines accelerometer, compass, gyrometer to get more sensitive movement)
- SimpleOrientation (orientation of the device including face up or down)
I tested the sensors using these sample apps.
All code samples below are directly from the Windows 8 Sample Apps that you can download from this link.
Accelerometer
private Accelerometer _accelerometer; private uint _desiredReportInterval;public Scenario1()
{
this.InitializeComponent();_accelerometer = Accelerometer.GetDefault(); if (_accelerometer != null) { // Select a report interval that is both suitable for the purposes of the app and supported by the sensor. // This value will be used later to activate the sensor. uint minReportInterval = _accelerometer.MinimumReportInterval; _desiredReportInterval = minReportInterval > 16 ? minReportInterval : 16; } else { rootPage.NotifyUser("No accelerometer found", NotifyType.StatusMessage); }
}
_accelerometer.ReadingChanged += new TypedEventHandler<Accelerometer, AccelerometerReadingChangedEventArgs>(ReadingChanged);
async private void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { AccelerometerReading reading = e.Reading; ScenarioOutput_X.Text = String.Format("{0,5:0.00}", reading.AccelerationX); ScenarioOutput_Y.Text = String.Format("{0,5:0.00}", reading.AccelerationY); ScenarioOutput_Z.Text = String.Format("{0,5:0.00}", reading.AccelerationZ); }); }
_accelerometer.Shaken += new TypedEventHandler<Accelerometer, AccelerometerShakenEventArgs>(Shaken);
async private void Shaken(object sender, AccelerometerShakenEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { _shakeCount++; ScenarioOutputText.Text = _shakeCount.ToString(); }); }
Compass
private Compass _compass;
_compass.ReadingChanged += new TypedEventHandler(ReadingChanged);
CompassReading reading = e.Reading; ScenarioOutput_MagneticNorth.Text = String.Format("{0,5:0.00}", reading.HeadingMagneticNorth);
Gyrometer
private Gyrometer _gyrometer;
_gyrometer.ReadingChanged += new TypedEventHandler(ReadingChanged);
async private void ReadingChanged(object sender, GyrometerReadingChangedEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { GyrometerReading reading = e.Reading; ScenarioOutput_X.Text = String.Format("{0,5:0.00}", reading.AngularVelocityX); ScenarioOutput_Y.Text = String.Format("{0,5:0.00}", reading.AngularVelocityY); ScenarioOutput_Z.Text = String.Format("{0,5:0.00}", reading.AngularVelocityZ); }); }
Inclinometer
private Inclinometer _inclinometer;
_inclinometer.ReadingChanged += new TypedEventHandler(ReadingChanged);
async private void ReadingChanged(object sender, InclinometerReadingChangedEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { InclinometerReading reading = e.Reading; ScenarioOutput_X.Text = String.Format("{0,5:0.00}", reading.PitchDegrees); ScenarioOutput_Y.Text = String.Format("{0,5:0.00}", reading.RollDegrees); ScenarioOutput_Z.Text = String.Format("{0,5:0.00}", reading.YawDegrees); }); }
LightSensor
private LightSensor _sensor;
_sensor.ReadingChanged += new TypedEventHandler(ReadingChanged);
async private void ReadingChanged(object sender, LightSensorReadingChangedEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { LightSensorReading reading = e.Reading; ScenarioOutput_LUX.Text = String.Format("{0,5:0.00}", reading.IlluminanceInLux); }); }
OrientationSensor
private OrientationSensor _sensor;
_sensor.ReadingChanged += new TypedEventHandler(ReadingChanged);
async private void ReadingChanged(object sender, OrientationSensorReadingChangedEventArgs e) { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { OrientationSensorReading reading = e.Reading;// Quaternion values SensorQuaternion quaternion = reading.Quaternion; // get a reference to the object to avoid re-creating it for each access ScenarioOutput_X.Text = String.Format("{0,8:0.00000}", quaternion.X); ScenarioOutput_Y.Text = String.Format("{0,8:0.00000}", quaternion.Y); ScenarioOutput_Z.Text = String.Format("{0,8:0.00000}", quaternion.Z); ScenarioOutput_W.Text = String.Format("{0,8:0.00000}", quaternion.W); // Rotation Matrix values SensorRotationMatrix rotationMatrix = reading.RotationMatrix; ScenarioOutput_M11.Text = String.Format("{0,8:0.00000}", rotationMatrix.M11); ScenarioOutput_M12.Text = String.Format("{0,8:0.00000}", rotationMatrix.M12); ScenarioOutput_M13.Text = String.Format("{0,8:0.00000}", rotationMatrix.M13); ScenarioOutput_M21.Text = String.Format("{0,8:0.00000}", rotationMatrix.M21); ScenarioOutput_M22.Text = String.Format("{0,8:0.00000}", rotationMatrix.M22); ScenarioOutput_M23.Text = String.Format("{0,8:0.00000}", rotationMatrix.M23); ScenarioOutput_M31.Text = String.Format("{0,8:0.00000}", rotationMatrix.M31); ScenarioOutput_M32.Text = String.Format("{0,8:0.00000}", rotationMatrix.M32); ScenarioOutput_M33.Text = String.Format("{0,8:0.00000}", rotationMatrix.M33); });
}
Wrap Up
Disclosure of Material Connection: I received one or more of the products or services mentioned above for free in the hope that I would mention it on my blog. Regardless, I only recommend products or services I use personally and believe my readers will enjoy. I am disclosing this in accordance with the Federal Trade Commission’s 16 CFR, Part 255: “Guides Concerning the Use of Endorsements and Testimonials in Advertising.”