Click here to Skip to main content
Click here to Skip to main content
Go to top

Using the APS Accelerometer in Lenovo Laptops

, 6 Jan 2009
Rate this:
Please Sign up or sign in to vote.
Use the accelerometer in Lenovo laptops to determine the computer's attitude and temperature.

LenovoAPS_src

Introduction

Lenovo's newer laptops include something called the Active Protection System (APS). It consists of a mediocre accelerometer, plus a controller that determines when you drop your laptop, hopefully in time to protect the drive and make peace with the computer God.

This is nice, but what's even nicer is that from C#, you can access the current status of the APS (shock, recent shock, hunky-dory, etc.), the current pitch and roll, and for some reason, the temperature.

The download contains a simple C# class for reading those values, and a fairly dorky demo app.

Background

You talk to the APS using the driver supplied by Lenovo. It comes pre-installed on laptops that feature APS. The interesting file is called sensor.dll, an unmanaged DLL which generally lives in system32. It exposes various functions, the most interesting of which is ShockproofGetAccelerometerData. To actually call it from managed code, you use good 'ole P/Invoke, like so:

[DllImport("sensor.dll")]
private static extern void ShockproofGetAccelerometerData(ref APSReading accData);

It takes a pointer to a structure that looks like this:

[StructLayout(LayoutKind.Sequential)]
public struct APSReading
{
    public APSStatus status;
    public ushort x;
    public ushort y;
    public ushort xx;
    public ushort yy;
    public byte temperature;
    public ushort x0;
    public ushort y0;
}

So, to call it, you would just do something like this:

var reading = new APSReading();
ShockproofGetAccelerometerData(ref reading);

The x, xx, and x0 fields contain roll, y, yy, and y0 hold pitch information, status tells you what the controller thinks is going on, and temperature contains the temperature in degrees Centigrade.

The x/y fields represent the latest raw reading from the accelerometer as a value ranging from ~200 to ~700 (at least on my much-abused T60). The xx/yy fields are more or less the same, but averaged over ~40ms, so they should yield much smoother values. The x0/y0 fields are the resting point, so essentially, the same thing but even more smoothed. So, if you set the computer on a table, all three will yield the same values, but x/y will probably wiggle a bit. If you slowly turn it on its side, x will respond quickly and noisily, xx almost as quickly but smoothly, and once you stop moving the machine, x0 will move.

For getting the laptop's attitude, the safest bets are xx/yy, since they give current information, but nicely smoothed.

Using the Code

To talk to the sensor, you just need the one call to sensor.dll, but I've attached a class that gives you the attitude of the laptop in degrees and the temperature in degrees Fahrenheit or Centigrade.

The first thing you'll need to do, of course, is instantiate the class like:

var aps = new APS();

Next, you'll need to calibrate it. This is needed because the laptop's resting attitude might not be perfectly flat depending on whether the person is holding it on their lap, or on a table, or what have you. You do it thusly:

aps.Calibrate();

You'll also want to call Calibrate again if you instruct the user to shift positions. For instance, in a ball-rolling game, you might call it after the user unpauses the game or advances to the next level. If you're writing a mouse-replacement driver thing, you'll want to call it after periods of inactivity.

And now, you can start reading, which you do thusly:

var att = aps.ReadAttitude();
Console.WriteLine("Pitch: {0}, Roll: {1}", att.pitch);

Lastly, if you want to pull the temperature, you do this:

var tempC = aps.ReadTempC();
var tempF = aps.ReadTempF();
Console.WriteLine("Internal temperature is {0}C/{1}F", tempC, tempF);

I can confirm the temperature is at least vaguely accurate; when I made my laptop work really hard, it went up, and when I stuck it in the fridge for several hours, it went down. I'm not sure where the temperature sensor is, but it must be inside the case somewhere since the values are too high to be external.

Credits

The code and info from Use your Thinkpad as a joystick [^] was indispensible, as was the code here [^].

History

Posted it.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

Sigfrid3141

United States United States
No Biography provided

Comments and Discussions

 
GeneralGreat, thanks! Pinmemberwisodev8-Jan-11 11:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140921.1 | Last Updated 6 Jan 2009
Article Copyright 2009 by Sigfrid3141
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid