Home>

I am learning Xamarin.
Install Xam.Plugin.DeviceMotion from Nuget and
I get the values ​​of accelerometer and gyro sensor and display them in XAML with data binding.
The value of the acceleration sensor and the value of the gyro sensor will be exactly the same no matter how you move.
The same is true on the emulator and the actual machine.


(Data binding to the Label element)

Source code

Acceleration sensor

public void StartACCEL () {
            motion.Start (MotionSensorType.Accelerometer, MotionSensorDelay.Ui);
            if (motion.IsActive (MotionSensorType.Accelerometer))
            {
                motion.SensorValueChanged + = (object s, SensorValueChangedEventArgs a) =>
                {
                    Device.BeginInvokeOnMainThread (() =>
                    {
                        this.xAccel = ((MotionVector) a.Value) .X.ToString ("0.0000");
                        this.yAccel = ((MotionVector) a.Value) .Y.ToString ("0.0000");
                        this.zAccel = ((MotionVector) a.Value) .Z.ToString ("0.0000");
                    });
                };
            }
        }

Gyro sensor

public void StartGYRO ()
        {
            motion.Start (MotionSensorType.Gyroscope, MotionSensorDelay.Default);
            if (motion.IsActive (MotionSensorType.Gyroscope))
            {
                motion.SensorValueChanged + = (object s, SensorValueChangedEventArgs v) =>
                {
                    Device.BeginInvokeOnMainThread (() =>
                    {
                        this.xGyro = ((MotionVector) v.Value) .X.ToString ("0.0000");
                        this.yGyro = ((MotionVector) v.Value) .Y.ToString ("0.0000");
                        this.zGyro = ((MotionVector) v.Value) .Z.ToString ("0.0000");
                    });
                };
            }
        }

Both are described in the same ViewModel (I will divide it into a Model when the operation is stable)
Each sensor value x, y, z value is converted to String type and displayed in View with data binding.

Tried

I thought it was caused by both running on the main thread, andDevice.BeginInvokeOnMainThread (() =>was deleted, but the result did not change.

  • Answer # 1

    SensorValueChangedneeds to check the type of the changed value.
    https://github.com/rdelrosario/xamarin-plugins/tree/master/DeviceMotion#events

    Acceleration sensor

    motion.SensorValueChanged + = (object s, SensorValueChangedEventArgs a) =>
    {
        if (a.SensorType == MotionSensorType.Accelerometer)
        {
            Device.BeginInvokeOnMainThread (() =>
            {
                this.xAccel = ((MotionVector) a.Value) .X.ToString ("0.0000");
                this.yAccel = ((MotionVector) a.Value) .Y.ToString ("0.0000");
                this.zAccel = ((MotionVector) a.Value) .Z.ToString ("0.0000");
            });
        }
    };


    Gyro sensor

    motion.SensorValueChanged + = (object s, SensorValueChangedEventArgs v) =>
    {
        if (v.SensorType == MotionSensorType.Gyroscope)
        {
            Device.BeginInvokeOnMainThread (() =>
            {
                this.xGyro = ((MotionVector) v.Value) .X.ToString ("0.0000");
                this.yGyro = ((MotionVector) v.Value) .Y.ToString ("0.0000");
                this.zGyro = ((MotionVector) v.Value) .Z.ToString ("0.0000");
            });
        }
    };