Android Sensors XI Jornadas SLCENT de Actualización Informática y Electrónica
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
What is a sensor? 3
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
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
Sensor stack Layers of the Android sensor stack and their respective owners 6
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
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
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
HAL / sensors.h Let s see the code https://android.googlesource.com/platform/hardware/libhardware/+/master/include/hardware/sensors.h 10
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
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
Source: http://www.lapis-semi.com/en/semicon/miconlp/sh-mcu.html 13
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
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
classification 1 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
Raw and Composite Sensors classification 2 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
Sensor types supported by the Android platform 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. TYPE_AMBIENT_TEMPERATURE Hardware Measures the ambient room temperature in degrees Celsius ( C). See note below. Motion detection (shake, tilt, etc.). 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). TYPE_LIGHT Hardware Measures the ambient light level (illumination) in lx. 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. Rotation detection (spin, turn, etc.). Controlling screen brightness. Monitoring acceleration along a single axis. Source: http://developer.android.com/guide/topics/sensors/sensors_overview.html 18
Sensor Type Description Common Uses 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. TYPE_PRESSURE Hardware Measures the ambient air pressure in hpa or mbar. 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. TYPE_RELATIVE_HUMIDITY Hardware Measures the relative ambient humidity in percent (%). Determining device position. Monitoring air pressure changes. Phone position during a call. Monitoring dewpoint, absolute, and relative 19
Sensor Type Description Common Uses 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. 20
Sensor Android 4.0 (API Level 14) Sensor availability by platform Android 2.3 (API Level 9) Android 2.2 (API Level 8) 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 Android 1.5 (API Level 3) 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. 21
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
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 sensorrelated 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
SensorManager SensorManager lets you access the device's sensors. Get an instance of this class by calling getsystemservice() with the argument SENSOR_SERVICE. private SensorManager msensormanager;... msensormanager = (SensorManager) getsystemservice(context.sensor_service); 24
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: List<Sensor> devicesensors = msensormanager.getsensorlist(sensor.type_all); Example 2: List<Sensor> devicesensors = msensormanager.getsensorlist(sensor.type_accelerometer); 25
SensorManager Example 3: 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. } 26
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
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
Example: 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. } 29
Sensor Rate @Override protected void onresume() { super.onresume(); msensormanager.registerlistener(this, mlight, SensorManager.SENSOR_DELAY_NORMAL); } @Override protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); } } 30
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
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
Ensuring that a given sensor is present on a device Detect sensors at runtime and enable or disable application features as appropriate. 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. } 34
Ensuring that a given sensor is present on a device Use Google Play filters to target devices with specific sensor configurations. <uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" /> 35
Sensor Coordinate System In general, the sensor framework uses a standard 3-axis coordinate system to express data values. 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. 36
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. private SensorManager msensormanager;... @Override protected void onpause() { super.onpause(); msensormanager.unregisterlistener(this); } 37
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
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
How to use sensors 40
Using the Proximity Sensor Sensor Sensor event data Description Units of measure TYPE_PROXIMITY SensorEvent.values[0] Distance from object. cm 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: 41
Using the Proximity Sensor 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]; Most // Do proximity something sensors with this return sensor the data. absolute distance, in cm, but some } return only near and far values. Most proximity sensors return the absolute distance, in cm, but some return only near and far values. 42
Using the Light, Pressure, and Temperature Sensors Sensor Sensor event data Units of Data description TYPE_AMBIENT_TEMPERATURE event.values[0] measure C Ambient air TYPE_LIGHT event.values[0] lx temperature. Illuminance. TYPE_PRESSURE event.values[0] hpa or mbar Ambient air pressure. TYPE_RELATIVE_HUMIDITY event.values[0] % Ambient relative TYPE_TEMPERATURE event.values[0] C humidity. Device temperature. 1 Implementations vary from device to device. This sensor was deprecated in Android 4.0 (API Level 14). 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. 43
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. } 44
Using Accelerometer Sensor Sensor event data Description Units of measure TYPE_ACCELEROMETER SensorEvent.values[0] Acceleration force along the x axis (including gravity). SensorEvent.values[1] Acceleration force along the y axis (including gravity). m/s SensorEvent.values[2] Acceleration force along the z axis (including gravity). 45
Using Accelerometer 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); 46
Using Accelerometer The norm of <x, y, z> should be close to 0 when in free fall. 47
Using Accelerometer 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: 48
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]; } 49
News Gyroscope http://crypto.stanford.edu/gyrophone/ 50
Good Book :) 51
Android Sensors XI Jornadas SLCENT de Actualización Informática y Electrónica