酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Windows Phoneで加速度センサーからのデータを取得する

概要

Windows Phoneアプリケーションからデバイスの加速度センサーへアクセスする手段を提供してます。

加速度センサーは、「重力方向に対する傾斜角を計測する」センサーで、現在端末が重力に対してどのような傾きになっているかを傾きの変化を数値として取得する事が出来ます。

"Mango"アップデートからはWindows Phone エミュレータの標準機能として加速度センサーシミュレータが付きますが、Mango以前の開発環境では「加速度センサをエミュレートする」を参考にして頂きながら、PC上での試験をおこなうようにするとテストがスムーズかもしれません。

名前空間:Microsoft.Devices.Sensors

System.Object
 +--Microsoft.Devices.Sensors.Accelerometer

Tips

加速度センサーからのデータを取得する

加速度センサーからのデータを取得します。

加速度センサーを使用するには、dll を参照して、Accelerometer クラスを使います。

Windows Mobleの場合だと大抵のメーカーは技術情報を公開してくれていないので、自前で解析したりあシリアルポートで通信させる必要があったので、標準でセンサーが使えるのは本当に嬉しいですね。(T-01Bでは非公開だけど.NET CFから使用出来るライブラリが存在しているんだっけ?)

本題に入っていきます。まずは、Microsoft.Devices.Sensors.dllを参照しておいてください。インスタンスを生成して、画面側に値をセットするイベントハンドラを登録して、データの取得を開始します。

Microsoft.Devices.Sensors名前空間のクラスを使用して位置情報を取得します。参照の追加ダイアログにて「Microsoft.Devices.Sensors」を参照しておきます。センサーからの情報はXNA FrameworkのVector3型で通知されるので、「Microsoft.Xna.Framework」も参照しておきます。usingディレクティブにも追加しておきましょう。

using System.Windows;
using System.Windows.Navigation;
using Microsoft.Devices.Sensors;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;

ここでは、XYZ軸の出力を表示すれば良いのでTextBlcokをコントロールを3つ配置して、それぞれ `labelX` 、 `labelY` 、 `labelZ` と名前をつけます。

f:id:ch3cooh393:20160324214238p:plain

加速度センサーの利用するには、Microsoft.Devices.Sensors名前空間のAccelerometerクラスを使用します。

以下のようにインスタンスフィールド Accelerometer accelerometer;として宣言します。

下記のサンプルコードではページ遷移後にOnNavigatedToメソッドが実行され、Accelerometerインスタンスの生成をおこない、Startメソッドで加速度センサーデバイスからのデータ取得を開始します。

using System.Windows;
using Microsoft.Devices.Sensors;
using Microsoft.Phone.Controls;
using Microsoft.Xna.Framework;

namespace AccelerometerTest {
    public partial class MainPage : PhoneApplicationPage {
        // コンストラクター
        public MainPage() {
            InitializeComponent();
        }

        Accelerometer accelerometer;

        // ページ遷移されてきた時に呼び出される
        protected override void OnNavigatedTo(NavigationEventArgs e) {

            // インスタンスの生成
            accelerometer = new Accelerometer();

            // 加速度センサの値が変化時した際に通知されるイベントにハンドラを登録
            accelerometer.CurrentValueChanged += accelerometer_CurrentValueChanged;

            // 加速度センサーデバイスのデータ取得の開始
            accelerometer.Start();
        }

センサーからの値が変化するとCurrentValueChangedイベントが発生します。

ここではイベントハンドラで値を受け取り、TextBlockコントロールに表示させています。別スレッドから通知される為、BeginInvokeメソッドを使用しています。

        // センサーからの新しい値が通知された時のイベントハンドラ
        void accelerometer_CurrentValueChanged(object sender, SensorReadingEventArgs<AccelerometerReading> e) {

            // UI要素を変更したいのでUIスレッド上で実行させる
            Deployment.Current.Dispatcher.BeginInvoke(() => {
                Vector3 v = e.SensorReading.Acceleration;

                labelX.Text = string.Format("{0:0.0000}", v.X);
                labelY.Text = string.Format("{0:0.0000}", v.Y);
                labelZ.Text = string.Format("{0:0.0000}", v.Z);
            });
        }

このページから別のページに遷移する際に、加速度センサーからのデータ取得を停止させる為に、Stopメソッドを使用します。

        // このページから別のページへ遷移する際に呼び出される
        protected override void OnNavigatedFrom(NavigationEventArgs e) {
            // 加速度センサーデバイスのデータ取得の終了
            accelerometer.Stop();
            accelerometer = null;
        }
    }
}

以上で、ページ遷移時から加速度センサーの出力値を表示し続ける処理が書けました。

f:id:ch3cooh393:20160324214314p:plain

テストの際には、Windows Phoneシミュレータに付属するテストツールを利用すると仮想的な重力加速度の値を取得することができます。

id:shiba-yan:20100319:1268928073 のコードをコピペしたんだけど、動かなかったので、どうもSDK Beta版で少しクラスが変わっていたみたい。

あとは、地磁気センサーと接近センサーを使ったアプリも作っておきたいなぁ。SDKの更新があれば嬉しいんだけどなぁ……。

参照