Getting raw sensor data from a wearable

I am a newbie in this field so need some help. For one of my projects, I need to collect raw sensor data specifically accelerometer data from a wearable. Can I do it using Samsung Gear fit? I mean if I write a native service app for this, can I run it in a Gear Fit independently?
Also if I record the data in a file in the wearable device, can I access that file from Tizen studio, copy and save it? If yes then how?

1 Like

I am a newbie in this field so need some help. For one of my projects, I need to collect raw sensor data specifically accelerometer data from a wearable. Can I do it using Samsung Gear fit?

If it is the 5/6 year old Gear Fit2 and Fit2 Pro it is possible, I’m not sure with the very original Gear Fit but I don’t think that is possible. If this is Galaxy Fit (the one released a couple years ago, no that is RealOS and can not be modified.

I mean if I write a native service app for this, can I run it in a Gear Fit independently?

I believe there are lots of examples on GitHub for Tizen sensors.

Also if I record the data in a file in the wearable device, can I access that file from Tizen studio, copy and save it? If yes then how?

Tizen Studio is an IDE could can connect to the watch from your computer and access data and there probably is a file reader app for this too.

Again this is for the very early Gear Fit2 and Fit2 Pro not the release a few years ago. If you don’t have a device I’d suggest you get something a bit newer like a Gear Sport, Gear S3, Galaxy Watch3 or Galaxy Watch Active2.

Ron
Samsung Developer Relations

Were you able to collect raw sensor data? I need to do that for my project also

I believe there is documentation for this on the Tizen.org site.

Ron
Samsung Developer Relations

To do this do I need to create a Tizen wearable .Net application? Or it must be Tizen wearable web application? Which one?

I need to get sensor data and give them to my machine learning model.

I found this example on Tizen for native applications

The difference between the Tizen Native API and the web API is the possibility to set the sampling frequency of the sensor and receive the data containing accurate information about the time of measurement. These features are certainly useful for the implementation of many complex algorithms, such as motion and gesture detection.

So it appears that if you don’t need the set the sampling frequency you can do it with the Web API. Search Tizen application developer site if you do not need that

Ron
Samsung Developer Relations

I am completely new to Tizen. I created a template project following instruction on Create Your First Tizen Wearable Web Application | Samsung Developers

Now I am reading documentation: Device Sensors | Tizen Docs where should I define variables and paste codes in this page?
should I put it in app.js file?

I read Sensor API guide in Tizen site. Then I found the following code to get sensor raw data:

var HRMrawsensor = tizen.sensorservice.getDefaultSensor(“HRM_RAW”);
function onGetSuccessCB(sensorData) {
console.log("HRMRaw light intensity : " + sensorData.lightIntensity);
}

function onerrorCB(error) { console.log(“error occurs”); }
function onsuccessCB() {
console.log(“HRMRaw sensor start”);
HRMrawsensor.getHRMRawSensorData(onGetSuccessCB, onerrorCB);
}

HRMrawsensor.start(onsuccessCB);

Now, I do not know where sensor data are saved? How can I get access to these data and transfer it to my PC? Please reply my message. I need this for my master thesis.

Hi @maryam.it86 , following is my code to get the accelerometer data saved in a file of your watch. When you connect your wearable with Tizen studio, you can access to the file system of your wearable through this. Then in the directory where I saved my file, you can see the output.
First of all create a service app of wearable version 4.0 and in the service.c file, paste the following code:

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

// headers that will be needed for our service:
#include <sensor.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#include <Eina.h>
#include <Ecore.h>
#include <storage.h>
#include <app_preference.h>
#include <linux/limits.h>
#include <system_settings.h>


// some constant values used in the app
#define MAX_PATH_SIZE 4096 // max file path size

// application data (context) that will be passed to functions when needed
typedef struct appdata
{
	sensor_h sensor[50]; // sensor handle
	sensor_listener_h listener[50]; // sensor listener handle
} appdata_s;


int listenerSize = 0;

FILE *fp;
FILE *fpAccl;
FILE *fpGrav;
FILE *fpLinAccl;
FILE *fpMag;
FILE *fpRot;
FILE *fpOri;
FILE *fpgyr;
char *dir = NULL;

/*
 * Returns corresponding File pointer to write sensor data to
 * If an additional sensor is planed to be added you might want to add a new *FILE here too @see open_all_files() and @see close_all_files()
 */
FILE *get_file_by_type(sensor_type_e type){
	switch(type){
		case SENSOR_ACCELEROMETER : return fpAccl;
		case SENSOR_GYROSCOPE:		return fpgyr;
//		case SENSOR_GRAVITY: 		return fpGrav;
//		case SENSOR_LINEAR_ACCELERATION:return fpLinAccl;
//		case SENSOR_MAGNETIC:		return fpMag;
//		case SENSOR_ROTATION_VECTOR:return fpRot;
//		case SENSOR_ORIENTATION:	return fpOri;
		}
	return fp;
}

char * open_dir() {
	char timebuf [1000] = "";
	time_t rawtime;
	struct tm * timeinfo;
	time (&rawtime);
	timeinfo = localtime (&rawtime);
	char *dirPath = NULL;
	dirPath = "/opt/usr/home/owner/media/";

	snprintf(timebuf,sizeof(timebuf),"%s%d_%d_%d", dirPath,timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
//    ecore_file_mkdir(timebuf);
	dlog_print(DLOG_INFO, LOG_TAG, "******************** SSS %s", timebuf);

    return timebuf;
}


char* get_write_filepath( char *filename)
{
	char *media_path = NULL;
	media_path = open_dir();
    char write_filepath[1000] = {0,};

    if(media_path)
    {

        snprintf(write_filepath,1000,"%s-%s",media_path,filename);
    }

    return write_filepath;
}

void open_all_files(){
	fpAccl = fopen(get_write_filepath("accData.csv"), "w");
//	fpgyr = fopen(get_write_filepath("gyroData.csv"), "w");
//	fpGrav = fopen(get_write_filepath("gravityData.csv"), "w");
//	fpMag = fopen(get_write_filepath("magData.csv"), "w");
//	fpLinAccl = fopen(get_write_filepath("linAccData.csv"), "w");
//	fpRot = fopen(get_write_filepath("rotData.csv"), "w");
//	fpOri = fopen(get_write_filepath("oriData.csv"), "w");
}

/*
 * Closes all Sensor Files
 */
void close_all_files(){
	fclose(fpAccl);
//	fclose(fpgyr);
//	fclose(fpOri);
//	fclose(fpGrav);
//	fclose(fpMag);
//	fclose(fpLinAccl);
//	fclose(fpRot);
}

static void app_get_data(const char *res_file_in, char *res_path_out, int res_path_max)
{

}



//sensor event callback implementation
void sensor_event_callback(sensor_h sensor, sensor_event_s *event, void *user_data)
{
	dlog_print(DLOG_INFO, LOG_TAG, "))))))))))Emni event %f", event->values[0]);

	// Extracting application data
	sensor_type_e type = (sensor_type_e)user_data;



	char fBuffer[1000] = "";

	time_t rawtime;
	struct tm * timeinfo;

	time (&rawtime);
	timeinfo = localtime (&rawtime);

	char out [1000] = "";
	for (int i = 0; i < event->value_count; i++){
		sprintf(fBuffer, "%f,",event->values[i]);
		strcat(out, fBuffer);
	}

	strcat(out, asctime(timeinfo));
	strcat(out, "\n");

	//write to file
	if (type == SENSOR_ACCELEROMETER) {
		dlog_print(DLOG_INFO, LOG_TAG, "ACC event %f", event->values[0]);

		fputs(out, fpAccl);
	}
//	else if (type == SENSOR_GYROSCOPE) {
//		dlog_print(DLOG_INFO, LOG_TAG, "GYR event %f", event->values[0]);
//
//		fputs(out, fpgyr);
//	}

//	  	fputs(out, get_file_by_type(type));

	snprintf(fBuffer,sizeof(fBuffer),"%s,", asctime(timeinfo));

//	appdata_s* ad = (appdata_s*)user_data;
//
//
//	sensor_type_e type = SENSOR_ALL;
//	dlog_print(DLOG_INFO, LOG_TAG, "))))))))))Emni event %f", event->values[0]);
//
//
//	if((sensor_get_type(sensor, &type) == SENSOR_ERROR_NONE) && (type == SENSOR_ACCELEROMETER || type == SENSOR_MAGNETIC ||
//			type == SENSOR_GYROSCOPE || type == SENSOR_LINEAR_ACCELERATION || type == SENSOR_ROTATION_VECTOR || type == SENSOR_ORIENTATION))
//	{
//		dlog_print(DLOG_INFO, LOG_TAG, "))))))))))Emni event %f %f %f", event->values[0], event->values[1], event->values[2]);
//	}
}

bool is_supported(sensor_type_e type){
	bool b;
	sensor_is_supported(type, &b);
	return b;
}


/*
 * Add a given listener to its sensor with the interval in ms
 */
void add_listener(int index, sensor_type_e type, sensor_event_cb cb_func, void *data, int interval){
	appdata_s *ad = (appdata_s *) data;

	sensor_get_default_sensor(type,&ad->sensor[listenerSize]);
	sensor_create_listener(ad->sensor[listenerSize], &ad->listener[listenerSize]);
	sensor_listener_set_event_cb(ad->listener[listenerSize], interval, cb_func, NULL);
	sensor_listener_set_option(ad->listener[listenerSize], SENSOR_OPTION_ALWAYS_ON);
	sensor_listener_start(ad->listener[listenerSize]);
	listenerSize++;
}

/*
 * Check if sensor is avaialbe and add them to start list
 */
void startListener(void *data){
	appdata_s *ad = (appdata_s *) data;

	if (is_supported(SENSOR_ACCELEROMETER)) {
		add_listener(0,SENSOR_ACCELEROMETER, sensor_event_callback,data,40); // 20 ms = 50 hz
	}

//	if (is_supported(SENSOR_LINEAR_ACCELERATION)){
//		add_listener(1,SENSOR_LINEAR_ACCELERATION, sensor_event_callback,data,200);
//	}
//	if (is_supported(SENSOR_GYROSCOPE)){
//		add_listener(1,SENSOR_GYROSCOPE, sensor_event_callback,data,20);
//	}
//	if (is_supported(SENSOR_MAGNETIC)){
//		add_listener(5,SENSOR_MAGNETIC, sensor_event_callback,data, 200);
//	}
//	if (is_supported(SENSOR_ROTATION_VECTOR)){
//		add_listener(7,SENSOR_ROTATION_VECTOR, sensor_event_callback,data, 200);
//	}
//	if (is_supported(SENSOR_GRAVITY)){
//		add_listener(7,SENSOR_GRAVITY, sensor_event_callback,data, 200);
//	}
//	if (is_supported(SENSOR_ORIENTATION)){
//		add_listener(7,SENSOR_ORIENTATION, sensor_event_callback,data, 200);
//	}
}

/*
 * Stops/removes Sensor Listener
 */
void stopListener(void *data){
	appdata_s *ad = (appdata_s *) data;

	for (int i = 0; i < listenerSize; i++) {
		sensor_listener_stop(ad->listener[i]);
		sensor_destroy_listener(ad->listener[i]);
	}
}

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

	startListener(data);

	open_all_files();

//	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, 100, 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;

	stopListener(data);
	close_all_files();
//	//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)
{
	// Todo: add your code here.
	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);
}

Also in the tizen-manifest.xml, go to the source and paste the following:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<manifest xmlns="http://tizen.org/ns/packages" api-version="2.3.1" package="org.example.service" version="1.0.0">
    <profile name="wearable"/>
    <service-application appid="org.example.service" auto-restart="true" exec="service" multiple="false" nodisplay="true" on-boot="true" taskmanage="false" type="capp">
        <label>service</label>
        <icon>service.png</icon>
    </service-application>
    <privileges>
        <privilege>http://tizen.org/privilege/mediastorage</privilege>
    </privileges>
</manifest>

Hope this should work.

1 Like

Hi ishratjahan039
Thanks for your reply.
Ho can I create service app in Tizen studio?
I can create service app project in Visual studio but I have project_name_App.cs file not service.c.

In my tizen studio when I want to creat a native application when I choose wearable 4.0 then the item for choosing Native Application is disabled.
Also I get this error with the provided code above:

service.h file not found.

When I try to create signed package by certificate that I have created it says: fail to build package
when I want to run the project it says: ‘service.h’ file not found.
Can you help me ?

I don’t know about Tizen, but I know C and this is almost always a path error.
Headers in quotes are user created headers.

When I created the Service Template the project was created in
C:\Users{username}\workspace\Service
And service.h was created in
C:\Users{username}\workspace\Service\inc

Ron
Samsung Developer Relations