Languages

Menu
Sites
Language
service app keep reading ACCELERATION SENSOR data during power save mode

I am working on a service application to detect acceleration values greater than a treshold continuously.

Is it possible to keep reading acceleration values when the device (GEAR SPORT = wearable 3.0) is set to power save mode?

I have been searching for this but only found individual lines of code for HRM sensor reading, that I could not get to work for my purpose.

I am beginner with tizen native implementation, so I would be very grateful for any help.

Here's my code so far:

#include <tizen.h> // standard header from the template
#include <service_app.h> // standard header from the template
#include "accelerationservice.h" // a header automatically created along with the template

// headers that will be needed for our service:
#include <sensor.h>
#include <player.h>
#include <stdlib.h>
#include <stdio.h>
#include <dlog.h> // for logging purposes
#include <device/haptic.h>

static void device_vibrate(int duration, int feedback) {
    haptic_device_h haptic_handle;
	haptic_effect_h effect_handle;

	if(device_haptic_open(0, &haptic_handle) == DEVICE_ERROR_NONE) {

		dlog_print(DLOG_INFO, LOG_TAG, "Connection to vibrator established");

		if(device_haptic_vibrate(haptic_handle, duration, feedback, &effect_handle) == DEVICE_ERROR_NONE) {
			dlog_print(DLOG_INFO, LOG_TAG, "Device vibrates!");
		}
//		To stop vibration which are being played use below code with proper handles
		//if(device_haptic_stop(haptic_handle, effect_handle) == DEVICE_ERROR_NONE) {
		//	dlog_print(DLOG_INFO, LOG_TAG, "Device vibration stopped");
		//}

//		When you decided not to use haptic anymore disconnect it
		//if(device_haptic_close(haptic_handle) == DEVICE_ERROR_NONE) {
		//	dlog_print(DLOG_INFO, LOG_TAG, "Vibrator disconnected");
		//}
	}
}

// some constant values used in the app
#define MAX_PATH_SIZE 4096 // max file path size
#define ACCELEROMETER_SHAKE_THRESHOLD_VALUE 15 // the value read on any accelerometer axis to be considered the shake event


// application data (context) that will be passed to functions when needed
typedef struct appdata
{
	sensor_h sensor; // sensor handle
	sensor_listener_h listener; // sensor listener handle
	char sound_path[MAX_PATH_SIZE]; // a path to a sound file that is used as an alarm
} appdata_s;

void playback_completed_cb(void *user_data)
{
	// Extracting application data
	appdata_s* ad = (appdata_s*)user_data;

	dlog_print(DLOG_INFO, LOG_TAG, "Sound playback completed.");
	if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
	{
		dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener started again.");
	}

}

//sensor event callback implementation
void sensor_event_callback(sensor_h sensor, sensor_event_s *event, void *user_data)
{
	// Extracting application data
	appdata_s* ad = (appdata_s*)user_data;

	sensor_type_e type = SENSOR_ALL;

	if((sensor_get_type(sensor, &type) == SENSOR_ERROR_NONE) && type == SENSOR_ACCELEROMETER)
	{
		int h0 = event->values[0];
		int h1 = event->values[1];
		int h2 = event->values[2];


		dlog_print(DLOG_INFO, LOG_TAG, "0, %i", h0);
		dlog_print(DLOG_INFO, LOG_TAG, "1, %i", h1);
		dlog_print(DLOG_INFO, LOG_TAG, "2, %i", h2);

		if (event->values[0] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
			|| event->values[1] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
			|| event->values[2] >= ACCELEROMETER_SHAKE_THRESHOLD_VALUE
			|| event->values[0] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE
			|| event->values[1] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE
			|| event->values[2] <= -ACCELEROMETER_SHAKE_THRESHOLD_VALUE)
		{
			dlog_print(DLOG_INFO, LOG_TAG, "Event occurred!");
			//vibrate
			dlog_print(DLOG_INFO, LOG_TAG, "Vibrator method called!");
			device_vibrate(1000,100);
			// We stop the sensor listener, because until the sound playback
			// is finished we don't need to monitor sensors.
			if (sensor_listener_stop(ad->listener) == SENSOR_ERROR_NONE)
			{
				dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener temporarily stopped!");
			}
			else
			{
				dlog_print(DLOG_INFO, LOG_TAG, "Something went wrong! Sensor listener could not be stopped!");
			}
			dlog_print(DLOG_INFO, LOG_TAG, "after Sensorlistener stopped!!!");
			if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
			{
				dlog_print(DLOG_INFO, LOG_TAG, "Sensor restarted.");
			}
			else
			{
				dlog_print(DLOG_ERROR, LOG_TAG, "Restarting sensor failed!");
			}



		}
	}
}



bool service_app_create(void *data)
{
	// Extracting application data
	appdata_s* ad = (appdata_s*)data;

	dlog_print(DLOG_INFO, LOG_TAG, "Starting sensor service...");

	bool sensor_supported = false;
	if (sensor_is_supported(SENSOR_ACCELEROMETER, &sensor_supported) != SENSOR_ERROR_NONE || sensor_supported == false)
	{
		dlog_print(DLOG_ERROR, LOG_TAG, "Accelerometer not supported! Service is useless, exiting...");
		service_app_exit();
		return false;
	}



	// Preparing and starting the sensor listener for the accelerometer.
	if (sensor_get_default_sensor(SENSOR_ACCELEROMETER, &(ad->sensor)) == SENSOR_ERROR_NONE)
	{
		if (sensor_create_listener(ad->sensor, &(ad->listener)) == SENSOR_ERROR_NONE
			&& sensor_listener_set_event_cb(ad->listener, 200, sensor_event_callback, ad) == SENSOR_ERROR_NONE
			&& sensor_listener_set_option(ad->listener, SENSOR_OPTION_ALWAYS_ON) == SENSOR_ERROR_NONE)
		{
			if (sensor_listener_start(ad->listener) == SENSOR_ERROR_NONE)
			{
				dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener started.");
			}
		}
	}
	return true;
}

void service_app_terminate(void *data)
{
	// Extracting application data
	appdata_s* ad = (appdata_s*)data;

	//Stopping & destroying sensor listener
	if ((sensor_listener_stop(ad->listener) == SENSOR_ERROR_NONE)
		&& (sensor_destroy_listener(ad->listener) == SENSOR_ERROR_NONE))
	{
		dlog_print(DLOG_INFO, LOG_TAG, "Sensor listener destroyed.");
	}
	else
	{
		dlog_print(DLOG_INFO, LOG_TAG, "Error occurred when destroying sensor listener or a sensor listener was never created!");
	}


}

void service_app_control(app_control_h app_control, void *data)
{
	dlog_print(DLOG_INFO, LOG_TAG, "Service app control has been called");
	return;
}

static void service_app_lang_changed(app_event_info_h event_info, void *user_data)
{
	/*APP_EVENT_LANGUAGE_CHANGED*/
	return;
}

static void service_app_region_changed(app_event_info_h event_info, void *user_data)
{
	/*APP_EVENT_REGION_FORMAT_CHANGED*/
}

static void service_app_low_battery(app_event_info_h event_info, void *user_data)
{
	/*APP_EVENT_LOW_BATTERY*/
}

static void service_app_low_memory(app_event_info_h event_info, void *user_data)
{
	/*APP_EVENT_LOW_MEMORY*/
}

int main(int argc, char* argv[])
{
	// we declare application data as a structure defined earlier
	appdata_s ad = {0,};
	service_app_lifecycle_callback_s event_callback = {0,};
	app_event_handler_h handlers[5] = {NULL, };

	event_callback.create = service_app_create;
	event_callback.terminate = service_app_terminate;
	event_callback.app_control = service_app_control; //we will not use this one yet

	service_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, service_app_low_battery, &ad);
	service_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, service_app_low_memory, &ad);
	service_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, service_app_lang_changed, &ad);
	service_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, service_app_region_changed, &ad);

	// we keep a template code above and then modify the line below
	return service_app_main(argc, argv, &event_callback, &ad);
}

 

 

 

Responses

1 Replies
K Johnson

To record sensor data in power save mode, set "alarm" on your program to wake up. You can launch an application at a specific time using alarms and get sensor data. Use APP_CONTROL_OPERATION_MAIN instead of APP_CONTROL_OPERATION_DEFAULT. Please go through this link to know more about Alarm API. Also please go through the discussion into this link specially GEUNSOO KIM's reply. Hope it'll help you.