La valutazione dell'hardware utilizza il seguente software:
- Audacity (installato sul PC)
- MATLAB (installato sul PC)
- App di test aptico (installata sul DUT)
Per saperne di più sui requisiti di sistema, consulta Audacity per Windows, Audacity per Mac e MATLAB.
Configurare Audacity
Audacity deve essere configurato per ricevere input dalla scheda audio Sound Blaster a una determinata frequenza di campionamento dei dati. Dopo aver collegato Sound Blaster alla porta USB del computer, apri Audacity e segui queste istruzioni.
Seleziona Line (USB Sound Blaster HD) come sorgente del microfono di ingresso collegando fisicamente l'uscita CCLD alla porta di ingresso Line In di Sound Blaster.
Figura 1. Selezionare l'input del microfono
Imposta la frequenza di campionamento su 48 kHz selezionando 48000 nel menu Project Rate.
Figura 2. Impostazione della frequenza di campionamento
Scaricare MATLAB
Scarica il file MATLAB.
Estrai il file e trova
Effect1NEffect2_V1p0_2020PM.m(per Effetto 1 ed Effetto 2) eEffect3_V1p0_2020PM.m(per Effetto 3).
Configurare l'app di test sullo smartphone
Questa sezione descrive come configurare l'app di test sullo smartphone.
Prepararsi per l'app di test
- Copia il codice sorgente dai blocchi di codice Java e Kotlin riportati di seguito. Scegli quella più adatta a te.
- Scrivi il tuo codice seguendo i parametri della GUI illustrati nella Figura 3. Se necessario, modifica i dettagli del codice sorgente del layout in modo che corrispondano a quelli del tuo smartphone.
Assicurati che la GUI includa tre pulsanti su cui è possibile fare clic e un indicatore visivo per definire l'area in cui si trova l'accelerometro.
- L'area in cui si trova l'accelerometro rappresenta lo spazio dello schermo del dispositivo che viene toccato più spesso con la mano.
- Durante questa misurazione, puoi spostare l'accelerometro all'interno dell'area turchese per trovare l'area dello schermo che acquisisce il segnale più forte.
Installa il codice sul dispositivo Android.
Se la modalità predefinita è impostata sui pulsanti, è consigliabile impostare la modalità di navigazione del sistema sui gesti.
- Impostando la modalità Gesti, puoi posizionare l'accelerometro il più possibile nella parte inferiore dello smartphone senza essere interrotto dalle GUI di navigazione del sistema dello smartphone.
Codice sorgente Java
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);
}
});
}
}
Codice sorgente 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)
}
}
}
}
Codice sorgente del layout (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>
Figura 3. Fissaggio dell'accelerometro lungo l'area consigliata nella GUI