راه‌اندازی نرم‌افزار آزمایش

ارزیابی سخت‌افزار از نرم‌افزار زیر استفاده می‌کند:

  • Audacity (نصب‌شده در رایانه)
  • MATLAB (نصب‌شده در رایانه)
  • برنامه آزمایش لمسی (نصب‌شده روی DUT)

برای کسب اطلاعات بیشتر درباره الزامات سیستم، Audacity برای Windows، Audacity برای Mac، و MATLAB را ببینید.

راه‌اندازی Audacity

باید Audacity را طوری تنظیم کنید که از کارت صدای Sound Blaster با نرخ نمونه‌برداری داده خاصی ورودی بگیرد. پس‌از اتصال Sound Blaster به درگاه USB رایانه، Audacity را باز کنید و این دستورالعمل‌ها را دنبال کنید.

  1. با اتصال فیزیکی خروجی CCLD به درگاه ورودی Line In در Sound Blaster، Line (USB Sound Blaster HD) را به‌عنوان منبع میکروفون ورودی انتخاب کنید.

    ورودی میکروفون

    شکل ۱. انتخاب ورودی میکروفون

  2. با انتخاب ۴۸۰۰۰ در منو پروژه نرخ، نرخ نمونه‌برداری را روی ۴۸ کیلوهرتز تنظیم کنید.

    بسامد نمونه‌برداری

    شکل ۲. تنظیم نرخ نمونه‌برداری

بارگیری MATLAB

  1. فایل MATLAB را بارگیری کنید.

  2. فایل را استخراج کنید و Effect1NEffect2_V1p0_2020PM.m (برای «جلوه ۱» و «جلوه ۲») و Effect3_V1p0_2020PM.m (برای «جلوه ۳») را پیدا کنید.

برنامه آزمایشی را در تلفن راه‌اندازی کنید

این بخش نحوه راه‌اندازی برنامه آزمایشی در تلفن را شرح می‌دهد.

آماده شدن برای برنامه آزمایشی

  1. کد منبع را از بلوک‌های کد Java و Kotlin در زیر کپی کنید. هرکدام را که برایتان مناسب‌تر است انتخاب کنید.
  2. کد خودتان را با پیروی از پارامترهای GUI نشان‌داده‌شده در شکل ۳ بنویسید. درصورت لزوم، جزئیات کد منبع چیدمان را اصلاح کنید تا با تلفنتان مطابقت داشته باشد.
  3. مطمئن شوید که «واسط کاربر گرافیکی» شما شامل سه دکمه کلیک‌کردنی و یک نشانگر دیداری برای تعریف ناحیه مکان‌یابی شتاب‌سنج باشد.

    • منطقه‌ای که شتاب‌سنج در آن قرار دارد نشان‌دهنده فضای واقعی صفحه دستگاه است که معمولاً با دست لمس می‌شود.
    • درطول این اندازه‌گیری، می‌توانید شتاب‌سنج را در ناحیه فیروزه‌ای جابه‌جا کنید تا ناحیه‌ای از صفحه‌نمایش را که قوی‌ترین سیگنال را دریافت می‌کند پیدا کنید.
  4. کد را در دستگاه Android نصب کنید.

  5. اگر حالت پیش‌فرض روی دکمه‌ها تنظیم شده است، اکیداً توصیه می‌شود حالت پیمایش سیستم را روی حالت اشاره‌ای تنظیم کنید

    • با تنظیم حالت اشاره، می‌توانید شتاب‌سنج را تا حد امکان در پایین تلفن قرار دهید، بدون اینکه رابط‌های گرافیکی کاربر پیمایش سیستم تلفن تداخلی ایجاد کنند.

کد منبع جاوا

package com.example.hapticeffectassessment;

import static android.os.VibrationEffect.EFFECT_CLICK;

import android.graphics.Color;
import android.os.Bundle;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;

public class MainActivity extends AppCompatActivity {

 private static final long oneShotTiming = 20;
 private static final int oneShotAmplitude = 255;

 private static final long[] waveformTimings = {500, 500};
 private static final int[] waveformAmplitudes = {128, 255};

 @Override
 protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);

   Vibrator vibrator = getSystemService(Vibrator.class);

   // Click R.id.button1 button to generate Effect 1
   findViewById(R.id.button1).setOnClickListener(
       view -> vibrator.vibrate(VibrationEffect.createPredefined(EFFECT_CLICK)));

   // Click R.id.button2 button to generate Effect 2
   findViewById(R.id.button2).setOnClickListener(
       view -> vibrator.vibrate(VibrationEffect.createOneShot(oneShotTiming, oneShotAmplitude)));

   // Click R.id.button3 button to generate Effect 3
   findViewById(R.id.button3).setOnClickListener(view -> {
     vibrator.vibrate(VibrationEffect.createWaveform(waveformTimings, waveformAmplitudes, -1));

     // See quick results of Effect 3
     Button button = (Button) view;
     if (vibrator.hasAmplitudeControl()) {
       button.setText("Effect 3: PASS");
       button.setBackgroundColor(Color.GREEN);
       button.setTextColor(Color.BLACK);
     } else {
       button.setText("Effect 3: FAIL");
       button.setBackgroundColor(Color.RED);
       button.setTextColor(Color.WHITE);
     }
   });
 }
}

کد منبع Kotlin

package com.example.hapticeffectassessment

import android.graphics.Color
import android.os.Bundle
import android.os.VibrationEffect
import android.os.VibrationEffect.EFFECT_CLICK
import android.os.Vibrator
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*

class MainActivityKt : AppCompatActivity() {

 private val oneShotTiming: Long = 20
 private val oneShotAmplitude = 255

 private val waveformTimings = longArrayOf(500, 500)
 private val waveformAmplitudes = intArrayOf(128, 255)

 override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   setContentView(R.layout.activity_main)

   val vibrator = getSystemService(Vibrator::class.java)

   // Click button1 to generate Effect 1
   button1.setOnClickListener {
     vibrator.vibrate(VibrationEffect.createPredefined(EFFECT_CLICK))
   }

   // Click button2 to generate Effect 2
   button2.setOnClickListener {
     vibrator.vibrate(VibrationEffect.createOneShot(oneShotTiming, oneShotAmplitude))
   }

   // Click button3 to generate Effect 3
   button3.setOnClickListener {
     vibrator.vibrate(
       VibrationEffect.createWaveform(waveformTimings, waveformAmplitudes, -1))

     // See quick results of Effect 3
     if (vibrator.hasAmplitudeControl()) {
       button3.text = "Effect 3: PASS"
       button3.setBackgroundColor(Color.GREEN)
       button3.setTextColor(Color.BLACK)
     } else {
       button3.text = "Effect 3: FAIL"
       button3.setBackgroundColor(Color.RED)
       button3.setTextColor(Color.WHITE)
     }
   }
 }
}

کد منبع چیدمان (activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/button1"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 1"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <Button
       android:id="@+id/button2"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 2"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button1" />

   <Button
       android:id="@+id/button3"
       android:layout_width="350dp"
       android:layout_height="60dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="5dp"
       android:layout_marginEnd="32dp"
       android:text="Effect 3"
       android:textSize="18sp"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button2" />

   <View
       android:id="@+id/divider"
       android:layout_width="363dp"
       android:layout_height="1dp"
       android:layout_marginStart="32dp"
       android:layout_marginTop="10dp"
       android:layout_marginEnd="32dp"
       android:background="?android:attr/listDivider"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHorizontal_bias="0.5"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/button3" />

   <androidx.constraintlayout.widget.ConstraintLayout
       android:layout_width="363dp"
       android:layout_height="0dp"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintEnd_toEndOf="parent"
       app:layout_constraintHorizontal_bias="0.5"
       app:layout_constraintStart_toStartOf="parent"
       app:layout_constraintTop_toBottomOf="@+id/divider">

       <ImageView
           android:id="@+id/imageView"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:adjustViewBounds="true"
           android:scaleType="fitXY"
           app:layout_constraintBottom_toBottomOf="parent"
           app:layout_constraintEnd_toEndOf="parent"
           app:layout_constraintHorizontal_bias="0.5"
           app:layout_constraintStart_toStartOf="parent"
           app:layout_constraintTop_toTopOf="parent"
           app:srcCompat="@drawable/bluebar" />
   </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

شتاب‌سنج

شکل ۳. اتصال شتاب‌سنج در امتداد ناحیه توصیه‌شده در GUI