0

I'm trying to use the sensors API for the accelerometers on a test phone (Nexus S). With the phone sitting on the bench doing nothing, I get some very strange readings (image attached). Has anyone else seen this sort of behavior?Glitches in accel reading? Any idea how to deal with it?

   package com.example.m6;

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.util.Calendar;

import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.view.Window;
import android.view.WindowManager;
import android.widget.TextView;
//import android.widget.Toast;

public class HelloAndroidActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager; 
    private TextView tv;
    private float accel[] = {0,0,0};
    private float gyro[] = {0,0,0};


    InetAddress addr; 
    int port         = 1337;
    DatagramSocket s = null;
    String out       = "";
    PowerManager.WakeLock wl;

    /** Called when the activity is first created. */

    @Override
    public void onCreate(Bundle savedInstanceState) {
        try{
            //Lock the screen 
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

            //Set up the output screen
            setContentView(R.layout.main);
            tv = (TextView) findViewById(R.id.textview);
            tv.setBackgroundColor(Color.BLACK);
            tv.setTextColor(Color.GREEN);

            //Set up the telemetry feed 
            addr = InetAddress.getByName("192.168.0.12");
            s = new DatagramSocket();

            //Turning off the power management!!
            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
            wl = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "My Tag");
            wl.acquire(); 

            //Set up the sensors
            sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

            out += "Done\n";
            tv.setText(out);

        } catch (Exception e) {
            out += "\nInit Error:" + e.getMessage() + "\n";
            tv.setText(out);
        }

    }

    private static final float NS2S = 1.0f / 1000000000.0f;
    private float timestamp;

    int down = 0; 
    float tstart = 0;
    @Override
    public void onSensorChanged(SensorEvent event) {            

        String type = "";
        float dT = 0;       
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
            if (timestamp != 0) {
                accel = event.values;
                dT = (event.timestamp - timestamp);
                tstart += dT;
            }
            timestamp = event.timestamp;
            type = "G";
        }

        if(event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
            if (timestamp != 0) {
                gyro = event.values;
                dT = (event.timestamp - timestamp);
                tstart += dT;
            }
            timestamp = event.timestamp;
            type = "A";
        }

        String out_packet = tstart / 1000 / 1000 + " "+ type + " " + dT + " " + accel[0] + " " + accel[1] + " " + accel[2] + " " + gyro[0] + " " + gyro[1] + " " + gyro[2] + "\n\0";

        try{
            DatagramPacket p = new DatagramPacket(out_packet.getBytes(),out_packet.length(), addr,port);
            s.send(p);
        }
    catch (Exception e) {
            out += "Packet send error: " + e.getMessage() + "\n";
        }

        tv.setText(timestamp + "\n" + out);
    }

    @Override
    protected void onResume() {
        super.onResume();
        out += "on resume\n";
        sensorManager.registerListener(this,sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_NORMAL);
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);
        tv.setText(out);
    }

    @Override
    protected void onPause() {
        out += "on pause";
        sensorManager.unregisterListener(this);
        tv.setText(out);
        super.onStop();

    }

    @Override
    protected void onDestroy() {
        out += "on destroy";
        wl.release();
        tv.setText(out);
        super.onDestroy();
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // TODO Auto-generated method stub

    }
}
MattieG
  • 1
  • 2
  • In using a Droid 1, I didn't notice any anomalies like that. I always had to use thresholds for what I wanted to detect (movement sequences) and wasn't trying to detect "any" motion events, though. – Matt H Oct 28 '11 at 03:17
  • I've added code. Hopefully this will be helpful about what events I'm listening to. – MattieG Oct 28 '11 at 03:54

2 Answers2

0

The code would be nice.. try this demo code. I know it works and makes a graph.

http://www.5laida.com/docs/android/samples/Sensors.html

I've tested this code on several devices.. So if that shows the same glitches, then it's probably your device.

DJPlayer
  • 3,244
  • 2
  • 33
  • 40
  • Yes of course! That was silly of me. Have edited question to include source. I should warn you, I'm mainly a C/C++ developer, my Java is pretty rusty. So, its possible I'm doing something wrong in the code. I just have no intuition in this language. – MattieG Oct 28 '11 at 03:46
0

I've figured out what's going on. I needed to include this line:

        if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE ){
        return;
    }

However, by doing so, I now get no values out of the gyroscope. Hmm...

MattieG
  • 1
  • 2
  • And here's the answer to that question: http://stackoverflow.com/questions/5985514/android-xoom-accelererometer-accuracy-is-always-unreliable/6141875#6141875 – MattieG Oct 28 '11 at 11:26
  • I'm not looking at the source for event.accuracy or Sensor_Status_unrelaible.. but does event.accuarcy ouput a numeric value.. it so maybe you can set a threshold. Looking at your graph the problem is complete drops. You could always with some if statements to exclude making changes if the change is to quick and drastic. It's hard to support all devices, especially when the OS differes but also the quality of the physical telephone build. – DJPlayer Oct 28 '11 at 11:59
  • Congrats on the solution. When you are able, please make sure to mark your answer as 'accepted' so that others might learn from you success. Cheers~ – Andrew Kozak Dec 21 '11 at 18:37