La evaluación de hardware usa el siguiente software:
- Audacity (instalado en la PC)
- MATLAB (instalado en la PC)
- App de prueba de tecnología háptica (instalada en el DUT)
Para obtener más información sobre los requisitos del sistema, consulta Audacity para Windows, Audacity para Mac y MATLAB.
Cómo configurar Audacity
Audacity debe configurarse para recibir la entrada de la tarjeta de sonido Sound Blaster a una determinada frecuencia de muestreo de datos. Después de conectar el Sound Blaster al puerto USB de la computadora, abre Audacity y sigue estas instrucciones.
Selecciona Line (USB Sound Blaster HD) como la fuente del micrófono de entrada conectando físicamente la salida del CCLD al puerto de entrada Line In de la Sound Blaster.
Figura 1: Cómo seleccionar la entrada de micrófono
Establece la frecuencia de muestreo en 48 kHz seleccionando 48000 en el menú Project Rate.
Figura 2: Cómo configurar la frecuencia de muestreo
Descarga MATLAB
Descarga el archivo de MATLAB.
Extrae el archivo y busca
Effect1NEffect2_V1p0_2020PM.m
(para Effect1 y Effect2) yEffect3_V1p0_2020PM.m
(para Effect3).
Configura la app de prueba en el teléfono
En esta sección, se describe cómo configurar la app de prueba en el teléfono.
Prepara la app de prueba
- Copia el código fuente de los bloques de código de Java y Kotlin que se muestran a continuación. Elige la que mejor se adapte a tus necesidades.
- Escribe tu propio código siguiendo los parámetros de la GUI que se ilustran en la figura 3. Si es necesario, ajusta los detalles del código fuente del diseño para que coincidan con tu teléfono.
Asegúrate de que tu GUI incluya tres botones en los que se pueda hacer clic y un indicador visual para definir el área en la que se ubicará el acelerómetro.
- El área para ubicar el acelerómetro representa el espacio de la pantalla del dispositivo que se suele tocar con la mano.
- Durante esta medición, puedes mover el acelerómetro dentro del área turquesa para encontrar el área de la pantalla que capta la señal más fuerte.
Instala el código en el dispositivo Android.
Se recomienda establecer el modo de navegación del sistema en modo de gestos si el modo predeterminado está configurado como botones.
- Si configuras el modo de gestos, puedes colocar el acelerómetro en la parte inferior del teléfono lo más posible sin que lo interrumpan las GUI de navegación del sistema del teléfono.
Código fuente de 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);
}
});
}
}
Código fuente de 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)
}
}
}
}
Código fuente del diseño (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: Cómo colocar el acelerómetro a lo largo del área recomendada en la GUI