Search code examples
androidandroid-studiowear-ossensorsandroid-sensors

Random gaps while recording data on Android smartwatch


I'm using a Fossil Gen 5 smartwatch running WearOS to record sensor data from Accelerometer, Gyroscope (32 Hz) and PPG sensor (64 Hz). I'm using a unique bufferedWriter object for each sensor to write data to a .txt file as each sensor event is created (shown below):

void registerSensor(){

    Log.i(TAG,"Sensor Registered");

    try {
        accWriter = new BufferedWriter(new FileWriter(accFile, true));
        gyrWriter = new BufferedWriter(new FileWriter(gyrFile, true));
        ppgWriter = new BufferedWriter(new FileWriter(ppgFile, true));
    } catch (IOException e) {
        e.printStackTrace();
    }

    //just in case
    if (sensorManager == null)
        sensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);

    listener = new SensorEventListener() {
        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {}
        @Override
        public void onSensorChanged(SensorEvent event) {

            switch (event.sensor.getType()) {
                case 65572:
                    String msg1 = "Recording PPG";
                    mData1.setText(msg1);
                    ppgTime = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000L;
                    try {
                        ppgWriter.write(ppgTime + ", " + event.values[0] + ", " + ambient + "\n");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;

                case Sensor.TYPE_ACCELEROMETER:
                    String msg2 = "Recording ACC";
                    mData2.setText(msg2);
                    accTime = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000L;
                    try {
                        accWriter.write(accTime + ", " + df.format(event.values[0]) + ", " + df.format(event.values[1]) + ", " + df.format(event.values[2]) + ", " + ambient + "\n");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;

                case Sensor.TYPE_GYROSCOPE:
                    String msg3 = "Recording GYR";
                    mData3.setText(msg3);
                    gyrTime = System.currentTimeMillis() + (event.timestamp - SystemClock.elapsedRealtimeNanos()) / 1000000L;
                    try {
                        gyrWriter.write(gyrTime + ", " + df.format(event.values[0]) + ", " + df.format(event.values[1]) + ", " + df.format(event.values[2]) + ", " + ambient + "\n");
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    };
    sensorManager.registerListener(listener, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),31250); // SensorManager.SENSOR_DELAY_FASTEST);
    sensorManager.registerListener(listener, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), 31250);
    sensorManager.registerListener(listener, sensorManager.getDefaultSensor(65572), 15625);

}

I expect the sampling frequency to hover around the intended value. But I'm getting random missing data chunks of ~ 60 s in all 3 sensor streams.

Please see this image that visually describes the issue (I'm not able to embed images yet)

I've tested this a number of times, with the same result. I thought some events might be dropped, so I tried writing all the data to a String and then writing the String to a file after a certain size is exceeded. This didn't solve the issue.

Any help or suggestions are greatly appreciated! Excuse my etiquette as I'm new to StackOverflow.


Solution

  • If the samples are being dropped when the screen is off you need to use wakeup sensors. You can do that by passing true to sensorManager.registerListener. And according to the doc, the sampling frequency is only a hint to the os.