Использование акселерометра в Metro-приложениях Windows 8* и пример обработки постукивания

Скачать статью

Скачать Using Accelerometer in Windows 8* Metro Style App and a Case Study of Tap Detection [Eng., PDF 744KB]

 

1. Введение

Акселерометры - это аппаратные датчики, встраиваемые во множество современных портативных устройств, таких как смартфоны и планшеты. Акселерометры измеряют ускорение устройства - вес на единицу массы по отношению к силе тяготения Земли на уровне моря. Акселерометры можно широко использовать для отслеживания движений, обнаружения падений, обнаружения жестов и пр. В этой статье рассматривается использование акселерометров в приложениях Windows 8* стиля Metro. Приводится пример использования акселерометра, чтобы определить постукивание по краям планшета. Кроме того, в примере показано, как обнаружить направление касаний, вызванных незначительным движением устройства.

 

2. Акселерометры

Существует множество типов акселерометров: оптические, магнитно-индукционные, лазерные и пр. Современные портативные устройства обычно оснащаются акселерометрами на основе микроэлектронных механических систем (МЭМС). В этой статье мы будем рассматривать типовые МЭМС-акселерометры, которыми оборудуются портативные устройства, такие как планшеты и смартфоны. В зависимости от модели, такие акселерометры могут обладать как базовыми, так и расширенными возможностями. В этом разделе мы опишем базовые и расширенные возможности, и также приведем классификацию различных примеров использования акселерометров в мобильных приложениях.

2.1. Возможности

Перечисленные ниже возможности поддерживаются драйверами акселерометров (в отличие от возможностей, обеспечиваемых операционной системой или пользовательскими приложениями).

2.1.1. Базовые возможности

Базовой функцией типовых МЭМС-акселерометров является измерение ускорения по сравнению с гравитационной постоянной, то есть силой тяготения Земли на уровне моря. Единицей измерения является ускорение силы тяжести (g), где 1 g = 9,81 м/с2. На базовом уровне следует обратить внимание на следующие характеристики акселерометров:

  • Количество осей: количество осей ускорения в евклидовом пространстве, по которым акселерометр измеряет ускорение. Для двухмерного позиционирования достаточно двух осей; акселерометр выдает значения ускорения по осям x и y. Для трехмерного позиционирования нужны три оси; акселерометр выдает значения ускорения по осям x, y и z.
  • Максимальный диапазон: диапазон между максимальным и минимальным измеряемыми значениями ускорения. Обычно это ±2 g, ±4 g, ±6 g или даже ±24 g.
  • Чувствительность: насколько сильно изменяется выходной сигнал акселерометра при заданном изменении ускорения. Как правило, чем выше чувствительность, тем лучше.
  • Частота дискретизации выходных данных: как часто можно делать замеры ускорения. Здесь показатели могут составлять от нескольких раз в секунду до нескольких сотен раз в секунду.
  • Диапазон рабочих температур: при какой температуре акселерометр может выдавать достоверные данные. Для МЭМС-акселерометров, используемых в портативных устройствах, диапазон рабочих температур обычно составляет от -40 до +85 градусов по Цельсию.

2.1.2. Расширенные возможности

Некоторые акселерометры оснащены встроенным контроллером. Контроллер может считывать данные акселерометра с высокой частотой (порядка сотен Гц) и анализировать эти данные для реализации расширенных возможностей, таких как режим пониженного потребления электроэнергии, обнаружение тряски, обнаружение касаний и пр .

  • Режим пониженного потребления электроэнергии: этот режим реализован в некоторых акселерометрах для снижения расхода электроэнергии. В этом режиме продлевается режим сна акселерометра, а данные в режиме бездействия выдаются реже.
  • Обнаружение встряхиваний: некоторые акселерометры могут определять быструю вибрацию. Путем анализа последовательного изменения ускорений обнаруживается быстрое встряхивание.
  • Обнаружение касаний: некоторые акселерометры могут обнаруживать касания. Под касанием здесь понимается не только касание сенсорного экрана, но и постукивание по краю устройства. Когда пользователь постукивает по краю устройства, встроенный контроллер акселерометра определяет это и отправляет прерывание.

Некоторые акселерометры поддерживают еще более широкий набор функций, к числу которых относится, к примеру, обнаружение свободного падения. Однако расширение функциональности приводит к удорожанию акселерометров. Акселерометры, которыми оснащаются типовые мобильные устройства, не имеют обширного набора дополнительных функций. В частности, большая часть поставляемых в настоящее время акселерометров не поддерживает обнаружение касаний.

2.2. Примеры использования

Данные акселерометра можно использовать в самых разных сценариях и для самых разных целей. Некоторые примеры использования приводятся ниже.

2.2.1 Отслеживание движения устройства

Данные акселерометра можно использовать для отслеживания движения устройства. Обычно для этого применяется сочетание данных акселерометра с данными гироскопа, компаса и других датчиков. Отслеживание движение применяется для обнаружения жестов, при работе шагомера, для рисования в пространстве, при использовании устройства в качестве дистанционного контроллера, для определения положения камеры и пр.

2.2.2. Обнаружение свободного падения устройства

Если устройство находится в состоянии свободного падения, то величина ускорения ниже порогового значения. Причина заключается в том, что свободно падающее устройство ускоряется в сторону земли с ускорением, равным гравитационной постоянной Земли. Поскольку сила тяготения земли используется в акселерометре в качестве эталонного значения, при свободном падении величина замеряемого ускорения будет близка к нулю.

2.2.3. Обнаружение движения

Можно использовать акселерометры для обнаружения движений, таких как тряска, постукивание и даже нажатие. Каждый тип движения отличается определенной последовательностью изменения ускорений. При выявлении определенной последовательности данных акселерометра определяется и соответствующее движение. Обнаружение движений используется в приложениях для различных целей, например для регулировки громкости голоса путем касания, регулировки масштаба изображения путем двойного касания, показа рисунков путем встряхивания устройства и пр.

 

3. Среда разработки для доступа к данным акселерометра

3.1. Оборудование

Наши эксперименты проводились на типовом планшете, оснащенном МЭМС-акселерометром производства компании STMicroelectronics. Этот акселерометр замеряет ускорение по трем осям: x (поперечная ось), y (продольная) и z (вертикальная). Частота дискретизации - 50 Гц или выше.

3.2. Программное обеспечение

3.2.1. Операционная система и средства разработки

На нашем планшете была установлена ОС Windows 8 Release Preview. Для разработки приложения стиля Metro на языке C# для акселерометра мы использовали Visual Studio* RC 2012.

3.2.2. Доступ к акселерометру

API Windows Runtime предоставляет доступ к поддерживаемым акселерометрам посредством класса accelerometer в пространстве имен Windows.Devices.Sensors для приложений стиля Metro.

Прежде всего нужно объявить экземпляр акселерометра с помощью класса Accelerometer. Затем нужно задать минимальный интервал считывания данных акселерометра. Обратите внимание, что минимальный интервал считывания отличается от частоты дискретизации, указанной в технических характеристиках акселерометра. Минимальный интервал считывания устанавливается для акселерометра средой Windows Runtime. Минимальный разрешенный интервал обращений к акселерометру в Windows Runtime равен 16 мс. Таким образом, максимальная частота считывания данных акселерометра равна 62,5 Гц. Эта частота может быть намного ниже типовой частоты дискретизации самого акселерометр, поскольку при слишком высокой частоте считывания данных существенно возрастет нагрузка на ЦП.

Мы задаем разрешенный минимальный интервал обращений в качестве значения по умолчанию (16 мс) для экземпляра акселерометра. После этого мы добавляем функцию обработчика событий, реагирующую на любые изменения показаний акселерометра. Пример кода приведен ниже.

// Intialize accelerameter
_accelerometer = Accelerometer.GetDefault();

if (_accelerometer != null)
{
// Initialize accelerometer stable values. Note that it will do automatical   
// calibration later.      
TapDetector.InitializeReading(0, 0, 0);

    // Establish the report interval for all scenarios.
    minReportInterval = _accelerometer.MinimumReportInterval;
    reportInterval = minReportInterval > 16 ? minReportInterval : 16;
    _accelerometer.ReportInterval = reportInterval;
}

if (_accelerometer != null)
{
_accelerometer.ReadingChanged += new TypedEventHandler<Accelerometer,     
                           AccelerometerReadingChangedEventArgs>(ReadingChanged);
}
else
{
    doneCalibrate = 0;
    DisplayAppOutput("No accelerometer found");
}

Пример 1: Инициализация экземпляра акселерометра и регистрация функции обработчика событий для реакции на изменения данных акселерометра **

3.2.3. Получение данных

В Windows Runtime при всяком изменении данных акселерометра происходит событие акселерометра. Это событие обрабатывается зарегистрированной функцией обработчика, а прочитанные данные акселерометра передаются в виде аргументов этой функции. В приведенном примере кода ReadingChanged является функцией обработчика событий и получает аргументы. Аргументы обработчика событий включают значения ускорения по трем осям: x (поперечная ось), y (продольная) и z (вертикальная). Также указывается время изменения данных акселерометра. Ниже приведен пример кода для получения данных акселерометра по трем осям.

// Intialize accelerameter
private void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
    {
        AccelerometerReading reading = e.Reading;

        AcceleroData_X.Text = String.Format("{0,5:0.00}", reading.AccelerationX);
        AcceleroData_Y.Text = String.Format("{0,5:0.00}", reading.AccelerationY);
        AcceleroData_Z.Text = String.Format("{0,5:0.00}", reading.AccelerationZ);
        AcceleroData_TimeStamp = reading.TimeStamp;
}

Пример 2: Получение выборки данных акселерометра и времени **

3.2.4. Данные акселерометра по трем осям

Как выглядят данные акселерометра? Все данные представляют собой величину ускорения g в заданной системе координат. Заданная система координат в Windows 8 Runtime совпадает с используемой в Silverlight*, SNA, и в операционной системе Windows Phone.

Система координат изображена на рис. 1. Это планшет с Windows 8 на неподвижной поверхности, лежащий экраном вверх, при этом устройство ориентировано камерой вверх. Если устройству придано ускорение, направленное влево вдоль оси х, то значение х, полученное через класс accelerometer, является положительным. В противном случае используется отрицательное значение. Если устройству придано ускорение, направленное в сторону нижней грани устройства, то значение y, полученное через класс accelerometer, является положительным. В противном случае используется отрицательное значение. Если устройству придано ускорение, направленное в сторону земли, и при этом ускорение превышает 1 g, то значение z, полученное через класс accelerometer, является положительным. В противном случае используется отрицательное значение.



Рисунок 1: Система координат данных акселерометра в Windows Runtime.

В идеале, если планшет неподвижно лежит на плоской поверхности, значения x и y равны 0, а значение z равно -1 g, поскольку ускорение всегда рассчитывается относительно силы тяготения на уровне моря.

Мы получаем фактические данные акселерометра с помощью API Windows Runtime для типового планшета в неподвижном состоянии на плоской поверхности, а затем строим график для этих данных, как показано на рис. 2. Как можно заметить, значения x, y и z отличны от идеальных (0, 0, -1), поскольку поверхность не является абсолютно ровной.



Рисунок 2: Данные акселерометра (устройство лежит на плоской поверхности экраном вверх и камерой вверх).


4. Пример - обнаружение постукивания

Среда Windows Runtime предоставляет доступ к данным типовых акселерометров для приложений Metro с минимальным интервалом считывания в 16 см (таким образом, максимальная частоты выборки данных составляет 62,5 Гц). При частоте 62,5 Гц не так просто определить шаблоны некоторых движений, если при движениях возникают лишь незначительные изменения данных акселерометра. Тем не менее, все же можно обнаруживать движения со сходными шаблонаи. В нашем примере показана возможность применения низкочастотного акселерометра для обнаружения постукиваний по краям устройства и направленных постукиваний с незначительным движением устройства. В обоих случаях регистрируются незначительные изменения данных акселерометра.

4.1. Данные эксперимента

Мы провели эксперимент с неподвижным планшетом, лежащим на плоской поверхности экраном вверх и камерой вверх. Мы постукивали по краям устройства и использовали API Windows Runtime для получения данных акселерометра и построения графиков изменения данных акселерометра со временем.

4.1.1. Постукивание

На рис. 3 показан график данных акселерометра при двукратном постукивании по каждому краю устройства (левому, правому, верхнему и нижнему). Мы назвали это постукиваниями слева, справа, сверху и снизу, и использовали различные цвета для изображения постукиваний.

Данные по осям х, у и z однородно изменяются при постукивании. Если использовать данные акселерометра неподвижного устройства в качестве базовых, а затем вычислить дельту, то есть разницу в изменениях данных акселерометра по сравнению с базовыми данными, мы обнаружим импульсы по осям x, y и z. Эти импульсы можно использовать в качестве критериев для определения постукивания.



Рисунок 3: Данные акселерометра по осям x, y и z для двух постукиваний по каждому краю устройства (левому, правому, верхнему и нижнему) без движения устройства


4.1.2. Направленное постукивание

Мы провели эксперименты для выявления однородных шаблонов при направленном постукивании. Однако при частоте выборки данных в 62,5 Гц направленное постукивание без движения устройства не позволяет выявить однородное изменение данных акселерометра. Чтобы выявить направленное постукивание без всякого движения устройства, требуется частота выборки свыше 400 Гц. Поэтому мы провели эксперимент по возможности определения направленного постукивания, когда оно приводило к незначительному движению устройства.

На рис. 3 для постукивания слева и справа данные акселерометра изменяются главным образом по оси x (устройство лежит экраном вверх на неподвижной ровной поверхности). На рис. 4 показан график данных акселерометра при постукивании по левому краю устройства (постукивание слева). На рис. 5 показан график данных акселерометра при постукивании по правому краю устройства (постукивание справа). На обоих рисунках мы не обращаем внимания на ось z, поскольку данные по этой оси практически не меняются.

Как можно увидеть, одно постукивание слева на рис. 4 приводит к образованию двух последовательных импульсов по оси x. Сначала идет отрицательный импульс, а за ним следует положительный импульс. Это обусловлено тем, что при постукивании слева устройство сначала с ускорением сдвигается вправо, а затем останавливается (ускорение меняется на противоположное) из-за трения устройства о поверхность, на которой оно лежит.

Сходным образом, постукивание справа на рис. 5 приводит к образованию двух последовательных импульсов по оси x. Сначала идет положительный импульс, а за ним следует отрицательный импульс. Это вызвано тем, что при постукивании справа устройство сначала с ускорением сдвигается влево, а затем останавливается из-за трения. Последовательности импульсов позволяют определить, с какой стороны было постукивание - слева или справа.



Рисунок 4: Данные акселерометра по осям x и y для двух постукиваний по левому краю устройства с незначительным движением устройства.



Рисунок 5: Данные акселерометра по осям x и y для трех постукиваний по правому краю устройства с незначительным движением устройства


Данные эксперимента показывают, что можно определить постукивания слева или справа с незначительным движением устройства путем определения двух последовательных импульсов по оси х и порядка положительных и отрицательных импульсов. Теперь мы продемонстрируем использование конечного автомата для реализации процесса обнаружения.

4.2. Конечный автомат

Чтобы определить текущее состояние (положительный импульс, отрицательный импульс или неактивное состояние), мы используем простой конечный автомат. Сначала мы определяем три состояния акселерометра: NonActive, PositivePulse, NegativePulse. NonActive означает, что изменение меньше порогового значения (мы определяем deltax_threshold в образце кода). PositivePulse означает, что изменение больше порогового значения, а ускорение по оси x больше этого ускорения в состоянии NonActive. NegativePulse означает, что изменение больше порогового значения, а ускорение по оси x меньше этого ускорения в состоянии NonActive.

Конечный автомат изображен на рис. 6. Пусть x - данные ускорения по оси x, переданные акселерометром. Мы определяем Δx = |x-x_initial|, где x_initial - среднее ускорение по оси x для неподвижного устройства. Мы сравниваем Δx с заранее заданным порогом (Th), чтобы определить, достаточно ли велико изменение данных акселерометра, чтобы можно было считать его постукиванием. Переключение состояний осуществляется, как показано на рис. 6.



Рисунок 6: Конечный автомат данных акселерометра по оси х, когда устройство лежит на ровной поверхности.

Как показано в следующем примере кода, сначала мы определяем класс DetectTap с членами.

public class DetectTap
{
    // Accelerometer data state
    enum PulseState
    {
        NonActive = 0,
        PositivePulse = 1,
        NegativePulse = 2,
        UnknownPulse = -1
    } ;

// Threshold on x, y, z axes for identifying whether a tap triggers the   
// accelerometer data change exceeds a threshold or not.  
    private static double deltax_threshold = 0.01;
    private static double deltay_threshold = 0.02;
    private static double deltaz_threshold = 0.03;

    // Declare the average x, y, z accelerometer data when device is static. 
    public double x_initial;
    public double y_initial;
    public double z_initial;

    // Declare the number of samples to calibrate the x_initial, y_intial, z_initial. 
    public int samplecounter_calibrate;
    // Declare the maximum number of samples for calibration. 
    public int MaxCalibrateInterval = 10;
    // Declare the previous state, current state of x axis accelerometer data. 
    private static PulseState PreviousState_X, CurrentState_X;

    // Ininitialization
    public DetectTap()
    {
        samplecounter_calibrate = 0;
      }
}

Пример 3: Определение класса DetectTap **

Чтобы получить значения ускорения устройства в состоянии NonActive, мы берем небольшой объем данных акселерометра и усредняем эти данные. Этот этап будет называться калибровкой. Калибровка осуществляется пользователем: пользователь должен положить устройство на ровную поверхность и нажать соответствующую кнопку. Функция калибровки определена в классе DetectTap. Усредненные значения ускорений в состоянии NonActive используются для обнаружения изменений по каждой оси для определения постукиваний.

public class DetectTap
{
    // Accelerometer calibration for the NonActive state. 
    public int CalibrateInitialReading(double x, double y, double z)
    {
        int done = 0;

        // Initialize the variables. 
        if (samplecounter_calibrate == 0)
        {
            x_initial = 0;
            y_initial = 0;
            z_initial = 0;
        }

        // Increment the sample number of calibration. 
        samplecounter_calibrate++;

        // Skip the first 5 samples and then average the rest samplings of           
        // accelerometer data. The skipping is to skip the accelerometer data 
        // change due to the button press for calibration.  
        if (samplecounter_calibrate > 5 
             && samplecounter_calibrate <= MaxCalibrateInterval)
        {
            x_initial = (x_initial * (samplecounter_calibrate - 6) + x) /  
                        (samplecounter_calibrate - 5);
            y_initial = (y_initial * (samplecounter_calibrate - 6) + y) / 
                        (samplecounter_calibrate - 5);
            z_initial = (z_initial * (samplecounter_calibrate - 6) + z) / 
                        (samplecounter_calibrate - 5);
        }

        if (samplecounter_calibrate >= MaxCalibrateInterval)
        {
            done = 1;
        }

        return done;
    }
}

Пример 4: Определение функции калибровки **

Класс DetectTap включает функцию theDetectXPulse для вывода текущего состояния данных по оси x на основе изменений по оси x. Вывод текущего состояния функцией применяется для обнаружения постукивания слева или справа с незначительным движением устройства.

public class DetectTap
{

    // State machine to detect the pulse on x axis accelerometer data. 
    public int DetectXPulse(double x)
    {
        double deltax;
        deltax = x - x_initial;


        if (Math.Abs(deltax) < deltax_threshold)
        {
            CurrentState_X = PulseState.NonActive;
            goto Exit;
        }

        if (Math.Abs(deltax) > Math.Abs(DeltaxPeak))
            DeltaxPeak = deltax;

        switch (PreviousState_X)
        {
            case PulseState.PositivePulse:
                if (deltax > 0)
                    CurrentState_X = PulseState.PositivePulse;
                else
                    CurrentState_X = PulseState.NegativePulse;
                break;

            case PulseState.NegativePulse:
                if (deltax > 0)
                    CurrentState_X = PulseState.PositivePulse;
                else
                    CurrentState_X = PulseState.NegativePulse;
                break;

            case PulseState.NonActive:
                if (deltax > 0)
                    CurrentState_X = PulseState.PositivePulse;
                else
                    CurrentState_X = PulseState.NegativePulse;
                break;
            default:
                break;
        }

    Exit:

        PreviousState_X = CurrentState_X;

        return (int)CurrentState_X;
    }
}

Пример 5: Определение функции конечного автомата **

 

Мы вставляем код обнаружения постукивания в функцию ReadingChanged (это функция обработчика событий изменения акселерометра).

Сначала мы используем текущие данные акселерометра с функцией конечного автомата DetectXPulse для получения текущего состояния по оси x и помещаем его в FIFO-очередь ограниченного размера. Состояния в этой очереди будут использованы для определения постукивания. Ниже приведен пример кода для сохранения текущего состояния в очереди.

private void ReadingChanged(object sender, AccelerometerReadingChangedEventArgs e)
{
    Dispatcher.RunAsync(CoreDispatcherPriority.High, () =>
    {
         AccelerometerReading reading = e.Reading;

         int currentXState, currentYState, currentZState;

         if (doneCalibrate != 1)                {
              //Do calibration
         }
         else {

            // Only keep small amount of history X, Y, Z data. 
         if (TapXStateQueue.Count >= MaxQueueLength) TapXStateQueue.Dequeue();
         if (TapYStateQueue.Count >= MaxQueueLength) TapYStateQueue.Dequeue();
         if (TapZStateQueue.Count >= MaxQueueLength) TapZStateQueue.Dequeue();

        // Use the state machine to detect positive or negative pulse on x, y, z axes. 
        // Put the current state in a first in first out queue. 
        currentXState = TapDetector.DetectXPulse((double)(reading.AccelerationX));
        TapXStateQueue.Enqueue(currentXState);
        currentYState = TapDetector.DetectYPulse((double)(reading.AccelerationY));
        TapYStateQueue.Enqueue(currentYState);
        currentZState = TapDetector.DetectZPulse((double)(reading.AccelerationZ));
        TapZStateQueue.Enqueue(currentZState);

        TapInterval++;
        SingleXYZTapInterval++;
….
}});}

Пример 6: Сохранение текущего состояния в очереди состояний для обнаружения касаний **


4.3. Обнаружение постукивания

Когда происходит постукивание, регистрируется импульс по оси x, y или z. Мы используем текущее состояние акселерометра по осям x, y и z для определения постукиваний. Если какое-либо состояние равно PositivePulse или NegativePulse, мы определяем, что обнаружено постукивание. Затем мы отключаем обнаружение на небольшой интервал времени. Вот соответствующий пример кода.

        // … continue with Dispatcher.RunAsync in function ReadingChanged
        // The below code detects single tap based on the x, y, z direction data    
        // pulse. If a pulse is detected in x, y, z (in this order),
        // we identify a tap is detected. Then we debounce the tap for a time window    
        //MinSingleTapInterval. 
                    
        // Debouncing condition
        if (TapXStateQueue.Count >= MaxQueueLength && (SingleXYZTapInterval >= 
            MinSingleTapInterval)) {
        // We identify x direction pulse by the X state from state 
        // machine. The sequence only can be NegativePulse, PositivePulse .
        if (currentXState == 1 || currentXState == 2 ||
            currentYState == 1 || currentYState == 2 ||
            currentZState == 1 || currentZState == 2) {
           SingleXYZTapInterval = 0;
        }

        // Tap is detected based on the pulse detection on x, y, z direction.
         if (SingleXYZTapInterval == 0) {
                TapCount++;
                NonDTapEventOutput.Text = TapCount.ToString() + " Tap detected");
         }

Пример 7: Обнаружение постукивания путем выявления импульсов **


4.4. Обнаружение постукивания справа и слева с незначительным движением устройства

Если постукивание слева или справа приводит к незначительному движению устройства по ровной поверхности, то по оси х возникают два последовательных импульса. Мы используем сохраненное в очереди состояние по оси х для обнаружения постукиваний слева или справа. Вот соответствующий пример кода.

 // … continue with Dispatcher.RunAsync in function ReadingChanged
 // The below code detects directional tap based on the x direction data pulse     
 //sequence. If a pulse sequence is detected in x, we identify a directional tap is 
 // detected. Then we debounce the tap for a time window MinTapInterval. 
 if (TapXStateQueue.Count >= MaxQueueLength && (TapInterval >= MinTapInterval)) {

 // We identify x direction negative pulse by the X state. 
 // The sequence for left tap is a negative pulse followed by a positive pulse.     
 // So, the state sequence could be : 2,1 or 2,0,1, or 2,0,0,1.
  
 if ((TapXStateQueue.ElementAt(MaxQueueLength - 3) == 2 && 
     TapXStateQueue.ElementAt(MaxQueueLength - 2) == 0 &&  
     TapXStateQueue.ElementAt(MaxQueueLength - 1) == 1)
     || (TapXStateQueue.ElementAt(MaxQueueLength - 4) == 2 && 
     TapXStateQueue.ElementAt(MaxQueueLength - 3) == 0 && 
     TapXStateQueue.ElementAt(MaxQueueLength - 2) == 0 &&   
     TapXStateQueue.ElementAt(MaxQueueLength - 1) == 1)
     || (TapXStateQueue.ElementAt(MaxQueueLength - 2) == 2 && 
     TapXStateQueue.ElementAt(MaxQueueLength - 1) == 1)) {
           LeftTapCount++;
           TapEventOutput.Text = LeftTapCount.ToString() + " Left Tap";
           TapInterval = 0;
           DirectionalTap = 1;
 }

  // We identify x direction positive pulse by the X state sequence from state 
  // machine. The sequence for right tap is a positive pulse followed by a negative   
  // pulse. So, the state sequence could be : 1,2 or 1,0,2, or 1,0,0,2. 
  if ((TapXStateQueue.ElementAt(MaxQueueLength - 3) == 1 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 2) == 0 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 1) == 2)
       || (TapXStateQueue.ElementAt(MaxQueueLength - 4) == 1 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 3) == 0 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 2) == 0 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 1) == 2)
       || (TapXStateQueue.ElementAt(MaxQueueLength - 2) == 1 && 
       TapXStateQueue.ElementAt(MaxQueueLength - 1) == 2)) {
           RightTapCount++;
           TapEventOutput.Text = RightTapCount.ToString() + " Right Tap";
           TapInterval = 0;
           DirectionalTap = 2;
  }

 if (TapInterval == 0)
    Dispatcher.RunAsync(CoreDispatcherPriority.High, (DispatchedHandler)OnAnimation);}
 }});} // End of function ReadingChanged

Пример 8: Обнаружение касания слева и справа с небольшим движением устройства путем выявления определенной последовательности импульсов **


5. Заключение

В этой статье мы описали возможности и некоторые примеры использования МЭМС-акселерометров в современных портативных устройствах. Также мы описали метод доступа в Windows Runtime для приложений стиля Metro. Также приведен пример с образцом кода, демонстрирующий обнаружение постукивания по краям устройства и движения вправо и влево, когда постукивание приводит к незначительному движению устройства.

 

Об авторе

Сушу Джанг (Sushu Zhang) работает программистом в департаменте Intel по разработке ПО и обслуживанию. Она занимается вопросами интеграции платформ на базе Intel с ОС Android и Windows в ISV. Ею разработан инструмент Intel® Power Monitoring Tool для устройств Android. В последнее время Сушу принимала участие в нескольких проектах Intel по оптимизации энергопотребления. Сушу получила степень доктора наук по компьютерным наукам в Университете штата Аризона. До перехода в Intel она работала в корпорации Майкрософт и занималась энергоэффективностью Windows. Областью ее научных интересов были энергопитание систем и управление рабочими температурами.

 

 

 



*Другие наименования и торговые марки могут быть собственностью третьих лиц.

**Пример исходного кода распространяется на условиях соглашения Intel Sample Source Code License Agreement.

Para obtener información más completa sobre las optimizaciones del compilador, consulte nuestro Aviso de optimización.
Etiquetas: