Reputation: 517
I'm having some issues getting data from the accelerometer and gyroscope simultaneously. I need to use these sensors to get acceleration and orientation in order to calculate relative position for a project I'm working on. When both sensors are used at the same time it leads to some very weird data output, in which the data only changes once every second. When only the accelerometer is run the data is not much better because it is only changing roughly 10 times a second on its fastest setting. This data is printed out to a file with a time stamp for each sensor reading.
I'm having trouble finding tutorials on the internet, particularly using more than one sensor together at the same time. Do I need to put each sensor on a different thread? I don't have much experience using threads, how could I do this.
Upvotes: 4
Views: 12617
Reputation: 355
Java code
import android.content.pm.ActivityInfo;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.content.Context;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
TextView textX, textY, textZ;
SensorManager sensorManager;
Sensor sensor;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
textX = findViewById(R.id.textX);
textY = findViewById(R.id.textY);
textZ = findViewById(R.id.textZ);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
public void onResume() {
super.onResume();
sensorManager.registerListener(gyroListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);
}
public void onStop() {
super.onStop();
sensorManager.unregisterListener(gyroListener);
}
public SensorEventListener gyroListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int acc) {
}
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
textX.setText("X : " + (int) x + " rad/s");
textY.setText("Y : " + (int) y + " rad/s");
textZ.setText("Z : " + (int) z + " rad/s");
}
};
}
XML file code
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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">
<TextView
android:id="@+id/textX"
android:layout_width="209dp"
android:layout_height="79dp"
android:layout_marginStart="91dp"
android:layout_marginLeft="91dp"
android:layout_marginEnd="111dp"
android:layout_marginRight="111dp"
android:gravity="center"
android:text=""
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textY"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/textY"
android:layout_width="209dp"
android:layout_height="79dp"
android:layout_marginStart="91dp"
android:layout_marginLeft="91dp"
android:layout_marginEnd="111dp"
android:layout_marginRight="111dp"
android:layout_marginBottom="8dp"
android:gravity="center"
android:text=""
android:textSize="30sp"
app:layout_constraintBottom_toTopOf="@+id/textZ"
app:layout_constraintEnd_toEndOf="@+id/textX"
app:layout_constraintHorizontal_bias="0.445"
app:layout_constraintStart_toStartOf="@+id/textX"
app:layout_constraintTop_toBottomOf="@+id/textX"
tools:ignore="MissingConstraints" />
<TextView
android:id="@+id/textZ"
android:layout_width="209dp"
android:layout_height="79dp"
android:layout_marginStart="153dp"
android:layout_marginLeft="153dp"
android:layout_marginEnd="49dp"
android:layout_marginRight="49dp"
android:layout_marginBottom="241dp"
android:gravity="center"
android:text=""
android:textSize="30sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/textY"
app:layout_constraintHorizontal_bias="0.757"
app:layout_constraintStart_toStartOf="@+id/textY"
app:layout_constraintTop_toBottomOf="@+id/textY"
tools:ignore="MissingConstraints" />
</android.support.constraint.ConstraintLayout>
Upvotes: 3
Reputation: 1888
This Kotlin solution is derived from Kroka's solution:
class MainActivity : AppCompatActivity(), SensorEventListener {
private lateinit var mSensorManager:SensorManager
private lateinit var mAccelerometer :Sensor
private lateinit var mGyroscope :Sensor
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mSensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mGyroscope = mSensorManager.getDefaultSensor(TYPE_GYROSCOPE)
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onSensorChanged(event: SensorEvent?) {
val sensorName: String = event?.sensor!!.getName();
Log.d("Sensor",sensorName + ": X: " + event.values[0] + "; Y: " + event.values[1] + "; Z: " + event.values[2] + ";")
}
override fun onResume() {
super.onResume()
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL)
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_NORMAL)
}
override fun onPause() {
super.onPause()
mSensorManager.unregisterListener(this)
}
}
Upvotes: 1
Reputation: 475
You don't need to put each sensor on a different thread. Yo can use the class SensorManager to register and unregister the different sensors that you need
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mAccelerometer;
private final Sensor mGyroscope;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mGyroscope = mSensorManager.getDefaultSensor(TYPE_GYROSCOPE);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
Implements the sensorEventList handler (specially the method onSensorChanged) and check who belongs the received data:
public void onSensorChanged(SensorEvent sensorEvent) {
sensorName = sensorEvent.sensor.getName();
Log.d(sensorName + ": X: " + sensorEvent.values[0] + "; Y: " + sensorEvent.values[1] + "; Z: " + sensorEvent.values[2] + ";");
}
Upvotes: 11