Most smartphones feature a 3-axis Gyroscope, a 3-axis magnetometer and a 3-axis accelerometer. Combining these sensors' measurements in a clever way (Kalman filter) should yield a fast, accurate, noise free and absolute device orientation. This could be stored as a quaternion or yaw/pitch/roll values.
What is the simplest way to achieve this in Android? Does the operating system already do those calculations for you? Are there open source implementations that one could use?
Most examples/tutorials I could find only focus on one type of sensor. But for my use case only the fusion of all three sensors via proper filtering would be of interest...
You need to implements SensorEventListener interface.
and in your class you must declare these :
Sensor sensor;
SensorManager sensorManager;
and override these methods:
public void onAccuracyChanged(Sensor sensor,int accuracy)
{
}
public void onSensorChanged(SensorEvent event)
{
}
and in constructor of your class(Activity or...)
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sensorManager.registerListener(this,sensor,SensorManager.SENSOR_DELAY_GAME);
Related
I want to detect the movement of the hand dynamically and modify sound accordingly. The phone is in the hand in a fixed orientation which does not change. For Example, I am holding the phone in my stretched hand and as it moves to the right or left, my music volume changes dynamically; If I move up and down the speed of playing changes and moving at some intermediate angle changes both speed and volume accordingly. I charted the accelerometer data while doing these motions and there seems to be some pattern but I am not sure how to filter those. I have looked at a lot of posts - High Pass/Low Pass filters, Kalman Filters, Gesture Recognizers but it is difficult to understand what is the appropriate method. Most of the posts don't seem to detect dynamically - but only when a certain gesture is finished. I only need to use accelerometer and not gyroscope and any other sensor. What is the correct approach here? Are there any existing libraries that do this?
if your activity implements
SensorEventListener
and you use the variables
private SensorManager sensorManager;
private Sensor mAccelerometer;
in your OnCreate() you instantiate them and register the listener like this:
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, mAccelerometer,
SensorManager.SENSOR_DELAY_FASTEST);
and then use this method to get the accelerometer data
public void onSensorChanged(SensorEvent event) {
double x = event.values[0];
double y = event.values[1];
double z = event.values[2];
}
and you can take it from there depending on the values you get from the accelerometer, make the changes to the volume or whatever
i want to get and move needle on co-ordinates as per user rotates or move device as compass does also as this app is doing already.you can see what i want to say on this link https://play.google.com/store/apps/details?id=com.plaincode.clinometer&hl=en but now at this time i am not able to understand on this context. i am unable to find hint for how to start..is their is any api to get and make it work or need to implement accelerometer on a very extensive level to get it done. please guide me if u have any code or link regarding this..thank in advance
I was looking for this solution more than a year ago and for that somehow i managed to do this similar this way. and source for that which i managed to do is -- link to source
You should start creating an activity that implements SensorEventListener, including the two following methods:
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
// add your code
// event.values[] contains the 3 accelerometer values
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int i) {
// add your code
}
As second step, start with the implementation of accelerometers into the Activity:
private SensorManager mSensorManager;
private Sensor mRotationSensor;
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Then register a sensor listener on it (you could do in onResume):
mSensorManager.registerListener(this, mRotationSensor, 16000);
// 16000 microseconds
and unregister it (in onPause):
mSensorManager.unregisterListener(this);
Please note that, if you want a very accurate measurement of angles and slopes in the 3 dimensions, you should implement a calibration routine of the onboard accelerometers, that usually need a small compensation in gain, offset and angle.
You can read a simple but complete usage of Accelerometers on the free and opensource BasicAirData Clinometer: https://github.com/BasicAirData/Clinometer
The app includes also a calibration routine.
I am developing a application which needs a new acceleration datum every 10 millisecond. And i need to save the data into a files. Can anyone give me some android accelerometer example codes as reference? Thanks very much.
Read up on the SensorManager to learn how to get accelerometer data:
http://developer.android.com/reference/android/hardware/SensorManager.html
You can access the SensorManager straight from your application context.
SensorManager manager = (SensorManager) context.getSystemService(Context.SensorManager);
Then you register a SensorEventListener, the sensor you want to listen to, and the rate. The SensorManager class provides constants for the refresh rate. For your purposes, SENSOR_DELAY_GAME might be fast enough, but I feel like SENSOR_DELAY_FASTEST is a safer bet. To my knowledge, there's no hard numbers on the rates of the defaults, so just see what works best.
Sensor accel = manager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
manager.registerListener(new MySensorEventListener(), accel, SensorManager.SENSOR_DELAY_GAME);
Then, every time a new event is polled from the accelerometer, it will call the listener's onSensorChanged method:
public class MySensorEventListener implements SensorEventListener {
#Override
public void onSensorChanged(SensorEvent event) {
// do what you need to do with the data from event
}
}
I am developing an android app for my project, I need to find room temperature as part of it. I am using Droid 2 A955 model for testing.
My Questions are:
What sensors need to be available in my Android phone to perform
this temperature sensing task?
Can Ambient Light Sensor (available in Droid 2) help in doing this
task?
Is there any Android api to find/sense room temperature
programmatically in my android code?
Thanks in advance for your help.
To answer all three of your questions in one fell swoop, no, I don't believe so. There can be a temperature sensor in android devices, but it senses the temperature of the battery, not the outside temperature. It would not provide an accurate gauge for that purpose.
I'm not sure how an ambient light sensor would help with temperature, it can be very bright out but it could be in an air conditioned room.
Lastly: there are lots of examples of temperature apps, but again, most are related to the battery.
Edit: Official documentation says:
Device implementations MAY but SHOULD NOT include a thermometer (i.e. temperature sensor.) If a device implementation does include a
thermometer, it MUST measure the temperature of the device CPU. It MUST NOT measure any other temperature. (Note that this sensor type is
deprecated in the Android 2.3 APIs.)
Update:
API level 14 (i.e. Android 4.0) onwards, support for measuring ambient temperature has been added (via TYPE_AMBIENT_TEMPERATURE). [Android doc reference]
This, however, will work only on devices with ambient temperature sensor.
It seems that there is a new sensor in the API.
This one is for the ambient temperature, but probably there are just a few devices with this implemented.
UPDATE: it seems that the Galaxy S4 is the first phone integrating ambient temperature sensor
You'll want to check out the Sensor reference docs. Offhand, I don't think there are accessible temperature sensors on-board most handhelds though.
Take a look at the Sensor class in the documentation.
You need to do something along the lines of this:
public class SensorActivity extends Activity, implements SensorEventListener {
private final SensorManager mSensorManager;
private final Sensor mTemp;
public SensorActivity() {
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
mtemp = mSensorManager.getDefaultSensor(Sensor.TYPE_TEMPERATURE);
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mTemp, SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public void onSensorChanged(SensorEvent event) {
}
}
This should give you access to the temperature sensors in it's own activity.
Play with this and see what you can find. The documentation has great examples for other types of sensors, the temp sensor should be even simpler than most of the provided ones.
Hope this helps!
You can use the iCelsius Wireless from Kickstarter. It has an API. It is impossible to measure accurately temperature using an internal sensor from a SmartPhone. It will always be few degree to high.
i have same your question long time ago. And what my found is :
check this offical site for Environment sensor
this tuts for environment sensor : Ambient Temperature (room temp) Ambient Light ... Tutsplus. on my phone only Ambient Light work
now as i know only samsung galaxy S4 have Ambient Temperature. if you have S4 search Holo Ambient Temperature on gg playstore .
this sounds interesting:
http://developer.android.com/reference/android/hardware/Sensor.html#TYPE_AMBIENT_TEMPERATURE
from API >= 13
There is the age old method of letting the phone and a "good" thermometer stabilize at room temperature (a few hours) and read both.
Then put it outside in a nice wintry garage at about 35F let it stabilize. Then pray for linearity.
Empirical is always nice. I am very interested in measuring a constant temperature in an empty house, and watch for the temperature dropping (or rising!!)
Bradshaw at Buzzards Bay
Try this one:
private float temperature = 0;
In onCreate put wìthis code:
SensorManager mySensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor AmbientTemperatureSensor
= mySensorManager.getDefaultSensor(Sensor.TYPE_AMBIENT_TEMPERATURE);
if (AmbientTemperatureSensor != null) {
mySensorManager.registerListener(
AmbientTemperatureSensorListener,
AmbientTemperatureSensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
And the method below:
private final SensorEventListener AmbientTemperatureSensorListener
= new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_AMBIENT_TEMPERATURE) {
temperature = event.values[0];
}
}
};
I'm making my first Android application. As a toy problem to learn the system I want to make a simple app that display as text which direction the phone is pointing using the built in compass.
How do I access the compass from my code, and have my code be aware of direction changes?
I believe I'll need the SensorManager class but I'm confused how to use it. How do I tell it I want the compass sensor? How do I tell it to do an action (update text) on a direction change?
// First, get an instance of the SensorManager
SensorManager sMan = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
// Second, get the sensor you're interested in
Sensor magnetField = sMan.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
// Third, implement a SensorEventListener class
SensorEventListener magnetListener = new SensorEventListener() {
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// do things if you're interested in accuracy changes
}
public void onSensorChanged(SensorEvent event) {
// implement what you want to do here
}
};
// Finally, register your listener
sMan.registerListener(magnetListener, magnetField, SensorManager.SENSOR_DELAY_NORMAL);
However, please note that this is actually a magnetic sensor; therefore if you have magnetic interference around you, it may be pointing to the wrong direction. Also, you need to know the difference between True North and Magnetic North. Since this code uses magnetic sensor, you obtain the Magnetic North, but if you need to calculate the True North, you would need to do some adjustments with GeomagneticField.getDeclination().
Have a look at the API demos. There is an application that has already been written which access the compass and accelerometer. Maybe that will give you a better idea on how you can go about your task.
you shall find it in:
/android-sdk-linux_86/samples/android-8/ApiDemos/src/com/example/android/apis/os/sensor.java
hope it helps.
First you should check if a compass sensor is present on the system
PackageManager m = getPackageManager();
if(!m.hasSystemFeature(PackageManager.FEATURE_SENSOR_COMPASS)) {
Log.d("COMPASS_SENSOR", "Device has no compass");
}