Vivoactive 5 Gyroscope

Hi everyone,

I'm working on an app that requires high-frequency sensor data logging for sports analysis (specifically, my goal is badminton stroke detection). I have encountered a significant and specific issue related to the Garmin vivoactive 5 watch.

The Issue

I am attempting to record and access Accelerometer and Gyroscope data using the SensorLogger class, and confirming the data stream using Sensor.registerSensorDataListener.

On the vivoactive 5, the Gyroscope data stream is consistently unavailable, returning null in the sensorData callback, while the Accelerometer data is always delivered successfully.

Key Observation (Cross-Device Test)

To rule out code errors, I used the Connect IQ simulator across multiple generations of the vívoactive line for a direct comparison, yielding the following results:

  • vivoactive 4: Accelerometer data stream works. Gyroscope data stream works.

  • vivoactive 5: Accelerometer data stream works. Gyroscope data stream FAILS / returns NULL.

  • vivoactive 6: Accelerometer data stream works. Gyroscope data stream works.

This strongly suggests an issue specific to the vivoactive 5 firmware or its sensor hub driver implementation that is preventing high-frequency Gyroscope data from being exposed to third-party CIQ apps, even though the sensor is physically present on the device.

The Test Code Used

import Toybox.Sensor;

class TestLogger
{
    private var _samplesX = null;
    private var _sampleGyroX = null;

    public function enableAccel() as Void {
        // var maxSampleRate = Sensor.getMaxSampleRate();

         var options = {
            :period => 1, 
            :accelerometer => {
                :enabled => true, 
                :sampleRate => 25
            },
            :gyroscope => { 
                :enabled => true,
                :sampleRate => 25
            }
        };
        try {
            Sensor.registerSensorDataListener(method(:accelHistoryCallback), options);
        }
        catch(e) {
            System.println(e.getErrorMessage());
        }


        System.println( "TestLogger started success." );
    }

    public function accelHistoryCallback(sensorData as SensorData) as Void {
        if (sensorData.accelerometerData != null) {
            _samplesX = sensorData.accelerometerData.x;
            System.println("Raw samples, X axis: " + _samplesX);
        } else {
            System.println("Accelerometer Data is NULL.");
        }
        
        if (sensorData.gyroscopeData != null) { 
            _sampleGyroX = sensorData.gyroscopeData.x;
            System.println("Raw samples Gyro, X axis: " + _sampleGyroX);
        } else {
            System.println("Gyroscope Data is NULL. Cannot be accessed.");
        }
    }

    public function disableAccel() as Void {
        Sensor.unregisterSensorDataListener();
    }
}

Request for Resolution

Could the Garmin team please confirm if the high-frequency Gyroscope data stream is intentionally restricted on the vivoactive 5 for Connect IQ applications (API Gating) ? 

Thank you for your time and assistance.

  • Unclear if you only experience this in the simulator or also on real device?

  • Hi flocsy, 

    I experience this both in the simulator and on the real device. 

    I use this very simple app on the real device to record the accelerometer and gyroscope data. 

    import Toybox.Application;
    import Toybox.Lang;
    import Toybox.WatchUi;
    import Toybox.System;
    
    
    using Toybox.Sensor;
    
    
    
    class AccGyroLoggerApp extends Application.AppBase {
    
        private var _testLogger = null;
        // private var _logger as LoggingController;
    
        function initialize() {
            AppBase.initialize();
            _testLogger = new TestLogger();
            // _logger = new LoggingController();
        }
    
        // onStart() is called on application start up
        function onStart(state as Dictionary?) as Void {
            _testLogger.enableAccel();
            // _logger.startLogging();
        }
    
        // onStop() is called when your application is exiting
        function onStop(state as Dictionary?) as Void {
            _testLogger.disableAccel();
            // _logger.stopLogging();
            // _logger.saveLogging();
        }
    
        // Return the initial view of your application here
        function getInitialView() as [Views] or [Views, InputDelegates] {
            return [ new AccGyroLoggerView(), new AccGyroLoggerDelegate() ];
        }
    
    }
    
    function getApp() as AccGyroLoggerApp {
        return Application.getApp() as AccGyroLoggerApp;
    }
    
    
    

    And here is the LoggingController class. 

    import Toybox.SensorLogging;
    using Toybox.ActivityRecording;
    
    class LoggingController {
        private var _logger as SensorLogger;
        private var _session as ActivityRecording.Session;
    
        public function initialize() {
            var _sensorLoggerOptions = {:accelerometer => {:enabled => true}, :gyroscope => {:enabled => true}, :synchronous => true};
            _logger = new SensorLogging.SensorLogger(_sensorLoggerOptions);
            var _activityRecordingOptions = {:name=>"Generic",                        
                                             :sport=>Activity.SPORT_GENERIC,          
                                             :subSport=>Activity.SUB_SPORT_GENERIC,
                                             :sensorLogger => _logger};
            _session = ActivityRecording.createSession(_activityRecordingOptions);
        }
    
        public function startLogging() {
            _session.start();
        }
    
        public function stopLogging() {
            _session.stop();
        }
    
        public function saveLogging() {
            _session.save();
        }
    }

    For some reason, I only get the accelerometer data, when opening the .fit files from the recorded activities. 

    Do you have a suggestion what could be wrong? Is something about the LoggingController wrong or do I have to set some permissions somewhere? 

    Thank you for your insights.