
The accelerometer, which is used in Pebble is calibrated to measure acceleration within ± 4G, using API it is possible to obtain acceleration on three axes x, y and z in thousandths of G. Thus, the range of possible values for each axis is from -4000 to 4000.
It is possible to set the frequency of data updating with the accelerometer in: 10, 25 (default), 50 and 100 Hz.
Below is about how to get data from the Pebble-built accelerometer and the extreme application of acquired knowledge.
The developers offer three
separate ways to use the accelerometer
[1] :
- Tap Event Service - the reaction of the application to the sharp movement of the clock. [2]
- Data Event Service - receiving all accelerometer data. [3]
- Service Peek - online data retrieval. [four]
Tap Event Service
Using when the application needs to track down the fact that the user has shaken for hours or tapped them.
The event handler will generally look like:
')
static void tap_handler(AccelAxisType axis, int32_t direction) { }
AccelAxisType axis - the axis along which the “tychek” occurred, the possible values are
ACCEL_AXIS_X ,
ACCEL_AXIS_Y ,
ACCEL_AXIS_Z .
int32_t direction - the direction of "poke" (-1 or +1). For the X axis, the positive direction is towards the right side of the clock, for Y it is the movement towards the top, for Z it is vertically up.
Subscribing to events, the
tap_handler handler
is called at every tap:
accel_tap_service_subscribe(tap_handler)
Data Event Service
Used to accumulate and analyze accelerometer data, the definition of a specific gesture or movement of the user.
The event handler will generally look like:
static void data_handler(AccelData *data, uint32_t num_samples) { }
AccelData * data - a set of data for all axes, plus a time stamp and a sign if the vibrator worked when receiving a set.
uint32_t num_samples - the number of sets in the buffer, from 0 to 25.
Subscribing to events, the
data_handler handler
is called each time a dataset is received.
uint32_t num_samples = 3; accel_data_service_subscribe(num_samples, data_handler);
And an example from the data processing documentation:
static void data_handler(AccelData *data, uint32_t num_samples) { // Long lived buffer static char s_buffer[128]; // Compose string of all data for 3 samples snprintf(s_buffer, sizeof(s_buffer), "NX,Y,Z\n0 %d,%d,%d\n1 %d,%d,%d\n2 %d,%d,%d", data[0].x, data[0].y, data[0].z, data[1].x, data[1].y, data[1].z, data[2].x, data[2].y, data[2].z ); //Show the data text_layer_set_text(s_output_layer, s_buffer); }
Service peek
Getting the latest saved values of accelerometer indicators.
NB Cannot be used when subscribing to the
Data Event Service .
At any given time, the call
accel_service_peek allows
you to read the latest data saved by the accelerometer.
Typical use:
AccelData accel = (AccelData) { .x = 0, .y = 0, .z = 0 }; accel_service_peek(&accel);
Determining the height of throwing hours
And, as a result, an example of an application that will determine how high the user does not mind throwing a clock.
The idea is not new at all, the first time I came across a similar one on the Nokia n900
[5] - the n900Fly toy. Then
SMTH (Send Me To Heaven) appeared .
Application functionality:
- determining the state of flight hours;
- determination of flight time and altitude calculation;
- display of the last result of throwing
In this case, neither the definition of tapes nor the analysis of data sets is used.
Without inventing a new one, to determine the moments of throwing and landing from the n900Fly:
- the average acceleration vector is calculated as sqrt (x ^ 2 + y ^ 2 + z ^ 2) ;
- if the vector becomes less than 400, the moment of separation;
- if the vector becomes more than 500 - the moment of landing.
We initialize the accelerometer, set the refresh rate to 25Hz and subscribe to a timer with an update interval of 20 milliseconds:
#define ACCEL_STEP_MS 20 static void init(void) { accel_service_set_sampling_rate(ACCEL_SAMPLING_25HZ); accel_data_service_subscribe(0, NULL); timer = app_timer_register(ACCEL_STEP_MS, accel_callback, NULL); }
Every 20 milliseconds, an accelerometer is polled, the average acceleration value is calculated and the state of the clock is determined:
static void accel_callback(void *data) { AccelData accel = (AccelData) { .x = 0, .y = 0, .z = 0 }; accel_service_peek(&accel); // if (( accel_abs(accel) < 400 ) && ( !iFlying)) { time_ms(&start.sec, &start.ms); iFlying = true; }; // if ( (accel_abs(accel) > 500) && (iFlying) ) { time_ms(&end.sec, &end.ms); flightTime = flight_time(start, end); flightHeight = flight_height(flightTime); iFlying = false; layer_mark_dirty(s_layer); timer = app_timer_register(1000, accel_callback, NULL); return; } timer = app_timer_register(ACCEL_STEP_MS, accel_callback, NULL); }
If we fix a touchdown, then we redraw the layer and delay the following access to the accelerometer data by 1 second, otherwise even a small bounce will be considered as a new throw.
Mathematical functions in the Pebble SDK are presented poorly. Therefore, to calculate the square root, an integer algorithm for calculating the inverse square root
[6] , found on the Internet, is used:
#define SQRT_MAGIC_F 0x5f3759df float my_sqrt(const float x) { const float xhalf = 0.5f*x; union { float x; int i; } u; ux = x; ui = SQRT_MAGIC_F - (ui >> 1); return x*ux*(1.5f - xhalf*ux*ux); }
For the accuracy of the calculation of flight time, it is necessary to take into account milliseconds
typedef struct time_with_ms { time_t sec; uint16_t ms; } time_with_ms; static time_with_ms start; static time_with_ms end; time_ms(&end.sec, &end.ms); time_ms(&start.sec, &start.ms); // static uint32_t flight_time(time_with_ms start, time_with_ms end) { return ( (end.sec - start.sec)*1000 + end.ms - start.ms ); }
And we consider the height at which the clock flies by the formula G * t ^ 2/2, where g = 9.8 m / s ^ 2:
// static uint32_t flight_height(uint32_t flightTime) { return (uint32_t)( 9.8 * ((flightTime/2)*(flightTime/2))/2 / 100 ); }
Calculated flightTime and flightHeight, you can show them in any convenient way for the user:

Who is higher?
Full code of the application
bitbucket / icanflyPebble App Store: I can fly1. Pebble Developers // Detection Acceleration2. Pebble Developers // Tap Event Service3. Pebble Developers // Data Event Service4. Pebble Developers // AccelerometerService5. maemo.org - package overview for n900Fly6. Wikipedia - Quick reverse square root