Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Android Sensors

Android Sensors

Presentación utilizada en XI Jornadas SLCENT de Actualización Informática y Electrónica. 19 de Noviembre de 2014, Almería.

http://hacklabalmeria.net/evento/20141119/

Esta charla trata de ofrecer una visión general sobre los diferentes tipos de sensores que podemos encontrar en los dispositivos Android y cómo podemos trabajar con ellos.

José Juan Sánchez Hernández

November 20, 2014
Tweet

More Decks by José Juan Sánchez Hernández

Other Decks in Programming

Transcript

  1. About me José Juan Sánchez Hernández ! Android Developer (In

    my spare time :) ! Member and collaborator of: - Android Almería Developer Group - HackLab Almería @josejuansanchez 2
  2. Microelectromechanical sensors (MEMS) MEMS are sensors that have been made

    on a tiny scale, usually on silicon chips using techniques borrowed from computer-chip manufacturing. 4
  3. What are Android Sensors? Android sensors give applications access to

    a mobile device's underlying physical sensors: ! accelerometers, gyroscopes, magnetometers, barometer, humidity, pressure, light, proximity and heart rate sensors. ! Camera, microphone and touch screen are currently not in the list of physical devices providing data through “Android sensors.” They have their own reporting mechanism. 5
  4. SDK Applications access sensors through the Sensors SDK (Software Development

    Kit) API. ! The SDK contains functions to list available sensors and to register to a sensor. 7
  5. Framework The framework is in charge of linking the several

    applications to the HAL. The HAL itself is single-client. ! Without this multiplexing happening at the framework level, only a single application could access each sensor at any given time. 8
  6. HAL (Hardware Abstraction Layer) The Sensors Hardware Abstraction Layer (HAL)

    API is the interface between the hardware drivers and the Android framework. ! It consists of one HAL interface sensors.h and one HAL implementation we refer to as sensors.cpp. 9
  7. Kernel driver The sensor drivers interact with the physical devices.

    In some cases, the HAL implementation (sensors.cpp) and the drivers are the same software entity. ! HAL implementation and kernel drivers are the responsibility of the hardware manufacturers, and Android does not provide preferred approaches to write them. ! 11
  8. Sensor hub The sensor stack of a device can optionally

    include a sensor hub, useful to perform some low-level computation at low power while the SoC (System on Chip) can be in a suspend mode. ! It is sometimes a separate chip, and sometimes included on the same chip as the SoC. ! Important characteristics of the sensor hub is that it should contain sufficient memory for batching and consume very little power to enable implementation of the low power Android sensors. 12
  9. Sensors Those are the physical MEMs chips making the measurements.

    In many cases, several physical sensors are present on the same chip. ! For example, some chips include an accelerometer, a gyroscope and a magnetometer. Such chips are often called 9-axis chips, as each sensor provides data over 3 axes. ! 14
  10. What is Batching? “Batching” refers to storing sensor events in

    a hardware FIFO before reporting them through the HAL instead of reporting them immediately. ! Batching can enable significant power savings by preventing the SoC from waking up to receive each event. Instead, the events can be grouped and processed together. ! Android 4.4 (KitKat) introduced platform support for hardware sensor batching. 15
  11. Types of Sensors The Android platform supports three broad categories

    of sensors: ! Motion sensors: These sensors measure acceleration forces and rotational forces along three axes. This category includes accelerometers, gravity sensors, gyroscopes and rotational vector sensors. ! Environmental sensors: These sensors measure various environmental parameters, such as ambient air temperature and pressure, illumination, and humidity. This category includes barometers, photometers and thermometers. ! Position sensors: These sensors measure the physical position of a device. This category includes orientation sensors and magnetometers. 16 classification 1
  12. Raw and Composite Sensors Raw sensors (hardware-based): give raw data

    from a sensor, and one raw sensor corresponds to one actual physical component inside the Android device. ! ! Composite sensors (software-based): provide an abstraction layer between application code and low-level device components by either combining the raw data of multiple raw sensors, or by modifying the raw sensor data to make it easier to consume. 17 classification 2
  13. 18 Sensor Type Description Common Uses TYPE_ACCELEROMETER Hardware Measures the

    acceleration force in m/s is applied to a device on all three physical axes (x, y, and z), including the force of gravity. Motion detection (shake, tilt, etc.). TYPE_AMBIENT_TEMPERATURE Hardware Measures the ambient room temperature in degrees Celsius (°C). See note below. Monitoring air temperatures. TYPE_GRAVITY Software or Hardware Measures the force of gravity in m/s applied to a device on all three physical axes (x, y, z). Motion detection (shake, tilt, etc.). TYPE_GYROSCOPE Hardware Measures a device's rate of rotation in rad/s around each of the three physical axes (x, y, and z). Rotation detection (spin, turn, etc.). TYPE_LIGHT Hardware Measures the ambient light level (illumination) in lx. Controlling screen brightness. TYPE_LINEAR_ACCELERATION Software or Hardware Measures the acceleration force in m/s is applied to a device on all three physical axes (x, y, and z), excluding the force of gravity. Monitoring acceleration along a single axis. Sensor types supported by the Android platform Source: http://developer.android.com/guide/topics/sensors/sensors_overview.html
  14. 19 TYPE_MAGNETIC_FIELD Hardware Measures the ambient geomagnetic field for all

    three physical axes (x, y, z) in μT. Creating a compass. TYPE_ORIENTATION Software Measures degrees of rotation that a device makes around all three physical axes (x, y, z). As of API level 3 you can obtain the inclination matrix and rotation matrix for a device by using the gravity sensor and the geomagnetic field sensor in conjunction with the getRotationMatrix() method. Determining device position. TYPE_PRESSURE Hardware Measures the ambient air pressure in hPa or mbar. Monitoring air pressure changes. TYPE_PROXIMITY Hardware Measures the proximity of an object in cm relative to the view screen of a device. This sensor is typically used to determine whether a handset is being held up to a person's ear. Phone position during a call. TYPE_RELATIVE_HUMIDITY Hardware Measures the relative ambient humidity in percent (%). Monitoring dewpoint, absolute, and relative Sensor Type Description Common Uses
  15. 20 TYPE_ROTATION_VECTOR Software or Hardware Measures the orientation of a

    device by providing the three elements of the device's rotation vector. Motion detection and rotation detection. TYPE_TEMPERATURE Hardware Measures the temperature of the device in degrees Celsius (°C). This sensor implementation varies across devices and this sensor was replaced with the TYPE_AMBIENT_TEMPERATURE sensor in API Level 14 Monitoring temperatures. Sensor Type Description Common Uses
  16. 21 Sensor Android 4.0 (API Level 14) Android 2.3 (API

    Level 9) Android 2.2 (API Level 8) Android 1.5 (API Level 3) TYPE_ACCELEROMETER Yes Yes Yes Yes TYPE_AMBIENT_TEMPERATURE Yes n/a n/a n/a TYPE_GRAVITY Yes Yes n/a n/a TYPE_GYROSCOPE Yes Yes n/a n/a TYPE_LIGHT Yes Yes Yes Yes TYPE_LINEAR_ACCELERATION Yes Yes n/a n/a TYPE_MAGNETIC_FIELD Yes Yes Yes Yes TYPE_ORIENTATION Yes Yes Yes Yes TYPE_PRESSURE Yes Yes n/a n/a TYPE_PROXIMITY Yes Yes Yes Yes TYPE_RELATIVE_HUMIDITY Yes n/a n/a n/a TYPE_ROTATION_VECTOR Yes Yes n/a n/a TYPE_TEMPERATURE Yes Yes Yes Yes 1 This sensor type was added in Android 1.5 (API Level 3), but it was not available for use until Android 2.3 (API Level 9). 2 This sensor is available, but it has been deprecated. Sensor availability by platform
  17. Android 4.1.x (Jellybean): New sensor types allow apps to better

    manage sensor readings. A game rotation vector lets game developers sense the device’s rotation without having to worry about magnetic interference. Uncalibrated gyroscope and uncalibrated magnetometer sensors report raw measurements as well as estimated biases to apps . ! Android 4.4 (KitKat): Introduces platform support for hardware sensor batching, a new optimization that can dramatically reduce power consumed by ongoing sensor activities. Adds platform support for two new composite sensors: step detector and step counter. ! Android 5.0 (Lollipop): A new tilt detector and a heart rate sensor reports the heart rate of the person touching the device. New interaction composite sensors are now available to detect special interactions such as a wake up gesture, a pick up gesture, and a glance gesture. 22
  18. Sensors SDK API SensorManager! Is the Android system service that

    gives an app access to hardware sensors. ! Sensor! Is the Android representation of a hardware sensor on a device. ! SensorEventListener! Is an interface that provides the callbacks to alert an app to sensor- related events. ! SensorEvent! Is the data structure that contains the information that is passed to an app when a hardware sensor has information to report. 23
  19. SensorManager SensorManager lets you access the device's sensors. Get an

    instance of this class by calling getSystemService() with the argument SENSOR_SERVICE. 24 ! private SensorManager mSensorManager;! ...! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);!
  20. SensorManager SensorManager provides two methods to access Sensor objects: !

    • getSensorList(): returns all the sensors. • getDefaultSensor(): returns the default sensor for the specified type. ! Example 1: 25 ! List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);! ! List<Sensor> deviceSensors = mSensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);! Example 2:
  21. SensorManager Example 3: 26 ! private SensorManager mSensorManager;! ...! mSensorManager

    = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! ! if (mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){! // Success! There's a magnetometer.! }! else {! // Failure! No magnetometer.! }!
  22. Sensor Sensor represents a hardware sensor on a device. !

    This class provides information about the sensor, such as: ! • Maximum range • Minimum delay • Name • Power • Resolution • Type • Vendor • Version ! Source code: Sensor.java 27
  23. SensorEventListener SensorEventListener is used for receiving notifications from the SensorManager

    when sensor values have changed. In this class there are two public methods: ! • onAccuracyChanged(Sensor sensor, int accuracy) Called when the accuracy of a sensor has changed. ! • onSensorChanged(SensorEvent event) Called when sensor values have changed. 28
  24. 29 ! public class SensorActivity extends Activity implements SensorEventListener {!

    private SensorManager mSensorManager;! private Sensor mLight;! ! @Override! public final void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.main);! ! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! mLight = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);! }! ! @Override! public final void onAccuracyChanged(Sensor sensor, int accuracy) {! // Do something here if sensor accuracy changes.! }! ! @Override! public final void onSensorChanged(SensorEvent event) {! // The light sensor returns a single value.! // Many sensors return 3 values, one for each axis.! float lux = event.values[0];! // Do something with this sensor value.! }! Example:
  25. 30 ! @Override! protected void onResume() {! super.onResume();! mSensorManager.registerListener(this, mLight,

    SensorManager.SENSOR_DELAY_NORMAL);! }! ! @Override! protected void onPause() {! super.onPause();! mSensorManager.unregisterListener(this);! }! }! Sensor Rate
  26. Sensor Rates When you register a listener, you specify the

    delay or measurement rate for the listener. The predefined rates are: ! • SENSOR_DELAY_FASTEST: get sensor data as fast as possible. (0 microsecond delay) ! • SENSOR_DELAY_GAME: rate suitable for games. (20.000 microseconds delay = 0.02 seconds) ! • SENSOR_DELAY_UI: rate suitable for the user interface functions. (60.000 microseconds delay = 0.06 seconds) ! • SENSOR_DELAY_NORMAL: rate suitable for screen orientation changes. (The default value). (200.000 microseconds delay = 0.2 seconds) 31
  27. SensorEvent SensorEvent is the data structure that contains the information

    that is passed to an app when a hardware sensor has information to report. The data members of the SensorEvent are: ! • accuracy: The accuracy of the event. Can have the following values: SensorManager.SENSOR_STATUS_ACCURACY_HIGH SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM SensorManager.SENSOR_STATUS_ACCURACY_LOW SensorManager.SENSOR_STATUS_UNRELIABLE • sensor: An instance of the Sensor class that generated the SensorEvent. • timestamp: The time in milliseconds when the SensorEvent occurred. • values: An array of values that represent sensor data. 33
  28. Ensuring that a given sensor is present on a device

    Detect sensors at runtime and enable or disable application features as appropriate. 34 ! private SensorManager mSensorManager;! ...! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! if (mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){! // Success! There's a pressure sensor.! }! else {! // Failure! No pressure sensor.! }!
  29. Ensuring that a given sensor is present on a device

    Use Google Play filters to target devices with specific sensor configurations. 35 ! <uses-feature android:name="android.hardware.sensor.accelerometer"! android:required="true" />!
  30. Sensor Coordinate System In general, the sensor framework uses a

    standard 3-axis coordinate system to express data values. 36 The coordinate-system is defined relative to the screen of the phone in its default orientation. The axes are not swapped when the device's screen orientation changes.
  31. Best Practices for Accessing and Using Sensors 1) Unregister sensor

    listeners! Always make sure to disable sensors you don't need, especially when your activity is paused. Failing to do so can drain the battery in just a few hours. Note that the system will not disable sensors automatically when the screen turns off. 37 ! private SensorManager mSensorManager;! ...! @Override! protected void onPause() {! super.onPause();! mSensorManager.unregisterListener(this);! }!
  32. Best Practices for Accessing and Using Sensors ! 2) Don’t

    block the onSensorChanged() method! ! Sensor data can change at a high rate, which means the system may call the onSensorChanged(SensorEvent) method quite often. As a best practice, you should do as little as possible within the onSensorChanged(SensorEvent) method so you don't block it. ! 3) Avoid using deprecated methods or sensor types! ! Several methods and constants have been deprecated. In particular, the TYPE_ORIENTATION sensor type has been deprecated. 38
  33. Best Practices for Accessing and Using Sensors 4) Verify sensors

    before you use them! ! Always verify that a sensor exists on a device before you attempt to acquire data from it. Don't assume that a sensor exists simply because it's a frequently-used sensor. ! 5) Choose sensor delays carefully! ! Sensors can provide data at very high rates. Allowing the system to send extra data that you don't need wastes system resources and uses battery power. 39
  34. 41 TYPE_PROXIMITY SensorEvent.values[0] Distance from object. cm Using the Proximity

    Sensor Sensor Sensor event data Description Units of measure The proximity sensor lets you determine how far away an object is from a device. ! The following code shows you how to get an instance of the default acceleration sensor:
  35. Using the Proximity Sensor 42 Most proximity sensors return the

    absolute distance, in cm, but some return only near and far values. ! private SensorManager mSensorManager;! private Sensor mSensor;! ...! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);! ...! ! @Override! public final void onAccuracyChanged(Sensor sensor, int accuracy) {! // Do something here if sensor accuracy changes.! }! ! @Override! public final void onSensorChanged(SensorEvent event) {! float cm = event.values[0];! // Do something with this sensor data.! }! Most proximity sensors return the absolute distance, in cm, but some return only near and far values.
  36. Using the Light, Pressure, and Temperature Sensors 43 The raw

    data you acquire from the light, pressure, and temperature sensors usually requires no calibration, filtering, or modification, which makes them some of the easiest sensors to use. Sensor Sensor event data Units of measure Data description TYPE_AMBIENT_TEMPERATURE event.values[0] °C Ambient air temperature. TYPE_LIGHT event.values[0] lx Illuminance. TYPE_PRESSURE event.values[0] hPa or mbar Ambient air pressure. TYPE_RELATIVE_HUMIDITY event.values[0] % Ambient relative humidity. TYPE_TEMPERATURE event.values[0] °C Device temperature. 1 Implementations vary from device to device. This sensor was deprecated in Android 4.0 (API Level 14).
  37. 44 ! public class SensorActivity extends Activity implements SensorEventListener {!

    private SensorManager mSensorManager;! private Sensor mPressure;! ! @Override! public final void onCreate(Bundle savedInstanceState) {! super.onCreate(savedInstanceState);! setContentView(R.layout.main);! ! // Get an instance of the sensor service, and use that to get an instance of! // a particular sensor.! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! mPressure = mSensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);! }! ! @Override! public final void onAccuracyChanged(Sensor sensor, int accuracy) {! // Do something here if sensor accuracy changes.! }! ! @Override! public final void onSensorChanged(SensorEvent event) {! float millibars_of_pressure = event.values[0];! // Do something with this sensor data.! }!
  38. Using Accelerometer 45 Sensor Sensor event data Description Units of

    measure TYPE_ACCELEROMETER SensorEvent.values[0] Acceleration force along the x axis (including gravity). m/s SensorEvent.values[1] Acceleration force along the y axis (including gravity). SensorEvent.values[2] Acceleration force along the z axis (including gravity).
  39. Using Accelerometer 46 An acceleration sensor measures the acceleration applied

    to the device, including the force of gravity. ! The following code shows you how to get an instance of the default acceleration sensor: ! private SensorManager mSensorManager;! private Sensor mSensor;! ...! mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);! mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);!
  40. Using Accelerometer 47 The norm of <x, y, z> should

    be close to 0 when in free fall.
  41. Using Accelerometer 48 To measure the real acceleration of the

    device, the contribution of the force of gravity must be removed from the accelerometer data. ! This can be achieved by applying a high-pass filter. Conversely, a low-pass filter can be used to isolate the force of gravity. ! ! The following example shows how you can do this:
  42. 49 ! public void onSensorChanged(SensorEvent event){! // In this example,

    alpha is calculated as t / (t + dT),! // where t is the low-pass filter's time-constant and! // dT is the event delivery rate.! ! final float alpha = 0.8;! ! // Isolate the force of gravity with the low-pass filter.! gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];! gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];! gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];! ! // Remove the gravity contribution with the high-pass filter.! linear_acceleration[0] = event.values[0] - gravity[0];! linear_acceleration[1] = event.values[1] - gravity[1];! linear_acceleration[2] = event.values[2] - gravity[2];! }!