Supported sensors

In the BlackBerry 10 Native SDK, you can access data from the device sensors using the BlackBerry Platform Services sensors or Qt sensors. The following sections describe supported sensors and how to access them in your app.

Accelerometer

The accelerometer measures the acceleration (including the force of gravity) applied to the device. This sensor is useful if your app is designed to handle motion input from a user. For example, in a racing game, the user might control the car's direction by tilting the device from side-to-side.

BlackBerry device showing the positive and negative x, y, and z axes of the sensor coordinates.

Acceleration values are reported in meters per second per second (m/s2).

When the device is lying on a flat surface in its natural orientation (for example, the BlackBerry logo is right-side-up and facing the user), the following are true:

  • Pushing the device to the right results in a positive acceleration value along the x axis.
  • Pushing the device away from the user results in a positive acceleration value along the y axis.
  • Pushing the device directly off the flat surface and into the air results in a positive acceleration along the z-axis. This acceleration includes the acceleration caused by the movement off the surface (accelup), minus the force of gravity. That is, accelz = accelup - (-9.81 m/s2) = accelup + 9.81 m/s2. At rest, the acceleration along the z-axis of the device is 9.81 m/s2.

If you are developing a Cascades app using QML or C++, you might want to configure the sensor to report only on certain types of movements by using the accelerationMode property. Possible values are Gravity (only movements caused by gravity), User (only movements caused by the user), and Combined (the default value). For more information, see QAccelerometer, QAccelerometerReading, and QAccelerometerFilter.

If you are developing an app using C, a BPS event with the code SENSOR_ACCELEROMETER_READING is generated when new accelerometer values are available. You can call the function sensor_event_get_xyz() to retrieve the acceleration values from the event.

The following code sample reads the accelerometer G-forces when the BlackBerry 10 device is tilted or moved. These forces allow the screen to be aligned with the orientation of the device.

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Accel: " + accel.x.toFixed(3) + "  " +
                    accel.y.toFixed(3) + "  " +
                    accel.z.toFixed(3) + " m/s/s"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
            layoutProperties: StackLayoutProperties {}
        }   
    }
    
    attachedObjects: [
        Accelerometer {
            id: accel
            property double x: 0
            property double y: 0
            property double z: 0
            active: true
            onReadingChanged: {
                accel.x = reading.x;
                accel.y = reading.y;
                accel.z = reading.z;    
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QAccelerometer>
#include <QtSensors/QAccelerometerReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    accel_label = new Label();
    top_container->add(accel_label);

	m_accel = new QAccelerometer(this);

    bool connectResult;
    
    Q_UNUSED(connectResult);
    
    connectResult = connect(m_accel, 
                            SIGNAL(readingChanged()),
                            this, 
                            SLOT(accelReadingChanged()));

    Q_ASSERT(connectResult);
    
	m_accel->start();
}

void SensorsApp::accelReadingChanged()
{
    QAccelerometerReading *reading = m_accel->reading();
    qreal x = reading->x();
    qreal y = reading->y();
    qreal z = reading->z();
    QString data = QString("Accel: %1  %2  %3 m/s/s")
   	    .arg(x, 0, 'f', 3).arg(y, 0, 'f', 3).arg(z, 0, 'f', 3);
    accel_label->setText(data);
}
#include <bps/sensor.h>
#include <bps/bps.h>
#include <stdio.h>

static const int ACCELEROMETER_RATE = 25000;
float force_x, force_y, force_z;
int angle = 0; 

bps_initialize();

if (!sensor_is_supported(SENSOR_TYPE_ACCELEROMETER)) {
    printf("Accelerometer not supported by device!");
    bps_shutdown();
    return EXIT_FAILURE;
}

sensor_set_rate(SENSOR_TYPE_ACCELEROMETER, ACCELEROMETER_RATE);
sensor_set_skip_duplicates(SENSOR_TYPE_ACCELEROMETER, true);

sensor_request_events(SENSOR_TYPE_ACCELEROMETER);

while (!shutdown) {
    bps_event_t *event = NULL;
    bps_get_event(&event, 0);


    if (event) {
        if (bps_event_get_domain(event) == sensor_get_domain()) {
            if (SENSOR_ACCELEROMETER_READING == bps_event_get_code(event)) {
                sensor_event_get_xyz(event,
                                     &force_x,
                                     &force_y,
                                     &force_z);

                /* Handle accelerometer readings here */
            }
        } else if (bps_event_get_domain(event) == navigator_get_domain()) {
            switch (bps_event_get_code(event)) {
            case NAVIGATOR_ORIENTATION:
                /* Get device orientation angle with respect to gravity */
                angle = navigator_event_get_orientation_angle(event);
                
                /* Instruct the sensor service to remap sensor data to
                   match the device orientation.
                   This remaps data that is returned by the functions:
                    - sensor_event_get_apr()
                    - sensor_event_get_rotation_matrix()
                    - sensor_event_get_rotation_xyz() 
                */

                sensor_remap_coordinates(angle);
                break;
            }
        }
    }
}

Ambient light sensor

If you are developing a Cascades app using QML or C++, you can use the ambient light sensor to retrieve a constant representing the current brightness of the external environment (dark, bright, sunny, and so on). This sensor is commonly used to help save the device's battery power level by checking the ambient light level and adjusting the backlighting of the device accordingly.

For more information, see QAmbientLightSensor, QAmbientLightReading, and QAmbientLightFilter.

The following code sample demonstrates how you can use the light sensor in your app:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Ambient Light Sensor: " + (als.data)
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        AmbientLightSensor {
            id: als
            property string data: ""
            active: true
            onReadingChanged: {
                if (reading.lightLevel == AmbientLightReading.Dark)
                    als.data = "Dark";
                else if (reading.lightLevel == AmbientLightReading.Twilight)
                    als.data = "Twilight";
                else if (reading.lightLevel == AmbientLightReading.Light)
                    als.data = "Light";
                else if (reading.lightLevel == AmbientLightReading.Bright)
                    als.data = "Bright";
                else if (reading.lightLevel == AmbientLightReading.Sunny)
                    als.data = "Sunny";
                else
                    als.data = "Undefined";
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QAmbientLightSensor>
#include <QtSensors/QAmbientLightReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    als_label = new Label();
    top_container->add(als_label);

	m_als = new QAmbientLightSensor(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_als, 
	                        SIGNAL(readingChanged()), 
	                        this,
							SLOT(alsReadingChanged()));

    Q_ASSERT(connectResult);
    
    m_als->start();
}

void SensorsApp::alsReadingChanged()
{
    QAmbientLightReading *reading = m_als->reading();
    QString data = QString ("Ambient Light Sensor: ");
    switch (reading->lightLevel())
    {
        case QAmbientLightReading::Undefined:
           data = data + QString ("Undefined");
           break;
        case QAmbientLightReading::Dark:
        	data = data + QString ("Dark");
        	break;
        case QAmbientLightReading::Twilight:
        	data = data + QString ("Twilight");
        	break;
        case QAmbientLightReading::Light:
        	data = data + QString ("Light");
            break;
        case QAmbientLightReading::Bright:
        	data = data + QString ("Bright");
        	break;
        case QAmbientLightReading::Sunny:
        	data = data + QString ("Sunny");
        	break;
    }
    als_label->setText(data);
}

Azimuth, pitch, and roll

The azimuth, pitch, and roll values provide the following positioning information about the device:

Azimuth
The heading of the device, which is the angle between the device's y-axis and magnetic north.
Pitch
The rotation around the device's x axis
Roll
The rotation around the device's y axis

If you are developing a Cascades app using QML or C++, the rotation sensor returns a reading containing three angles, measured in degrees, that define the orientation of the device in three-dimensional space. These angles are similar to yaw, pitch, and roll but are defined using only right-hand rotation with axes as defined by the right-hand Cartesian coordinate system. You can also use the Compass sensor to find the device heading.

If you are developing an app using C, a BPS event with the code SENSOR_AZIMUTH_PITCH_ROLL_READING is generated when new azimuth, pitch, and roll values are available. You can call the function sensor_event_get_apr() to retrieve the azimuth, pitch, and roll values from the event. Pitch and roll values are reported in degrees.

The following code sample demonstrates how you can use the azimuth, pitch, and roll sensor in your app:

Not applicable

Not applicable

#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>

int main(void)
{
  int event_domain;
  unsigned int event_code;

  /* Create variables to store the current */ 
  /* azimuth, pitch, and roll values */
  float azimuth, pitch, roll;

  bps_initialize();

  if (sensor_is_supported(SENSOR_TYPE_AZIMUTH_PITCH_ROLL))
  {
    sensor_request_events(SENSOR_TYPE_AZIMUTH_PITCH_ROLL);
  }

  while (1)
  {
    bps_event_t *current_event = NULL;
    bps_get_event(&current_event, -1);

    event_domain = bps_event_get_domain(current_event);
    event_code = bps_event_get_code(current_event);

    if (event_domain == sensor_get_domain())
    {
      switch (event_code)
      {
        case SENSOR_AZIMUTH_PITCH_ROLL_READING:
          /* Get current azimuth, pitch, and roll values */
          sensor_event_get_apr(current_event, 
                               &azimuth, 
                               &pitch, 
                               &roll);
          /* Adjust application based on the  */
          /* azimuth, pitch, and roll values */
          break;

        default:
          break;
      }
    }
  }

  /* Clean up */
  sensor_stop_events(SENSOR_TYPE_GYROSCOPE);
  bps_shutdown();

  return 0;
}

Compass

If you are developing a Cascades app using QML or C++, the compass sensor takes the 3D device orientation and turns it into a 2D device heading (otherwise known as the azimuth). For more information, see QCompass, QCompassReading, and QCompassFilter.

The following code sample demonstrates how you can capture readings from the compass sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Compass Azimuth: " + compass.azimuth.toFixed(3) + 
                    " deg"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        Compass {
            id: compass
            property double azimuth: 0
            active: true
            onReadingChanged: {
                compass.azimuth = reading.azimuth;
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QCompass>
#include <QtSensors/QCompassReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    compass_label = new Label();
    top_container->add(compass_label);

	m_compass = new QCompass(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_compass, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(compassReadingChanged()));

    Q_ASSERT(connectResult);
							 
	m_compass->start();
}

void SensorsApp::compassReadingChanged()
{
    QCompassReading *reading = m_compass->reading();
    qreal azimuth = reading->azimuth();
    QString data = QString("Azimuth: %1 deg")
   	    .arg(azimuth);
	compass_label->setText(data);
}

Gravity

Gravity is a fused sensor that removes the effects of user (or linear) acceleration. A BPS event with the code SENSOR_GRAVITY_READING is generated when a new gravity reading is available.

Gravity is calculated by subtracting the device's linear acceleration from its acceleration: GRAVITY = ACCELERATION - LINEAR ACCELERATION

Gravity values are reported in meters per second per second (m/s2).

A BPS event with the code SENSOR_GRAVITY_READING is generated when new gravity values are available. You can call the function sensor_event_get_xyz() to retrieve the gravity values from the event.

The following code sample demonstrates how you can use the gravity sensor in your app:

Not applicable

Not applicable

#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>

int main(void)
{
    int eventDomain;
    unsigned int event_code;

    /* Create variables to store the current linear acceleration values */
    float x_gravity, y_gravity, z_gravity;

    bps_initialize();

    if (sensor_is_supported(SENSOR_TYPE_GRAVITY))
    {
        sensor_request_events(SENSOR_TYPE_GRAVITY);
    }

    while (1)
    {
        bps_event_t *current_event = NULL;
        bps_get_event(&current_event, -1);

        eventDomain = bps_event_get_domain(current_event);
        event_code = bps_event_get_code(current_event);

        if (eventDomain == sensor_get_domain())
        {
            switch (event_code)
            {
                case SENSOR_GRAVITY_READING:
                    /* Get the current gravity values */
                    sensor_event_get_xyz(current_event, 
                                         &x_gravity, 
                                         &y_gravity, 
                                         &z_gravity);
                    /* Adjust app based on gravity values */
                    break;

                default:
                    break;
            }
        }
    }

    /* Clean up */
    sensor_stop_events(SENSOR_TYPE_GRAVITY);
    bps_shutdown();

    return 0;
}

Gyroscope

The gyroscope returns readings that measure the velocity of the device along three axes. Unlike the rotation reading, the gyroscope's readings represent the current angular velocity rather than a fixed rotation.

If you are developing a Cascades app using QML or C++, you can use the QGyroscope, QGyroscopeReading, and QGyroscopeFilter. The measurements are in degrees per second.

If you are developing an app using C, a BPS event with the code SENSOR_GYROSCOPE_READING is generated when new gyroscope values are available. You can call the function sensor_event_get_xyz() to retrieve the values from the event. The measurements are in radians per second (rad/s), where counterclockwise rotations are positive when looking from the positive end of the axis, and negative otherwise.

The following code sample demonstrates how you can capture readings from the gyroscope:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Gyroscope: " + gyro.x.toFixed(3) + "  " +
                    gyro.y.toFixed(3) + "  " + gyro.z.toFixed(3) +
                    " deg/s"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        Gyroscope {
            id: gyro
            property double x: 0
            property double y: 0
            property double z: 0
            active: true
            onReadingChanged: {
                gyro.x = reading.x;
                gyro.y = reading.y;
                gyro.z = reading.z;
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QGyroscope>
#include <QtSensors/QGyroscopeReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    gyro_label = new Label();
    top_container->add(gyro_label);

	m_gyro = new QGyroscope(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_gyro, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(gyroReadingChanged()));

    Q_ASSERT(connectResult);
    
    m_gyro->start();
}

void SensorsApp::gyroReadingChanged()
{
    QGyroscopeReading *reading = m_gyro->reading();
    qreal x = reading->x();
    qreal y = reading->y();
    qreal z = reading->z();
    QString data = QString("Gyro: %1  %2  %3 deg/s")
   	    .arg(x, 0, 'f', 3).arg(y, 0, 'f', 3).arg(z, 0, 'f', 3);
    gyro_label->setText(data);
}
#include <stddef.h>
#include <math.h>
#include <bps/bps.h>
#include <bps/navigator.h>
#include <bps/sensor.h>

int main(void)
{
    int event_domain;
    unsigned int event_code;

    /* Create variables to store the current gyroscope values */
    float x_velocity, y_velocity, z_velocity;

    bps_initialize();

    if (sensor_is_supported(SENSOR_TYPE_GYROSCOPE))
    {
        sensor_request_events(SENSOR_TYPE_GYROSCOPE);
    }

    while (1)
    {
        bps_event_t *current_event = NULL;
        bps_get_event(&current_event, -1);

        event_domain = bps_event_get_domain(current_event);
        event_code = bps_event_get_code(current_event);

        if (event_domain == sensor_get_domain())
        {
            switch (event_code)
            {
                case SENSOR_GYROSCOPE_READING:
                    /* Get the current gyroscope values */
                    sensor_event_get_xyz(current_event, 
                                         &x_velocity, 
                                         &y_velocity, 
                                         &z_velocity);
                    /* Adjust app based on gyroscope values */
                    break;

                default:
                    break;
            }
        }
    }

    /* Clean up */
    sensor_stop_events(SENSOR_TYPE_GYROSCOPE);
    bps_shutdown();

    return 0;
}

Holster sensor

The holster sensor returns a Boolean value that indicates whether the device is in the holster or not.

If you are developing a Cascades app using QML or C++, see QHolsterSensor, QHolsterReading, and QHolsterFilter.

If you are developing an app using C, a BPS event is generated when the holster sensor reports a new reading. You can determine if a BPS event was triggered by the holster sensor by calling holster_get_domain(). When you determine that the event is from the holster sensor, you can call holster_event_get_holster_status() to retrieve whether or not the device is in a holster.

The following code sample demonstrates how you can capture readings from the holster:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Holster Sensor: " + holster.holstered
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        HolsterSensor {
            id: holster
            property string holstered: null
            active: true
            onReadingChanged: {
                holster.holstered = reading.holstered;
                if (reading.holstered == true)
                    holster.holstered = "Holstered";
                else
                    holster.holstered = "Not Holstered";
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QHolsterSensor>
#include <QtSensors/QHolsterReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    holster_label = new Label();
    top_container->add(holster_label);

	m_holster = new QHolsterSensor(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_holster, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(holsterReadingChanged()));

    Q_ASSERT(connectResult);
    
    m_holster->start();
}

void SensorsApp::holsterReadingChanged()
{
    QHolsterReading *reading = m_holster->reading();
    QString data = QString("Holster Sensor: ");
    if (reading->holstered())
    	data = data + QString("Holstered");
    else
    	data = data + QString("Not Holstered");
    holster_label->setText(data);
}
#include <stddef.h>
#include <bps/bps.h>
#include <bps/holster.h>

int main(void)
{
    int event_domain;
    unsigned int event_code;
    int holster_status;

    bps_initialize();

    /* All BlackBerry 10 devices support holster events */
    holster_request_events(0);

    while (1)
    {
        bps_event_t *current_event = NULL;
        bps_get_event(&current_event, -1);

        event_domain = bps_event_get_domain(current_event);
        event_code = bps_event_get_code(current_event);

        if (event_domain == holster_get_domain()) {
            holster_status = 
                holster_event_get_holster_status(current_event);
            if (holster_status == HOLSTER_IN) {
                /* Adjust app for operation while holstered */
            } else if (holster_status == HOLSTER_OUT) {
                /* Adjust app for operation while out of holster */
            } else {
                /* Unknown status; handle error */
            }
        }
    }

    holster_stop_events(0);
    bps_shutdown();
    return 0;
}

Infrared proximity sensor

The infrared proximity sensor can detect the proximity of a nearby object by emitting infrared light and detecting how much of the light the object reflects back to the device. However, there is no reliable way to turn reflectance values into distances unless both the item that light is reflecting off and the ambient lighting conditions are known. For example, a material like black felt absorbs a lot of the inferred light, making the object appear farther away than it actually is.

If you are developing a Cascades app using QML or C++, see QIRProximitySensor, QIRProximityReading, and QIRProximityFilter.

The following code sample demonstrates how you can capture readings from the infrared proximity sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "IR Proximity Sensor: " + 
            		(irproximity.reflectance * 100).toFixed(3) + " %"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        IRProximitySensor {
            id: irproximity
            property double reflectance: 0
            active: true
            onReadingChanged: {
                irproximity.reflectance = reading.reflectance
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QIRProximitySensor>
#include <QtSensors/QIRProximityReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    irProx_label = new Label();
    top_container->add(irProx_label);

	m_irProx = new QIRProximitySensor(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_irProx, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(irProxReadingChanged()));
 
        Q_ASSERT(connectResult);
    
    m_irProx->start();
}

void SensorsApp::irProxReadingChanged()
{
    QIRProximityReading *reading = m_irProx->reading();
    qreal reflectance = reading->reflectance();
    QString data = QString("IR Proximity Sensor: %1  %")
   	    .arg(reflectance, 0, 'f', 3);
    irProx_label->setText(data);
}

Not applicable

Light sensor

The light sensor returns a value representing the actual illuminance of the external environment. Values are measured in lux.

If you are developing a Cascades app using QML or C++, see QLightSensor, QLightReading, and QLightFilter.

If you are developing an app using C, a BPS event with the code SENSOR_LIGHT_READING is generated when a new illuminance value is available. You can call the function sensor_event_get_illuminance() to retrieve the value of the sensor reading from the event. The light sensor returns a value that is measured in lux (lx), where 1 lux is equal to 1 lumen per square meter (1 lx = 1 lm/m2).

The following code sample demonstrates how you can capture readings from the light sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Light: " + light.lux.toFixed(3) + " lux"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        LightSensor {
            id: light
            property double lux: 0
            active: true
            onReadingChanged: {
                light.lux = reading.lux;
            }
        } 
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QLightSensor>
#include <QtSensors/QLightReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    light_label = new Label();
    top_container->add(light_label);

	m_light = new QLightSensor(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_light, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(lightReadingChanged()));

    Q_ASSERT(connectResult);
							 
	m_light->start();
}

void SensorsApp::lightReadingChanged()
{
    QLightReading *reading = m_light->reading();
    qreal lux = reading->lux();
    QString data = QString("Light: %1 lux")
      	    .arg(lux);
    light_label->setText(data);
}
#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>


int main(void)
{
  int event_domain;
  unsigned int event_code;
  bool isDark = false;
  float luxlevel;

  bps_initialize();

  /* Request light sensor events */
  if (sensor_is_supported(SENSOR_TYPE_LIGHT))
  {
    sensor_request_events(SENSOR_TYPE_LIGHT);
  }

  while (1)
  {
    bps_event_t *current_event = NULL;
    bps_get_event(&current_event, -1);

    event_domain = bps_event_get_domain(current_event);
    if (event_domain == sensor_get_domain())
    {
      event_code = bps_event_get_code(current_event);
      switch (event_code)
      {
        case SENSOR_LIGHT_READING:
          /* Get latest reading from the light sensor */
          luxlevel = 
              sensor_event_get_illuminance(current_event);

              /* Determine if light level has changed */
              /* from light to dark, or dark to light */
              if ((luxlevel < 100) && (!isDark)) {
                isDark = true;
                /* Adjust app for low-light operation */
              } else if ((luxlevel >= 100) && (isDark)) {
                isDark = false;
                /* Adjust app for regular operation */
              } else {
                /* No change to lighting conditions */
              }
              break;

            default:
              break;
      } 
    } 
  } 

  /* Clean up */
  sensor_stop_events(SENSOR_TYPE_LIGHT);
  bps_shutdown();

  return 0;
}

Linear acceleration

Linear acceleration is the acceleration of the device minus the acceleration due to gravity. This value is calculated by combining inputs from several device sensors, and the result is returned from the linear accelerometer sensor type (SENSOR_TYPE_LINEAR_ACCEL). These values are in meters per second per second (m/s2).

A BPS event with the code SENSOR_LINEAR_ACCEL_READING is generated when new linear acceleration values are available. You can call the function sensor_event_get_xyz() to retrieve the linear acceleration values from the event.

The following code sample demonstrates how you can use the linear accelerometer sensor in your app:

Not applicable

Not applicable

#include <stddef.h>
#include <math.h>
#include <bps/bps.h>
#include <bps/navigator.h>
#include <bps/sensor.h>

int main(void)
{
  int event_domain;
  unsigned int event_code;

  /* Create variables for the current linear acceleration values */
  float x_accel, y_accel, z_accel;
  float magnitude;

  bps_initialize();

  if (sensor_is_supported(SENSOR_TYPE_LINEAR_ACCEL))
  {
    sensor_request_events(SENSOR_TYPE_LINEAR_ACCEL);
  }

  while (1)
  {
    bps_event_t *current_event = NULL;
    bps_get_event(&current_event, -1);

    event_domain = bps_event_get_domain(current_event);
    event_code = bps_event_get_code(current_event);

    if (event_domain == sensor_get_domain())
    {
      switch (event_code)
      {
        case SENSOR_LINEAR_ACCEL_READING:
          /* Get the current linear acceleration values */
          sensor_event_get_xyz(current_event, 
                               &x_accel, 
                               &y_accel, 
                               &z_accel);
          /* Calculate the magnitude of linear acceleration */
          magnitude = sqrtf((x_accel * x_accel) + 
                            (y_accel * y_accel) + 
                            (z_accel * z_accel));
          /* Adjust app based on linear acceleration */
          /* values and magnitude */
          break;

        default:
          break;
      }
    }
  }

  /* Clean up */
  sensor_stop_events(SENSOR_TYPE_LINEAR_ACCEL);
  bps_shutdown();

  return 0;
}

Magnetometer

The magnetometer measures the strength and direction of magnetic fields in three dimensions. Unlike the compass, readings are returned as magnetic flux density values along three axes, in teslas. This sensor supports both raw magnetic flux values or geomagnetic flux values, with raw magnetic flux values being the default. Unlike raw magnetic flux values, geomagnetic flux values are processed to compensate for local interference, and provide data based on the Earth's magnetic field only.

If you are developing a Cascades app using QML or C++, see QMagnetometer, QMagnetometerReading, and QMagnetometerFilter.

If you are developing an app using C, a BPS event with the code SENSOR_MAGNETOMETER_READING is generated when new magnetometer values are available. You can call the function sensor_event_get_xyz() to retrieve the magnetic field values from the event. The magnetometer sensor returns magnetic flux density values in microteslas (µT). These values are processed to compensate for local interference, and provide data based on the Earth's magnetic field.

The following code sample demonstrates how you can capture readings from the magnetometer:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Mag: " + mag.x.toFixed(3) + "  " + mag.x.toFixed(3) 
                   + "  " + mag.x.toFixed(3) + " μTesla"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        Magnetometer {
            id: mag
            property double x: 0
            property double y: 0
            property double z: 0
            active: true
            onReadingChanged: {
                mag.x = reading.x * 1000000;
                mag.y = reading.y * 1000000;
                mag.z = reading.z * 1000000;
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QMagnetometer>
#include <QtSensors/QMagnetometerReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    mag_label = new Label();
    top_container->add(mag_label);

	m_mag = new QMagnetometer(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_mag, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(magReadingChanged()));

    Q_ASSERT(connectResult);
	
	m_mag->start();
}

void SensorsApp::magReadingChanged()
{
    QMagnetometerReading *reading = m_mag->reading();
    qreal x = reading->x() * 1000000;
    qreal y = reading->y() * 1000000;
    qreal z = reading->z() * 1000000;
    QString data = QString("Mag: %1  %2  %3 uTesla")
   	    .arg(x, 0, 'f', 3).arg(y, 0, 'f', 3).arg(z, 0, 'f', 3);
    mag_label->setText(data);
}
#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>

int main(void)
{
    int event_domain;
    unsigned int event_code;

    /* Create variables to store magnetometer sensor readings */
    float x_magflux, y_magflux, z_magflux;

    bps_initialize();

    if (sensor_is_supported(SENSOR_TYPE_MAGNETOMETER))
    {
        sensor_request_events(SENSOR_TYPE_MAGNETOMETER);
    }

    while (1)
    {
        bps_event_t *current_event = NULL;
        bps_get_event(&current_event, -1);

        event_domain = bps_event_get_domain(current_event);
        event_code = bps_event_get_code(current_event);

        if (event_domain == sensor_get_domain())
        {
            switch (event_code)
            {
                case SENSOR_MAGNETOMETER_READING:
                    /* Get the current magnetic flux density values */
                    sensor_event_get_xyz(current_event, 
                                         &x_magflux, 
                                         &y_magflux, 
                                         &z_magflux);
                    /* Update program based on current  */
                    /* magnetic flux values */
                    break;

                default:
                    break;
            }
        }
    }

    /* Clean up */
    sensor_stop_events(SENSOR_TYPE_MAGNETOMETER);
    bps_shutdown();
    return 0;
}

Orientation sensor

The orientation sensor reports on the orientation of the device. You can detect which side of the device is pointing up, and whether the device is face up or face down. Because this sensor operates below the UI level, it's not able to detect the UI orientation. For information on handling app orientation, see Orientation.

If you are developing a Cascades app using QML or C++, see QOrientationSensor, QOrientationReading, and QOrientationFilter.

If you are developing an app using C, see Remapping sensor data based on device orientation.

The following code sample demonstrates how you can capture readings from the orientation sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Orientation: " + orientation.data
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        OrientationSensor {
            id: orientation
            property string data: ""
            active: true
            onReadingChanged: {
                if (reading.orientation == OrientationReading.TopUp)
                    orientation.data = "Top Up";
                else if (reading.orientation == OrientationReading.TopDown)
                    orientation.data = "Top Down";
                else if (reading.orientation == OrientationReading.LeftUp)
                    orientation.data = "Left Up";
                else if (reading.orientation == OrientationReading.RightUp)
                    orientation.data = "Right Up";
                else if (reading.orientation == OrientationReading.FaceUp)
                    orientation.data = "Face Up";
                else if (reading.orientation == OrientationReading.FaceDown)
                    orientation.data = "Face Down";
                else
                    orientation.data = "Undefined";
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QOrientationSensor>
#include <QtSensors/QOrientationReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    orientation_label = new Label();
    top_container->add(orientation_label);

	m_orientation = new QOrientationSensor(this);
	
	bool connectResult;
	
	Q_UNUSED(connectResult);
	
	connectResult = connect(m_orientation, 
                            SIGNAL(readingChanged()),
                            this, 
                            SLOT(orientationReadingChanged()));

    Q_ASSERT(connectResult);

	m_orientation->start();
}

void SensorsApp::orientationReadingChanged()
{
    QOrientationReading *reading = m_orientation->reading();
    QString data = QString ("Orientation: ");
    switch (reading->orientation())
    {
        case QOrientationReading::Undefined:
           data = data + QString ("Undefined");
           break;
        case QOrientationReading::TopUp:
        	data = data + QString ("Top Up");
        	break;
        case QOrientationReading::TopDown:
        	data = data + QString ("Top Down");
        	break;
        case QOrientationReading::LeftUp:
        	data = data + QString ("Left Up");
            break;
        case QOrientationReading::RightUp:
        	data = data + QString ("Right Up");
        	break;
        case QOrientationReading::FaceUp:
        	data = data + QString ("Face Up");
        	break;
        case QOrientationReading::FaceDown:
            data = data + QString ("Face Down");
            break;
    }
    orientation_label->setText(data);
}

Proximity sensor

The proximity sensor determines whether an object is close to the device or not. Unlike the IR proximity sensor, which returns a raw reflectance value, the proximity sensor returns a value that indicates whether an object is close or far away. The proximity is still based on reflectance, but takes other factors into consideration when determining the value.

The proximity sensor determines whether an object is close or far from the top of the device. This sensor is most commonly used to determine when a person is holding the device close to their head. For example, when a person is making/receiving a call, any touch events that occur are likely the result of the screen brushing against the user's head, and this unintentional input should be ignored. You can do this by programming your app to ignore touch events when the proximity sensor reports that something is close to the device.

If you are developing a Cascades app using QML or C++, see QProximitySensor, QProximityReading, and QProximityFilter.

If you are developing an app using C, a BPS event with the code SENSOR_PROXIMITY_READING is generated when a new proximity value is available. BPS offers two functions to get information from a proximity sensor event: sensor_event_get_proximity() and sensor_event_get_proximity_normalized().

The sensor_event_get_proximity() function returns the distance in centimeters (cm) of the object that is closest to the device. On some devices, the proximity sensor can't provide an accurate distance, and returns either the range minimum value (0.0) to represent near or the range maximum value (1.0) to represent far.

The following code sample demonstrates how you can capture readings from the proximity sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Proximity: " + prox.data
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        ProximitySensor {
            id: prox
            property string data: ""
            active: true
            onReadingChanged: {
                if (reading.close == true)
                    prox.data = "Close";
                else
                    prox.data = "Far";
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QProximitySensor>
#include <QtSensors/QProximityReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    prox_label = new Label();
    top_container->add(prox_label);

	m_prox = new QProximitySensor(this);
	
	bool connectResult;
	

	Q_UNUSED(connectResult);
	
	connectResult = connect(m_prox, 
                            SIGNAL(readingChanged()), 
                            this,
                            SLOT(proxReadingChanged()));

    Q_ASSERT(connectResult);
	
	m_prox->start();
}

void SensorsApp::proxReadingChanged()
{
    QProximityReading *reading = m_prox->reading();
    QString data = QString ("Proximity: ");
    if(reading->close() == true)
    	data = data + QString ("Close");
    else
    	data = data + QString ("Far");
    prox_label->setText(data);
}
sensor_info_t *sensorinfo;
int min_range, max_range;
                
if (sensor_info(SENSOR_TYPE_PROXIMITY, &sensorinfo) == BPS_SUCCESS)
{
  min_range = sensor_info_get_range_minimum(sensorinfo);
  max_range = sensor_info_get_range_maximum(sensorinfo);
  sensor_info_destroy(sensorinfo);
			        
  if ((min_range == 0) && (max_range == 1)
  {
    /* Sensor only returns values of 0 or 1, */ 
    /* representing near and far */
  }
}
            

sensor_event_get_proximity_normalized() returns the distance of the closest object to the device mapped to a range between 0.0 and 1.0 (near to far). The code sample below takes the value returned by this function and uses it to determine whether to handle or ignore screen events.

#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>
#include <bps/screen.h>

/* An (arbitrary) threshold under which we want to ignore touch events.  */
/* Used with the normalized proximity value, this sets the threshold to  */
/* be proximity events that fall in the lower 40% of the sensor's range. */

#define FAR_THRESHOLD 0.4
#define DEVICE_IS_FAR(X) (X > FAR_THRESHOLD)

typedef struct sensor_info_t sensor_info_t;

int main(void)
{
  int event_domain;
  int min_range, max_range;
  unsigned int event_code;

  /* Create a variable to store the current proximity sensor reading */
  float proximity;

  bps_initialize();

  if (sensor_is_supported(SENSOR_TYPE_PROXIMITY))
  {
    sensor_request_events(SENSOR_TYPE_PROXIMITY);
  }

  while (1)
  {
    bps_event_t *current_event = NULL;
    bps_get_event(&current_event, -1);

    event_domain = bps_event_get_domain(current_event);
    event_code = bps_event_get_code(current_event);

    if (event_domain == sensor_get_domain())
    {
      switch (event_code)
      {
        case SENSOR_PROXIMITY_READING:
        proximity = 
          sensor_event_get_proximity_normalized(current_event);
        break;

      default:
        break;
      }
    } else if ((event_domain == screen_get_domain()) && 
               (DEVICE_IS_FAR(proximity))) {
      /* Handle touch events when device is not close to user */
    }
  }

  /* Clean up */
  sensor_stop_events(SENSOR_TYPE_PROXIMITY);
  bps_shutdown();

  return 0;
}

Rotation sensor

The rotation sensor returns a reading containing three angles, measured in degrees, that define the orientation of the device in three-dimensional space. These angles are similar to yaw, pitch, and roll but are defined using only right-hand rotation with axes as defined by the right-hand Cartesian coordinate system.

If you are developing a Cascades app using QML or C++, see QRotationSensor, QRotationReading, and QRotationFilter.

If you are developing an app using C, a BPS event with the code SENSOR_ROTATION_MATRIX_READING is generated when a new rotation matrix is available. You can call the function sensor_event_get_rotation_matrix() to retrieve the rotation matrix from the event. The rotation matrix sensor fuses sensor data from different sources to create a rotation matrix based on the position of the device. You can use this matrix to rotate screen items to match the position of the device. For example, rotating text fields in an augmented reality app.

The following code sample demonstrates how you can capture readings from the rotation sensor:

import bb.cascades 1.0
import QtMobility.sensors 1.2

Page {
    Container {
        Label {
            text: "Rotation: " + rotation.x.toFixed(3) + "  " + 
                    rotation.y.toFixed(3) + "  " + 
                    rotation.z.toFixed(3) + " deg"
            textStyle.base: SystemDefaults.TextStyles.Text
            textStyle.fontSize: FontSize.Medium
            verticalAlignment: VerticalAlignment.Center
            horizontalAlignment: HorizontalAlignment.Left
        }
    }
    
    attachedObjects: [
        RotationSensor {
            id: rotation
            property double x: 0
            property double y: 0
            property double z: 0
            active: true
            onReadingChanged: {
                rotation.x = reading.x;
                rotation.y = reading.y;
                rotation.z = reading.z;
            }
        }
    ]
}
#include "SensorsApp.hpp"

#include <QtSensors/QRotationSensor>
#include <QtSensors/QRotationReading>

using namespace bb::cascades;
using namespace QtMobility;

SensorsApp::SensorsApp(bb::cascades::Application *app)
: QObject(app)
{
    root = new Page;
    top_container = new Container;

    rotation_label = new Label();
    top_container->add(rotation_label);

	m_rotation = new QRotationSensor(this);
	
	bool rotation_res = connect(m_rotation, 
                                SIGNAL(readingChanged()),
                                this, 
                                SLOT(rotationReadingChanged()));

    Q_ASSERT(rotation_res);
	
	Q_UNUSED(rotation_res);
	m_rotation->start();
}

void SensorsApp::rotationReadingChanged()
{
    QRotationReading *reading = m_rotation->reading();
    qreal x = reading->x();
    qreal y = reading->y();
    qreal z = reading->z();
    QString data = QString("Rotation: %1  %2  %3 deg")
   	    .arg(x, 0, 'f', 3).arg(y, 0, 'f', 3).arg(z, 0, 'f', 3);
    rotation_label->setText(data);
}
#include <stddef.h>
#include <bps/bps.h>
#include <bps/sensor.h>

int main(void)
{
  int event_domain;
  unsigned int event_code;

  /* Create variables to store the current rotation matrix */
  sensor_rotation_matrix_t rotation_matrix;

  bps_initialize();

  if (sensor_is_supported(SENSOR_TYPE_ROTATION_MATRIX))
  {
    sensor_request_events(SENSOR_TYPE_ROTATION_MATRIX);
  }

  while (1)
  {
    bps_event_t *current_event = NULL;
    bps_get_event(&current_event, -1);

    event_domain = bps_event_get_domain(current_event);
    event_code = bps_event_get_code(current_event);

    if (event_domain == sensor_get_domain())
    {
      switch (event_code)
      {
        case SENSOR_ROTATION_MATRIX_READING:
          /* Get the rotation matrix for this event */
          sensor_event_get_rotation_matrix(current_event, 
                                        &rotation_matrix);

          /* Adjust position of on-screen items  
             using the rotation matrix          */
          break;

        default:
          break;
      }
    }
  }

  /* Clean up */
  sensor_stop_events(SENSOR_TYPE_ROTATION_MATRIX);
  bps_shutdown();

  return 0;
}

Last modified: 2015-03-31



Got questions about leaving a comment? Get answers from our Disqus FAQ.

comments powered by Disqus